Skip to content

Documentation of import statement should include binding to global and nonlocal namespaces #137337

@matthewyu0311

Description

@matthewyu0311

The docs on import statement states that

The basic import statement (no from clause) is executed in two steps:

  1. find a module, loading and initializing it if necessary
  2. 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

No one assigned

    Labels

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      pFad - Phonifier reborn

      Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

      Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy