Mailing List Archive

import * and __future__ imports
If you have a __future__ import in a script, and you import * from it in another script, the object for this future appears in the dir() of the other script, even though the __future__ import has no effect there.
% cat x.py
from __future__ import annotations
% cat y.py
from x import *

print(dir())

class D:
def f(self, a: D):
return 42

% ./python.exe y.py
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'annotations']
Traceback (most recent call last):
File "/Users/iritkatriel/src/cpython-654/y.py", line 5, in <module>
class D:
^^^^^^^^
File "/Users/iritkatriel/src/cpython-654/y.py", line 6, in D
def f(self, a: D):
^
NameError: name 'D' is not defined
I think we should change import * to exclude the __future__ import objects, and perhaps also to not show them in dir(x).   Any objections?

This came up in the discussion about https://bugs.python.org/issue26120 . See the attached PR for a technique we can use to identify those objects.
Re: import * and __future__ imports [ In reply to ]
On 28. 03. 22 15:25, Irit Katriel via Python-Dev wrote:
> If you have a __future__ import in a script, and you import * from it in
> another script, the object for this future appears in the dir() of the
> other script, even though the __future__ import has no effect there.
>
> % cat x.py
> from __future__ import annotations
>
>
> % cat y.py
> from x import *
>
> print(dir())
>
> class D:
> def f(self, a: D):
> return 42
>
> % ./python.exe y.py
> ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '*annotations*']
> Traceback (most recent call last):
> File "/Users/iritkatriel/src/cpython-654/y.py", line 5, in <module>
> class D:
> ^^^^^^^^
> File "/Users/iritkatriel/src/cpython-654/y.py", line 6, in D
> def f(self, a: D):
> ^
>
> NameError: name 'D' is not defined
>
>
> I think we should change import * to exclude the __future__ import
> objects, and perhaps also to not show them in dir(x).   Any objections?
>
> This came up in the discussion about https://bugs.python.org/issue26120
> <https://bugs.python.org/issue26120> . See the attached PR for a
> technique we can use to identify those objects.


__future__ imports are just one way to put garbage in the global
namespace. I don't think they should be handled specially.

IMO, it would be better to document the current best practice that
`import *` should only be used with modules designed for `import *` (by
setting `__all__`; carefully `del`-ing what they don't want to export
might work too but it's fragile), or when you don't care about namespace
pollution (e.g. in interactive sessions).


_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/PTYURIZ4KHKTRDKOVATUYQW55EG6YGLK/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: import * and __future__ imports [ In reply to ]
On Mon, Mar 28, 2022 at 6:29 AM Irit Katriel via Python-Dev <
python-dev@python.org> wrote:

> If you have a __future__ import in a script, and you import * from it in
> another script, the object for this future appears in the dir() of the
> other script, even though the __future__ import has no effect there.
>
> % cat x.py
> from __future__ import annotations
>
>
> % cat y.py
> from x import *
>
> print(dir())
>
> class D:
> def f(self, a: D):
> return 42
>
> % ./python.exe y.py
> ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '*annotations*']
> Traceback (most recent call last):
> File "/Users/iritkatriel/src/cpython-654/y.py", line 5, in <module>
> class D:
> ^^^^^^^^
> File "/Users/iritkatriel/src/cpython-654/y.py", line 6, in D
> def f(self, a: D):
> ^
>
> NameError: name 'D' is not defined
>
>
> I think we should change import * to exclude the __future__ import
> objects, and perhaps also to not show them in dir(x). Any objections?
>
> This came up in the discussion about https://bugs.python.org/issue26120 .
> See the attached PR for a technique we can use to identify those objects.
>

"Future" imports are special to the parser, and they may also set a flag
for the runtime to alter its behavior, but they are intentionally not
treated specially by code generation, so they are still properly imported.
However the presence of the imported thing is not used by the runtime to
determine its behavior; those flags are stored elsewhere guided by the code
generator.

I don't think there's anything to do here.

--
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*
<http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
Re: import * and __future__ imports [ In reply to ]
On Mon, Mar 28, 2022 at 4:44 PM Guido van Rossum <guido@python.org> wrote:

>
> "Future" imports are special to the parser, and they may also set a flag
> for the runtime to alter its behavior, but they are intentionally not
> treated specially by code generation, so they are still properly imported.
> However the presence of the imported thing is not used by the runtime to
> determine its behavior; those flags are stored elsewhere guided by the code
> generator.
>

Right, this is why it's confusing when the object is there for no reason
(the future import did not have any impact on the module, but the object
showed up via an import *).


>
I don't think there's anything to do here.
>

How about the suggestion in https://bugs.python.org/issue26120 ? It's about
these objects showing up in pydoc (both when the __future__ had an impact
and when it didn't - in either case it's not an interesting part of the
module's API).
Re: import * and __future__ imports [ In reply to ]
On Mon, Mar 28, 2022 at 8:52 AM Irit Katriel <iritkatriel@googlemail.com>
wrote:

>
>
> On Mon, Mar 28, 2022 at 4:44 PM Guido van Rossum <guido@python.org> wrote:
>
>>
>> "Future" imports are special to the parser, and they may also set a flag
>> for the runtime to alter its behavior, but they are intentionally not
>> treated specially by code generation, so they are still properly imported.
>> However the presence of the imported thing is not used by the runtime to
>> determine its behavior; those flags are stored elsewhere guided by the code
>> generator.
>>
>
> Right, this is why it's confusing when the object is there for no reason
> (the future import did not have any impact on the module, but the object
> showed up via an import *).
>

As Petr said, it's no more confusing than any other imported thing showing
up as a global.


> I don't think there's anything to do here.
>>
>
> How about the suggestion in https://bugs.python.org/issue26120 ? It's
> about these objects showing up in pydoc (both when the __future__ had an
> impact and when it didn't - in either case it's not an interesting part of
> the module's API).
>

If pydoc wants to filter that's up to pydoc (I'm not maintaining that).
Though really this should be keyed off `__all__`.


--
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*
<http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>