Skip to main content

Human-oriented abstract syntax tree (AST) parser/unparser for Python 3 that doesn’t discard comments.

package version from PyPI build status from Travis CI build status from AppVeyor grade from Codacy test coverage from Codecov license

This package provides new AST node types (Comment and Directive) which inherit from nodes in typed_ast.ast3 module. Additionally, it provides implementation of parser and unparser for the extended AST allowing straightforward readable code generation.

Simple example of how to use this package:

from horast import parse, unparse

tree = parse("""a = 1  # a equals one after this""")
print(unparse(tree))
# this will print the code with original comment

More examples in examples.ipynb.

technical details

Parser is based on built-in tokenize module, as well as community packages asttokens and typed_ast.

Unparser is essentially an extension of Unparser class from static_typing package.

Nodes provided and handled by horast are listed below.

Comment

Full line as well as end-of-line comments are parsed/unparsed correctly when they are outside of multi-line expressions.

Currently, handling of comments within multi-line expressions is implemented only partially.

BlockComment

Not implemented yet.

This node type is intended to store consecutive full-line comments in a single AST node, therefore simplifying handling of large blocks of comments.

Directive

Since Python doesn’t offer a direct way to convey directives in code, comments beginning with any of the following prefixes will not be classified as typical comments, but as directives:

  • if

  • else

  • endif

  • def

  • undef

  • ifdef

  • ifndef

However in Python code they still remain as usual comments.

For example, the comments in the following code will all be classified as directives.

#ifdef DEBUG
debugging = True
#else
debugging = False
#fi

However, when executed as Python, debugging will always end up False because directives are preserved as usual comments in Python and therefore they are ignored.

Therefore, the Directive node is not meant to enable preprocessing of Python, at least for now.

Note: the prefix is checked exactly. See the following example:

#if something
# if some other thing

The comment in the first line will become Directive object, while the one on the second like will become Comment object.

Currently, this node is meant to work towards AST compatibility between Python and other languages, to aide code generation from Python AST into code in other languages – one such use case is *transpyle* project.

Pragma

Pragma nodes follow the same general rules as Directive nodes, i.e. they are stored in Python code as comments, but a comment will be classified as a pragma when it’s prefixed with a predefined prefix:

  • " pragma:"

Additionally, two subclasses of Pragma are defined in horast, each with its own prefix that builds upon the generic pragma prefix:

  • OpenMpPragma class defines prefix " pragma: omp" and stores OpenMP pragmas.

  • OpenAccPragma class defines prefix " pragma: acc" and stores OpenACC pragmas.

A code snippet below contains all 3 pragma types.

# pragma: once
use_openmp = True
use_openacc = True
...
a, b = np.ndarray(...)
c = np.zeros(...)
# pragma: acc parallel copyin(a,b) copyout(c)
# pragma: acc loop gang
for y in range(ymax): # type: np.int32
    # pragma: acc loop worker
    for i in range(imax): # type: np.int32
        # pragma: acc loop vector reduction(+: c[y][x])
        for x in range(xmax): # type: np.int32
            c[y, x] += a[y, i] * b[i, x]
# pragma: acc end parallel
...
# pragma: omp parallel do
for i in range(input_data.size):  # type: int
    # here we compute spam spam spam
    heavy_compute(input_data[i])
...

And thus, in the example above:

  • all comments starting with " pragma: omp" become OpenMpPragma objects,

  • all comments starting with " pragma: acc" become OpenAccPragma objects,

  • all other comments starting with " pragma:" become Pragma objects,

  • type comments are ignored, and

  • all other comments become Comment objects.

Additionally, horast module provides an extensible infrastructure to define custom Pragma subclasses, enabling user to define their own pragmas for experimentation. The provided OpenMP and OpenACC pragma definitions serve as examples of how to use this feature.

Include

Similarly to how pragmas are handled, if a comment begins with " include:" prefix, it will be classified as a special kind of include directive.

Again, this will be preserved as comment in Python code, but it’s useful for enhancing syntactic compatibility between Python and other, especially statically compiled languages.

requirements

CPython 3.5 or later.

Python libraries as specified in requirements.txt.

Building and running tests additionally requires packages listed in test_requirements.txt.

Metadata

Release files for horast-rereleased 0.4.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for horast-rereleased 0.4.3
File Size Uploaded Provenance
horast-rereleased-0.4.3.tar.gz 29.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for horast-rereleased 0.4.3
File Interpreter ABI Platform
horast_rereleased-0.4.3-py3-none-any.whl Python 3 none any Details

Total release size: 51.3 kB

Release files / horast-rereleased-0.4.3.tar.gz

Download URL horast-rereleased-0.4.3.tar.gz
Size 29.8 kB
Tags Source
SHA-256 checksum
How to use checksums
babd547a19588d103640390496c7433f0831e34e811baa0e42fee98b37b00673
BLAKE2b-256 checksum
How to use checksums
fc9bb3a6fb804b6bce74e0bc9b3b4c3ca234b95d91da4d09e8ca644672979e40
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.2.0 pkginfo/1.6.0 requests/2.24.0 setuptools/50.3.0 requests-toolbelt/0.9.1 tqdm/4.50.2 CPython/3.8.6

Release files / horast_rereleased-0.4.3-py3-none-any.whl

Download URL horast_rereleased-0.4.3-py3-none-any.whl
Size 21.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d92cc6142a9b0d5f67c3b8964529b3c88e12b1790699fde9c6592deb74fab149
BLAKE2b-256 checksum
How to use checksums
02fc9c0b1ba86b1a0f7df0e7c0d02f9cbb4ee7f407d4512b1493ed7f7ee581c0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.2.0 pkginfo/1.6.0 requests/2.24.0 setuptools/50.3.0 requests-toolbelt/0.9.1 tqdm/4.50.2 CPython/3.8.6

Security for horast-rereleased 0.4.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page