[Python-checkins] r42317 - peps/trunk/pep-0338.txt

nick.coghlan python-checkins at python.org
Sat Feb 11 15:18:13 CET 2006


Author: nick.coghlan
Date: Sat Feb 11 15:18:13 2006
New Revision: 42317

Modified:
   peps/trunk/pep-0338.txt
Log:
Don't try to hide exec's quirks


Modified: peps/trunk/pep-0338.txt
==============================================================================
--- peps/trunk/pep-0338.txt	(original)
+++ peps/trunk/pep-0338.txt	Sat Feb 11 15:18:13 2006
@@ -8,7 +8,7 @@
 Content-Type: text/x-rst
 Created: 16-Oct-2004
 Python-Version: 2.5
-Post-History: 8-Nov-2004, 11-Feb-2006
+Post-History: 8-Nov-2004, 11-Feb-2006, 12-Feb-2006
 
 
 Abstract
@@ -142,36 +142,25 @@
 ``run_module`` is only one of a number of functions ``runpy`` exposes to
 make it easier to run Python code dynamically. The proposed functions
 are listed below (the descriptions are taken from the proposed
-documenation).
+documentation).
 
-``run_code(code[, globals])``
+``run_code(code[, globals][, locals])``
 
     Execute the supplied Python code object or string of source code and
-    return the resulting module globals dictionary. If supplied, the
-    optional globals dictionary is used as the module globals.
-    Otherwise, a new dictionary is used.
-    The special variable ``__builtins__`` in the globals dictionary is
-    automatically initialised with a reference to the top level
-    namespace of the ``__builtin__`` module. 
+    return the resulting locals dictionary.
 
-``run_function_code(code[, globals][, locals])``
+    The optional ``globals`` argument may be used to specify the
+    dictionary to use as the ``globals()`` dictionary when running the
+    code. If the argument is omitted, a new dictionary is used.
+
+    The ``locals`` argument may be used to specify the
+    dictionary to use as the ``locals()`` dictionary when running the
+    code. If it is omitted, the same dictionary is used as is used for
+    ``globals()``.
 
-    Execute the supplied function code object and return a tuple
-    containing the resulting globals and locals dictionaries. If
-    supplied, the optional globals dictionary is used as the module
-    globals. Otherwise, a new dictionary is used. Similarly, if
-    supplied, the optional locals dictionary is used as the function
-    locals. Otherwise, a new dictionary is used.
-
-    As for ``run_code()`` the special variable ``__builtins__`` in the
-    globals dictionary is automatically initialised with a reference to
-    the top level namespace of the ``__builtin__`` module.
-
-    A function code object is required, as module level Python code
-    cannot resolve names correctly when the locals and globals
-    dictionaries are not the same (specifically, new names are bound in
-    the locals dictionary, but this dictionary is not used when looking
-    up references to names at module level from inside a function). 
+    The special variable ``__builtins__`` in the globals dictionary is
+    automatically initialised with a reference to the top level
+    namespace of the ``__builtin__`` module.
 
 
 ``run_module_code(code[, init_globals][, mod_name][, mod_file]\
@@ -186,12 +175,12 @@
     variables below are defined in the supplied dictionary, those
     definitions are overridden.
 
-    The special global variables ``__name__``, ``__file__``,
-    ``__loader__`` and ``__builtins__`` are set in the globals
-    dictionary before the module code is executed. ``__name__``,
-    ``__file__``, ``__loader__`` are set based on the optional arguments
-    ``mod_name``, ``mod_file`` and ``mod_loader``. If the arguments are
-    omitted, the corresponding special variable is set to ``None``.
+    The special global variables ``__name__``, ``__file__``, and
+    ``__loader__`` are set in the globals dictionary before the module
+    code is executed. ``__name__``, ``__file__``, ``__loader__`` are
+    set based on the optional arguments ``mod_name``, ``mod_file`` and
+    ``mod_loader``. If the arguments are omitted, the corresponding
+    special variable is set to ``None``.
 
     If the argument ``as_script`` is supplied and evaluates to ``True``,
     then ``sys.argv[0]`` is updated with the value of ``mod_file``
@@ -229,6 +218,9 @@
     level function is ``run_name`` if this optional argument is supplied
     and ``None`` otherwise. 
 
+    The ``mod_loader`` argument to the lower level function is set to
+    ``None`` and the ``mod_file`` argument is set to ``filename``.
+
 ``run_compiled_file(filename[, init_globals][, run_name]\
 [, as_script])``
 
@@ -241,6 +233,9 @@
     level function is ``run_name`` if this optional argument is supplied
     and ``None`` otherwise. 
 
+    The ``mod_loader`` argument to the lower level function is set to
+    ``None`` and the ``mod_file`` argument is set to ``filename``.
+
 ``run_file(filename[, init_globals][, run_name][, as_script])``
 
     Execute the specified Python file and return the resulting module
@@ -257,6 +252,9 @@
     level function is ``run_name`` if this optional argument is supplied
     and ``None`` otherwise. 
 
+    The ``mod_loader`` argument to the lower level function is set to
+    ``None`` and the ``mod_file`` argument is set to ``filename``.
+
 
 When invoked as a script, the ``runpy`` module finds and executes the
 module supplied as the first argument.  It adjusts ``sys.argv`` by
@@ -272,46 +270,14 @@
 the ``runpy`` module. These are listed below.
 
 - the ``-m`` switch really only needs the ``run_module`` function. The
-  other six functions are included to give the module API coverage
+  other five functions are included to give the module API coverage
   of the other sources of executable Python code (strings, code objects
   source files, compiled files).
 
-- when using ``exec`` with a separate locals dictionary, name resolution
-  only works right if the code being executed was compiled expecting
-  that the locals dictionary and the globals dictionary were different.
-  Module level code, and anything compiled using ``compile()`` (such as
-  a source string passed to ``exec``) assumes that the two dictionaries
-  are the same. If they're different, references to globals from inside
-  functions aren't resolved using the locals dictionary::
-
-      >>> code = """
-      ... x = 1
-      ... print x
-      ... def f():
-      ...    print "Try to resolve x from inside a function"
-      ...    print x
-      ... f()
-      ... """
-      >>> exec code
-      1
-      Try to resolve x from inside a function
-      1
-      >>> exec code in {}
-      1
-      Try to resolve x from inside a function
-      1
-      >>> exec code in {}, {}
-      1
-      Try to resolve x from inside a function
-      Traceback (most recent call last):
-        File "<stdin>", line 1, in <module>
-        File "<string>", line 7, in <module>
-        File "<string>", line 6, in f
-      NameError: global name 'x' is not defined
-
-  Accordingly, the basic ``run_code`` function doesn't accept a locals
-  dictionary, and the ``run_function_code`` function checks that the
-  supplied code object expects locals and globals to be different.
+- no attempt is made to conceal the quirks of the exec statement when it
+  comes to executing function code objects, or attempting to reference
+  module level names from inside functions when a separate locals
+  dictionary is supplied.
 
 - The special variables ``__name__``, ``__file__`` and ``__loader__``
   are set in a module's global namespace before the module is executed.
@@ -325,9 +291,9 @@
   these variables are simply set to ``None`` when the relevant
   information cannot be determined.
 
-- Lastly, there is no special protection on the as_script argument when
-  file information is not available. This may result in ``sys.srgv[0]``
-  being set to ``None`` if file name information is not available.
+- Lastly, there is no special protection on the as_script argument.
+  This may result in ``sys.argv[0]`` being set to ``None`` if file
+  name information is not available.
 
 
 Alternatives
@@ -345,6 +311,12 @@
 ``-m`` switch -- to allow the full Python namespace to be used to
 locate modules for execution from the command line.
 
+An earlier version of this PEP included some mistaken assumption
+about the way ``exec`` handled locals dictionaries and code from
+function objects. These mistaken assumptions led to some unneeded
+design complexity which has now been removed - ``run_code`` shares all
+of the quirks of ``exec``.
+
 
 References
 ==========


More information about the Python-checkins mailing list