add static type information to Python abstract syntax trees
Project description
Augument Python 3 abstract syntax trees (ASTs) with static type information.
Python is a dynamically typed programming language. However, much of typically seen Python code would work even if it was statically typed!
With this package, one can insert static type information into Python abstract syntax trees (ASTs), so assuming that given code would work if Python was statically typed, one can reason about the types in the code statically, ahead of execution.
Such augmented AST is mainly intended for analysis/consumption using other tools.
Works best with ASTs from typed_ast module, however it also works with built-in ast module.
Be advised that this is an ongoing work, and current implementation is subject to sudden changes.
Support of typed_ast will be dropped after Python 3.8 is released, as its functionality will be merged into the built-in AST parser.
How to use
You can use the static_typing module to parse the code directly using parse() function:
import static_typing as st
class MyClass:
pass
module = st.parse('def my_fun(obj: MyClass) -> MyClass: return obj')
# TODO: currently there is no public API yet
functions = module._functions
my_fun = module._functions['my_fun']
assert MyClass in my_fun._params['obj']
Or, you can augment existing AST using augment() function:
import static_typing as st
import typed_ast.ast3
module = typed_ast.ast3.parse('''def spam(): x, y, z = 'ham', 42, 3.1415 # type: str, int, float''')
module = st.augment(module)
# TODO: currently there is no public API yet
function = module._functions['spam']
assert len(function._local_vars) == 3
assert float in function._local_vars['z']
For more examples see examples.ipynb notebook.
AST manipulation
Additionally to the main features, the library contains static_typing.ast_manipulation module which contains low-level tools and building blocks allowing for:
recursive AST traversal,
AST validation,
recursive AST transformations,
AST transcribing (from typed_ast to built-in ast and vice versa) and
resolving type hints (described in detail below).
How it’s implemented
The process or static typing, which the augment() function implements, has 3 main steps:
type hint resolution,
type information combining and
AST rewriting.
Type hint resolution
In all applicable nodes, type hints are stored in fields type_comment, annotation and returns. The type hint resolver reads those fields – which themseves are either raw strings or ASTs.
It uses provided Python symbol tables to resolve type hints into actual type objects using introspection.
By default, the resolver uses only built-in symbols when called directly or through augment(). However, when called through parse() it uses globals() and locals() of the caller by default.
The resolved type hints are stored directly in the AST. Specifically, each resolved field is stored in a correspondingly named field, which is either resolved_type_comment, resolved_annotation or resolved_returns.
Thus, static type information becomes available in the AST.
Type information combining
For each AST node that might contain any name declarations, an exetended version of a node is provided. Each extended AST node has new fields that store those declared names and type information associated with each name.
These new fields store all type information from all resolved type hints within any local scope, so that a type conflict or lack of type information can be detected. Also, based on this combined information, type inference can be performed.
Specifically, new versions of following AST nodes with new fields are provided: Module, FunctionDef, ClassDef, Assign, AnnAssign, For and With. Those new versions have their names prefixed StaticallyTyped....
A list of entities for which information is gathered in those new fields follows.
For Module:
defined variables
defined functions
defined classes
For FunctionDef:
parameters and their types
return types
kind (i.e. function, instance method, class method, static method, etc.)
local variables and their types
For ClassDef:
defined methods (all together and grouped by kind)
class fields and their types
instance fields and their types
For Assign and AnnAssign:
assignment targets and their types
For For:
index variables and their types
For With:
context variables and their types
AST rewriting
The AST rewriting means replacing ordinary AST nodes listed above with their extended versions.
Requirements
Python version 3.5 or later.
Python libraries as specified in requirements.txt.
Building and running tests additionally requires packages listed in test_requirements.txt.
Tested on Linux and Windows.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file static-typing-0.2.7.tar.gz
.
File metadata
- Download URL: static-typing-0.2.7.tar.gz
- Upload date:
- Size: 38.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.7.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | bc0f8257e4f0e084ef982c8b963478731e7b0474151f420c640dd546207d8242 |
|
MD5 | 5e9a6c2bd3f0b3c710e3d0743a6b88cb |
|
BLAKE2b-256 | 12775c45db0160122b9224cc9950797a939a1fb75e57dc6e00da3e6327bf6a88 |
File details
Details for the file static_typing-0.2.7-py3-none-any.whl
.
File metadata
- Download URL: static_typing-0.2.7-py3-none-any.whl
- Upload date:
- Size: 32.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.7.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 30e300a10ecffd1008cefe36fc67a5e66a8e2a825950fcbea984f1a75bccdfca |
|
MD5 | 2b2aabf71915a6fefadc28853dcd219c |
|
BLAKE2b-256 | ff5781ca43d3c3fb3979550dc3165208f6e4828477383932694e645ec47b221e |