diff options
author | Jeremy Hylton <jeremy@alum.mit.edu> | 2001-03-23 17:23:50 (GMT) |
---|---|---|
committer | Jeremy Hylton <jeremy@alum.mit.edu> | 2001-03-23 17:23:50 (GMT) |
commit | aa90adcfb9ed2d5bed743e18e83489930296bd25 (patch) | |
tree | d575195b2cf177bdadef96a5890617f5aeef8747 /Doc | |
parent | 7190247e0b43b5193a00239b209334aa34e70217 (diff) | |
download | cpython-aa90adcfb9ed2d5bed743e18e83489930296bd25.zip cpython-aa90adcfb9ed2d5bed743e18e83489930296bd25.tar.gz cpython-aa90adcfb9ed2d5bed743e18e83489930296bd25.tar.bz2 |
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.
Diffstat (limited to 'Doc')
-rw-r--r-- | Doc/lib/libdis.tex | 27 | ||||
-rw-r--r-- | Doc/ref/ref3.tex | 41 | ||||
-rw-r--r-- | Doc/ref/ref7.tex | 20 | ||||
-rw-r--r-- | 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. |