-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
Open
Labels
Description
The docs on import
statement states that
The basic import statement (no from clause) is executed in two steps:
- find a module, loading and initializing it if necessary
- define a name or names in the local namespace for the scope where the import statement occurs.
The same is also mentioned for the from ... import ...
flavor:
a reference to that value is stored in the local namespace, using the name in the as clause if it is present, otherwise using the attribute name.
If the import statement is preceded by global
or nonlocal
the assignment will be to enclosing namespace rather than the local namespace. In other words, global
and nonlocal
work as expected for both flavors of import
statements, but the documentation doesn't state this.
This has been tested on Python 3.13.5, though the same wording in the documentation can be found on 3.14 and 3.15.
def outer():
global sys, Decimal
import sys
from decimal import Decimal
os = None # Without this line there'll be SyntaxError: no binding for nonlocal 'os' found
deque = None # Same
def inner():
nonlocal os, deque
import os
from collections import deque
assert sys is not None # global bare import
assert os is not None # nonlocal bare import
assert Decimal is not None # global from import
assert deque is not None # nonlocal from import
inner()
assert sys is not None # global bare import
assert os is not None # nonlocal bare import
assert Decimal is not None # global from import
assert deque is not None # nonlocal from import
outer()
assert sys is not None # global bare import
# assert os is not None # NameError.nonlocal bare import not at module level
assert Decimal is not None # global from import (Pylance also gets this wrong, saying Decimal is unbound)
# assert deque is not None # NameError. nonlocal from import not at module level
Metadata
Metadata
Assignees
Labels
Projects
Status
Todo