Skip to main content

Use procedural macros with type annotations in Python

Project description

Typed macros in Python

Status: like really early pre-alpha

Inspired by Rust procedural macros, this package creates a macro system for Python. You can define a macro by writing a function that accepts a string of code and returns another string of code.

Your expanded macro is written to a __macro__ file in the same directory, and automatically imported.

You don't need to add another build step, just run your code as normal. As soon as it runs, your IDE and type checker will start to pass.

Note: ideally, you should load your module on every save, so that you get better IDE support when using macros. That part's sort of optional, but for my small projects, it's been handy.

Why would I want this?

Python is a dynamic language, so you can technically do anything... if you don't care about type hinting. But if you're a sane person, then you must care about type hinting, and therefore you might care about macros 😛

I like to think of Python as:

  • runtime code can talk to runtime code (normal)
  • type checking code can talk to type checking code (normal)
  • type checking code can talk to runtime code (e.g. dataclasses)
  • ...but runtime code can't talk to type hinting code

^ macros fill the gap on that last missing step

Example use cases

  • If you have a decorator that's impossible to fit with type hints (python generics are nowhere near as powerful as typescript generics, for example); make it a macro instead!
    • E.g. you want to Concatenate a kwarg to a paramspec, but it only supports positional arguments
  • If you want to modify the behavior of Python code at runtime
    • E.g. you want to build a system where if/else statements are eager evaluated rather than lazy evaluated
  • If you have some auto-generated code and you want to auto-generate some type-safe code on top of it
    • E.g. you want to add extra methods to the OpenAPI spec objects that were previously generated

Differences from Rust

  • Rust puts your code inline, this package puts it in a separate file. So you can't automatically use things from the outer scope unless you specify them in the macro.
  • Rust macros deal with syntax trees, but this package lets you parse the code yourself; sometimes the formatting of your python code could be important -- it's up to you whether you parse the AST or just do basic string manipulation.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

typed_macro-0.1.15.tar.gz (9.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

typed_macro-0.1.15-py3-none-any.whl (11.1 kB view details)

Uploaded Python 3

File details

Details for the file typed_macro-0.1.15.tar.gz.

File metadata

  • Download URL: typed_macro-0.1.15.tar.gz
  • Upload date:
  • Size: 9.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.1

File hashes

Hashes for typed_macro-0.1.15.tar.gz
Algorithm Hash digest
SHA256 b61c9a282b37f6700d8ad0b9a84a4f4259b5b1d5e283b3cb2eb9228de60deb4a
MD5 6d77ae1ff7783b702e0dab781009248a
BLAKE2b-256 7f775a4faf5c0ab4a3793d56e4415ee7c0317f4e5fc0021e2d86506a9a0e463f

See more details on using hashes here.

File details

Details for the file typed_macro-0.1.15-py3-none-any.whl.

File metadata

File hashes

Hashes for typed_macro-0.1.15-py3-none-any.whl
Algorithm Hash digest
SHA256 83608c66012e6b7e6e924fcac1b45bd9e2cf145db0104b86e15c932a6cee89b5
MD5 fd136916bb4b511f9a78d5fc8d490293
BLAKE2b-256 e85642e27548436e21c93e723ead3d0ee76d95d007ad26fd16b6f732fb352600

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page