You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Documentation of import statement should include binding to global and nonlocal namespaces #137337
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.
defouter():
globalsys, DecimalimportsysfromdecimalimportDecimalos=None# Without this line there'll be SyntaxError: no binding for nonlocal 'os' founddeque=None# Samedefinner():
nonlocalos, dequeimportosfromcollectionsimportdequeassertsysisnotNone# global bare importassertosisnotNone# nonlocal bare importassertDecimalisnotNone# global from importassertdequeisnotNone# nonlocal from importinner()
assertsysisnotNone# global bare importassertosisnotNone# nonlocal bare importassertDecimalisnotNone# global from importassertdequeisnotNone# nonlocal from importouter()
assertsysisnotNone# global bare import# assert os is not None # NameError.nonlocal bare import not at module level assertDecimalisnotNone# 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
It's the current namespace for the scope where it occurs. There is a current local namespace, a current global namespace, etc. The scope of the statement is used to decide where the assignment happens. I think the best thing here is to lean on "just as an assignment statement would." There's no need to repeat the scope logic everywhere an assignment happens.
I was not aware of this behavior (and am a bit curious if it worked for global names way back in 1.3, for instance). So I agree it should be properly documented, even though only relevent when the import is not at global scope. To me, the 'current namespace' is the namespace of the statement, which is the local namespace, so I prefer something like
define a name or names in the their namespace, which is the scope where the import statement occurs, unless the names are declared global or nonlocal.
define a name or names in the their namespace, which is the scope where the import statement occurs, unless the names are declared global or nonlocal.
I don't see the need to repeat how scopes work specifically for import statements. I think our best teaching approach is to highlight that an import statement is an assignment to a name, and works exactly as an assignment would in the same location.
Perhaps we can agree on:
define a name or names in the current namespace for the scope where the import statement occurs, just as an assignment statement would, including global, local, and nonlocal semantics.
Activity
nedbat commentedon Aug 3, 2025
I think we can fix this with a small change to this line:
Change it to:
serhiy-storchaka commentedon Aug 3, 2025
Is there such thing as the "current namespace"? The global namespace and the local namespace are passed to
exec()as arguments.We should look at
defandclassdefinitions. They assign a name in a similar way. They also can assign to global or nonlocal variable.nedbat commentedon Aug 3, 2025
It's the current namespace for the scope where it occurs. There is a current local namespace, a current global namespace, etc. The scope of the statement is used to decide where the assignment happens. I think the best thing here is to lean on "just as an assignment statement would." There's no need to repeat the scope logic everywhere an assignment happens.
terryjreedy commentedon Aug 4, 2025
I was not aware of this behavior (and am a bit curious if it worked for global names way back in 1.3, for instance). So I agree it should be properly documented, even though only relevent when the import is not at global scope. To me, the 'current namespace' is the namespace of the statement, which is the local namespace, so I prefer something like
nedbat commentedon Aug 4, 2025
I don't see the need to repeat how scopes work specifically for import statements. I think our best teaching approach is to highlight that an import statement is an assignment to a name, and works exactly as an assignment would in the same location.
Perhaps we can agree on:
gh-137337: Clarify import statement namespace binding (GH-144607)
[3.13] gh-137337: Clarify import statement namespace binding (GH-144607…
[3.14] gh-137337: Clarify import statement namespace binding (GH-144607…