PEP 329: Resolve uses of the default role (#3372)
This commit is contained in:
parent
c946ae0bbb
commit
0737e8b5cd
26
pep-0329.txt
26
pep-0329.txt
|
@ -49,14 +49,14 @@ of performance.
|
||||||
There are currently over a hundred instances of ``while 1`` in the
|
There are currently over a hundred instances of ``while 1`` in the
|
||||||
library. They were not replaced with the more readable ``while True``
|
library. They were not replaced with the more readable ``while True``
|
||||||
because of performance reasons (the compiler cannot eliminate the test
|
because of performance reasons (the compiler cannot eliminate the test
|
||||||
because `True` is not known to always be a constant). Conversion of
|
because ``True`` is not known to always be a constant). Conversion of
|
||||||
True to a constant will clarify the code while retaining performance.
|
True to a constant will clarify the code while retaining performance.
|
||||||
|
|
||||||
Many other basic Python operations run much slower because of global
|
Many other basic Python operations run much slower because of global
|
||||||
lookups. In try/except statements, the trapped exceptions are
|
lookups. In try/except statements, the trapped exceptions are
|
||||||
dynamically looked up before testing whether they match.
|
dynamically looked up before testing whether they match.
|
||||||
Similarly, simple identity tests such as ``while x is not None``
|
Similarly, simple identity tests such as ``while x is not None``
|
||||||
require the `None` variable to be re-looked up on every pass.
|
require the ``None`` variable to be re-looked up on every pass.
|
||||||
Builtin lookups are especially egregious because the enclosing global
|
Builtin lookups are especially egregious because the enclosing global
|
||||||
scope must be checked first. These lookup chains devour cache space
|
scope must be checked first. These lookup chains devour cache space
|
||||||
that is best used elsewhere.
|
that is best used elsewhere.
|
||||||
|
@ -69,7 +69,7 @@ Proposal
|
||||||
========
|
========
|
||||||
|
|
||||||
Add a module called codetweaks.py which contains two functions,
|
Add a module called codetweaks.py which contains two functions,
|
||||||
`bind_constants()` and `bind_all()`. The first function performs
|
``bind_constants()`` and ``bind_all()``. The first function performs
|
||||||
constant binding and the second recursively applies it to every
|
constant binding and the second recursively applies it to every
|
||||||
function and class in a target module.
|
function and class in a target module.
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ the end of the script::
|
||||||
codetweaks.bind_all(sys.modules[__name__])
|
codetweaks.bind_all(sys.modules[__name__])
|
||||||
|
|
||||||
In addition to binding builtins, there are some modules (like
|
In addition to binding builtins, there are some modules (like
|
||||||
`sre_compile`) where it also makes sense to bind module variables
|
``sre_compile``) where it also makes sense to bind module variables
|
||||||
as well as builtins into constants.
|
as well as builtins into constants.
|
||||||
|
|
||||||
|
|
||||||
|
@ -97,17 +97,17 @@ Questions and Answers
|
||||||
|
|
||||||
Every function has attributes with its bytecodes (the language of
|
Every function has attributes with its bytecodes (the language of
|
||||||
the Python virtual machine) and a table of constants. The bind
|
the Python virtual machine) and a table of constants. The bind
|
||||||
function scans the bytecodes for a `LOAD_GLOBAL` instruction and
|
function scans the bytecodes for a ``LOAD_GLOBAL`` instruction and
|
||||||
checks to see whether the value is already known. If so, it adds
|
checks to see whether the value is already known. If so, it adds
|
||||||
that value to the constants table and replaces the opcode with
|
that value to the constants table and replaces the opcode with
|
||||||
`LOAD_CONSTANT`.
|
``LOAD_CONSTANT``.
|
||||||
|
|
||||||
3. When does it work?
|
3. When does it work?
|
||||||
|
|
||||||
When a module is imported for the first time, python compiles the
|
When a module is imported for the first time, python compiles the
|
||||||
bytecode and runs the binding optimization. Subsequent imports
|
bytecode and runs the binding optimization. Subsequent imports
|
||||||
just re-use the previous work. Each session repeats this process
|
just re-use the previous work. Each session repeats this process
|
||||||
(the results are not saved in `pyc` files).
|
(the results are not saved in ``pyc`` files).
|
||||||
|
|
||||||
4. How do you know this works?
|
4. How do you know this works?
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ Questions and Answers
|
||||||
5. What if the module defines a variable shadowing a builtin?
|
5. What if the module defines a variable shadowing a builtin?
|
||||||
|
|
||||||
This does happen. For instance, True can be redefined at the module
|
This does happen. For instance, True can be redefined at the module
|
||||||
level as `True = (1==1)`. The sample implementation below detects the
|
level as ``True = (1==1)``. The sample implementation below detects the
|
||||||
shadowing and leaves the global lookup unchanged.
|
shadowing and leaves the global lookup unchanged.
|
||||||
|
|
||||||
6. Are you the first person to recognize that most global lookups are for
|
6. Are you the first person to recognize that most global lookups are for
|
||||||
|
@ -130,22 +130,22 @@ Questions and Answers
|
||||||
implementations?
|
implementations?
|
||||||
|
|
||||||
Either do this before importing a module, or just reload the
|
Either do this before importing a module, or just reload the
|
||||||
module, or disable `codetweaks.py` (it will have a disable flag).
|
module, or disable ``codetweaks.py`` (it will have a disable flag).
|
||||||
|
|
||||||
8. How susceptible is this module to changes in Python's byte coding?
|
8. How susceptible is this module to changes in Python's byte coding?
|
||||||
|
|
||||||
It imports `opcode.py` to protect against renumbering. Also, it
|
It imports ``opcode.py`` to protect against renumbering. Also, it
|
||||||
uses `LOAD_CONST` and `LOAD_GLOBAL` which are fundamental and have
|
uses ``LOAD_CONST`` and ``LOAD_GLOBAL`` which are fundamental and have
|
||||||
been around forever. That notwithstanding, the coding scheme could
|
been around forever. That notwithstanding, the coding scheme could
|
||||||
change and this implementation would have to change along with
|
change and this implementation would have to change along with
|
||||||
modules like `dis` which also rely on the current coding scheme.
|
modules like ``dis`` which also rely on the current coding scheme.
|
||||||
|
|
||||||
9. What is the effect on startup time?
|
9. What is the effect on startup time?
|
||||||
|
|
||||||
I could not measure a difference. None of the startup modules are
|
I could not measure a difference. None of the startup modules are
|
||||||
bound except for warnings.py. Also, the binding function is very
|
bound except for warnings.py. Also, the binding function is very
|
||||||
fast, making just a single pass over the code string in search of
|
fast, making just a single pass over the code string in search of
|
||||||
the `LOAD_GLOBAL` opcode.
|
the ``LOAD_GLOBAL`` opcode.
|
||||||
|
|
||||||
|
|
||||||
Sample Implementation
|
Sample Implementation
|
||||||
|
|
Loading…
Reference in New Issue