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")]

Consider how Annotated[Annotated[int, 1], 2] == Annotated[int, 1, 2], to preserve the 2 annotation, every annotation after the trolskgen one is kept.


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.29

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.29
File Size Uploaded Provenance
trolskgen-0.0.29.tar.gz 17.1 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 30.1 kB

Release files / trolskgen-0.0.29.tar.gz

Download URL trolskgen-0.0.29.tar.gz
Size 17.1 kB
Tags Source
SHA-256 checksum
How to use checksums
671a28855cfb71c3e2c48a258eb657a402791f91c62d40f01fd4849bdb26275a
BLAKE2b-256 checksum
How to use checksums
9032c361a8e067898acbb7b31b410cd33f1230a416fd3996e24cd5efa834b993
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.29-py3-none-any.whl

Download URL trolskgen-0.0.29-py3-none-any.whl
Size 13.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1484451248b7e7445ee260c5d95450a616a49bc0c343f4e376be0da74cb262cf
BLAKE2b-256 checksum
How to use checksums
1b51c6a351f7069e82421b62634dfbc30e9dd9496452959aac28b1e7727c972e
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.29

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.29 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