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 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