An open API service indexing awesome lists of open source software.

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.

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.