https://github.com/flyte/ast-to-xml
Converts a Python abstract source tree (AST) to an XML representation. Uses lxml to enable full XPath searching.
https://github.com/flyte/ast-to-xml
Last synced: 4 months ago
JSON representation
Converts a Python abstract source tree (AST) to an XML representation. Uses lxml to enable full XPath searching.
- Host: GitHub
- URL: https://github.com/flyte/ast-to-xml
- Owner: flyte
- License: mit
- Created: 2021-04-03T10:59:43.000Z (about 5 years ago)
- Default Branch: develop
- Last Pushed: 2025-04-03T13:21:48.000Z (about 1 year ago)
- Last Synced: 2025-10-07T05:04:27.723Z (9 months ago)
- Language: Python
- Size: 19.5 KB
- Stars: 1
- Watchers: 1
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# ast-to-xml
Converts a Python abstract source tree (AST) to an XML representation. Uses lxml to enable full XPath searching.
## Installation
```bash
pip install ast-to-xml
```
## Usage
Given the following code as `code.py`:
```python
SOME_CONSTANT = "some constant"
def a_function(arg1, arg2, kwarg1=None):
def a_subfunction(arg1, kwarg1=None):
print("Hello, World!")
class SomeClass:
def __init__(self, arg1):
self.arg1 = arg1
def a_method(self, arg1, kwarg1=None):
pass
```
Parse the code and convert to XML:
```python
import ast
from ast_to_xml import visit_node
with open("code.py") as code_file:
ast_tree = ast.parse(code_file.read())
xml_tree = visit_node(ast_tree)
```
Click to expand rendered XML
```xml
some constant
None
None
arg1
None
None
arg2
None
None
kwarg1
None
None
None
None
None
None
arg1
None
None
kwarg1
None
None
None
None
None
None
Hello, World!
None
None
None
None
None
self
None
None
arg1
None
None
None
None
arg1
None
None
None
self
None
None
arg1
None
None
kwarg1
None
None
None
None
None
None
None
None
```
You may now query `xml_tree` with xpath to get details of various sections of the Python source code:
```python
>>> # All function definitions
>>> xml_tree.xpath("//FunctionDef")
[, , , ]
>>> # Get the line numbers of the `s_subfunction` function
>>> xml_tree.xpath("./body/FunctionDef[name='a_function']/body/FunctionDef[name='a_subfunction']")[0].attrib
{'lineno': '6', 'col_offset': '4', 'end_lineno': '7', 'end_col_offset': '30'}
>>> # The above can be made simpler, since there's only one function called `a_subfunction`:
>>> xml_tree.xpath("//FunctionDef[name='a_subfunction']")[0].attrib
{'lineno': '6', 'col_offset': '4', 'end_lineno': '7', 'end_col_offset': '30'}
>>> # Get all of the methods within `SomeClass`:
>>> xml_tree.xpath("./body/ClassDef[name='SomeClass']//FunctionDef")
[, ]
```
Use the `source()`, `file_source()` and `module_source()` functions to get source code for the given xpath query:
```python
>>> source, _ = file_source("code.py", "//FunctionDef[name='a_subfunction']")[0]
>>> print(source)
def a_subfunction(arg1, kwarg1=None):
print("Hello, World!")
```
The first arguments to these three functions differ:
- `source()` - the actual code as a string
- `file_source()` - a string filesystem path to the source file
- `module_source()` - an importable module path as a string, or the improted module object itself
The second argument is always the xpath query string, and you may set `dedent=False` to preserve the indentation.