Add section on specific design decisions for the runpy module
This commit is contained in:
parent
d8ac0a56d0
commit
31438973ae
69
pep-0338.txt
69
pep-0338.txt
|
@ -171,7 +171,7 @@ documenation).
|
|||
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).
|
||||
up references to names at module level from inside a function).
|
||||
|
||||
|
||||
``run_module_code(code[, init_globals][, mod_name][, mod_file]\
|
||||
|
@ -265,12 +265,69 @@ and then invokes ``run_module(sys.argv[0], run_name="__main__",
|
|||
as_script=True)``.
|
||||
|
||||
|
||||
Open Issues
|
||||
===========
|
||||
Design Decisions
|
||||
================
|
||||
|
||||
- the ``-m`` switch really only needs the ``run_module`` function. The
|
||||
other six functions are merely about giving the module API coverage
|
||||
of the other sources of executable Python code.
|
||||
There were some key design decisions that influenced the development of
|
||||
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
|
||||
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.
|
||||
|
||||
- The special variables ``__name__``, ``__file__`` and ``__loader__``
|
||||
are set in a module's global namespace before the module is executed.
|
||||
As ``run_module_code`` (and the functions that use it) alter these
|
||||
values, they do **not** mutate the supplied dictionary. If they did,
|
||||
then passing ``globals()`` to any of these functions could have nasty
|
||||
side effects.
|
||||
|
||||
- Sometimes, the information needed to populate the three special
|
||||
variables simply isn't available. Rather than trying to be too clever,
|
||||
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.
|
||||
|
||||
|
||||
Alternatives
|
||||
|
|
Loading…
Reference in New Issue