Last active
November 16, 2015 23:18
-
-
Save kawa-kokosowa/3900761c601568f5ac1e to your computer and use it in GitHub Desktop.
Retreive __version__ from a package's __init__.py, without executing or using regular expressions.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Demo the ability to use Abstract Syntax Trees to | |
retrieve the value of __version__ from a package's | |
__init__.py, without executing __init__.py or using | |
regular expressions. | |
Works in Python 2 and Python 3. | |
See Also: | |
* https://greentreesnakes.readthedocs.org/en/latest/tofrom.html | |
* http://eli.thegreenplace.net/2009/11/28/python-internals-working-with-python-asts/ | |
""" | |
import ast | |
class MyVisitor(ast.NodeVisitor): | |
"""This visitor traverses the nodes in an | |
__init__.py file to find the __version__. | |
This is useful particularly in setup cases | |
when you want to fetch __version__ from | |
the package __init__.py without executing it. | |
Example: | |
>>> with open('fakepkg/__init__.py') as source_file: | |
... tree = ast.parse(source_file.read()) | |
>>> visitor = MyVisitor() | |
>>> visitor.visit(tree) | |
>>> visitor.version_found | |
'0.3.0' | |
Attributes: | |
version_found (str): If __version__ assignment | |
is found, the value will be reflected here. | |
""" | |
version_found = None | |
def visit_Assign(self, node): | |
"""This function is called when a node is | |
traversed which is an ast.Assign object. | |
The ast.Assign object represents a variable | |
assignment, in the form of a list of (variable) | |
names and respective values. This is because | |
you can set multiple variables in one assignment | |
in Python. | |
>>> a, b = (1, 2) | |
>>> z = "boo!" | |
For our case, we only check the first variable | |
name available (ala note.targets[0]) and if it | |
matches "__version__" we want the assignment's | |
value (i.e., node.value.s). | |
When the __version__ is found, its value is | |
copied to the self.version_found attribute. | |
Warning: | |
This presumes __version__ is set only | |
once, it does not check global-only. | |
This means if __version__ is set twice, the | |
last value will be used for version_found. | |
""" | |
if node.targets[0].id == '__version__': | |
self.version_found = node.value.s |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment