macro-polo

Explore new syntax!

licence version pyversions docs

macro-polo brings Rust-inspired macros to Python, as well as a a full API for building custom Python preprocessors.

Enabling macros in your project is as simple as installing macro-polo and adding coding: macro-polo to the top of your modules:

# coding: macro-polo
"""Add `if` and `for` support to dict literals."""


macro_rules! power_dict:
    [@ [if $($[!:] $cond:tt)+: $($item:tt)+] $($tail:tt)*]:
        **({$($item)*} if ($($cond)*) else {}), power_dict!(@ $($tail)*)

    [@ [for $($[!:] $for_stmt:tt)+: $($item:tt)+] $($tail:tt)*]:
        **{$($item)* for $($for_stmt)*}, power_dict!(@ $($tail)*)

    [@ [$($item:tt)+] $($tail:tt)*]:
        $($item)*, power_dict!(@ $($tail)*)

    [@]:

    [$($($[!,] $items:tt)+),* $(,)?]:
        { power_dict!(@ $([$($items)*])*) }


if __name__ == '__main__':
    from pprint import pprint

    pprint(power_dict! {
        0: 1,
        if 1 == 2:
            1: 2,
        if 2 == 2:
            2: 2,
        for word in ('cat', 'bird', 'horse'):
            word: word[::-1],
        for i in range(4) for j in range(4) if i < j:
            (i, j): i * j,
    })
"""Add `if` and `for` support to dict literals."""

if __name__ == '__main__':
    from pprint import pprint

    pprint(
        {
            0: 1,
            **({1: 2} if (1 == 2) else {}),
            **({2: 2} if (2 == 2) else {}),
            **{word: word[::-1] for word in ('cat', 'bird', 'horse')},
            **{(i, j): i * j for i in range(4) for j in range(4) if i < j},
        }
    )
$ python3 examples/macro_rules/power_dict.py 
{0: 1,
 2: 2,
 'bird': 'drib',
 'cat': 'tac',
 'horse': 'esroh',
 (0, 1): 0,
 (0, 2): 0,
 (0, 3): 0,
 (1, 2): 2,
 (1, 3): 3,
 (2, 3): 6}

Getting Started

Interested? Check out Getting Started to start exploring.

Warning

macro-polo is currently in very early alpha, but even if it ever gets a stable release, you probably shouldn’t use it in any serious project. Even if you find a legitimate use case, the complete lack of tooling support almost definitely outweighs the benefits. That said, if you do decide to use it, I’d love to know why!