{"id":25039254,"url":"https://github.com/zerlok/astlab","last_synced_at":"2026-03-08T01:18:34.933Z","repository":{"id":273945693,"uuid":"921288840","full_name":"zerlok/astlab","owner":"zerlok","description":"A Python library for building and generating Abstract Syntax Trees (ASTs) with a simple, intuitive API.","archived":false,"fork":false,"pushed_at":"2025-03-09T12:33:11.000Z","size":137,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-24T12:04:58.653Z","etag":null,"topics":["abstract-syntax-tree","ast","codegen","codegenerator","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zerlok.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-23T17:24:00.000Z","updated_at":"2025-02-24T17:39:06.000Z","dependencies_parsed_at":null,"dependency_job_id":"c5ca18a6-97d2-4f5f-b6e9-75b24be48859","html_url":"https://github.com/zerlok/astlab","commit_stats":null,"previous_names":["zerlok/astlab"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zerlok%2Fastlab","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zerlok%2Fastlab/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zerlok%2Fastlab/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zerlok%2Fastlab/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zerlok","download_url":"https://codeload.github.com/zerlok/astlab/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248363329,"owners_count":21091334,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["abstract-syntax-tree","ast","codegen","codegenerator","python"],"created_at":"2025-02-06T02:20:28.036Z","updated_at":"2026-03-08T01:18:34.924Z","avatar_url":"https://github.com/zerlok.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# astlab\n\n[![Latest Version](https://img.shields.io/pypi/v/astlab.svg)](https://pypi.python.org/pypi/astlab)\n[![Python Supported Versions](https://img.shields.io/pypi/pyversions/astlab.svg)](https://pypi.python.org/pypi/astlab)\n[![MyPy Strict](https://img.shields.io/badge/mypy-strict-blue)](https://mypy.readthedocs.io/en/stable/getting_started.html#strict-mode-and-configuration)\n[![Test Coverage](https://codecov.io/gh/zerlok/astlab/branch/main/graph/badge.svg)](https://codecov.io/gh/zerlok/astlab)\n[![Downloads](https://img.shields.io/pypi/dm/astlab.svg)](https://pypistats.org/packages/astlab)\n[![GitHub stars](https://img.shields.io/github/stars/zerlok/astlab)](https://github.com/zerlok/astlab/stargazers)\n\n**astlab** is a Python library that provides an intuitive API for building and manipulating Abstract Syntax Trees (ASTs) to generate Python code. With **astlab**, you can easily construct Python modules, classes, functions, type aliases, and generics using a fluent API — then render them into valid, executable Python code.\n\n## Features\n\n* **Easy AST construction**: Build Python code using a fluent, structured API.\n* **Code generation**: Generate fully valid, formatted Python source without templates.\n* **Supports nested scopes \u0026 auto imports**: Create classes, methods, and nested modules with automatic import resolution.\n* **Type system support**: Define and use **type variables**, **generic classes**, and **type aliases** compatible with Python 3.9–3.14 syntax.\n* **Highly customizable**: Extend the builder model for any Python AST use case.\n\n## Installation\n\n```bash\npip install astlab\n```\n\n## Usage\n\n### Simple Example\n\n```python\nimport ast\nimport astlab\n\nwith astlab.module(\"foo\") as foo:\n    with foo.class_def(\"Bar\").dataclass() as bar:\n        bar.field_def(\"spam\", int)\n\nprint(foo.render())\nprint(ast.dump(foo.build(), indent=4))\n```\n\n#### Output\n\n```python\nimport builtins\nimport dataclasses\n\n@dataclasses.dataclass()\nclass Bar:\n    spam: builtins.int\n```\n\n---\n\n### Function Definition \u0026 Call Example\n\n```python\nimport astlab\n\nwith astlab.module(\"foo\") as foo:\n    with foo.class_def(\"Bar\") as bar:\n        with bar.method_def(\"do_stuff\").arg(\"spam\", int).returns(str) as stuff:\n            stuff.assign_stmt(\"result\", stuff.call(str).arg(stuff.attr(\"spam\")))\n            stuff.return_stmt(stuff.attr(\"result\"))\n\nprint(foo.render())\n```\n\n#### Output\n\n```python\nimport builtins\n\nclass Bar:\n\n    def do_stuff(self, spam: builtins.int) -\u003e builtins.str:\n        result = builtins.str(spam)\n        return result\n```\n\n---\n\n### Type Reference Example\n\n```python\nimport astlab\n\nwith astlab.package(\"main\") as main:\n    with main.module(\"foo\") as foo:\n        with foo.class_def(\"Bar\") as bar:\n            pass\n\n    with main.module(\"spam\") as spam:\n        with spam.class_def(\"Eggs\").inherits(bar) as eggs:\n            with eggs.method_def(\"do_stuff\").returns(bar.ref().optional()) as stuff:\n                pass\n\nprint(spam.render())\n```\n\n#### Output (python \u003e= 3.10)\n\n```python\nimport main.foo\n\nclass Eggs(main.foo.Bar):\n\n    def do_stuff(self) -\u003e main.foo.Bar | None:\n        pass\n```\n\n---\n\n### Generics and Type Variables\n\n**astlab** supports defining type variables and generic classes.\nBoth the legacy (`typing.TypeVar`) and modern (`class Node[T: int]`) syntaxes are supported depending on Python version.\n\n#### Example\n\n```python\nimport astlab\n\nwith astlab.module(\"generic\") as mod:\n    with mod.class_def(\"Node\") as node, node.type_var(\"T\").lower(int) as T:\n        node.field_def(\"value\", T)\n        node.field_def(\"parent\", node.ref().type_params(T).optional(), mod.none())\n\nprint(mod.render())\n```\n\n#### Output (python 3.10, 3.11)\n\n```python\nimport builtins\nimport typing\n\nT = typing.TypeVar('T', bound=builtins.int)\n\nclass Node(typing.Generic[T]):\n    value: T\n    parent: 'Node[T] | None' = None\n```\n\n#### Output (python 3.12, 3.13)\n\n```python\nimport builtins\nimport typing\n\nclass Node[T: builtins.int]:\n    value: T\n    parent: 'Node[T] | None' = None\n```\n\n#### Output (python ≥ 3.14)\n\n```python\nimport builtins\nimport typing\n\nclass Node[T: builtins.int]:\n    value: T\n    parent: Node[T] | None = None\n```\n\n---\n\n### Type Aliases\n\n**astlab** allows declarative creation of type aliases, including recursive and generic aliases.\nIt automatically emits valid syntax for both `typing.TypeAlias` (pre-3.12) and `type X = Y` (3.12+).\n\n#### Example\n\n```python\nimport astlab\nfrom astlab.types import predef\n\nwith astlab.module(\"alias\") as mod:\n    mod.type_alias(\"MyInt\").assign(int)\n\n    with mod.type_alias(\"Json\") as json_alias:\n        json_alias.assign(\n            json_alias.union_type(\n                None,\n                bool,\n                int,\n                float,\n                str,\n                mod.list_type(json_alias),\n                mod.dict_type(str, json_alias),\n            )\n        )\n\n    with (\n        mod.type_alias(\"Nested\") as nested_alias,\n        nested_alias.type_var(\"T\") as T,\n    ):\n        nested_alias.assign(\n            nested_alias.union_type(\n                T,\n                nested_alias.sequence_type(nested_alias.type_params(T)),\n            )\n        )\n```\n\n#### Output (python 3.10, 3.11)\n\n```python\nimport builtins\nimport typing\n\nMyInt: typing.TypeAlias = builtins.int\nJson: typing.TypeAlias = None | builtins.bool | builtins.int | builtins.float | builtins.str | builtins.list['Json'] | builtins.dict[builtins.str, 'Json']\nT = typing.TypeVar(\"T\")\nNested: typing.TypeAlias = T | typing.Sequence['Nested[T]']\n```\n\n#### Output (python 3.12, 3.13)\n\n```python\nimport builtins\nimport typing\n\ntype MyInt = builtins.int\ntype Json =  None | builtins.bool | builtins.int | builtins.float | builtins.str | builtins.list['Json'] | builtins.dict[builtins.str, 'Json']\ntype Nested[T] = T | typing.Sequence['Nested[T]']\n```\n\n#### Output (python ≥ 3.14)\n\n```python\nimport builtins\nimport typing\n\ntype MyInt = builtins.int\ntype Json =  None | builtins.bool | builtins.int | builtins.float | builtins.str | builtins.list[Json] | builtins.dict[builtins.str, Json]\ntype Nested[T] = T | typing.Sequence[Nested[T]]\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzerlok%2Fastlab","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzerlok%2Fastlab","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzerlok%2Fastlab/lists"}