summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/reference/executionmodel.rst163
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS5
3 files changed, 107 insertions, 62 deletions
diff --git a/Doc/reference/executionmodel.rst b/Doc/reference/executionmodel.rst
index 6309e59..5dfa0d2 100644
--- a/Doc/reference/executionmodel.rst
+++ b/Doc/reference/executionmodel.rst
@@ -5,29 +5,18 @@
Execution model
***************
-.. index:: single: execution model
-
-
-.. _naming:
-
-Naming and binding
-==================
-
.. index::
+ single: execution model
pair: code; block
- single: namespace
- single: scope
-.. index::
- single: name
- pair: binding; name
+.. _prog_structure:
-:dfn:`Names` refer to objects. Names are introduced by name binding operations.
-Each occurrence of a name in the program text refers to the :dfn:`binding` of
-that name established in the innermost function block containing the use.
+Structure of a programm
+=======================
.. index:: block
+A Python program is constructed from code blocks.
A :dfn:`block` is a piece of Python program text that is executed as a unit.
The following are blocks: a module, a function body, and a class definition.
Each command typed interactively is a block. A script file (a file given as
@@ -43,43 +32,25 @@ A code block is executed in an :dfn:`execution frame`. A frame contains some
administrative information (used for debugging) and determines where and how
execution continues after the code block's execution has completed.
-.. index:: scope
-
-A :dfn:`scope` defines the visibility of a name within a block. If a local
-variable is defined in a block, its scope includes that block. If the
-definition occurs in a function block, the scope extends to any blocks contained
-within the defining one, unless a contained block introduces a different binding
-for the name. The scope of names defined in a class block is limited to the
-class block; it does not extend to the code blocks of methods -- this includes
-comprehensions and generator expressions since they are implemented using a
-function scope. This means that the following will fail::
-
- class A:
- a = 42
- b = list(a + i for i in range(10))
+.. _naming:
-.. index:: single: environment
+Naming and binding
+==================
-When a name is used in a code block, it is resolved using the nearest enclosing
-scope. The set of all such scopes visible to a code block is called the block's
-:dfn:`environment`.
+.. index::
+ single: namespace
+ single: scope
-.. index:: pair: free; variable
+.. _bind_names:
-If a name is bound in a block, it is a local variable of that block, unless
-declared as :keyword:`nonlocal`. If a name is bound at the module level, it is
-a global variable. (The variables of the module code block are local and
-global.) If a variable is used in a code block but not defined there, it is a
-:dfn:`free variable`.
+Binding of names
+----------------
.. index::
- single: NameError (built-in exception)
- single: UnboundLocalError
+ single: name
+ pair: binding; name
-When a name is not found at all, a :exc:`NameError` exception is raised. If the
-name refers to a local variable that has not been bound, an
-:exc:`UnboundLocalError` exception is raised. :exc:`UnboundLocalError` is a
-subclass of :exc:`NameError`.
+:dfn:`Names` refer to objects. Names are introduced by name binding operations.
.. index:: statement: from
@@ -99,6 +70,46 @@ this purpose (though the actual semantics are to unbind the name).
Each assignment or import statement occurs within a block defined by a class or
function definition or at the module level (the top-level code block).
+.. index:: pair: free; variable
+
+If a name is bound in a block, it is a local variable of that block, unless
+declared as :keyword:`nonlocal` or :keyword:`global`. If a name is bound at
+the module level, it is a global variable. (The variables of the module code
+block are local and global.) If a variable is used in a code block but not
+defined there, it is a :dfn:`free variable`.
+
+Each occurrence of a name in the program text refers to the :dfn:`binding` of
+that name established by the following name resolution rules.
+
+.. _resolve_names:
+
+Resolution of names
+-------------------
+
+.. index:: scope
+
+A :dfn:`scope` defines the visibility of a name within a block. If a local
+variable is defined in a block, its scope includes that block. If the
+definition occurs in a function block, the scope extends to any blocks contained
+within the defining one, unless a contained block introduces a different binding
+for the name.
+
+.. index:: single: environment
+
+When a name is used in a code block, it is resolved using the nearest enclosing
+scope. The set of all such scopes visible to a code block is called the block's
+:dfn:`environment`.
+
+.. index::
+ single: NameError (built-in exception)
+ single: UnboundLocalError
+
+When a name is not found at all, a :exc:`NameError` exception is raised.
+If the current scope is a function scope, and the name refers to a local
+variable that has not yet been bound to a value at the point where the name is
+used, an :exc:`UnboundLocalError` exception is raised.
+:exc:`UnboundLocalError` is a subclass of :exc:`NameError`.
+
If a name binding operation occurs anywhere within a code block, all uses of the
name within the block are treated as references to the current block. This can
lead to errors when a name is used within a block before it is bound. This rule
@@ -115,7 +126,41 @@ global namespace is searched first. If the name is not found there, the
builtins namespace is searched. The :keyword:`global` statement must precede
all uses of the name.
-.. XXX document "nonlocal" semantics here
+The :keyword:`global` statement has the same scope as a name binding operation
+in the same block. If the nearest enclosing scope for a free variable contains
+a global statement, the free variable is treated as a global.
+
+.. XXX say more about "nonlocal" semantics here
+
+The :keyword:`nonlocal` statement causes corresponding names to refer
+to previously bound variables in the nearest enclosing function scope.
+:exc:`SyntaxError` is raised at compile time if the given name does not
+exist in any enclosing function scope.
+
+.. index:: module: __main__
+
+The namespace for a module is automatically created the first time a module is
+imported. The main module for a script is always called :mod:`__main__`.
+
+Class definition blocks and arguments to :func:`exec` and :func:`eval` are
+special in the context of name resolution.
+A class definition is an executable statement that may use and define names.
+These references follow the normal rules for name resolution with an exception
+that unbound local variables are looked up in the global namespace.
+The namespace of the class definition becomes the attribute dictionary of
+the class. The scope of names defined in a class block is limited to the
+class block; it does not extend to the code blocks of methods -- this includes
+comprehensions and generator expressions since they are implemented using a
+function scope. This means that the following will fail::
+
+ class A:
+ a = 42
+ b = list(a + i for i in range(10))
+
+.. _restrict_exec:
+
+Builtins and restricted execution
+---------------------------------
.. index:: pair: restricted; execution
@@ -135,26 +180,20 @@ weak form of restricted execution.
:keyword:`import` the :mod:`builtins` module and modify its
attributes appropriately.
-.. index:: module: __main__
-
-The namespace for a module is automatically created the first time a module is
-imported. The main module for a script is always called :mod:`__main__`.
-
-The :keyword:`global` statement has the same scope as a name binding operation
-in the same block. If the nearest enclosing scope for a free variable contains
-a global statement, the free variable is treated as a global.
-
-A class definition is an executable statement that may use and define names.
-These references follow the normal rules for name resolution. The namespace of
-the class definition becomes the attribute dictionary of the class. Names
-defined at the class scope are not visible in methods.
-
-
.. _dynamic-features:
Interaction with dynamic features
---------------------------------
+Name resolution of free variables occurs at runtime, not at compile time.
+This means that the following code will print 42::
+
+ i = 10
+ def f():
+ print(i)
+ i = 42
+ f()
+
There are several cases where Python statements are illegal when used in
conjunction with nested scopes that contain free variables.
diff --git a/Misc/ACKS b/Misc/ACKS
index e45d95c..e2e8387 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -836,6 +836,7 @@ Christopher Tur Lesniewski-Laas
Alain Leufroy
Mark Levinson
Mark Levitt
+Ivan Levkivskyi
William Lewis
Akira Li
Xuanji Li
diff --git a/Misc/NEWS b/Misc/NEWS
index b28f5ea..337e582 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -40,6 +40,11 @@ Library
Documentation
-------------
+- Issue #24129: Clarify the reference documentation for name resolution.
+ This includes removing the assumption that readers will be familiar with the
+ name resolution scheme Python used prior to the introduction of lexical
+ scoping for function namespaces. Patch by Ivan Levkivskyi.
+
- Issue #20769: Improve reload() docs. Patch by Dorian Pula.
- Issue #23589: Remove duplicate sentence from the FAQ. Patch by Yongzhi Pan.