Skip to main content

trolskgen

pip install trolskgen

Easily compose types/values/string-templates/AST-nodes, then convert to source.

Codgen .to_source()
trolskgen.e(
    "foo: {t}",
    t=trolskgen.e("some.Class") | int,
)
foo: some.Class | int
trolskgen.e(
    """
    class {name}({bases:*}):
        {fields:*}
    """,
    name="Foo",
    bases=[int, list],
    fields=[
        trolskgen.e("foo: {int}", int=int),
        trolskgen.e("{field_name}: str", field_name="bar"),
    ],
)
class Foo(int, list):
    foo: int
    bar: str
trolskgen.e(
    "f({args,kwargs:*})",
    args=[],
    kwargs={"a": 1, "b": [2, 3]},
)
f(a=1, b=[2, 3])

If you want formatting, run ruff format over the output. If you want comments, sorry, instead use a docstring, some Annotated[] wizardry, or fork this library to use LibCST.

Blog post with a motivating example.

API

Building templates
trolskgen.t(s: str, **kwargs: object) -> trolskgen.templates.Template
trolskgen.e(s: str, **kwargs: object) -> trolskgen.ASTModule

trolskgen.t creates source templates. If you use the format string :*, it will splat in place - see above: {bases:*}, {fields:*}, {args,kwargs:*}

Note on Python 3.14 template strings.

From Python 3.14 upwards, there are template strings, these make trolskgen significantly more succinct.

Where previously you'd do:

name = trolskgen.t("f")
func = trolskgen.t(
    """
    def {name}():
        ...
    """,
    name=name,
)
trolskgen.to_source(func)

As of Python 3.14, you can do:

name = t"f"
func = t"""
    def {name}():
        ...
"""
trolskgen.to_source(func)

There are some if sys.version_info >= (3, 14) flags around, but it should just work come release date.


e is for "eager" - this might be preferable to use, otherwise error messages can become pretty inscrutable.



Converting to AST/source
trolskgen.to_ast(o: object, *, config: Config) -> trolskgen.ASTModule
trolskgen.to_source(o: object, *, config: Config, ruff_format: bool, ruff_line_length: int) -> str

Lower level functions to convert o into an ast.AST/str representation.

The following are special cases for the value of o:

  • ast.Module | ast.expr nodes - these just get passed straight back out.
  • trolskgen.templates.Template or string.templatelib.Template - these get parsed as Python code.

trolskgen will generate sensible ASTs, for the following types:

  • None
  • int
  • float
  • str
  • bool
  • list
  • tuple
  • dict
  • set
  • classes
  • functions
  • dt.datetime
  • dt.date
  • enum.Enum
  • decimal.Decimal
  • dataclass
  • Annotated, T | U, etc.
  • pydantic.BaseModel

If you have ruff installed, you can call with ruff_format=True.



Configuring/Overriding
__trolskgen__
__trolskgen_cls__
trolskgen.Converter
trolskgen.Config
trolskgen.Config().prepend_converter(converter: Converter, *, before: Converter | None) -> Config
trolskgen.GLOBAL_CONFIG

If you own the class, you can just add a __trolskgen__ method:

For example:

class MyInterfaceClass:
    def __trolskgen__(self, f: trolskgen.F) -> ast.Module:
        return f(trolskgen.t("MyInterfaceClass({values:*})", values=[1, 2, 3]))


trolskgen.to_source(MyInterfaceClass()) == "MyInterfaceClass(1, 2, 3)"

You can also add a __trolskgen_cls__ @classmethod:

@dataclass
class MyJustName:
    a: str

    @classmethod
    def __trolskgen_cls__(cls, f: trolskgen.F) -> ast.Module:
        return f(trolskgen.t("Foo"))


trolskgen.to_source(MyJustName("bar")) == "Foo(a='bar')"

Note that we use f to recursively call trolskgen.to_ast(...) while preserving the current Config.


You can do simple overrides with a tuple in Annotated, for example:

MySpecialInt = Annotated[int, ("__trolskgen__", "my_module.MySpecialInt")]

If you don't own the class, you can build a trolskgen.Config with a custom Converter function.

For example, if you for some reason wanted to render all ints in the form x + 1, you could:

def custom_int_converter(o: object, f: trolskgen.F) -> ast.Module | None:
    if not isinstance(o, int):
        return None
    return f(trolskgen.t(f"{o - 1} + 1"))


config = trolskgen.Config().prepend_converter(custom_int_converter)
trolskgen.to_source([6, 9], config=config) == "[5 + 1, 8 + 1]"

You can also set a global trolskgen.GLOBAL_CONFIG ContextVar.

with trolskgen.GLOBAL_CONFIG.set(config):
    trolskgen.to_source([6, 9]) == "[5 + 1, 8 + 1]"

Metadata

Release files for trolskgen 0.0.28

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

Source distribution (sdist)

Source distribution for trolskgen 0.0.28
File Size Uploaded Provenance
trolskgen-0.0.28.tar.gz 16.9 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for trolskgen 0.0.28
File Interpreter ABI Platform
trolskgen-0.0.28-py3-none-any.whl Python 3 none any Details

Total release size: 29.9 kB

Release files / trolskgen-0.0.28.tar.gz

Download URL trolskgen-0.0.28.tar.gz
Size 16.9 kB
Tags Source
SHA-256 checksum
How to use checksums
81625404a41ea8f64d467769bd7678b0e1ba0b1739e318201edb81b98bb4a481
BLAKE2b-256 checksum
How to use checksums
6b4dd8a22212f0b3cc819583c07b4e35bbbaa88ee12e29933d316fdf9e6669bb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / trolskgen-0.0.28-py3-none-any.whl

Download URL trolskgen-0.0.28-py3-none-any.whl
Size 12.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5547ae9bf878e75702439acf8f550d1c3ebb15a956cbeb9e029a5fd2f856efe6
BLAKE2b-256 checksum
How to use checksums
04ef30837d14a60b448d77b9a3b80111bcce8290a9c84e575da4e8735b743feb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for trolskgen 0.0.28

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.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.0.28 This release

2 release files No provenance

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