pylt ("Python Language Transformations") is a system for source-to-source transformations...and more.
Once one or more transforms is registered, you can simply import any module for which the source should be transformed. An import hook
You can also use transform_raw() and transform_by_inspection() to transform source directly.
A transform is a function that takes the source and the triggering tag/suffix, as well as any other keyword arguments:
some_transform(source, [tag, [suffix]], **kwargs)
Each transform will return the transformed source.
A variety of sample transforms are located in pylt.transforms.
Use register() to register a transform. It may be used as a decorator. Once a transform is registered, it will be used during import to transform the module's source if the tag and file suffix match.
- token stream (from tokenization)
- AST (from parsing)
- bytecode (from compiling)
- do string replace on source before tokenization
- do regex replace on source before tokenization
- do token replace on token stream before parsing
- do AST replace on AST before compilation
- do bytecode replacement
possible future stuff
- function to activate/deactivate pylt import hook
- other plugin systems
- transforms (catalog of "built in" transforms)
- transforms['inline_pylt'] (pragma or fake context manager, a la pwang)
- Policy (for registration collisions, etc.)
- Transform (base class) or helper functions
- warning when pylt actually changes the source
- transform type based on transform strategy (handle each differently)
- Existing AST hacks and peephole optimizer in CPython...
2 to 3
3 to 2
DSL (domain-specific languages)
- other languages to Python:
- new syntax:
- given statement (PEP 3150)
- function locals constants
- attr wrapper - obj.(name)
- implicit namespace binding - "def x.y(...):"
- conditional except clause
- python to C-ext module
- python optimizer
registration collisions/duplicate keys order constraints
activate() deactivate() is_activated() activated() (context manager) deactivated() (context manager)
register() unregister() is_registered() registered() (context manager) unregistered() (context manager)
possible approaches for "inlined" transforms
- applies to the block (with the "with" clause removed and proper indent)
- with pylt.transformed(tag, sufficx, ...):
- applies to the block (with proper indentation)
- # pylt: tag, suffix, ...
- applies just to the statement:
- # pylt: tag, suffix, ... <statement>
- clean up docs/wiki/source/etc. and make them consistent
- create the sample transforms (with tests)
- initial release
- make compatible with Python 3.2
- backport to 2.7?