Allow import (some,list,of,modules,with,parenthesis)

Basically, I think the import statement ought to accept parenthesis, just as “from blah import (a,b,c)” does.

Ie this code, which is currently a syntax error:

import (os, sys, ...
        importlib)

ought to be accepted and be equivalent to

import os, sys, ..., importlib

Currently, the workaround is to simply break this up into separate import statements, but I don’t see any benefit to forcing that split and the inconsistency with “from blah import (a,b,c)” is awkward and surprising imo. (I’ve been using python since ~2.6 and forgot that this wasn’t allowed.)

This came up tangentially last year in another thread, Parentheses in global statement , but there the discussion was more about the global/nonlocal statements and got into debates about functional need there, with not much debate centered around this proposal. Here, I’m specifically and exclusively advocating for parenthesis for the simple import statement.

I’ve searched my old emails and have searched in discourse and don’t see any discussions specifically about this topic, but if anyone is aware of any, please let me know.

Thanks

3 Likes

I don’t understand. The workaround would be to remove the unnecessary brackets. Unless perhaphs you wanted to be able to write:

import (
    os,
    sys,
    importlib,
)

Is that why you’d want this?

2 Likes

Not really sure what the point is here. If you’re wrapping it across lines anyway, why not just put the word “import” at the start of each line?

3 Likes

Yes, I want the ability to wrap my lines on multiple lines. A real example:

import functools, nose, random, collections, time, datetime, time, datetime, itertools, \
        decimal, os, re, inspect, importlib

Here, the line runs past 90 chars, which I try to prevent in my codebase. (Not slavishly, but obviously this line can’t go on forever)

As acknowledged, this could also be written:

import functools, nose, random, collections, time, datetime, time, datetime, itertools
import decimal, os, re, inspect, importlib

and with the proposal:

import (functools, nose, random, collections, time, datetime, time, datetime, itertools,
        decimal, os, re, inspect, importlib)

I personally feel the form with parenthesis is slightly more clear, though obviously it’s subjective. I also appreciate the consistency with ‘from module import (…)’.

Obviously this is not a critical omission (python is so old now, there are no critical omissions left), but why is the language better by disallowing parentheses here?

Also note that you can do this:

import os, \
       sys, \
       importlib

Because the more ways there are to do something, the more ways it will be done. There’s value in consistency.

The spirit of this suggestion seems to be “why not?” And I counter: “why?”

New syntax has a cost. It needs to be justified.

2 Likes

Taking into account that such style directly contradicts PEP 8, there is a little chance to accept this feature.

2 Likes

I feel I’ve already answered that (you can of course feel that the benefits do not outweigh the costs, but my argument is not ‘why not?’):

A) it’s slightly more readable
B) it’s more consistent with other existing syntax in the language (from W import (X, Y, Z))

Re PEP 8: I don’t understand, PEP 8 is only the style guide for cpython internal code, why is it relevant to the discussion of what is accepted syntactically? If this argument were to be taken seriously, why is the form import X, Y, Z accepted by the parser?

1 Like

I think you’ll have a slightly better argument of readability if instead of:

import (os, sys, ...
        importlib)

you put each module name/path on a separate line:

import (
    os,
    sys,
    importlib,
)

so that it’s at least as diff-friendly as the status quo.

While I agree with the consistency argument, I can see why the devs may think it would generate unnecessary churns without offering any functional benefit over the status quo of writing a separate import statement for each module.

Maybe there can be additional functionalities to justify a new syntax, such as an as clause:

import (
    os,
    sys,
    importlib,
) as _private # a simple namespace object

_private.sys.exit(0)

or maybe if the async import statement from Async imports to reduce startup times ever reaches consensus in the future, it will be more apparent that repeatedly writing async import statements:

async import os
async import sys
async import importlib

is too much clutter compared to:

async import (
    os,
    sys,
    importlib,
)

Neither is too compelling still though.

1 Like

Okay, maybe I was unfair in how I characterized your presentation. I do not feel that you’ve demonstrated the value added to be anywhere near the cost of the addition. IMO the justification you’ve given is very weak.

Every piece of code working with ast, libcst, and their ilk is potentially negatively impacted when syntax changes. So a syntax change has to “do enough” to be worth it. Some things are worth the downsides. Is this?

You cite readability. Readability needs demonstration, as it’s a largely subjective topic. You haven’t shown how the new syntax is more readable than the alternatives. I think an import per line reads just fine.

You also cite consistency with FromImport. Here I agree with you that it would be better in a perfect world for the two to align. But I view it as a pretty minor and unimportant inconsistency.

If the change didn’t have any cost, I’d be completely neutral towards it. I wouldn’t use the style, others would, and that would be fine. But it’s not 0 cost. If I’m going to have to do a bunch of maintenance on all of my linters and formatting tools, I’d like it to be well justified.

3 Likes

Well, that is hardly a good argument: if this syntax ever comes true, Pep 8 would likely be accommodated for this to be the preferred way to do it, since it implies in the same readability of one import per line, without the repetition of the import keyword)

1 Like

Yes, being able to write imports this way seens nice enough.
Importing a tuple doesn’t make sense anyway, so there is no syntax ambiguity or conflict.