PEP 329: Resolve uses of the default role (#3372)

This commit is contained in:
Adam Turner 2023-09-01 20:19:00 +01:00 committed by GitHub
parent c946ae0bbb
commit 0737e8b5cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 13 additions and 13 deletions

View File

@ -49,14 +49,14 @@ of performance.
There are currently over a hundred instances of ``while 1`` in the
library. They were not replaced with the more readable ``while True``
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.
Many other basic Python operations run much slower because of global
lookups. In try/except statements, the trapped exceptions are
dynamically looked up before testing whether they match.
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
scope must be checked first. These lookup chains devour cache space
that is best used elsewhere.
@ -69,7 +69,7 @@ Proposal
========
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
function and class in a target module.
@ -80,7 +80,7 @@ the end of the script::
codetweaks.bind_all(sys.modules[__name__])
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.
@ -97,17 +97,17 @@ Questions and Answers
Every function has attributes with its bytecodes (the language of
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
that value to the constants table and replaces the opcode with
`LOAD_CONSTANT`.
``LOAD_CONSTANT``.
3. When does it work?
When a module is imported for the first time, python compiles the
bytecode and runs the binding optimization. Subsequent imports
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?
@ -117,7 +117,7 @@ Questions and Answers
5. What if the module defines a variable shadowing a builtin?
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.
6. Are you the first person to recognize that most global lookups are for
@ -130,22 +130,22 @@ Questions and Answers
implementations?
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?
It imports `opcode.py` to protect against renumbering. Also, it
uses `LOAD_CONST` and `LOAD_GLOBAL` which are fundamental and have
It imports ``opcode.py`` to protect against renumbering. Also, it
uses ``LOAD_CONST`` and ``LOAD_GLOBAL`` which are fundamental and have
been around forever. That notwithstanding, the coding scheme could
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?
I could not measure a difference. None of the startup modules are
bound except for warnings.py. Also, the binding function is very
fast, making just a single pass over the code string in search of
the `LOAD_GLOBAL` opcode.
the ``LOAD_GLOBAL`` opcode.
Sample Implementation