[Python-ideas] PEP 511: Add a check function to decide if a "language extension" code transformer should be used or not
Petr Viktorin
encukou at gmail.com
Wed Jan 27 11:36:47 EST 2016
On 01/27/2016 04:39 PM, Victor Stinner wrote:
> Hi,
>
> Thank you for all feedback on my PEP 511. It looks like the current
> blocker point is the unclear status of "language extensions": code
> tranformers which deliberately changes the Python semantics. I would
> like to discuss how we should register them. I think that the PEP 511
> must discuss "language extensions" even if it doesn't have to propose
> a solution to make their usage easier. It's an obvious usage of code
> transformers. If possible, I would like to find a compromise to
> support them, but make it explicit that they change the Python
> semantics.
>
> By the way, I discussed with Joseph Jevnik who wrote codetransformer
> (bytecode transformer) and lazy_python (AST transformer). He wrote me:
>
> "One concern that I have though is that transformers are registered
> globally. I think that the decorators in codetransformer do a good job
> of signalling to reader the scope of some new code generation."
>
>
> Currently, the PEP 511 doesn't provide a way to register a code
> transformer but only use it under some conditions. For example, if
> fatoptimizer is registered, all .pyc files will be called
> file.cpython-36.fat-0.pyc even if fatoptimizer was disabled.
>
> I propose to change the design of sys.set_code_transformers() to use
> it more like a registry similar to the codecs registry
> (codecs.register), but different (details below). A difference is that
> the codecs registry uses a mapping (codec name => codec functions),
> whereas sys.set_code_transformers() uses an ordered sequence (list) of
> code transformers. A sequence is used because multiple code
> transformers can be applied sequentially on a single .py file.
>
>
> Petr Viktorin wrote that language extensions "target specific modules,
> with which they're closely coupled: The modules won't run without the
> transformer. And with other modules, the transformer either does
> nothing (as with MacroPy, hopefully), or would fail altogether (as
> with Hy). So, they would benefit from specific packages opting in. The
> effects of enabling them globally range from inefficiency (MacroPy) to
> failures or needing workarounds (Hy)."
>
>
> Problem (A): solutions proposed below don't make code tranformers
> mandatory. If a code *requires* a code transformer and the code
> transformer is not registered, Python doesn't complain. Do you think
> that it is a real issue in practice? For MacroPy, it's not a problem
> in practice since functions must be decorated using a decorator from
> the macropy package. If importing macropy fails, the module cannot be
> imported.
>
>
> Problem (B): proposed solutions below adds markers to ask to enable a
> specific code transformer, but a code transformer can decide to always
> modify the Python semantics without using such marker. According to
> Nick Coghlan, code transformers changing the Python semantics *must*
> require a marker in the code using them. IMHO it's the responsability
> of the author of the code transformer to use markers, not the
> responsability of Python.
I believe Nick meant that if a transformer modifies semantics of
un-marked code, it would be considered a badly written transformer that
doesn't play well with the rest of the language.
The responsibility of Python is just to make it easy to do the right thing.
> Code transformers should maybe return a flag telling if they changed
> the code or not. I prefer a flag rather than comparing the output to
> the input, since the comparison can be expensive, especially for a
> deep AST tree. Example:
>
> class Optimizer:
> def ast_optimizer(self, tree, context):
> # ...
> return modified, tree
>
> *modified* must be True if tree was modified.
What would this flag be useful for?
> There are several options to decide if a code transformer must be used
> on a specific source file.
>
>
[...]
> (2) Petr proposed to extend importlib to pass a code transformer when
> importing a module.
>
> importlib.util.import_with_transformer(
> 'mypackage.specialmodule', MyTransformer())
>
>
[...]
> (5) Nick proposed (indirectly) to use a different filename (don't use
> ".py") for language extensions.
>
> This option works with my option (2): the context contains the
> filename which can be used to decide to enable or not the code
> transformer.
>
> I understand that the code transformer must also install an importlib
> hook to search for other filenames than only .py files. Am I right?
Yes, you are. But once a custom import hook is in place, you can just
use a regular import, the hack in (2) isn't necessary.
Also, note that this would solve problem (A) -- without the hook
enabled, the source won't be found.
More information about the Python-ideas
mailing list