From aa90adcfb9ed2d5bed743e18e83489930296bd25 Mon Sep 17 00:00:00 2001
From: Jeremy Hylton <jeremy@alum.mit.edu>
Date: Fri, 23 Mar 2001 17:23:50 +0000
Subject: Add nested scopes spec to appendix.

Add new opcodes LOAD_CLOSURE, LOAD_DEREF, STORE_DEREF, MAKE_CLOSURE to
docs for dis module.

Add docs for new function and code members in Sec. 3 of ref manual.
They're present regardless of whether nested scopes are used.

Remove description of default argument hack from Sec. 7 of the ref
manual and refer the reader to the appendix.
---
 Doc/lib/libdis.tex |  27 ++++++++++++++
 Doc/ref/ref3.tex   |  41 +++++++++++++++------
 Doc/ref/ref7.tex   |  20 ++--------
 Doc/ref/refa1.tex  | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 4 files changed, 161 insertions(+), 32 deletions(-)

diff --git a/Doc/lib/libdis.tex b/Doc/lib/libdis.tex
index 7fc831a..3a274ef 100644
--- a/Doc/lib/libdis.tex
+++ b/Doc/lib/libdis.tex
@@ -556,6 +556,25 @@ Stores TOS into the local \code{co_varnames[\var{var_num}]}.
 Deletes local \code{co_varnames[\var{var_num}]}.
 \end{opcodedesc}
 
+\begin{opcodedesc}{LOAD_CLOSURE}{i}
+Pushes a reference to the cell contained in slot \var{i} of the
+cell and free variable storage.  The name of the variable is 
+\code{co_cellvars[\var{i}]} if \var{i} is less than the length of
+\var{co_cellvars}.  Otherwise it is 
+\code{co_freevars[\var{i} - len(co_cellvars)]}.
+\end{opcodedesc}
+
+\begin{opcodedesc}{LOAD_DEREF}{i}
+Loads the cell contained in slot \var{i} of the cell and free variable
+storage.  Pushes a reference to the object the cell contains on the
+stack. 
+\end{opcodedesc}
+
+\begin{opcodedesc}{STORE_DEREF}{i}
+Stores TOS into the cell contained in slot \var{i} of the cell and
+free variable storage.
+\end{opcodedesc}
+
 \begin{opcodedesc}{SET_LINENO}{lineno}
 Sets the current line number to \var{lineno}.
 \end{opcodedesc}
@@ -583,6 +602,14 @@ with the function.  The function object is defined to have \var{argc}
 default parameters, which are found below TOS.
 \end{opcodedesc}
 
+\begin{opcodedesc}{MAKE_CLOSURE}{argc}
+Creates a new function object, sets its \var{func_closure} slot, and
+pushes it on the stack.  TOS is the code associated with the function.
+If the code object has N free variables, the next N items on the stack
+are the cells for these variables.  The function also has \var{argc}
+default parameters, where are found before the cells.
+\end{opcodedesc}
+
 \begin{opcodedesc}{BUILD_SLICE}{argc}
 Pushes a slice object on the stack.  \var{argc} must be 2 or 3.  If it
 is 2, \code{slice(TOS1, TOS)} is pushed; if it is 3,
diff --git a/Doc/ref/ref3.tex b/Doc/ref/ref3.tex
index 4aa218f..c453b85 100644
--- a/Doc/ref/ref3.tex
+++ b/Doc/ref/ref3.tex
@@ -416,15 +416,20 @@ the compiled function body; \member{func_globals} is (a reference to)
 the dictionary that holds the function's global variables --- it
 defines the global namespace of the module in which the function was
 defined; \member{func_dict} or \member{__dict__} contains the
-namespace supporting arbitrary function attributes.
+namespace supporting arbitrary function attributes;
+\member{func_closure} is \code{None} or a tuple of cells that contain
+binding for the function's free variables.
 
-Of these, \member{func_code}, \member{func_defaults},
+Of these, \member{func_code}, \member{func_defaults}, \member{func_closure},
 \member{func_doc}/\member{__doc__}, and
 \member{func_dict}/\member{__dict__} may be writable; the
-others can never be changed.
-Additional information about a function's definition can be
-retrieved from its code object; see the description of internal types
-below.
+others can never be changed.  Additional information about a
+function's definition can be retrieved from its code object; see the
+description of internal types below.
+
+In Python 2.1, the \member{func_closure} slot is always \code{None}
+unless nested scopes are enabled.  (See the appendix.)
+
 \withsubitem{(function attribute)}{
   \ttindex{func_doc}
   \ttindex{__doc__}
@@ -714,8 +719,11 @@ name; \member{co_argcount} is the number of positional arguments
 (including arguments with default values); \member{co_nlocals} is the
 number of local variables used by the function (including arguments);
 \member{co_varnames} is a tuple containing the names of the local
-variables (starting with the argument names); \member{co_code} is a
-string representing the sequence of bytecode instructions;
+variables (starting with the argument names); \member{co_cellvars} is
+a tuple containing the names of local variables that are referenced by
+nested functions; \member{co_freevars} is a tuple containing the names
+of local variables that are neither local nor global; \member{co_code}
+is a string representing the sequence of bytecode instructions;
 \member{co_consts} is a tuple containing the literals used by the
 bytecode; \member{co_names} is a tuple containing the names used by
 the bytecode; \member{co_filename} is the filename from which the code
@@ -725,6 +733,11 @@ byte code offsets to line numbers (for details see the source code of
 the interpreter); \member{co_stacksize} is the required stack size
 (including local variables); \member{co_flags} is an integer encoding
 a number of flags for the interpreter.
+
+The \member{co_cellvars} and \member{co_freevars} are present in
+Python 2.1 when nested scopes are not enabled, but the code itself
+does not use or create cells.
+
 \withsubitem{(code object attribute)}{
   \ttindex{co_argcount}
   \ttindex{co_code}
@@ -737,16 +750,20 @@ a number of flags for the interpreter.
   \ttindex{co_names}
   \ttindex{co_nlocals}
   \ttindex{co_stacksize}
-  \ttindex{co_varnames}}
+  \ttindex{co_varnames}
+  \ttindex{co_cellvars}
+  \ttindex{co_freevars}}
 
 The following flag bits are defined for \member{co_flags}: bit
 \code{0x04} is set if the function uses the \samp{*arguments} syntax
 to accept an arbitrary number of positional arguments; bit
 \code{0x08} is set if the function uses the \samp{**keywords} syntax
 to accept arbitrary keyword arguments; other bits are used internally
-or reserved for future use.  If\index{documentation string} a code
-object represents a function, the first item in \member{co_consts} is
-the documentation string of the function, or \code{None} if undefined.
+or reserved for future use; bit \code{0x10} is set if the function was
+compiled with nested scopes enabled.  If\index{documentation string} a
+code object represents a function, the first item in
+\member{co_consts} is the documentation string of the function, or
+\code{None} if undefined.
 
 \item[Frame objects]
 Frame objects represent execution frames.  They may occur in traceback
diff --git a/Doc/ref/ref7.tex b/Doc/ref/ref7.tex
index b8fac0b..9107fe9 100644
--- a/Doc/ref/ref7.tex
+++ b/Doc/ref/ref7.tex
@@ -364,23 +364,9 @@ allows the execution of multiple statements.
 
 \strong{Programmer's note:} a ``\code{def}'' form executed inside a
 function definition defines a local function that can be returned or
-passed around.  Because of Python's two-scope philosophy, a local
-function defined in this way does not have access to the local
-variables of the function that contains its definition; the same rule
-applies to functions defined by a lambda form.  A standard trick to
-pass selected local variables into a locally defined function is to
-use default argument values, like this:
-
-\begin{verbatim}
-# Return a function that returns its argument incremented by 'n'
-def make_incrementer(n):
-    def increment(x, n=n):
-        return x+n
-    return increment
-
-add1 = make_incrementer(1)
-print add1(3)  # This prints '4'
-\end{verbatim}
+passed around.  The semantics of name resolution in the nested
+function will change in Python 2.2.  See the appendix for a
+description of the new semantics.
 
 \section{Class definitions\label{class}}
 \indexii{class}{definition}
diff --git a/Doc/ref/refa1.tex b/Doc/ref/refa1.tex
index 36a04a5..e93cf0e 100644
--- a/Doc/ref/refa1.tex
+++ b/Doc/ref/refa1.tex
@@ -145,9 +145,108 @@ Instances of class \class{_Feature} have two corresponding methods,
 
 No feature description will ever be deleted from \module{__future__}.
 
-
 \section{Nested scopes \label{nested-scopes}}
-
 \indexii{nested}{scopes}
 
-Nested scopes are left as an exercise for the reader.
+This section defines the new scoping semantics that will be introduced
+in Python 2.2.  They are available in Python 2.1 by using the future
+statement \samp{nested_scopes}.  This section begins with a bit of
+terminology. 
+
+\subsection{Definitions and rules \label{defintions}}
+
+\dfn{Names} refer to objects.  Names are introduced by name binding
+operations.  Each occurrence of a name in the program text refers to
+the binding of that name established in the innermost function block
+containing the use.
+
+A \dfn{block} is a pice of Python program text that can is executed as
+a unit.  The following are blocks: a module, a function body, and a
+class defintion.
+
+A \dfn{scope} defines the visibility of a name within a block.  If a
+local variable is defined in a block, it's 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.
+
+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}.  
+
+If a name is bound in a block, it is a local variable of that block.
+If a name is bound at the module level, it is a global variable.  (The
+ariables 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}.
+
+The name binding operations are assignment, class and function
+definition, import statements, for statements, and except statements.
+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).
+
+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.
+
+The previous rule is a subtle.  Python lacks declarations and allows
+name binding operations to occur anywhere within a code block.  The
+local variables of a code block can be determined by scanning the
+entire text of the block for name binding operations.
+
+If the global statement occurs within a block, all uses of the name
+specified in the statement refer to the binding of that name in the
+top-level namespace.  Names are resolved in the top-level namespace by
+searching the global namespace, i.e. the namespace of the module
+containing the code block, and the builtin namespace, the namespace of
+the module \module{__builtin__}.  The global namespace is searched
+first.  If the name is not found there, the builtin namespace is
+searched.  The global statement must precede all uses of the name.
+
+The 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. 
+
+\subsection{Interaction with dynamic features \label{dynamic-features}}
+
+There are several cases where Python statements are illegal when
+used in conjunction with nested scopes that contain free
+variables.
+
+If a variable is referenced in an enclosing scope, it is illegal
+to delete the name.  An error will be reported at compile time.
+
+If the wild card form of import --- \samp{import *} --- is used in a
+function and the function contains or is a nested block with free
+variables, the compiler will raise a SyntaxError.
+
+If exec is used in a function and the function contains or is a nested
+block with free variables, the compiler will raise a SyntaxError
+unless the exec explicitly specifies the local namespace for the exec.
+(In other words, "exec obj" would be illegal, but "exec obj in ns"
+would be legal.)
+
+The builtin functions \function{eval()} and \function{input()} can not
+access free variables unless the variables are also referenced by the
+program text of the block that contains the call to \function{eval()}
+or \function{input()}.
+
+\emph{Compatibility note}: The compiler for Python 2.1 will issue
+warnings for uses of nested functions that will behave differently
+with nested scopes.  The warnings will not be issued if nested scopes
+are enabled via a future statement.  If a name bound in a function
+scope and the function contains a nested function scope that uses the
+name, the compiler will issue a warning.  The name resolution rules
+will result in different bindings under Python 2.1 than under Python
+2.2.  The warning indicates that the program may not run correctly
+with all versions of Python.
-- 
cgit v0.12

