[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