Skip to content

synt.stmt ¤

assertion ¤

assert_ module-attribute ¤

assert_ = Assert

Alias Assert.

Assert ¤

Bases: Statement

The assert statement.

Examples:

assert_stmt = assert_(TRUE, litstr("Condition is true"))
assert assert_stmt.into_code() == "assert True, 'Condition is true'"
References

Assert.

Source code in synt/stmt/assertion.py
class Assert(Statement):
    r"""The `assert` statement.

    Examples:
        ```python
        assert_stmt = assert_(TRUE, litstr("Condition is true"))
        assert assert_stmt.into_code() == "assert True, 'Condition is true'"
        ```

    References:
        [`Assert`](https://docs.python.org/3/library/ast.html#ast.Assert).
    """

    test: Expression
    """The expression to assert."""
    msg: Expression | None
    """The assert message."""

    def __init__(self, test: IntoExpression, msg: IntoExpression | None = None):
        """Initialize the assertion.

        Args:
            test: The expression to assert.
            msg: The assert message.
        """
        self.test = test.into_expression()
        if msg:
            self.msg = msg.into_expression()
        else:
            self.msg = None

    def indented(self, indent_width: int, indent_atom: str) -> str:
        msg = f", {self.msg.into_code()}" if self.msg else ""
        return f"{indent_width * indent_atom}assert {self.test.into_code()}{msg}"

msg instance-attribute ¤

msg: Expression | None

The assert message.

test instance-attribute ¤

test: Expression = into_expression()

The expression to assert.

__init__ ¤

1
2
3
__init__(
    test: IntoExpression, msg: IntoExpression | None = None
)

Initialize the assertion.

Parameters:

Name Type Description Default
test IntoExpression

The expression to assert.

required
msg IntoExpression | None

The assert message.

None
Source code in synt/stmt/assertion.py
def __init__(self, test: IntoExpression, msg: IntoExpression | None = None):
    """Initialize the assertion.

    Args:
        test: The expression to assert.
        msg: The assert message.
    """
    self.test = test.into_expression()
    if msg:
        self.msg = msg.into_expression()
    else:
        self.msg = None

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/assertion.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    msg = f", {self.msg.into_code()}" if self.msg else ""
    return f"{indent_width * indent_atom}assert {self.test.into_code()}{msg}"

assign ¤

assign module-attribute ¤

assign = Assignment

Alias Assignment.

Assignment ¤

Bases: Statement

Assignment statement.

Examples:

1
2
3
4
5
6
ass = tup(id_("a"), id_("b")).assign(tup(litint(1), litstr("foo")))
assert ass.into_code() == "a, b = (1, 'foo')" # automatically unpack
ass = id_("a").expr().ty(id_("str")).assign(litstr("foo"))
assert ass.into_code() == "a: str = 'foo'" # explicitly typing
ass = id_("a").expr().ty(id_("str"))
assert ass.into_code() == "a: str" # only typing
References

Assign
AnnAssign
AugAssign.

Source code in synt/stmt/assign.py
class Assignment(Statement):
    r"""Assignment statement.

    Examples:
        ```python
        ass = tup(id_("a"), id_("b")).assign(tup(litint(1), litstr("foo")))
        assert ass.into_code() == "a, b = (1, 'foo')" # automatically unpack
        ass = id_("a").expr().ty(id_("str")).assign(litstr("foo"))
        assert ass.into_code() == "a: str = 'foo'" # explicitly typing
        ass = id_("a").expr().ty(id_("str"))
        assert ass.into_code() == "a: str" # only typing
        ```

    References:
        [`Assign`](https://docs.python.org/3/library/ast.html#ast.Assign)<br/>
        [`AnnAssign`](https://docs.python.org/3/library/ast.html#ast.AnnAssign)<br/>
        [`AugAssign`](https://docs.python.org/3/library/ast.html#ast.AugAssign).
    """

    target: Expression
    """Target of the assignment."""
    target_ty: Expression | None
    """The type of the target."""
    value: Expression | None
    """The value to be assigned."""

    def __init__(self, target: IntoExpression):
        """Initialize a new assignment statement.

        Args:
            target: The variable to be assigned to.
        """
        self.target = target.into_expression()
        self.target_ty = None
        self.value = None

    def type(self, ty: IntoExpression) -> Self:
        """Set the target's type.

        Args:
            ty: The type of the target variable.
        """
        self.target_ty = ty.into_expression()
        return self

    def assign(self, v: IntoExpression) -> Self:
        """Set the target's value.

        Args:
            v: The value of the assignment.
        """
        self.value = v.into_expression()
        return self

    def indented(self, indent_width: int, indent_atom: str) -> str:
        if is_tuple(self.target):  # implicit tuple, like `a, b = foo`.
            target = self.target.into_code_implicit()
        else:
            target = self.target.into_code()
        tty = f": {self.target_ty.into_code()}" if self.target_ty is not None else ""
        ass = f" = {self.value.into_code()}" if self.value is not None else ""
        return f"{indent_atom * indent_width}{target}{tty}{ass}"

target instance-attribute ¤

target: Expression = into_expression()

Target of the assignment.

target_ty instance-attribute ¤

target_ty: Expression | None = None

The type of the target.

value instance-attribute ¤

value: Expression | None = None

The value to be assigned.

__init__ ¤

__init__(target: IntoExpression)

Initialize a new assignment statement.

Parameters:

Name Type Description Default
target IntoExpression

The variable to be assigned to.

required
Source code in synt/stmt/assign.py
def __init__(self, target: IntoExpression):
    """Initialize a new assignment statement.

    Args:
        target: The variable to be assigned to.
    """
    self.target = target.into_expression()
    self.target_ty = None
    self.value = None

type ¤

type(ty: IntoExpression) -> Self

Set the target's type.

Parameters:

Name Type Description Default
ty IntoExpression

The type of the target variable.

required
Source code in synt/stmt/assign.py
def type(self, ty: IntoExpression) -> Self:
    """Set the target's type.

    Args:
        ty: The type of the target variable.
    """
    self.target_ty = ty.into_expression()
    return self

assign ¤

assign(v: IntoExpression) -> Self

Set the target's value.

Parameters:

Name Type Description Default
v IntoExpression

The value of the assignment.

required
Source code in synt/stmt/assign.py
def assign(self, v: IntoExpression) -> Self:
    """Set the target's value.

    Args:
        v: The value of the assignment.
    """
    self.value = v.into_expression()
    return self

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/assign.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    if is_tuple(self.target):  # implicit tuple, like `a, b = foo`.
        target = self.target.into_code_implicit()
    else:
        target = self.target.into_code()
    tty = f": {self.target_ty.into_code()}" if self.target_ty is not None else ""
    ass = f" = {self.value.into_code()}" if self.value is not None else ""
    return f"{indent_atom * indent_width}{target}{tty}{ass}"

block ¤

Block ¤

Bases: Statement

A Python code block.

Source code in synt/stmt/block.py
class Block(Statement):
    r"""A Python code block."""

    body: list[Statement]
    """Code lines in the block."""

    def __init__(self, *args: Statement):
        """Initialize a new code block.

        Args:
            args: code lines.
        """
        self.body = list(args)

    def indented(self, indent_width: int, indent_atom: str) -> str:
        return "\n".join(
            f"{line.indented(indent_width, indent_atom)}" for line in self.body
        )

body instance-attribute ¤

body: list[Statement] = list(args)

Code lines in the block.

__init__ ¤

__init__(*args: Statement)

Initialize a new code block.

Parameters:

Name Type Description Default
args Statement

code lines.

()
Source code in synt/stmt/block.py
def __init__(self, *args: Statement):
    """Initialize a new code block.

    Args:
        args: code lines.
    """
    self.body = list(args)

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/block.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    return "\n".join(
        f"{line.indented(indent_width, indent_atom)}" for line in self.body
    )

branch ¤

Branch ¤

Bases: Statement

The branch statement, aka if ... elif ... else.

Examples:

if_stmt = if_(id_("foo").expr().eq(litstr("bar"))).block(
              return_(TRUE)
          )
assert if_stmt.into_code() == "if foo == 'bar':\n    return True"
# if foo == 'bar'
#     return True

if_stmt = if_(id_("foo").expr().eq(litstr("bar"))).block(
              return_(TRUE)
          ).elif_(id_("foo").expr().is_not(NONE)).block(
              return_(FALSE)
          )
assert if_stmt.into_code() == '''if foo == 'bar':
    return True
elif foo is not None:
    return False'''
# if foo == 'bar':
#     return True
# elif foo is not None:
#     return False

if_stmt = if_(id_("foo").expr().eq(litstr("bar"))).block(
              return_(TRUE)
          ).elif_(id_("foo").expr().is_not(NONE)).block(
              return_(FALSE)
          ).else_(
              raise_(id_("ValueError").expr().call(litstr("Unexpected value")))
          )
assert if_stmt.into_code() == '''if foo == 'bar':
    return True
elif foo is not None:
    return False
else:
    raise ValueError('Unexpected value')'''
# if foo == 'bar':
#     return True
# elif foo is not None:
#     return False
# else:
#     raise ValueError('Unexpected value')
References

If.

Source code in synt/stmt/branch.py
class Branch(Statement):
    r"""The branch statement, aka `if ... elif ... else`.

    Examples:
        ```python
        if_stmt = if_(id_("foo").expr().eq(litstr("bar"))).block(
                      return_(TRUE)
                  )
        assert if_stmt.into_code() == "if foo == 'bar':\n    return True"
        # if foo == 'bar'
        #     return True

        if_stmt = if_(id_("foo").expr().eq(litstr("bar"))).block(
                      return_(TRUE)
                  ).elif_(id_("foo").expr().is_not(NONE)).block(
                      return_(FALSE)
                  )
        assert if_stmt.into_code() == '''if foo == 'bar':
            return True
        elif foo is not None:
            return False'''
        # if foo == 'bar':
        #     return True
        # elif foo is not None:
        #     return False

        if_stmt = if_(id_("foo").expr().eq(litstr("bar"))).block(
                      return_(TRUE)
                  ).elif_(id_("foo").expr().is_not(NONE)).block(
                      return_(FALSE)
                  ).else_(
                      raise_(id_("ValueError").expr().call(litstr("Unexpected value")))
                  )
        assert if_stmt.into_code() == '''if foo == 'bar':
            return True
        elif foo is not None:
            return False
        else:
            raise ValueError('Unexpected value')'''
        # if foo == 'bar':
        #     return True
        # elif foo is not None:
        #     return False
        # else:
        #     raise ValueError('Unexpected value')
        ```

    References:
        [`If`](https://docs.python.org/3/library/ast.html#ast.ImportFrom).
    """

    tests: list[tuple[Expression, Block]]
    """Branches of the statement, including `if` and `elif`."""
    fallback: Block | None
    """Fallback branch, aka `else`."""

    def __init__(self) -> None:
        """Initialize a new empty branch statement.

        **DO NOT USE THIS IN YOUR CODE!**
        """
        self.tests = []
        self.fallback = None

    def elif_(self, test: IntoExpression) -> BranchBuilder:
        """Create a new branch.

        Args:
            test: Expression to test.
        """
        return BranchBuilder(self, test)

    def else_(self, *statements: Statement) -> Self:
        """Add a fallback branch.

        Args:
            statements: List of statements.
        """
        self.fallback = Block(*statements)
        return self

    def indented(self, indent_width: int, indent_atom: str) -> str:
        if len(self.tests) == 0:
            raise ValueError("Empty branches, at least one test should be added.")
        indent = indent_atom * indent_width
        if_item = self.tests[0]
        if_text = f"{indent}if {if_item[0].into_code()}:\n{if_item[1].indented(indent_width + 1, indent_atom)}"
        if len(self.tests) > 1:
            elif_item = self.tests[1:]
            elif_text = "\n" + "\n".join(
                f"{indent}elif {x[0].into_code()}:\n{x[1].indented(indent_width + 1, indent_atom)}"
                for x in elif_item
            )
        else:
            elif_text = ""
        if self.fallback is not None:
            else_text = f"\n{indent}else:\n{self.fallback.indented(indent_width + 1, indent_atom)}"
        else:
            else_text = ""
        return if_text + elif_text + else_text

tests instance-attribute ¤

tests: list[tuple[Expression, Block]] = []

Branches of the statement, including if and elif.

fallback instance-attribute ¤

fallback: Block | None = None

Fallback branch, aka else.

__init__ ¤

__init__() -> None

Initialize a new empty branch statement.

DO NOT USE THIS IN YOUR CODE!

Source code in synt/stmt/branch.py
def __init__(self) -> None:
    """Initialize a new empty branch statement.

    **DO NOT USE THIS IN YOUR CODE!**
    """
    self.tests = []
    self.fallback = None

elif_ ¤

Create a new branch.

Parameters:

Name Type Description Default
test IntoExpression

Expression to test.

required
Source code in synt/stmt/branch.py
def elif_(self, test: IntoExpression) -> BranchBuilder:
    """Create a new branch.

    Args:
        test: Expression to test.
    """
    return BranchBuilder(self, test)

else_ ¤

else_(*statements: Statement) -> Self

Add a fallback branch.

Parameters:

Name Type Description Default
statements Statement

List of statements.

()
Source code in synt/stmt/branch.py
def else_(self, *statements: Statement) -> Self:
    """Add a fallback branch.

    Args:
        statements: List of statements.
    """
    self.fallback = Block(*statements)
    return self

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/branch.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    if len(self.tests) == 0:
        raise ValueError("Empty branches, at least one test should be added.")
    indent = indent_atom * indent_width
    if_item = self.tests[0]
    if_text = f"{indent}if {if_item[0].into_code()}:\n{if_item[1].indented(indent_width + 1, indent_atom)}"
    if len(self.tests) > 1:
        elif_item = self.tests[1:]
        elif_text = "\n" + "\n".join(
            f"{indent}elif {x[0].into_code()}:\n{x[1].indented(indent_width + 1, indent_atom)}"
            for x in elif_item
        )
    else:
        elif_text = ""
    if self.fallback is not None:
        else_text = f"\n{indent}else:\n{self.fallback.indented(indent_width + 1, indent_atom)}"
    else:
        else_text = ""
    return if_text + elif_text + else_text

BranchBuilder ¤

A single branch builder for the branch statement.

Source code in synt/stmt/branch.py
class BranchBuilder:
    r"""A single branch builder for the branch statement."""

    parent: Branch
    """Parent node."""
    test: Expression
    """The expression to test."""

    def __init__(self, parent: Branch, test: IntoExpression):
        """Initialize a branch builder.

        Args:
            parent: The parent node.
            test: The expression to test.
        """
        self.parent = parent
        self.test = test.into_expression()

    def block(self, *statements: Statement) -> Branch:
        """Append a block to the branch.

        Args:
            statements: Statements to include in the block.
        """
        block = Block(*statements)
        self.parent.tests.append((self.test, block))
        return self.parent

parent instance-attribute ¤

parent: Branch = parent

Parent node.

test instance-attribute ¤

test: Expression = into_expression()

The expression to test.

__init__ ¤

__init__(parent: Branch, test: IntoExpression)

Initialize a branch builder.

Parameters:

Name Type Description Default
parent Branch

The parent node.

required
test IntoExpression

The expression to test.

required
Source code in synt/stmt/branch.py
def __init__(self, parent: Branch, test: IntoExpression):
    """Initialize a branch builder.

    Args:
        parent: The parent node.
        test: The expression to test.
    """
    self.parent = parent
    self.test = test.into_expression()

block ¤

block(*statements: Statement) -> Branch

Append a block to the branch.

Parameters:

Name Type Description Default
statements Statement

Statements to include in the block.

()
Source code in synt/stmt/branch.py
def block(self, *statements: Statement) -> Branch:
    """Append a block to the branch.

    Args:
        statements: Statements to include in the block.
    """
    block = Block(*statements)
    self.parent.tests.append((self.test, block))
    return self.parent

if_ ¤

Initialize a new branch statement.

Parameters:

Name Type Description Default
test IntoExpression

The expression to test.

required
References

Branch.

Source code in synt/stmt/branch.py
def if_(test: IntoExpression) -> BranchBuilder:
    r"""Initialize a new branch statement.

    Args:
        test: The expression to test.

    References:
        [`Branch`][synt.stmt.branch.Branch].
    """
    return Branch().elif_(test)

cls ¤

ClassDef ¤

Bases: Statement

Class definition.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Examples:
    ```python
    cls = (
        dec(id_("foo"))
        .class_(id_("Bar"))[id_("T")](metaclass=id_("ABCMeta"))
        .block(
            dec(id_("abstractmethod"))
            .def_(id_("baz"))(id_("self"), arg(id_("a"), id_("T"))).returns(id_("str"))
            .block(
                return_(fstring("Bar(", fnode(id_("a")), ").baz"))
            )
        )
    )
    assert cls.into_code() == '''@foo

class BarT: @abstractmethod def baz(self, a: T) -> str: return f"Bar({a}).baz"'''

1
2
3
4
5
6
7
8
9
    # @foo
    # class Bar[T](metaclass=ABCMeta):
    #     @abstractmethod
    #     def baz(self, a: T) -> str:
    #         return f"Bar({a}).baz"
    ```

References:
    [`ClassDef`](https://docs.python.org/3/library/ast.html#ast.ClassDef).
Source code in synt/stmt/cls.py
class ClassDef(Statement):
    r"""Class definition.

        Examples:
            ```python
            cls = (
                dec(id_("foo"))
                .class_(id_("Bar"))[id_("T")](metaclass=id_("ABCMeta"))
                .block(
                    dec(id_("abstractmethod"))
                    .def_(id_("baz"))(id_("self"), arg(id_("a"), id_("T"))).returns(id_("str"))
                    .block(
                        return_(fstring("Bar(", fnode(id_("a")), ").baz"))
                    )
                )
            )
            assert cls.into_code() == '''@foo
    class Bar[T](metaclass=ABCMeta):
        @abstractmethod
        def baz(self, a: T) -> str:
            return f"Bar({a}).baz"'''

            # @foo
            # class Bar[T](metaclass=ABCMeta):
            #     @abstractmethod
            #     def baz(self, a: T) -> str:
            #         return f"Bar({a}).baz"
            ```

        References:
            [`ClassDef`](https://docs.python.org/3/library/ast.html#ast.ClassDef).
    """

    decorators: list[Expression]
    """Decorators."""
    name: Identifier
    """Class name."""
    type_params: list[TypeParam]
    """Type parameters."""
    cargs: list[Expression]
    """Class arguments.

    E.g., base classes.
    """
    ckwargs: list[tuple[Identifier, Expression]]
    """Class keyword arguments.

    E.g., meta classes.
    """
    body: Block
    """Function body."""

    def __init__(
        self,
        decorators: list[Expression],
        type_params: list[TypeParam],
        name: Identifier,
        cargs: list[Expression],
        ckwargs: list[tuple[Identifier, Expression]],
        body: Block,
    ):
        """Initialize a function definition.

        **DO NOT USE THIS IN YOUR CODE!**
        """
        self.decorators = decorators
        self.type_params = type_params
        self.cargs = cargs
        self.ckwargs = ckwargs
        self.name = name
        self.body = body

    def indented(self, indent_width: int, indent_atom: str) -> str:
        indent = indent_width * indent_atom
        decorators = "".join(f"{indent}@{t.into_code()}\n" for t in self.decorators)
        type_param = (
            ""
            if not self.type_params
            else f"[{', '.join(x.into_code() for x in self.type_params)}]"
        )
        args_l: list[str] = []
        args_l.extend(x.into_code() for x in self.cargs)
        args_l.extend(f"{x[0].into_code()}={x[1].into_code()}" for x in self.ckwargs)
        args = f"({', '.join(args_l)})" if args_l else ""
        body = self.body.indented(indent_width + 1, indent_atom)
        return f"{decorators}{indent}class {self.name.into_code()}{type_param}{args}:\n{body}"

decorators instance-attribute ¤

decorators: list[Expression] = decorators

Decorators.

type_params instance-attribute ¤

type_params: list[TypeParam] = type_params

Type parameters.

cargs instance-attribute ¤

Class arguments.

E.g., base classes.

ckwargs instance-attribute ¤

Class keyword arguments.

E.g., meta classes.

name instance-attribute ¤

name: Identifier = name

Class name.

body instance-attribute ¤

body: Block = body

Function body.

__init__ ¤

1
2
3
4
5
6
7
8
__init__(
    decorators: list[Expression],
    type_params: list[TypeParam],
    name: Identifier,
    cargs: list[Expression],
    ckwargs: list[tuple[Identifier, Expression]],
    body: Block,
)

Initialize a function definition.

DO NOT USE THIS IN YOUR CODE!

Source code in synt/stmt/cls.py
def __init__(
    self,
    decorators: list[Expression],
    type_params: list[TypeParam],
    name: Identifier,
    cargs: list[Expression],
    ckwargs: list[tuple[Identifier, Expression]],
    body: Block,
):
    """Initialize a function definition.

    **DO NOT USE THIS IN YOUR CODE!**
    """
    self.decorators = decorators
    self.type_params = type_params
    self.cargs = cargs
    self.ckwargs = ckwargs
    self.name = name
    self.body = body

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/cls.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    indent = indent_width * indent_atom
    decorators = "".join(f"{indent}@{t.into_code()}\n" for t in self.decorators)
    type_param = (
        ""
        if not self.type_params
        else f"[{', '.join(x.into_code() for x in self.type_params)}]"
    )
    args_l: list[str] = []
    args_l.extend(x.into_code() for x in self.cargs)
    args_l.extend(f"{x[0].into_code()}={x[1].into_code()}" for x in self.ckwargs)
    args = f"({', '.join(args_l)})" if args_l else ""
    body = self.body.indented(indent_width + 1, indent_atom)
    return f"{decorators}{indent}class {self.name.into_code()}{type_param}{args}:\n{body}"

ClassDefBuilder ¤

Class definition builder.

References

ClassDef.

Source code in synt/stmt/cls.py
class ClassDefBuilder:
    r"""Class definition builder.

    References:
        [`ClassDef`][synt.stmt.cls.ClassDef].
    """

    decorators: list[Expression]
    """Decorators."""
    name: Identifier | None
    """Class name."""
    type_params: list[TypeParam]
    """Type parameters."""
    cargs: list[Expression]
    """Class arguments.

    E.g., base classes.
    """
    ckwargs: list[tuple[Identifier, Expression]]
    """Class keyword arguments.

    E.g., meta classes.
    """

    def __init__(self) -> None:
        """Initialize an empty builder."""
        self.decorators = []
        self.name = None
        self.type_params = []
        self.cargs = []
        self.ckwargs = []

    def decorator(self, decorator: IntoExpression) -> Self:
        """Append a decorator.

        Args:
            decorator: Decorator to append.
        """
        self.decorators.append(decorator.into_expression())
        return self

    def dec(self, decorator: IntoExpression) -> Self:
        """Alias [`decorator`][synt.stmt.cls.ClassDefBuilder.decorator]."""
        return self.decorator(decorator)

    def class_(self, name: Identifier) -> Self:
        """Initialize a class.

        Args:
            name: Class name.
        """
        self.name = name
        return self

    def type_param(self, *args: TypeParam | Identifier) -> Self:
        """Add generic type parameters.

        Args:
            *args: Type parameters to add.
        """
        from synt.tokens.ident import Identifier

        self.type_params = [
            TypeVar(x) if isinstance(x, Identifier) else x for x in args
        ]
        return self

    def ty(self, *args: TypeParam | Identifier) -> Self:
        """Alias [`type_param`][synt.stmt.cls.ClassDefBuilder.type_param]."""
        return self.type_param(*args)

    def __getitem__(
        self, items: tuple[TypeParam | Identifier, ...] | TypeParam | Identifier
    ) -> Self:
        """Alias [`type_param`][synt.stmt.cls.ClassDefBuilder.type_param]."""
        if isinstance(items, tuple):
            return self.type_param(*items)
        else:
            return self.type_param(items)

    def arg(
        self,
        *args: IntoExpression | tuple[Identifier, IntoExpression],
        **kwargs: IntoExpression,
    ) -> Self:
        """Add arguments for the class.

        Args:
            *args: Arguments to add.
            **kwargs: Keyword arguments to add with their default values.
        """
        from synt.tokens.ident import Identifier

        self.cargs = []
        self.ckwargs = []
        for a in args:
            if isinstance(a, tuple):
                self.ckwargs.append((a[0], a[1].into_expression()))
            else:
                self.cargs.append(a.into_expression())
        for k, v in kwargs.items():
            self.ckwargs.append((Identifier(k), v.into_expression()))
        return self

    def __call__(
        self,
        *args: IntoExpression | tuple[Identifier, IntoExpression],
        **kwargs: IntoExpression,
    ) -> Self:
        """Alias [`arg`][synt.stmt.cls.ClassDefBuilder.arg]."""
        return self.arg(*args, **kwargs)

    def block(self, *statements: Statement) -> ClassDef:
        """Set the block of the class, and build it.

        Args:
            *statements: Statements to include in the class body.

        Raises:
            ValueError: If the required fields (`[name,]`) are not set.
        """
        err_fields = []
        if self.name is None:
            err_fields.append("name")

        if err_fields:
            raise ValueError(
                f"Missing required fields: {', '.join(f'`{t}`' for t in err_fields)}"
            )

        return ClassDef(
            decorators=self.decorators,
            type_params=self.type_params,
            cargs=self.cargs,
            ckwargs=self.ckwargs,
            name=self.name,  # type:ignore[arg-type]
            body=Block(*statements),
        )

decorators instance-attribute ¤

decorators: list[Expression] = []

Decorators.

name instance-attribute ¤

name: Identifier | None = None

Class name.

type_params instance-attribute ¤

type_params: list[TypeParam] = []

Type parameters.

cargs instance-attribute ¤

cargs: list[Expression] = []

Class arguments.

E.g., base classes.

ckwargs instance-attribute ¤

ckwargs: list[tuple[Identifier, Expression]] = []

Class keyword arguments.

E.g., meta classes.

__init__ ¤

__init__() -> None

Initialize an empty builder.

Source code in synt/stmt/cls.py
def __init__(self) -> None:
    """Initialize an empty builder."""
    self.decorators = []
    self.name = None
    self.type_params = []
    self.cargs = []
    self.ckwargs = []

decorator ¤

decorator(decorator: IntoExpression) -> Self

Append a decorator.

Parameters:

Name Type Description Default
decorator IntoExpression

Decorator to append.

required
Source code in synt/stmt/cls.py
def decorator(self, decorator: IntoExpression) -> Self:
    """Append a decorator.

    Args:
        decorator: Decorator to append.
    """
    self.decorators.append(decorator.into_expression())
    return self

dec ¤

dec(decorator: IntoExpression) -> Self

Alias decorator.

Source code in synt/stmt/cls.py
def dec(self, decorator: IntoExpression) -> Self:
    """Alias [`decorator`][synt.stmt.cls.ClassDefBuilder.decorator]."""
    return self.decorator(decorator)

class_ ¤

class_(name: Identifier) -> Self

Initialize a class.

Parameters:

Name Type Description Default
name Identifier

Class name.

required
Source code in synt/stmt/cls.py
def class_(self, name: Identifier) -> Self:
    """Initialize a class.

    Args:
        name: Class name.
    """
    self.name = name
    return self

type_param ¤

type_param(*args: TypeParam | Identifier) -> Self

Add generic type parameters.

Parameters:

Name Type Description Default
*args TypeParam | Identifier

Type parameters to add.

()
Source code in synt/stmt/cls.py
def type_param(self, *args: TypeParam | Identifier) -> Self:
    """Add generic type parameters.

    Args:
        *args: Type parameters to add.
    """
    from synt.tokens.ident import Identifier

    self.type_params = [
        TypeVar(x) if isinstance(x, Identifier) else x for x in args
    ]
    return self

ty ¤

ty(*args: TypeParam | Identifier) -> Self

Alias type_param.

Source code in synt/stmt/cls.py
def ty(self, *args: TypeParam | Identifier) -> Self:
    """Alias [`type_param`][synt.stmt.cls.ClassDefBuilder.type_param]."""
    return self.type_param(*args)

__getitem__ ¤

1
2
3
4
5
6
7
__getitem__(
    items: (
        tuple[TypeParam | Identifier, ...]
        | TypeParam
        | Identifier
    )
) -> Self

Alias type_param.

Source code in synt/stmt/cls.py
def __getitem__(
    self, items: tuple[TypeParam | Identifier, ...] | TypeParam | Identifier
) -> Self:
    """Alias [`type_param`][synt.stmt.cls.ClassDefBuilder.type_param]."""
    if isinstance(items, tuple):
        return self.type_param(*items)
    else:
        return self.type_param(items)

arg ¤

Add arguments for the class.

Parameters:

Name Type Description Default
*args IntoExpression | tuple[Identifier, IntoExpression]

Arguments to add.

()
**kwargs IntoExpression

Keyword arguments to add with their default values.

{}
Source code in synt/stmt/cls.py
def arg(
    self,
    *args: IntoExpression | tuple[Identifier, IntoExpression],
    **kwargs: IntoExpression,
) -> Self:
    """Add arguments for the class.

    Args:
        *args: Arguments to add.
        **kwargs: Keyword arguments to add with their default values.
    """
    from synt.tokens.ident import Identifier

    self.cargs = []
    self.ckwargs = []
    for a in args:
        if isinstance(a, tuple):
            self.ckwargs.append((a[0], a[1].into_expression()))
        else:
            self.cargs.append(a.into_expression())
    for k, v in kwargs.items():
        self.ckwargs.append((Identifier(k), v.into_expression()))
    return self

__call__ ¤

1
2
3
4
5
__call__(
    *args: IntoExpression
    | tuple[Identifier, IntoExpression],
    **kwargs: IntoExpression
) -> Self

Alias arg.

Source code in synt/stmt/cls.py
def __call__(
    self,
    *args: IntoExpression | tuple[Identifier, IntoExpression],
    **kwargs: IntoExpression,
) -> Self:
    """Alias [`arg`][synt.stmt.cls.ClassDefBuilder.arg]."""
    return self.arg(*args, **kwargs)

block ¤

block(*statements: Statement) -> ClassDef

Set the block of the class, and build it.

Parameters:

Name Type Description Default
*statements Statement

Statements to include in the class body.

()

Raises:

Type Description
ValueError

If the required fields ([name,]) are not set.

Source code in synt/stmt/cls.py
def block(self, *statements: Statement) -> ClassDef:
    """Set the block of the class, and build it.

    Args:
        *statements: Statements to include in the class body.

    Raises:
        ValueError: If the required fields (`[name,]`) are not set.
    """
    err_fields = []
    if self.name is None:
        err_fields.append("name")

    if err_fields:
        raise ValueError(
            f"Missing required fields: {', '.join(f'`{t}`' for t in err_fields)}"
        )

    return ClassDef(
        decorators=self.decorators,
        type_params=self.type_params,
        cargs=self.cargs,
        ckwargs=self.ckwargs,
        name=self.name,  # type:ignore[arg-type]
        body=Block(*statements),
    )

class_ ¤

class_(name: Identifier) -> ClassDefBuilder

Initialize a class without decorators.

Parameters:

Name Type Description Default
name Identifier

Class name.

required
Source code in synt/stmt/cls.py
def class_(name: Identifier) -> ClassDefBuilder:
    r"""Initialize a class without decorators.

    Args:
        name: Class name.
    """
    return ClassDefBuilder().class_(name)

context ¤

with_item module-attribute ¤

with_item = WithItem

Alias WithItem.

with_ module-attribute ¤

with_ = WithBuilder

Alias WithBuilder.

WithItem ¤

Bases: IntoCode

An item of the with statement.

References

withitem.

Source code in synt/stmt/context.py
class WithItem(IntoCode):
    """An item of the `with` statement.

    References:
        [`withitem`](https://docs.python.org/3/library/ast.html#ast.withitem).
    """

    context: Expression
    """The context expression."""
    asname: Expression | None
    """The alias for the context expression.

    Notes:
        ```python
        with a as b:
            ...
        ```
        Consider the above example, the context returned by `a` is assigned to `b`.
        Hence, `b`, the syntax node, must be an assignable object, that is,
        a `tuple`, `list`, or a single `Identifier`.
    """

    def __init__(self, context: IntoExpression):
        """Initialize a new `with` item.

        Args:
            context: The context expression.
        """
        self.context = context.into_expression()
        self.asname = None

    def as_(self, asname: IntoExpression) -> Self:
        """Set the alias.

        Args:
            asname: The alias for the context expression.
        """
        self.asname = asname.into_expression()
        return self

    def into_code(self) -> str:
        asname_text = (
            f" as {self.asname.into_code()}" if self.asname is not None else ""
        )
        return f"{self.context.into_code()}{asname_text}"

context instance-attribute ¤

context: Expression = into_expression()

The context expression.

asname instance-attribute ¤

asname: Expression | None = None

The alias for the context expression.

Notes

with a as b:
    ...
Consider the above example, the context returned by a is assigned to b. Hence, b, the syntax node, must be an assignable object, that is, a tuple, list, or a single Identifier.

__init__ ¤

__init__(context: IntoExpression)

Initialize a new with item.

Parameters:

Name Type Description Default
context IntoExpression

The context expression.

required
Source code in synt/stmt/context.py
def __init__(self, context: IntoExpression):
    """Initialize a new `with` item.

    Args:
        context: The context expression.
    """
    self.context = context.into_expression()
    self.asname = None

as_ ¤

as_(asname: IntoExpression) -> Self

Set the alias.

Parameters:

Name Type Description Default
asname IntoExpression

The alias for the context expression.

required
Source code in synt/stmt/context.py
def as_(self, asname: IntoExpression) -> Self:
    """Set the alias.

    Args:
        asname: The alias for the context expression.
    """
    self.asname = asname.into_expression()
    return self

into_code ¤

into_code() -> str
Source code in synt/stmt/context.py
def into_code(self) -> str:
    asname_text = (
        f" as {self.asname.into_code()}" if self.asname is not None else ""
    )
    return f"{self.context.into_code()}{asname_text}"

With ¤

Bases: Statement

The with statement.

Examples:

```python with_stmt = with_(id_("a"), (id_("b"), id_("b2")), with_item(id_("c")).as_(id_("c2"))).block( PASS ) assert with_stmt.into_code() == "with a, b as b2, c as c2:

pass" ```

References: With.

Source code in synt/stmt/context.py
class With(Statement):
    """The `with` statement.

    Examples:
        ```python
        with_stmt = with_(id_("a"), (id_("b"), id_("b2")), with_item(id_("c")).as_(id_("c2"))).block(
                        PASS
                    )
        assert with_stmt.into_code() == "with a, b as b2, c as c2:\n    pass"
        ```

    References:
        [`With`](https://docs.python.org/3/library/ast.html#ast.With).
    """

    items: list[WithItem]
    """`with` items."""
    body: Block
    """Statement block."""

    def __init__(self, items: list[WithItem], body: Block):
        """Initialize a `with` statement.

        **DO NOT USE THIS IN YOUR CODE!**

        Args:
            items: `with` items.
            body: Statement block.

        Raises:
            ValueError: If `items` is empty.
        """
        if len(items) == 0:
            raise ValueError("At least one `with` item is required.")
        self.items = items
        self.body = body

    def indented(self, indent_width: int, indent_atom: str) -> str:
        return (
            f"{indent_atom * indent_width}with {', '.join(x.into_code() for x in self.items)}:\n"
            f"{self.body.indented(indent_width + 1, indent_atom)}"
        )

items instance-attribute ¤

items: list[WithItem] = items

with items.

body instance-attribute ¤

body: Block = body

Statement block.

__init__ ¤

__init__(items: list[WithItem], body: Block)

Initialize a with statement.

DO NOT USE THIS IN YOUR CODE!

Parameters:

Name Type Description Default
items list[WithItem]

with items.

required
body Block

Statement block.

required

Raises:

Type Description
ValueError

If items is empty.

Source code in synt/stmt/context.py
def __init__(self, items: list[WithItem], body: Block):
    """Initialize a `with` statement.

    **DO NOT USE THIS IN YOUR CODE!**

    Args:
        items: `with` items.
        body: Statement block.

    Raises:
        ValueError: If `items` is empty.
    """
    if len(items) == 0:
        raise ValueError("At least one `with` item is required.")
    self.items = items
    self.body = body

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/context.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    return (
        f"{indent_atom * indent_width}with {', '.join(x.into_code() for x in self.items)}:\n"
        f"{self.body.indented(indent_width + 1, indent_atom)}"
    )

WithBuilder ¤

The builder for With.

Source code in synt/stmt/context.py
class WithBuilder:
    """The builder for [`With`][synt.stmt.context.With]."""

    items: list[WithItem]
    """`with` items."""

    def __init__(
        self, *items: WithItem | IntoExpression | tuple[IntoExpression, IntoExpression]
    ):
        """Initialize a `with` statement.

        The `items`'s item could be either `WithItem` object, an expression-like or a tuple:
        - `WithItem`: Save as-is.
        - Expression-like: Convert into a `WithItem` without any alias.
        - `tuple[IntoExpression, IntoExpression]`: The first element is the context, and the second is the alias.

        Args:
            items: `with` items.

        Raises:
            ValueError: If `items` is empty.
        """
        if len(items) == 0:
            raise ValueError("At least one `with` item is required.")
        self.items = []
        for item in items:
            if isinstance(item, tuple):
                self.items.append(
                    WithItem(item[0].into_expression()).as_(item[1].into_expression())
                )
            elif isinstance(item, WithItem):
                self.items.append(item)
            else:
                self.items.append(WithItem(item.into_expression()))

    def block(self, *statements: Statement) -> With:
        """Set the code block.

        Args:
            statements: block statements.
        """
        return With(self.items, Block(*statements))

items instance-attribute ¤

items: list[WithItem] = []

with items.

__init__ ¤

Initialize a with statement.

The items's item could be either WithItem object, an expression-like or a tuple: - WithItem: Save as-is. - Expression-like: Convert into a WithItem without any alias. - tuple[IntoExpression, IntoExpression]: The first element is the context, and the second is the alias.

Parameters:

Name Type Description Default
items WithItem | IntoExpression | tuple[IntoExpression, IntoExpression]

with items.

()

Raises:

Type Description
ValueError

If items is empty.

Source code in synt/stmt/context.py
def __init__(
    self, *items: WithItem | IntoExpression | tuple[IntoExpression, IntoExpression]
):
    """Initialize a `with` statement.

    The `items`'s item could be either `WithItem` object, an expression-like or a tuple:
    - `WithItem`: Save as-is.
    - Expression-like: Convert into a `WithItem` without any alias.
    - `tuple[IntoExpression, IntoExpression]`: The first element is the context, and the second is the alias.

    Args:
        items: `with` items.

    Raises:
        ValueError: If `items` is empty.
    """
    if len(items) == 0:
        raise ValueError("At least one `with` item is required.")
    self.items = []
    for item in items:
        if isinstance(item, tuple):
            self.items.append(
                WithItem(item[0].into_expression()).as_(item[1].into_expression())
            )
        elif isinstance(item, WithItem):
            self.items.append(item)
        else:
            self.items.append(WithItem(item.into_expression()))

block ¤

block(*statements: Statement) -> With

Set the code block.

Parameters:

Name Type Description Default
statements Statement

block statements.

()
Source code in synt/stmt/context.py
def block(self, *statements: Statement) -> With:
    """Set the code block.

    Args:
        statements: block statements.
    """
    return With(self.items, Block(*statements))

decorator ¤

dec module-attribute ¤

DecoratorGroup ¤

A group of decorators.

Source code in synt/stmt/decorator.py
class DecoratorGroup:
    r"""A group of decorators."""

    decorators: list[Expression]
    """Decorators."""

    def __init__(self, decorator: IntoExpression):
        """Initialize a decorator and create a new group.

        Args:
            decorator: The decorator to add.
        """
        self.decorators = [decorator.into_expression()]

    def dec(self, decorator: IntoExpression) -> Self:
        """Append a new decorator.

        Args:
            decorator: The decorator to add.
        """
        self.decorators.append(decorator.into_expression())
        return self

    def class_(self, name: Identifier) -> ClassDefBuilder:
        """Initialize a class with the decorators.

        Args:
            name: The name of the class.
        """
        cls = ClassDefBuilder()
        cls.decorators = self.decorators
        return cls.class_(name)

    def def_(self, name: Identifier) -> FunctionDefBuilder:
        """Initialize a function with the decorators.

        Args:
            name: The name of the function.
        """
        fn = FunctionDefBuilder()
        fn.decorators = self.decorators
        return fn.def_(name)

    def async_def(self, name: Identifier) -> FunctionDefBuilder:
        """Initialize an async function with the decorators.

        Args:
            name: The name of the function.
        """
        return self.def_(name).async_()

decorators instance-attribute ¤

decorators: list[Expression] = [into_expression()]

Decorators.

__init__ ¤

__init__(decorator: IntoExpression)

Initialize a decorator and create a new group.

Parameters:

Name Type Description Default
decorator IntoExpression

The decorator to add.

required
Source code in synt/stmt/decorator.py
def __init__(self, decorator: IntoExpression):
    """Initialize a decorator and create a new group.

    Args:
        decorator: The decorator to add.
    """
    self.decorators = [decorator.into_expression()]

dec ¤

dec(decorator: IntoExpression) -> Self

Append a new decorator.

Parameters:

Name Type Description Default
decorator IntoExpression

The decorator to add.

required
Source code in synt/stmt/decorator.py
def dec(self, decorator: IntoExpression) -> Self:
    """Append a new decorator.

    Args:
        decorator: The decorator to add.
    """
    self.decorators.append(decorator.into_expression())
    return self

class_ ¤

class_(name: Identifier) -> ClassDefBuilder

Initialize a class with the decorators.

Parameters:

Name Type Description Default
name Identifier

The name of the class.

required
Source code in synt/stmt/decorator.py
def class_(self, name: Identifier) -> ClassDefBuilder:
    """Initialize a class with the decorators.

    Args:
        name: The name of the class.
    """
    cls = ClassDefBuilder()
    cls.decorators = self.decorators
    return cls.class_(name)

def_ ¤

Initialize a function with the decorators.

Parameters:

Name Type Description Default
name Identifier

The name of the function.

required
Source code in synt/stmt/decorator.py
def def_(self, name: Identifier) -> FunctionDefBuilder:
    """Initialize a function with the decorators.

    Args:
        name: The name of the function.
    """
    fn = FunctionDefBuilder()
    fn.decorators = self.decorators
    return fn.def_(name)

async_def ¤

async_def(name: Identifier) -> FunctionDefBuilder

Initialize an async function with the decorators.

Parameters:

Name Type Description Default
name Identifier

The name of the function.

required
Source code in synt/stmt/decorator.py
def async_def(self, name: Identifier) -> FunctionDefBuilder:
    """Initialize an async function with the decorators.

    Args:
        name: The name of the function.
    """
    return self.def_(name).async_()

delete ¤

del_ module-attribute ¤

del_ = Delete

Alias Delete.

Delete ¤

Bases: Statement

The del statement.

Examples:

d = del_(id_("foo").expr().attr("bar"))
assert d.into_code() == "del foo.bar"
References

Delete.

Source code in synt/stmt/delete.py
class Delete(Statement):
    r"""The `del` statement.

    Examples:
        ```python
        d = del_(id_("foo").expr().attr("bar"))
        assert d.into_code() == "del foo.bar"
        ```

    References:
        [`Delete`](https://docs.python.org/3/library/ast.html#ast.Delete).
    """

    target: Expression
    """The expression to be deleted."""

    def __init__(self, target: IntoExpression):
        """Initialize the delete statement.

        Args:
            target: The expression to be deleted.
        """
        self.target = target.into_expression()

    def indented(self, indent_width: int, indent_atom: str) -> str:
        return f"{indent_atom * indent_width}del {self.target.into_code()}"

target instance-attribute ¤

target: Expression = into_expression()

The expression to be deleted.

__init__ ¤

__init__(target: IntoExpression)

Initialize the delete statement.

Parameters:

Name Type Description Default
target IntoExpression

The expression to be deleted.

required
Source code in synt/stmt/delete.py
def __init__(self, target: IntoExpression):
    """Initialize the delete statement.

    Args:
        target: The expression to be deleted.
    """
    self.target = target.into_expression()

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/delete.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    return f"{indent_atom * indent_width}del {self.target.into_code()}"

expression ¤

stmt module-attribute ¤

Alias ExprStatement.

ExprStatement ¤

Bases: Statement

A statement that only contains a single expression.

Examples:

stmt = id_("print").expr().call(litstr("Hello world!")).stmt()
assert stmt.into_code() == "print('Hello world!')"
Source code in synt/stmt/expression.py
class ExprStatement(Statement):
    """A statement that only contains a single expression.

    Examples:
        ```python
        stmt = id_("print").expr().call(litstr("Hello world!")).stmt()
        assert stmt.into_code() == "print('Hello world!')"
        ```
    """

    expr: Expression
    """Inner expression."""

    def __init__(self, expr: IntoExpression):
        """Initialize a nwe statement.

        Args:
            expr: Inner expression.
        """
        self.expr = expr.into_expression()

    def indented(self, indent_width: int, indent_atom: str) -> str:
        return f"{indent_atom * indent_width}{self.expr.into_code()}"

expr instance-attribute ¤

expr: Expression = into_expression()

Inner expression.

__init__ ¤

__init__(expr: IntoExpression)

Initialize a nwe statement.

Parameters:

Name Type Description Default
expr IntoExpression

Inner expression.

required
Source code in synt/stmt/expression.py
def __init__(self, expr: IntoExpression):
    """Initialize a nwe statement.

    Args:
        expr: Inner expression.
    """
    self.expr = expr.into_expression()

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/expression.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    return f"{indent_atom * indent_width}{self.expr.into_code()}"

fn ¤

arg module-attribute ¤

arg = FnArg

Alias FnArg.

FnArg ¤

Bases: IntoCode

Function argument.

Examples:

a = arg(id_("foo")).ty(id_("int")).default(litint(1))
assert a.into_code() == "foo: int = 1"
References

arg.

Source code in synt/stmt/fn.py
class FnArg(IntoCode):
    r"""Function argument.

    Examples:
        ```python
        a = arg(id_("foo")).ty(id_("int")).default(litint(1))
        assert a.into_code() == "foo: int = 1"
        ```

    References:
        [`arg`](https://docs.python.org/3/library/ast.html#ast.arg).
    """

    name: Identifier
    """Argument name."""
    annotation: Expression | None
    """Argument annotation."""
    default_expr: Expression | None
    """Argument default expression."""
    is_vararg: bool
    """Whether the argument is a variable argument, or `*args`."""
    is_kwarg: bool
    """Whether the argument is a keyword argument, or `**kwargs`."""

    def __init__(
        self,
        name: Identifier,
        annotation: IntoExpression | None = None,
        default: IntoExpression | None = None,
        is_vararg: bool = False,
        is_kwarg: bool = False,
    ):
        """Initialize a new argument.

        Args:
            name: Argument keyword.
            annotation: Argument annotation.
            default: Default value for the argument.
            is_vararg: Whether the argument is a variable argument, or `*args`.
            is_kwarg: Whether the argument is a keyword argument, or `**kwargs`.
        """
        self.name = name
        self.annotation = (
            annotation.into_expression() if annotation is not None else None
        )
        self.default_expr = default.into_expression() if default is not None else None
        self.is_vararg = is_vararg
        self.is_kwarg = is_kwarg

    def vararg(self) -> Self:
        """Set the argument as a variable argument."""
        self.is_vararg = True
        return self

    def kwarg(self) -> Self:
        """Set the argument as a keyword argument."""
        self.is_kwarg = True
        return self

    def annotate(self, annotation: IntoExpression) -> Self:
        """Add annotation for the argument.

        Args:
            annotation: Argument annotation.
        """
        self.annotation = annotation.into_expression()
        return self

    def ty(self, annotation: IntoExpression) -> Self:
        """Alias [`annotate`][synt.stmt.fn.FnArg.annotate]."""
        return self.annotate(annotation)

    def default(self, default: IntoExpression) -> Self:
        """Set the default value of the argument.

        Args:
            default: Default value for the argument.
        """
        self.default_expr = default.into_expression()
        return self

    def into_code(self) -> str:
        if self.is_vararg:
            name = f"*{self.name.into_code()}"
        elif self.is_kwarg:
            name = f"**{self.name.into_code()}"
        else:
            name = self.name.into_code()
        ret = name
        if self.annotation is not None:
            ret += f": {self.annotation.into_code()}"
        if self.default_expr is not None:
            ret += f" = {self.default_expr.into_code()}"
        return ret

name instance-attribute ¤

name: Identifier = name

Argument name.

annotation instance-attribute ¤

1
2
3
annotation: Expression | None = (
    into_expression() if annotation is not None else None
)

Argument annotation.

default_expr instance-attribute ¤

1
2
3
default_expr: Expression | None = (
    into_expression() if default is not None else None
)

Argument default expression.

is_vararg instance-attribute ¤

is_vararg: bool = is_vararg

Whether the argument is a variable argument, or *args.

is_kwarg instance-attribute ¤

is_kwarg: bool = is_kwarg

Whether the argument is a keyword argument, or **kwargs.

__init__ ¤

1
2
3
4
5
6
7
__init__(
    name: Identifier,
    annotation: IntoExpression | None = None,
    default: IntoExpression | None = None,
    is_vararg: bool = False,
    is_kwarg: bool = False,
)

Initialize a new argument.

Parameters:

Name Type Description Default
name Identifier

Argument keyword.

required
annotation IntoExpression | None

Argument annotation.

None
default IntoExpression | None

Default value for the argument.

None
is_vararg bool

Whether the argument is a variable argument, or *args.

False
is_kwarg bool

Whether the argument is a keyword argument, or **kwargs.

False
Source code in synt/stmt/fn.py
def __init__(
    self,
    name: Identifier,
    annotation: IntoExpression | None = None,
    default: IntoExpression | None = None,
    is_vararg: bool = False,
    is_kwarg: bool = False,
):
    """Initialize a new argument.

    Args:
        name: Argument keyword.
        annotation: Argument annotation.
        default: Default value for the argument.
        is_vararg: Whether the argument is a variable argument, or `*args`.
        is_kwarg: Whether the argument is a keyword argument, or `**kwargs`.
    """
    self.name = name
    self.annotation = (
        annotation.into_expression() if annotation is not None else None
    )
    self.default_expr = default.into_expression() if default is not None else None
    self.is_vararg = is_vararg
    self.is_kwarg = is_kwarg

vararg ¤

vararg() -> Self

Set the argument as a variable argument.

Source code in synt/stmt/fn.py
def vararg(self) -> Self:
    """Set the argument as a variable argument."""
    self.is_vararg = True
    return self

kwarg ¤

kwarg() -> Self

Set the argument as a keyword argument.

Source code in synt/stmt/fn.py
def kwarg(self) -> Self:
    """Set the argument as a keyword argument."""
    self.is_kwarg = True
    return self

annotate ¤

annotate(annotation: IntoExpression) -> Self

Add annotation for the argument.

Parameters:

Name Type Description Default
annotation IntoExpression

Argument annotation.

required
Source code in synt/stmt/fn.py
def annotate(self, annotation: IntoExpression) -> Self:
    """Add annotation for the argument.

    Args:
        annotation: Argument annotation.
    """
    self.annotation = annotation.into_expression()
    return self

ty ¤

ty(annotation: IntoExpression) -> Self

Alias annotate.

Source code in synt/stmt/fn.py
def ty(self, annotation: IntoExpression) -> Self:
    """Alias [`annotate`][synt.stmt.fn.FnArg.annotate]."""
    return self.annotate(annotation)

default ¤

default(default: IntoExpression) -> Self

Set the default value of the argument.

Parameters:

Name Type Description Default
default IntoExpression

Default value for the argument.

required
Source code in synt/stmt/fn.py
def default(self, default: IntoExpression) -> Self:
    """Set the default value of the argument.

    Args:
        default: Default value for the argument.
    """
    self.default_expr = default.into_expression()
    return self

into_code ¤

into_code() -> str
Source code in synt/stmt/fn.py
def into_code(self) -> str:
    if self.is_vararg:
        name = f"*{self.name.into_code()}"
    elif self.is_kwarg:
        name = f"**{self.name.into_code()}"
    else:
        name = self.name.into_code()
    ret = name
    if self.annotation is not None:
        ret += f": {self.annotation.into_code()}"
    if self.default_expr is not None:
        ret += f" = {self.default_expr.into_code()}"
    return ret

FunctionDef ¤

Bases: Statement

Function definition.

Examples:

With dsl-like aliases:

func = (
    dec(id_("foo"))
    .async_def(id_("bar"))[id_("T")](
        id_("a"),
        arg(id_("b")).ty(id_("int")),
        kw=NONE
    ).returns(id_("float")).block(
        return_(ELLIPSIS)
    )
)
assert func.into_code() == "@foo\nasync def bar[T](a, b: int, kw = None) -> float:\n    return ..."
# @foo
# async def bar[T](a, b: int, kw = None) -> float:
#     return ...

With raw ast:

func = (
    dec(id_("foo"))
    .async_def(id_("bar"))
    .type_param(id_("T"))
    .arg(
        id_("a"),
        arg(id_("b")).ty(id_("int")),
        kw=NONE
    )
    .returns(id_("float"))
    .block(
        return_(ELLIPSIS)
    )
)
assert func.into_code() == "@foo\nasync def bar[T](a, b: int, kw = None) -> float:\n    return ..."
# @foo
# async def bar[T](a, b: int, kw = None) -> float:
#     return ...

References

FunctionDef
AsyncFunctionDef

Source code in synt/stmt/fn.py
class FunctionDef(Statement):
    r"""Function definition.

    Examples:
        With dsl-like aliases:
        ```python
        func = (
            dec(id_("foo"))
            .async_def(id_("bar"))[id_("T")](
                id_("a"),
                arg(id_("b")).ty(id_("int")),
                kw=NONE
            ).returns(id_("float")).block(
                return_(ELLIPSIS)
            )
        )
        assert func.into_code() == "@foo\nasync def bar[T](a, b: int, kw = None) -> float:\n    return ..."
        # @foo
        # async def bar[T](a, b: int, kw = None) -> float:
        #     return ...
        ```

        With raw ast:
        ```python
        func = (
            dec(id_("foo"))
            .async_def(id_("bar"))
            .type_param(id_("T"))
            .arg(
                id_("a"),
                arg(id_("b")).ty(id_("int")),
                kw=NONE
            )
            .returns(id_("float"))
            .block(
                return_(ELLIPSIS)
            )
        )
        assert func.into_code() == "@foo\nasync def bar[T](a, b: int, kw = None) -> float:\n    return ..."
        # @foo
        # async def bar[T](a, b: int, kw = None) -> float:
        #     return ...
        ```

    References:
        [`FunctionDef`](https://docs.python.org/3/library/ast.html#ast.FunctionDef)<br/>
        [`AsyncFunctionDef`](https://docs.python.org/3/library/ast.html#ast.AsyncFunctionDef)
    """

    is_async: bool
    """Whether this function is asynchronous."""
    decorators: list[Expression]
    """Decorators."""
    name: Identifier
    """Function name."""
    type_params: list[TypeParam]
    """Type parameters."""
    args: list[FnArg]
    """Function arguments."""
    returns: Expression | None
    """Return types of the function."""
    body: Block
    """Function body."""

    def __init__(
        self,
        decorators: list[Expression],
        is_async: bool,
        type_params: list[TypeParam],
        args: list[FnArg],
        returns: Expression | None,
        name: Identifier,
        body: Block,
    ):
        """Initialize a function definition.

        **DO NOT USE THIS IN YOUR CODE!**
        """
        self.is_async = is_async
        self.decorators = decorators
        self.type_params = type_params
        self.args = args
        self.returns = returns
        self.name = name
        self.body = body

    def indented(self, indent_width: int, indent_atom: str) -> str:
        indent = indent_width * indent_atom
        decorators = "".join(f"{indent}@{t.into_code()}\n" for t in self.decorators)
        type_param = (
            ""
            if not self.type_params
            else f"[{', '.join(x.into_code() for x in self.type_params)}]"
        )
        args = ", ".join(a.into_code() for a in self.args)
        returns = f" -> {self.returns.into_code()}" if self.returns else ""
        body = self.body.indented(indent_width + 1, indent_atom)
        async_ = "async " if self.is_async else ""
        return f"{decorators}{indent}{async_}def {self.name.into_code()}{type_param}({args}){returns}:\n{body}"

is_async instance-attribute ¤

is_async: bool = is_async

Whether this function is asynchronous.

decorators instance-attribute ¤

decorators: list[Expression] = decorators

Decorators.

type_params instance-attribute ¤

type_params: list[TypeParam] = type_params

Type parameters.

args instance-attribute ¤

args: list[FnArg] = args

Function arguments.

returns instance-attribute ¤

returns: Expression | None = returns

Return types of the function.

name instance-attribute ¤

name: Identifier = name

Function name.

body instance-attribute ¤

body: Block = body

Function body.

__init__ ¤

1
2
3
4
5
6
7
8
9
__init__(
    decorators: list[Expression],
    is_async: bool,
    type_params: list[TypeParam],
    args: list[FnArg],
    returns: Expression | None,
    name: Identifier,
    body: Block,
)

Initialize a function definition.

DO NOT USE THIS IN YOUR CODE!

Source code in synt/stmt/fn.py
def __init__(
    self,
    decorators: list[Expression],
    is_async: bool,
    type_params: list[TypeParam],
    args: list[FnArg],
    returns: Expression | None,
    name: Identifier,
    body: Block,
):
    """Initialize a function definition.

    **DO NOT USE THIS IN YOUR CODE!**
    """
    self.is_async = is_async
    self.decorators = decorators
    self.type_params = type_params
    self.args = args
    self.returns = returns
    self.name = name
    self.body = body

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/fn.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    indent = indent_width * indent_atom
    decorators = "".join(f"{indent}@{t.into_code()}\n" for t in self.decorators)
    type_param = (
        ""
        if not self.type_params
        else f"[{', '.join(x.into_code() for x in self.type_params)}]"
    )
    args = ", ".join(a.into_code() for a in self.args)
    returns = f" -> {self.returns.into_code()}" if self.returns else ""
    body = self.body.indented(indent_width + 1, indent_atom)
    async_ = "async " if self.is_async else ""
    return f"{decorators}{indent}{async_}def {self.name.into_code()}{type_param}({args}){returns}:\n{body}"

FunctionDefBuilder ¤

Function definition builder.

References

FunctionDef

Source code in synt/stmt/fn.py
class FunctionDefBuilder:
    r"""Function definition builder.

    References:
        [`FunctionDef`][synt.stmt.fn.FunctionDef]
    """

    is_async: bool
    """Whether this function is asynchronous."""
    decorators: list[Expression]
    """Decorators."""
    name: Identifier | None
    """Function name."""
    type_params: list[TypeParam]
    """Type parameters."""
    args: list[FnArg]
    """Function arguments."""
    returns_ty: Expression | None
    """Return types of the function."""

    def __init__(self) -> None:
        """Initialize an empty builder."""
        self.is_async = False
        self.decorators = []
        self.type_params = []
        self.args = []
        self.returns_ty = None
        self.name = None

    def async_(self) -> Self:
        """Set this function as asynchronous."""
        self.is_async = True
        return self

    def decorator(self, decorator: IntoExpression) -> Self:
        """Append a decorator.

        Args:
            decorator: Decorator to append.
        """
        self.decorators.append(decorator.into_expression())
        return self

    def dec(self, decorator: IntoExpression) -> Self:
        """Alias [synt.stmt.fn.FunctionDefBuilder.decorator]."""
        return self.decorator(decorator)

    def def_(self, name: Identifier) -> Self:
        """Initialize a function.

        Args:
            name: Function name.
        """
        self.name = name
        return self

    def async_def(self, name: Identifier) -> Self:
        """Initialize an async function.

        This is equivalent to `self.async_().def_(name)`.

        Args:
            name: Function name.
        """
        return self.async_().def_(name)

    def type_param(self, *args: TypeParam | Identifier) -> Self:
        """Add generic type parameters.

        Args:
            *args: Type parameters to add.
        """
        from synt.tokens.ident import Identifier

        self.type_params = [
            TypeVar(x) if isinstance(x, Identifier) else x for x in args
        ]
        return self

    def ty(self, *args: TypeParam | Identifier) -> Self:
        """Alias [`type_param`][synt.stmt.fn.FunctionDefBuilder.type_param]."""
        return self.type_param(*args)

    def __getitem__(
        self, items: tuple[TypeParam | Identifier, ...] | TypeParam | Identifier
    ) -> Self:
        """Alias [`type_param`][synt.stmt.fn.FunctionDefBuilder.type_param]."""
        if isinstance(items, tuple):
            return self.type_param(*items)
        else:
            return self.type_param(items)

    def arg(self, *args: FnArg | Identifier, **kwargs: IntoExpression) -> Self:
        """Add arguments for the function.

        Args:
            *args: Arguments to add.
            **kwargs: Keyword arguments to add with their default values.
        """
        from synt.tokens.ident import Identifier

        self.args = []
        for a in args:
            if isinstance(a, Identifier):
                self.args.append(FnArg(a))
            else:
                self.args.append(a)
        for k, v in kwargs.items():
            self.args.append(FnArg(Identifier(k), default=v.into_expression()))
        return self

    def __call__(self, *args: FnArg | Identifier, **kwargs: IntoExpression) -> Self:
        """Alias [`arg`][synt.stmt.fn.FunctionDefBuilder.arg]."""
        return self.arg(*args, **kwargs)

    def returns(self, returns: IntoExpression) -> Self:
        """Set the return type of the function.

        Args:
            returns: Return type of the function.
        """
        self.returns_ty = returns.into_expression()
        return self

    def block(self, *statements: Statement) -> FunctionDef:
        """Set the block of the function, and build it.

        Args:
            *statements: Statements to include in the function body.

        Raises:
            ValueError: If the required fields (`[name,]`) are not set.
        """
        err_fields = []
        if self.name is None:
            err_fields.append("name")

        if err_fields:
            raise ValueError(
                f"Missing required fields: {', '.join(f'`{t}`' for t in err_fields)}"
            )

        return FunctionDef(
            decorators=self.decorators,
            is_async=self.is_async,
            type_params=self.type_params,
            args=self.args,
            returns=self.returns_ty,
            name=self.name,  # type:ignore[arg-type]
            body=Block(*statements),
        )

is_async instance-attribute ¤

is_async: bool = False

Whether this function is asynchronous.

decorators instance-attribute ¤

decorators: list[Expression] = []

Decorators.

type_params instance-attribute ¤

type_params: list[TypeParam] = []

Type parameters.

args instance-attribute ¤

args: list[FnArg] = []

Function arguments.

returns_ty instance-attribute ¤

returns_ty: Expression | None = None

Return types of the function.

name instance-attribute ¤

name: Identifier | None = None

Function name.

__init__ ¤

__init__() -> None

Initialize an empty builder.

Source code in synt/stmt/fn.py
def __init__(self) -> None:
    """Initialize an empty builder."""
    self.is_async = False
    self.decorators = []
    self.type_params = []
    self.args = []
    self.returns_ty = None
    self.name = None

async_ ¤

async_() -> Self

Set this function as asynchronous.

Source code in synt/stmt/fn.py
def async_(self) -> Self:
    """Set this function as asynchronous."""
    self.is_async = True
    return self

decorator ¤

decorator(decorator: IntoExpression) -> Self

Append a decorator.

Parameters:

Name Type Description Default
decorator IntoExpression

Decorator to append.

required
Source code in synt/stmt/fn.py
def decorator(self, decorator: IntoExpression) -> Self:
    """Append a decorator.

    Args:
        decorator: Decorator to append.
    """
    self.decorators.append(decorator.into_expression())
    return self

dec ¤

dec(decorator: IntoExpression) -> Self

Alias [synt.stmt.fn.FunctionDefBuilder.decorator].

Source code in synt/stmt/fn.py
def dec(self, decorator: IntoExpression) -> Self:
    """Alias [synt.stmt.fn.FunctionDefBuilder.decorator]."""
    return self.decorator(decorator)

def_ ¤

def_(name: Identifier) -> Self

Initialize a function.

Parameters:

Name Type Description Default
name Identifier

Function name.

required
Source code in synt/stmt/fn.py
def def_(self, name: Identifier) -> Self:
    """Initialize a function.

    Args:
        name: Function name.
    """
    self.name = name
    return self

async_def ¤

async_def(name: Identifier) -> Self

Initialize an async function.

This is equivalent to self.async_().def_(name).

Parameters:

Name Type Description Default
name Identifier

Function name.

required
Source code in synt/stmt/fn.py
def async_def(self, name: Identifier) -> Self:
    """Initialize an async function.

    This is equivalent to `self.async_().def_(name)`.

    Args:
        name: Function name.
    """
    return self.async_().def_(name)

type_param ¤

type_param(*args: TypeParam | Identifier) -> Self

Add generic type parameters.

Parameters:

Name Type Description Default
*args TypeParam | Identifier

Type parameters to add.

()
Source code in synt/stmt/fn.py
def type_param(self, *args: TypeParam | Identifier) -> Self:
    """Add generic type parameters.

    Args:
        *args: Type parameters to add.
    """
    from synt.tokens.ident import Identifier

    self.type_params = [
        TypeVar(x) if isinstance(x, Identifier) else x for x in args
    ]
    return self

ty ¤

ty(*args: TypeParam | Identifier) -> Self

Alias type_param.

Source code in synt/stmt/fn.py
def ty(self, *args: TypeParam | Identifier) -> Self:
    """Alias [`type_param`][synt.stmt.fn.FunctionDefBuilder.type_param]."""
    return self.type_param(*args)

__getitem__ ¤

1
2
3
4
5
6
7
__getitem__(
    items: (
        tuple[TypeParam | Identifier, ...]
        | TypeParam
        | Identifier
    )
) -> Self

Alias type_param.

Source code in synt/stmt/fn.py
def __getitem__(
    self, items: tuple[TypeParam | Identifier, ...] | TypeParam | Identifier
) -> Self:
    """Alias [`type_param`][synt.stmt.fn.FunctionDefBuilder.type_param]."""
    if isinstance(items, tuple):
        return self.type_param(*items)
    else:
        return self.type_param(items)

arg ¤

1
2
3
arg(
    *args: FnArg | Identifier, **kwargs: IntoExpression
) -> Self

Add arguments for the function.

Parameters:

Name Type Description Default
*args FnArg | Identifier

Arguments to add.

()
**kwargs IntoExpression

Keyword arguments to add with their default values.

{}
Source code in synt/stmt/fn.py
def arg(self, *args: FnArg | Identifier, **kwargs: IntoExpression) -> Self:
    """Add arguments for the function.

    Args:
        *args: Arguments to add.
        **kwargs: Keyword arguments to add with their default values.
    """
    from synt.tokens.ident import Identifier

    self.args = []
    for a in args:
        if isinstance(a, Identifier):
            self.args.append(FnArg(a))
        else:
            self.args.append(a)
    for k, v in kwargs.items():
        self.args.append(FnArg(Identifier(k), default=v.into_expression()))
    return self

__call__ ¤

1
2
3
__call__(
    *args: FnArg | Identifier, **kwargs: IntoExpression
) -> Self

Alias arg.

Source code in synt/stmt/fn.py
def __call__(self, *args: FnArg | Identifier, **kwargs: IntoExpression) -> Self:
    """Alias [`arg`][synt.stmt.fn.FunctionDefBuilder.arg]."""
    return self.arg(*args, **kwargs)

returns ¤

returns(returns: IntoExpression) -> Self

Set the return type of the function.

Parameters:

Name Type Description Default
returns IntoExpression

Return type of the function.

required
Source code in synt/stmt/fn.py
def returns(self, returns: IntoExpression) -> Self:
    """Set the return type of the function.

    Args:
        returns: Return type of the function.
    """
    self.returns_ty = returns.into_expression()
    return self

block ¤

block(*statements: Statement) -> FunctionDef

Set the block of the function, and build it.

Parameters:

Name Type Description Default
*statements Statement

Statements to include in the function body.

()

Raises:

Type Description
ValueError

If the required fields ([name,]) are not set.

Source code in synt/stmt/fn.py
def block(self, *statements: Statement) -> FunctionDef:
    """Set the block of the function, and build it.

    Args:
        *statements: Statements to include in the function body.

    Raises:
        ValueError: If the required fields (`[name,]`) are not set.
    """
    err_fields = []
    if self.name is None:
        err_fields.append("name")

    if err_fields:
        raise ValueError(
            f"Missing required fields: {', '.join(f'`{t}`' for t in err_fields)}"
        )

    return FunctionDef(
        decorators=self.decorators,
        is_async=self.is_async,
        type_params=self.type_params,
        args=self.args,
        returns=self.returns_ty,
        name=self.name,  # type:ignore[arg-type]
        body=Block(*statements),
    )

vararg ¤

vararg(i: Identifier) -> FnArg

Initialize a variable argument.

This is equivalent to FnArg(...).vararg().

Examples:

va = vararg(id_("foo")).ty(id_("int"))
assert va.into_code() == "*foo: int"
Source code in synt/stmt/fn.py
def vararg(i: Identifier) -> FnArg:
    r"""Initialize a variable argument.

    This is equivalent to `FnArg(...).vararg()`.

    Examples:
        ```python
        va = vararg(id_("foo")).ty(id_("int"))
        assert va.into_code() == "*foo: int"
        ```
    """
    return FnArg(i).vararg()

kwarg ¤

kwarg(i: Identifier) -> FnArg

Initialize a keyword argument.

This is equivalent to FnArg(...).kwarg().

Examples:

va = kwarg(id_("foo")).ty(id_("tuple").expr()[id_("str"), id_("int")])
assert va.into_code() == "**foo: tuple[str, int]"
Source code in synt/stmt/fn.py
def kwarg(i: Identifier) -> FnArg:
    r"""Initialize a keyword argument.

    This is equivalent to `FnArg(...).kwarg()`.

    Examples:
        ```python
        va = kwarg(id_("foo")).ty(id_("tuple").expr()[id_("str"), id_("int")])
        assert va.into_code() == "**foo: tuple[str, int]"
        ```
    """
    return FnArg(i).kwarg()

def_ ¤

Initialize a function definition.

Parameters:

Name Type Description Default
name Identifier

Function name.

required
Source code in synt/stmt/fn.py
def def_(name: Identifier) -> FunctionDefBuilder:
    r"""Initialize a function definition.

    Args:
        name: Function name.
    """
    return FunctionDefBuilder().def_(name)

async_def ¤

async_def(name: Identifier) -> FunctionDefBuilder

Initialize an async function definition.

Parameters:

Name Type Description Default
name Identifier

Function name.

required
Source code in synt/stmt/fn.py
def async_def(name: Identifier) -> FunctionDefBuilder:
    r"""Initialize an async function definition.

    Args:
        name: Function name.
    """
    return FunctionDefBuilder().async_def(name)

importing ¤

import_ module-attribute ¤

import_ = Import

Alias Import.

from_ module-attribute ¤

Import ¤

Bases: Statement

The import statement.

Examples:

1
2
3
4
5
6
im = import_(id_("path"))
assert im.into_code() == "import path"
im = import_(id_("asyncio").as_(id_("aio")))
assert im.into_code() == "import asyncio as aio"
im = import_(path(id_("io"), id_("path")))
assert im.into_code() == "import io.path"
References

Import.

Source code in synt/stmt/importing.py
class Import(Statement):
    r"""The `import` statement.

    Examples:
        ```python
        im = import_(id_("path"))
        assert im.into_code() == "import path"
        im = import_(id_("asyncio").as_(id_("aio")))
        assert im.into_code() == "import asyncio as aio"
        im = import_(path(id_("io"), id_("path")))
        assert im.into_code() == "import io.path"
        ```

    References:
        [`Import`](https://docs.python.org/3/library/ast.html#ast.Import).
    """

    names: list[ImportType]
    """Identifiers that are imported."""

    def __init__(self, *names: ImportType):
        """Initialize a new `import` statement.

        Args:
            names: Identifiers that are imported.

        Raises:
            ValueError: If no import names are provided.
        """
        if len(names) == 0:
            raise ValueError("At least one import name is required.")

        self.names = list(names)

    def indented(self, indent_width: int, indent_atom: str) -> str:
        names: list[str] = []
        for name in self.names:
            if isinstance(name, str):
                names.append(name)
            else:
                names.append(name.into_code())

        return f"{indent_atom * indent_width}import {', '.join(names)}"

names instance-attribute ¤

names: list[ImportType] = list(names)

Identifiers that are imported.

__init__ ¤

__init__(*names: ImportType)

Initialize a new import statement.

Parameters:

Name Type Description Default
names ImportType

Identifiers that are imported.

()

Raises:

Type Description
ValueError

If no import names are provided.

Source code in synt/stmt/importing.py
def __init__(self, *names: ImportType):
    """Initialize a new `import` statement.

    Args:
        names: Identifiers that are imported.

    Raises:
        ValueError: If no import names are provided.
    """
    if len(names) == 0:
        raise ValueError("At least one import name is required.")

    self.names = list(names)

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/importing.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    names: list[str] = []
    for name in self.names:
        if isinstance(name, str):
            names.append(name)
        else:
            names.append(name.into_code())

    return f"{indent_atom * indent_width}import {', '.join(names)}"

ImportFrom ¤

Bases: Statement

The from ... import statement.

Examples:

1
2
3
4
5
6
7
8
fi = from_(id_("io")).import_(id_("path"))
assert fi.into_code() == "from io import path"
fi = from_(id_("io")).import_(id_("path").as_(id_("p")))
assert fi.into_code() == "from io import path as p"
fi = from_(id_("io")).import_(path(id_("path")), id_("os").as_(id_("p")))
assert fi.into_code() == "from io import path, os as p"
fi = from_(id_("io")).import_("*")
assert fi.into_code() == "from io import *"
References

ImportFrom.

Source code in synt/stmt/importing.py
class ImportFrom(Statement):
    r"""The `from ... import` statement.

    Examples:
        ```python
        fi = from_(id_("io")).import_(id_("path"))
        assert fi.into_code() == "from io import path"
        fi = from_(id_("io")).import_(id_("path").as_(id_("p")))
        assert fi.into_code() == "from io import path as p"
        fi = from_(id_("io")).import_(path(id_("path")), id_("os").as_(id_("p")))
        assert fi.into_code() == "from io import path, os as p"
        fi = from_(id_("io")).import_("*")
        assert fi.into_code() == "from io import *"
        ```

    References:
        [`ImportFrom`](https://docs.python.org/3/library/ast.html#ast.ImportFrom).
    """

    module: ModPath
    """The module to import from."""
    names: list[ImportType]
    """Identifiers that are imported."""

    def __init__(self, module: ModPath, *names: ImportType):
        """Initialize a new `from ... import` statement.

        Args:
            module: The module to import from.
            names: Identifiers that are imported.

        Raises:
            ValueError: If no import names are provided.
        """
        if len(names) == 0:
            raise ValueError("At least one import name is required.")

        self.names = list(names)
        self.module = module

    def indented(self, indent_width: int, indent_atom: str) -> str:
        names: list[str] = []
        for name in self.names:
            if isinstance(name, str):
                names.append(name)
            else:
                names.append(name.into_code())

        return f"{indent_atom * indent_width}from {self.module.into_code()} import {', '.join(names)}"

names instance-attribute ¤

names: list[ImportType] = list(names)

Identifiers that are imported.

module instance-attribute ¤

module: ModPath = module

The module to import from.

__init__ ¤

__init__(module: ModPath, *names: ImportType)

Initialize a new from ... import statement.

Parameters:

Name Type Description Default
module ModPath

The module to import from.

required
names ImportType

Identifiers that are imported.

()

Raises:

Type Description
ValueError

If no import names are provided.

Source code in synt/stmt/importing.py
def __init__(self, module: ModPath, *names: ImportType):
    """Initialize a new `from ... import` statement.

    Args:
        module: The module to import from.
        names: Identifiers that are imported.

    Raises:
        ValueError: If no import names are provided.
    """
    if len(names) == 0:
        raise ValueError("At least one import name is required.")

    self.names = list(names)
    self.module = module

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/importing.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    names: list[str] = []
    for name in self.names:
        if isinstance(name, str):
            names.append(name)
        else:
            names.append(name.into_code())

    return f"{indent_atom * indent_width}from {self.module.into_code()} import {', '.join(names)}"

ImportFromBuilder ¤

The builder for ImportFrom.

Source code in synt/stmt/importing.py
class ImportFromBuilder:
    r"""The builder for [`ImportFrom`][synt.stmt.importing.ImportFrom]."""

    module: ModPath
    """The module to import from."""

    def __init__(self, module: ModPath | Identifier):
        """Initialize a new `from ... import` statement builder.

        Args:
            module: The module to import from.
        """
        from synt.expr.modpath import ModPath
        from synt.tokens.ident import Identifier

        if isinstance(module, Identifier):
            self.module = ModPath(module)
        else:
            self.module = module

    def import_(self, *names: ImportType) -> ImportFrom:
        """Import target objects from the module.

        Args:
            names: Items that are imported.

        Raises:
            ValueError: If no import names are provided.
        """
        return ImportFrom(self.module, *names)

module instance-attribute ¤

module: ModPath

The module to import from.

__init__ ¤

__init__(module: ModPath | Identifier)

Initialize a new from ... import statement builder.

Parameters:

Name Type Description Default
module ModPath | Identifier

The module to import from.

required
Source code in synt/stmt/importing.py
def __init__(self, module: ModPath | Identifier):
    """Initialize a new `from ... import` statement builder.

    Args:
        module: The module to import from.
    """
    from synt.expr.modpath import ModPath
    from synt.tokens.ident import Identifier

    if isinstance(module, Identifier):
        self.module = ModPath(module)
    else:
        self.module = module

import_ ¤

import_(*names: ImportType) -> ImportFrom

Import target objects from the module.

Parameters:

Name Type Description Default
names ImportType

Items that are imported.

()

Raises:

Type Description
ValueError

If no import names are provided.

Source code in synt/stmt/importing.py
def import_(self, *names: ImportType) -> ImportFrom:
    """Import target objects from the module.

    Args:
        names: Items that are imported.

    Raises:
        ValueError: If no import names are provided.
    """
    return ImportFrom(self.module, *names)

keyword ¤

PASS module-attribute ¤

PASS = KeywordStatement('pass')

BREAK module-attribute ¤

BREAK = KeywordStatement('break')

CONTINUE module-attribute ¤

CONTINUE = KeywordStatement('continue')

KeywordStatement ¤

Bases: Statement

A statement that only contains a specific keyword.

Examples:

1
2
3
assert PASS.into_code() == "pass"
assert BREAK.into_code() == "break"
assert CONTINUE.into_code() == "continue"
Source code in synt/stmt/keyword.py
class KeywordStatement(Statement):
    r"""A statement that only contains a specific keyword.

    Examples:
        ```python
        assert PASS.into_code() == "pass"
        assert BREAK.into_code() == "break"
        assert CONTINUE.into_code() == "continue"
        ```
    """

    keyword: str

    def __init__(self, keyword: str):
        """Initialize a new keyword statement.

        Args:
            keyword: The keyword to be used in the statement.
        """
        self.keyword = keyword

    def indented(self, indent_width: int, indent_atom: str) -> str:
        return f"{indent_width * indent_atom}{self.keyword}"

keyword instance-attribute ¤

keyword: str = keyword

__init__ ¤

__init__(keyword: str)

Initialize a new keyword statement.

Parameters:

Name Type Description Default
keyword str

The keyword to be used in the statement.

required
Source code in synt/stmt/keyword.py
def __init__(self, keyword: str):
    """Initialize a new keyword statement.

    Args:
        keyword: The keyword to be used in the statement.
    """
    self.keyword = keyword

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/keyword.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    return f"{indent_width * indent_atom}{self.keyword}"

loop ¤

for_ module-attribute ¤

while_ module-attribute ¤

ForLoop ¤

Bases: Statement

The for loop.

Examples:

for_loop = for_(id_("i")).in_(id_("range").expr().call(litint(5))).block(
               if_(id_("i").expr().gt(litint(2))).block(
                   BREAK
               ).else_(
                   CONTINUE
               )
           ).else_(
               PASS
           )
assert for_loop.into_code() == '''for i in range(5):
    if i > 2:
        break
    else:
        continue
else:
    pass'''
# for i in range(5):
#     if i > 2:
#         break
#     else:
#         continue
# else:
#     pass
References

For.

Source code in synt/stmt/loop.py
class ForLoop(Statement):
    r"""The `for` loop.

    Examples:
        ```python
        for_loop = for_(id_("i")).in_(id_("range").expr().call(litint(5))).block(
                       if_(id_("i").expr().gt(litint(2))).block(
                           BREAK
                       ).else_(
                           CONTINUE
                       )
                   ).else_(
                       PASS
                   )
        assert for_loop.into_code() == '''for i in range(5):
            if i > 2:
                break
            else:
                continue
        else:
            pass'''
        # for i in range(5):
        #     if i > 2:
        #         break
        #     else:
        #         continue
        # else:
        #     pass
        ```

    References:
        [`For`](https://docs.python.org/3/library/ast.html#ast.For).
    """

    target: Expression
    """Target item for the iteration.

    Notes:
        Tuples will be automatically unwrapped.
    """
    iter: Expression
    """The expression to iterate over."""
    body: Block
    """The body of the loop."""
    orelse: Block | None
    """The body of the fallback block, aka `for ... else`."""

    def __init__(self, target: IntoExpression, it: IntoExpression, body: Block):
        """Initialize the loop.

        **DO NOT USE THIS IN YOUR CODE!**

        Args:
            target: Target item for the iteration.
            it: The expression to iterate over.
            body: The body of the loop.
        """
        self.target = target.into_expression()
        self.iter = it.into_expression()
        self.body = body
        self.orelse = None

    def else_(self, *statements: Statement) -> Self:
        """Set the fallback `else` block.

        Args:
            statements: The body of the fallback block.
        """
        self.orelse = Block(*statements)
        return self

    def indented(self, indent_width: int, indent_atom: str) -> str:
        indent = indent_atom * indent_width
        if self.orelse is not None:
            else_text = f"\n{indent}else:\n{self.orelse.indented(indent_width + 1, indent_atom)}"
        else:
            else_text = ""
        if is_tuple(self.target):
            target_text = self.target.into_code_implicit()
        else:
            target_text = self.target.into_code()
        return (
            f"{indent}for {target_text} in {self.iter.into_code()}:\n"
            f"{self.body.indented(indent_width + 1, indent_atom)}"
            f"{else_text}"
        )

target instance-attribute ¤

target: Expression = into_expression()

Target item for the iteration.

Notes

Tuples will be automatically unwrapped.

iter instance-attribute ¤

iter: Expression = into_expression()

The expression to iterate over.

body instance-attribute ¤

body: Block = body

The body of the loop.

orelse instance-attribute ¤

orelse: Block | None = None

The body of the fallback block, aka for ... else.

__init__ ¤

1
2
3
__init__(
    target: IntoExpression, it: IntoExpression, body: Block
)

Initialize the loop.

DO NOT USE THIS IN YOUR CODE!

Parameters:

Name Type Description Default
target IntoExpression

Target item for the iteration.

required
it IntoExpression

The expression to iterate over.

required
body Block

The body of the loop.

required
Source code in synt/stmt/loop.py
def __init__(self, target: IntoExpression, it: IntoExpression, body: Block):
    """Initialize the loop.

    **DO NOT USE THIS IN YOUR CODE!**

    Args:
        target: Target item for the iteration.
        it: The expression to iterate over.
        body: The body of the loop.
    """
    self.target = target.into_expression()
    self.iter = it.into_expression()
    self.body = body
    self.orelse = None

else_ ¤

else_(*statements: Statement) -> Self

Set the fallback else block.

Parameters:

Name Type Description Default
statements Statement

The body of the fallback block.

()
Source code in synt/stmt/loop.py
def else_(self, *statements: Statement) -> Self:
    """Set the fallback `else` block.

    Args:
        statements: The body of the fallback block.
    """
    self.orelse = Block(*statements)
    return self

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/loop.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    indent = indent_atom * indent_width
    if self.orelse is not None:
        else_text = f"\n{indent}else:\n{self.orelse.indented(indent_width + 1, indent_atom)}"
    else:
        else_text = ""
    if is_tuple(self.target):
        target_text = self.target.into_code_implicit()
    else:
        target_text = self.target.into_code()
    return (
        f"{indent}for {target_text} in {self.iter.into_code()}:\n"
        f"{self.body.indented(indent_width + 1, indent_atom)}"
        f"{else_text}"
    )

ForLoopBuilder ¤

Builder for for loop.

References

ForLoop.

Source code in synt/stmt/loop.py
class ForLoopBuilder:
    r"""Builder for `for` loop.

    References:
        [`ForLoop`][synt.stmt.loop.ForLoop].
    """

    target: Expression
    """Target item for the iteration."""
    iter: Expression | None
    """The expression to iterate over."""

    def __init__(self, target: IntoExpression):
        """Initialize a new `for` loop builder.

        Args:
            target: Target item for the iteration.
        """
        self.target = target.into_expression()
        self.iter = None

    def in_(self, it: IntoExpression) -> Self:
        """Set the iterator of the loop.

        Args:
            it: The expression to iterate over.
        """
        self.iter = it.into_expression()
        return self

    def block(self, *statements: Statement) -> ForLoop:
        """Set the block of the loop.

        Args:
            *statements: Statements to include in the loop body.

        Raises:
            ValueError: If the required fields (`[iter,]`) are not set.
        """
        err_fields = []
        if self.iter is None:
            err_fields.append("iter")

        if err_fields:
            raise ValueError(
                f"Missing required field(s): {', '.join(f'`{t}`' for t in err_fields)}"
            )

        return ForLoop(self.target, self.iter, Block(*statements))  # type:ignore[arg-type]

target instance-attribute ¤

target: Expression = into_expression()

Target item for the iteration.

iter instance-attribute ¤

iter: Expression | None = None

The expression to iterate over.

__init__ ¤

__init__(target: IntoExpression)

Initialize a new for loop builder.

Parameters:

Name Type Description Default
target IntoExpression

Target item for the iteration.

required
Source code in synt/stmt/loop.py
def __init__(self, target: IntoExpression):
    """Initialize a new `for` loop builder.

    Args:
        target: Target item for the iteration.
    """
    self.target = target.into_expression()
    self.iter = None

in_ ¤

in_(it: IntoExpression) -> Self

Set the iterator of the loop.

Parameters:

Name Type Description Default
it IntoExpression

The expression to iterate over.

required
Source code in synt/stmt/loop.py
def in_(self, it: IntoExpression) -> Self:
    """Set the iterator of the loop.

    Args:
        it: The expression to iterate over.
    """
    self.iter = it.into_expression()
    return self

block ¤

block(*statements: Statement) -> ForLoop

Set the block of the loop.

Parameters:

Name Type Description Default
*statements Statement

Statements to include in the loop body.

()

Raises:

Type Description
ValueError

If the required fields ([iter,]) are not set.

Source code in synt/stmt/loop.py
def block(self, *statements: Statement) -> ForLoop:
    """Set the block of the loop.

    Args:
        *statements: Statements to include in the loop body.

    Raises:
        ValueError: If the required fields (`[iter,]`) are not set.
    """
    err_fields = []
    if self.iter is None:
        err_fields.append("iter")

    if err_fields:
        raise ValueError(
            f"Missing required field(s): {', '.join(f'`{t}`' for t in err_fields)}"
        )

    return ForLoop(self.target, self.iter, Block(*statements))  # type:ignore[arg-type]

WhileLoop ¤

The while loop.

References

While.

Source code in synt/stmt/loop.py
class WhileLoop:
    r"""The `while` loop.

    References:
        [`While`](https://docs.python.org/3/library/ast.html#ast.While).
    """

    test: Expression
    """The condition."""
    orelse: Block | None
    """The body of the fallback block, aka `while ... else`."""

    def __init__(self, test: IntoExpression, body: Block):
        """Initialize a new `while` loop.

        **DO NOT USE THIS IN YOUR CODE!**

        Args:
            test: The condition.
            body: The body of the loop.
        """
        self.test = test.into_expression()
        self.orelse = None
        self.body = body

    def else_(self, *statements: Statement) -> Self:
        """Set the fallback `else` block.

        Args:
            statements: The body of the fallback block.
        """
        self.orelse = Block(*statements)
        return self

    def indented(self, indent_width: int, indent_atom: str) -> str:
        indent = indent_atom * indent_width
        if self.orelse is not None:
            else_text = f"\n{indent}else:\n{self.orelse.indented(indent_width + 1, indent_atom)}"
        else:
            else_text = ""
        return (
            f"{indent}while {self.test.into_code()}:\n"
            f"{self.body.indented(indent_width + 1, indent_atom)}"
            f"{else_text}"
        )

test instance-attribute ¤

test: Expression = into_expression()

The condition.

orelse instance-attribute ¤

orelse: Block | None = None

The body of the fallback block, aka while ... else.

body instance-attribute ¤

body = body

__init__ ¤

__init__(test: IntoExpression, body: Block)

Initialize a new while loop.

DO NOT USE THIS IN YOUR CODE!

Parameters:

Name Type Description Default
test IntoExpression

The condition.

required
body Block

The body of the loop.

required
Source code in synt/stmt/loop.py
def __init__(self, test: IntoExpression, body: Block):
    """Initialize a new `while` loop.

    **DO NOT USE THIS IN YOUR CODE!**

    Args:
        test: The condition.
        body: The body of the loop.
    """
    self.test = test.into_expression()
    self.orelse = None
    self.body = body

else_ ¤

else_(*statements: Statement) -> Self

Set the fallback else block.

Parameters:

Name Type Description Default
statements Statement

The body of the fallback block.

()
Source code in synt/stmt/loop.py
def else_(self, *statements: Statement) -> Self:
    """Set the fallback `else` block.

    Args:
        statements: The body of the fallback block.
    """
    self.orelse = Block(*statements)
    return self

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/loop.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    indent = indent_atom * indent_width
    if self.orelse is not None:
        else_text = f"\n{indent}else:\n{self.orelse.indented(indent_width + 1, indent_atom)}"
    else:
        else_text = ""
    return (
        f"{indent}while {self.test.into_code()}:\n"
        f"{self.body.indented(indent_width + 1, indent_atom)}"
        f"{else_text}"
    )

WhileLoopBuilder ¤

Builder for while loop.

Examples:

while_loop = while_(id_("i").expr().lt(litint(5))).block(
                 id_("i").assign(id_("i").expr() + litint(1))
             ).else_(
                 PASS
             )
assert while_loop.into_code() == '''while i < 5:
    i = i + 1
else:
    pass'''
# while i < 5:
#     i = i + 1
# else:
#     pass
References

WhileLoop.

Source code in synt/stmt/loop.py
class WhileLoopBuilder:
    r"""Builder for `while` loop.

    Examples:
        ```python
        while_loop = while_(id_("i").expr().lt(litint(5))).block(
                         id_("i").assign(id_("i").expr() + litint(1))
                     ).else_(
                         PASS
                     )
        assert while_loop.into_code() == '''while i < 5:
            i = i + 1
        else:
            pass'''
        # while i < 5:
        #     i = i + 1
        # else:
        #     pass
        ```

    References:
        [`WhileLoop`][synt.stmt.loop.WhileLoop].
    """

    test: Expression
    """The condition."""

    def __init__(self, test: IntoExpression):
        """Initialize a new `while` loop builder.

        Args:
            test: The condition.
        """
        self.test = test.into_expression()

    def block(self, *statements: Statement) -> WhileLoop:
        """Set the block of the loop.

        Args:
            *statements: Statements to include in the loop body.
        """
        return WhileLoop(self.test, Block(*statements))

test instance-attribute ¤

test: Expression = into_expression()

The condition.

__init__ ¤

__init__(test: IntoExpression)

Initialize a new while loop builder.

Parameters:

Name Type Description Default
test IntoExpression

The condition.

required
Source code in synt/stmt/loop.py
def __init__(self, test: IntoExpression):
    """Initialize a new `while` loop builder.

    Args:
        test: The condition.
    """
    self.test = test.into_expression()

block ¤

block(*statements: Statement) -> WhileLoop

Set the block of the loop.

Parameters:

Name Type Description Default
*statements Statement

Statements to include in the loop body.

()
Source code in synt/stmt/loop.py
def block(self, *statements: Statement) -> WhileLoop:
    """Set the block of the loop.

    Args:
        *statements: Statements to include in the loop body.
    """
    return WhileLoop(self.test, Block(*statements))

match_case ¤

match_ module-attribute ¤

match_ = Match

Alias Match.

MatchCase ¤

Bases: Statement

A case statement.

References

matchcase.

Source code in synt/stmt/match_case.py
class MatchCase(Statement):
    r"""A `case` statement.

    References:
        [`matchcase`](https://docs.python.org/3/library/ast.html#ast.match_case).
    """

    pattern: Expression
    """Match pattern."""
    guard: Expression | None
    """Pattern guard."""
    body: Block
    """Case body."""

    def __init__(
        self, pattern: IntoExpression, guard: IntoExpression | None, body: Block
    ):
        """Initialize a `case` statement.

        **DO NOT USE THIS IN YOUR CODE!**

        Args:
            pattern: Match pattern.
            guard: Pattern guard.
            body: Case body.
        """
        self.pattern = pattern.into_expression()
        self.guard = guard.into_expression() if guard is not None else None
        self.body = body

    def indented(self, indent_width: int, indent_atom: str) -> str:
        guard = f" if {self.guard.into_code()}" if self.guard is not None else ""
        return (
            f"{indent_atom * indent_width}case {self.pattern.into_code()}{guard}:\n"
            f"{self.body.indented(indent_width + 1, indent_atom)}"
        )

pattern instance-attribute ¤

pattern: Expression = into_expression()

Match pattern.

guard instance-attribute ¤

1
2
3
guard: Expression | None = (
    into_expression() if guard is not None else None
)

Pattern guard.

body instance-attribute ¤

body: Block = body

Case body.

__init__ ¤

1
2
3
4
5
__init__(
    pattern: IntoExpression,
    guard: IntoExpression | None,
    body: Block,
)

Initialize a case statement.

DO NOT USE THIS IN YOUR CODE!

Parameters:

Name Type Description Default
pattern IntoExpression

Match pattern.

required
guard IntoExpression | None

Pattern guard.

required
body Block

Case body.

required
Source code in synt/stmt/match_case.py
def __init__(
    self, pattern: IntoExpression, guard: IntoExpression | None, body: Block
):
    """Initialize a `case` statement.

    **DO NOT USE THIS IN YOUR CODE!**

    Args:
        pattern: Match pattern.
        guard: Pattern guard.
        body: Case body.
    """
    self.pattern = pattern.into_expression()
    self.guard = guard.into_expression() if guard is not None else None
    self.body = body

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/match_case.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    guard = f" if {self.guard.into_code()}" if self.guard is not None else ""
    return (
        f"{indent_atom * indent_width}case {self.pattern.into_code()}{guard}:\n"
        f"{self.body.indented(indent_width + 1, indent_atom)}"
    )

MatchCaseBuilder ¤

Builder for MatchCase.

Source code in synt/stmt/match_case.py
class MatchCaseBuilder:
    """Builder for [`MatchCase`][synt.stmt.match_case.MatchCase]."""

    pattern: Expression
    """Match pattern."""
    guard: Expression | None
    """Pattern guard."""
    parent: Match
    """Parent node."""

    def __init__(self, pattern: IntoExpression, parent: Match):
        """Initialize a new builder.

        Args:
            pattern: Match pattern.
        """
        self.pattern = pattern.into_expression()
        self.guard = None
        self.parent = parent

    def if_(self, guard: IntoExpression) -> Self:
        """Set the guard.

        Args:
            guard: Pattern guard.
        """
        self.guard = guard.into_expression()
        return self

    def block(self, *statements: Statement) -> Match:
        """Set the body statements.

        Args:
            *statements: Body statements.
        """
        case = MatchCase(self.pattern, self.guard, Block(*statements))
        self.parent.cases.append(case)
        return self.parent

pattern instance-attribute ¤

pattern: Expression = into_expression()

Match pattern.

guard instance-attribute ¤

guard: Expression | None = None

Pattern guard.

parent instance-attribute ¤

parent: Match = parent

Parent node.

__init__ ¤

__init__(pattern: IntoExpression, parent: Match)

Initialize a new builder.

Parameters:

Name Type Description Default
pattern IntoExpression

Match pattern.

required
Source code in synt/stmt/match_case.py
def __init__(self, pattern: IntoExpression, parent: Match):
    """Initialize a new builder.

    Args:
        pattern: Match pattern.
    """
    self.pattern = pattern.into_expression()
    self.guard = None
    self.parent = parent

if_ ¤

if_(guard: IntoExpression) -> Self

Set the guard.

Parameters:

Name Type Description Default
guard IntoExpression

Pattern guard.

required
Source code in synt/stmt/match_case.py
def if_(self, guard: IntoExpression) -> Self:
    """Set the guard.

    Args:
        guard: Pattern guard.
    """
    self.guard = guard.into_expression()
    return self

block ¤

block(*statements: Statement) -> Match

Set the body statements.

Parameters:

Name Type Description Default
*statements Statement

Body statements.

()
Source code in synt/stmt/match_case.py
def block(self, *statements: Statement) -> Match:
    """Set the body statements.

    Args:
        *statements: Body statements.
    """
    case = MatchCase(self.pattern, self.guard, Block(*statements))
    self.parent.cases.append(case)
    return self.parent

Match ¤

Bases: Statement

The match statement.

Examples:

match_stmt = (
    match_(id_("a"))
    .case_(id_("b")).block(PASS)
    .case_(id_("Point").expr().call(id_("x"), id_("y"))).block(PASS)
    .case_(list_(id_("x")).as_(id_("y"))).block(PASS)
    .case_(UNDERSCORE).block(PASS)
)
assert match_stmt.into_code() == '''match a:
    case b:
        pass
    case Point(x, y):
        pass
    case [x] as y:
        pass
    case _:
        pass'''
# match a:
#     case b:
#         pass
#     case Point(x, y):
#         pass
#     case [x] as y:
#         pass
#     case _:
#         pass
Notes

Python views [x], (x), etc, as different case nodes, but Synt views them as the same. Synt accepts any form of expression as case patterns, and you must check yourself.

References

Match.

Source code in synt/stmt/match_case.py
class Match(Statement):
    r"""The `match` statement.

    Examples:
        ```python
        match_stmt = (
            match_(id_("a"))
            .case_(id_("b")).block(PASS)
            .case_(id_("Point").expr().call(id_("x"), id_("y"))).block(PASS)
            .case_(list_(id_("x")).as_(id_("y"))).block(PASS)
            .case_(UNDERSCORE).block(PASS)
        )
        assert match_stmt.into_code() == '''match a:
            case b:
                pass
            case Point(x, y):
                pass
            case [x] as y:
                pass
            case _:
                pass'''
        # match a:
        #     case b:
        #         pass
        #     case Point(x, y):
        #         pass
        #     case [x] as y:
        #         pass
        #     case _:
        #         pass
        ```

    Notes:
        Python views `[x]`, `(x)`, etc, as different `case` nodes,
        but Synt views them as the same.
        Synt accepts any form of expression as case patterns,
        and you must check yourself.

    References:
        [`Match`](https://docs.python.org/3/library/ast.html#ast.Match).
    """

    subject: Expression
    """Match subject."""
    cases: list[MatchCase]
    """Match cases."""

    def __init__(self, subject: IntoExpression):
        """Initialize a new `match` statement.

        Args:
            subject: Match subject.
        """
        self.subject = subject.into_expression()
        self.cases = []

    def case_(self, pattern: IntoExpression) -> MatchCaseBuilder:
        """Append a new case.

        Args:
            pattern: Match pattern.
        """
        return MatchCaseBuilder(pattern, self)

    def indented(self, indent_width: int, indent_atom: str) -> str:
        if len(self.cases) == 0:
            cases = f"{indent_atom * (indent_width + 1)}pass"
        else:
            cases = "\n".join(
                x.indented(indent_width + 1, indent_atom) for x in self.cases
            )
        return (
            f"{indent_atom * indent_width}match {self.subject.into_code()}:\n"
            f"{cases}"
        )

subject instance-attribute ¤

subject: Expression = into_expression()

Match subject.

cases instance-attribute ¤

cases: list[MatchCase] = []

Match cases.

__init__ ¤

__init__(subject: IntoExpression)

Initialize a new match statement.

Parameters:

Name Type Description Default
subject IntoExpression

Match subject.

required
Source code in synt/stmt/match_case.py
def __init__(self, subject: IntoExpression):
    """Initialize a new `match` statement.

    Args:
        subject: Match subject.
    """
    self.subject = subject.into_expression()
    self.cases = []

case_ ¤

case_(pattern: IntoExpression) -> MatchCaseBuilder

Append a new case.

Parameters:

Name Type Description Default
pattern IntoExpression

Match pattern.

required
Source code in synt/stmt/match_case.py
def case_(self, pattern: IntoExpression) -> MatchCaseBuilder:
    """Append a new case.

    Args:
        pattern: Match pattern.
    """
    return MatchCaseBuilder(pattern, self)

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/match_case.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    if len(self.cases) == 0:
        cases = f"{indent_atom * (indent_width + 1)}pass"
    else:
        cases = "\n".join(
            x.indented(indent_width + 1, indent_atom) for x in self.cases
        )
    return (
        f"{indent_atom * indent_width}match {self.subject.into_code()}:\n"
        f"{cases}"
    )

namespace ¤

global_ module-attribute ¤

global_ = Global

Alias Global.

nonlocal_ module-attribute ¤

nonlocal_ = Nonlocal

Alias Nonlocal.

Global ¤

Bases: Statement

The global statement.

Examples:

global_stmt = global_(id_('foo'))
assert global_stmt.into_code() == 'global foo'
References

Global.

Source code in synt/stmt/namespace.py
class Global(Statement):
    """The `global` statement.

    Examples:
        ```python
        global_stmt = global_(id_('foo'))
        assert global_stmt.into_code() == 'global foo'
        ```

    References:
        [`Global`](https://docs.python.org/3/library/ast.html#ast.Global).
    """

    names: list[Identifier]
    """Global variable names."""

    def __init__(self, *names: Identifier):
        """Initialize a new `global` statement.

        Args:
            names: Global variable names.

        Raises:
            ValueError: If the `names` list is empty.
        """
        if len(names) == 0:
            raise ValueError("At least one global variable name is required.")
        self.names = list(names)

    def indented(self, indent_width: int, indent_atom: str) -> str:
        return f"{indent_atom * indent_width}global {', '.join(name.into_code() for name in self.names)}"

names instance-attribute ¤

Global variable names.

__init__ ¤

__init__(*names: Identifier)

Initialize a new global statement.

Parameters:

Name Type Description Default
names Identifier

Global variable names.

()

Raises:

Type Description
ValueError

If the names list is empty.

Source code in synt/stmt/namespace.py
def __init__(self, *names: Identifier):
    """Initialize a new `global` statement.

    Args:
        names: Global variable names.

    Raises:
        ValueError: If the `names` list is empty.
    """
    if len(names) == 0:
        raise ValueError("At least one global variable name is required.")
    self.names = list(names)

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/namespace.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    return f"{indent_atom * indent_width}global {', '.join(name.into_code() for name in self.names)}"

Nonlocal ¤

Bases: Statement

The nonlocal statement.

Examples:

nonlocal_stmt = nonlocal_(id_('foo'))
assert nonlocal_stmt.into_code() == 'nonlocal foo'
References

Nonlocal.

Source code in synt/stmt/namespace.py
class Nonlocal(Statement):
    """The `nonlocal` statement.

    Examples:
        ```python
        nonlocal_stmt = nonlocal_(id_('foo'))
        assert nonlocal_stmt.into_code() == 'nonlocal foo'
        ```

    References:
        [`Nonlocal`](https://docs.python.org/3/library/ast.html#ast.Nonlocal).
    """

    names: list[Identifier]
    """Nonlocal variable names."""

    def __init__(self, *names: Identifier):
        """Initialize a new `nonlocal` statement.

        Args:
            names: Nonlocal variable names.

        Raises:
            ValueError: If the `names` list is empty.
        """
        if len(names) == 0:
            raise ValueError("At least one nonlocal variable name is required.")
        self.names = list(names)

    def indented(self, indent_width: int, indent_atom: str) -> str:
        return f"{indent_atom * indent_width}nonlocal {', '.join(name.into_code() for name in self.names)}"

names instance-attribute ¤

Nonlocal variable names.

__init__ ¤

__init__(*names: Identifier)

Initialize a new nonlocal statement.

Parameters:

Name Type Description Default
names Identifier

Nonlocal variable names.

()

Raises:

Type Description
ValueError

If the names list is empty.

Source code in synt/stmt/namespace.py
def __init__(self, *names: Identifier):
    """Initialize a new `nonlocal` statement.

    Args:
        names: Nonlocal variable names.

    Raises:
        ValueError: If the `names` list is empty.
    """
    if len(names) == 0:
        raise ValueError("At least one nonlocal variable name is required.")
    self.names = list(names)

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/namespace.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    return f"{indent_atom * indent_width}nonlocal {', '.join(name.into_code() for name in self.names)}"

raising ¤

raise_ module-attribute ¤

raise_ = Raise

Alias Raise.

Raise ¤

Bases: Statement

The raise statement.

Examples:

1
2
3
4
5
6
r = raise_()
assert r.into_code() == "raise"
r = raise_(litint(42))
assert r.into_code() == "raise 42"
r = raise_(litint(42)).from_(litstr("Custom exception"))
assert r.into_code() == "raise 42 from 'Custom exception'"
References

Raise.

Source code in synt/stmt/raising.py
class Raise(Statement):
    r"""The `raise` statement.

    Examples:
        ```python
        r = raise_()
        assert r.into_code() == "raise"
        r = raise_(litint(42))
        assert r.into_code() == "raise 42"
        r = raise_(litint(42)).from_(litstr("Custom exception"))
        assert r.into_code() == "raise 42 from 'Custom exception'"
        ```

    References:
        [`Raise`](https://docs.python.org/3/library/ast.html#ast.Raise).
    """

    exception: Expression | None
    """The exception to raise."""
    cause: Expression | None
    """The origin of the raised exception."""

    def __init__(self, exception: IntoExpression | None = None):
        """Initialize a new `raise` statement.

        Args:
            exception: The exception to raise.
        """
        if exception:
            self.exception = exception.into_expression()
        else:
            self.exception = None
        self.cause = None

    def from_(self, cause: IntoExpression) -> Self:
        """Set the cause of the raised exception.

        Args:
            cause: The origin of the raised exception.

        Raises:
            ValueError: If `exception` is `None`.
        """
        if self.exception is None:
            raise ValueError("Cannot set cause without setting exception.")
        self.cause = cause.into_expression()
        return self

    def indented(self, indent_width: int, indent_atom: str) -> str:
        cause = f" from {self.cause.into_code()}" if self.cause is not None else ""
        exc = f" {self.exception.into_code()}" if self.exception is not None else ""
        return f"{indent_width * indent_atom}raise{exc}{cause}"

exception instance-attribute ¤

exception: Expression | None

The exception to raise.

cause instance-attribute ¤

cause: Expression | None = None

The origin of the raised exception.

__init__ ¤

__init__(exception: IntoExpression | None = None)

Initialize a new raise statement.

Parameters:

Name Type Description Default
exception IntoExpression | None

The exception to raise.

None
Source code in synt/stmt/raising.py
def __init__(self, exception: IntoExpression | None = None):
    """Initialize a new `raise` statement.

    Args:
        exception: The exception to raise.
    """
    if exception:
        self.exception = exception.into_expression()
    else:
        self.exception = None
    self.cause = None

from_ ¤

from_(cause: IntoExpression) -> Self

Set the cause of the raised exception.

Parameters:

Name Type Description Default
cause IntoExpression

The origin of the raised exception.

required

Raises:

Type Description
ValueError

If exception is None.

Source code in synt/stmt/raising.py
def from_(self, cause: IntoExpression) -> Self:
    """Set the cause of the raised exception.

    Args:
        cause: The origin of the raised exception.

    Raises:
        ValueError: If `exception` is `None`.
    """
    if self.exception is None:
        raise ValueError("Cannot set cause without setting exception.")
    self.cause = cause.into_expression()
    return self

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/raising.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    cause = f" from {self.cause.into_code()}" if self.cause is not None else ""
    exc = f" {self.exception.into_code()}" if self.exception is not None else ""
    return f"{indent_width * indent_atom}raise{exc}{cause}"

returns ¤

return_ module-attribute ¤

return_ = Return

Alias Return.

ret module-attribute ¤

ret = Return

Alias Return.

Return ¤

Bases: Statement

The return statement.

Examples:

1
2
3
4
return_stmt = return_(litint(42))
assert return_stmt.into_code() == "return 42"
return_stmt = ret()
assert return_stmt.into_code() == "return"
References

Returns.

Source code in synt/stmt/returns.py
class Return(Statement):
    r"""The `return` statement.

    Examples:
        ```python
        return_stmt = return_(litint(42))
        assert return_stmt.into_code() == "return 42"
        return_stmt = ret()
        assert return_stmt.into_code() == "return"
        ```

    References:
        [`Returns`](https://docs.python.org/3/library/ast.html#ast.Return).
    """

    expression: Expression | None
    """The value to return from the function."""

    def __init__(self, expression: IntoExpression | None = None):
        """Initialize the return statement.

        Args:
            expression: The value to return from the function.
        """
        if expression:
            self.expression = expression.into_expression()
        else:
            self.expression = None

    def indented(self, indent_width: int, indent_atom: str) -> str:
        if self.expression:
            return f"{indent_atom * indent_width}return {self.expression.into_code()}"
        else:
            return f"{indent_atom * indent_width}return"

expression instance-attribute ¤

expression: Expression | None

The value to return from the function.

__init__ ¤

__init__(expression: IntoExpression | None = None)

Initialize the return statement.

Parameters:

Name Type Description Default
expression IntoExpression | None

The value to return from the function.

None
Source code in synt/stmt/returns.py
def __init__(self, expression: IntoExpression | None = None):
    """Initialize the return statement.

    Args:
        expression: The value to return from the function.
    """
    if expression:
        self.expression = expression.into_expression()
    else:
        self.expression = None

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/returns.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    if self.expression:
        return f"{indent_atom * indent_width}return {self.expression.into_code()}"
    else:
        return f"{indent_atom * indent_width}return"

stmt ¤

IntoStatement ¤

Any type that can be converted into a statement.

Source code in synt/stmt/stmt.py
class IntoStatement(metaclass=ABCMeta):
    r"""Any type that can be converted into a statement."""

    @abstractmethod
    def into_statement(self) -> Statement:
        """Convert the object into a statement."""

into_statement abstractmethod ¤

into_statement() -> Statement

Convert the object into a statement.

Source code in synt/stmt/stmt.py
@abstractmethod
def into_statement(self) -> Statement:
    """Convert the object into a statement."""

Statement ¤

Bases: IntoCode, IntoStatement

A base class for any Python statement.

Source code in synt/stmt/stmt.py
class Statement(IntoCode, IntoStatement, metaclass=ABCMeta):
    r"""A base class for any Python statement."""

    def into_statement(self) -> Statement:
        """A statement can always be converted into a statement."""
        return self

    @abstractmethod
    def indented(self, indent_width: int, indent_atom: str) -> str:
        """Return the code block with appropriate indentation.

        Args:
            indent_width: number of `indent_atom`s per indentation level.
            indent_atom: string to use for indentation. E.g. `\\t`, whitespace, etc.

        Returns:
            indented code block.
        """

    def into_code(self) -> str:
        """Convert the object into a code string."""
        return self.indented(0, "    ")

into_statement ¤

into_statement() -> Statement

A statement can always be converted into a statement.

Source code in synt/stmt/stmt.py
def into_statement(self) -> Statement:
    """A statement can always be converted into a statement."""
    return self

indented abstractmethod ¤

indented(indent_width: int, indent_atom: str) -> str

Return the code block with appropriate indentation.

Parameters:

Name Type Description Default
indent_width int

number of indent_atoms per indentation level.

required
indent_atom str

string to use for indentation. E.g. \t, whitespace, etc.

required

Returns:

Type Description
str

indented code block.

Source code in synt/stmt/stmt.py
@abstractmethod
def indented(self, indent_width: int, indent_atom: str) -> str:
    """Return the code block with appropriate indentation.

    Args:
        indent_width: number of `indent_atom`s per indentation level.
        indent_atom: string to use for indentation. E.g. `\\t`, whitespace, etc.

    Returns:
        indented code block.
    """

into_code ¤

into_code() -> str

Convert the object into a code string.

Source code in synt/stmt/stmt.py
def into_code(self) -> str:
    """Convert the object into a code string."""
    return self.indented(0, "    ")

try_catch ¤

ExceptionHandler ¤

Bases: Statement

Exception handler.

References

ExceptionHandler.

Source code in synt/stmt/try_catch.py
class ExceptionHandler(Statement):
    r"""Exception handler.

    References:
        [`ExceptionHandler`](https://docs.python.org/3/library/ast.html#ast.ExceptHandler).
    """

    is_group: bool
    """Whether the exception handler is a group handler."""
    type: Expression | None
    """The type of exception to catch."""
    asname: Identifier | None
    """The alias name."""
    body: Block
    """The handler body."""

    def __init__(
        self,
        ty: IntoExpression | None,
        is_group: bool,
        asname: Identifier | None,
        body: Block,
    ):
        """Initialize a new exception handler.

        **DO NOT USE THIS IN YOUR CODE!**

        Args:
            ty: The type of exception to catch.
            is_group: Whether the exception handler is a group handler, aka `except*`.
            asname: The alias name.
            body: The handler body.
        """
        if ty is not None:
            self.type = ty.into_expression()
        else:
            self.type = None
        self.is_group = is_group
        self.asname = asname
        self.body = body

    def indented(self, indent_width: int, indent_atom: str) -> str:
        indent = indent_width * indent_atom
        except_kwd = "except*" if self.is_group else "except"
        type_text = f" {self.type.into_code()}" if self.type is not None else ""
        as_text = f" as {self.asname.into_code()}" if self.asname is not None else ""
        return (
            f"{indent}{except_kwd}{type_text}{as_text}:\n"
            f"{self.body.indented(indent_width + 1, indent_atom)}"
        )

type instance-attribute ¤

type: Expression | None

The type of exception to catch.

is_group instance-attribute ¤

is_group: bool = is_group

Whether the exception handler is a group handler.

asname instance-attribute ¤

asname: Identifier | None = asname

The alias name.

body instance-attribute ¤

body: Block = body

The handler body.

__init__ ¤

1
2
3
4
5
6
__init__(
    ty: IntoExpression | None,
    is_group: bool,
    asname: Identifier | None,
    body: Block,
)

Initialize a new exception handler.

DO NOT USE THIS IN YOUR CODE!

Parameters:

Name Type Description Default
ty IntoExpression | None

The type of exception to catch.

required
is_group bool

Whether the exception handler is a group handler, aka except*.

required
asname Identifier | None

The alias name.

required
body Block

The handler body.

required
Source code in synt/stmt/try_catch.py
def __init__(
    self,
    ty: IntoExpression | None,
    is_group: bool,
    asname: Identifier | None,
    body: Block,
):
    """Initialize a new exception handler.

    **DO NOT USE THIS IN YOUR CODE!**

    Args:
        ty: The type of exception to catch.
        is_group: Whether the exception handler is a group handler, aka `except*`.
        asname: The alias name.
        body: The handler body.
    """
    if ty is not None:
        self.type = ty.into_expression()
    else:
        self.type = None
    self.is_group = is_group
    self.asname = asname
    self.body = body

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/try_catch.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    indent = indent_width * indent_atom
    except_kwd = "except*" if self.is_group else "except"
    type_text = f" {self.type.into_code()}" if self.type is not None else ""
    as_text = f" as {self.asname.into_code()}" if self.asname is not None else ""
    return (
        f"{indent}{except_kwd}{type_text}{as_text}:\n"
        f"{self.body.indented(indent_width + 1, indent_atom)}"
    )

ExceptionHandlerBuilder ¤

The builder for exception handlers.

References

ExceptionHandler.

Source code in synt/stmt/try_catch.py
class ExceptionHandlerBuilder:
    r"""The builder for exception handlers.

    References:
        [`ExceptionHandler`][synt.stmt.try_catch.ExceptionHandler].
    """

    is_group: bool
    """Whether the exception handler is a group handler, aka `except*`."""
    type: Expression | None
    """The type of exception to catch."""
    asname: Identifier | None
    """The alias name."""
    parent: Try
    """Parent node."""

    def __init__(self, ty: IntoExpression | None, is_group: bool, parent: Try):
        """Initialize a new exception handler builder.

        Args:
            ty: The type of exception to catch.
            is_group: Whether the exception handler is a group handler, aka `except*`.
            parent: Parent node.
        """
        if ty is not None:
            self.type = ty.into_expression()
        else:
            self.type = None
        self.asname = None
        self.is_group = is_group
        self.parent = parent

    def as_(self, asname: Identifier) -> Self:
        """Set the alias.

        Args:
            asname: The alias name.
        """
        self.asname = asname
        return self

    def block(self, *statements: Statement) -> Try:
        """Set the block of the statement.

        Args:
            statements: The block of the statement.
        """
        handler = ExceptionHandler(
            self.type, self.is_group, self.asname, Block(*statements)
        )
        self.parent.handlers.append(handler)
        return self.parent

type instance-attribute ¤

type: Expression | None

The type of exception to catch.

asname instance-attribute ¤

asname: Identifier | None = None

The alias name.

is_group instance-attribute ¤

is_group: bool = is_group

Whether the exception handler is a group handler, aka except*.

parent instance-attribute ¤

parent: Try = parent

Parent node.

__init__ ¤

1
2
3
__init__(
    ty: IntoExpression | None, is_group: bool, parent: Try
)

Initialize a new exception handler builder.

Parameters:

Name Type Description Default
ty IntoExpression | None

The type of exception to catch.

required
is_group bool

Whether the exception handler is a group handler, aka except*.

required
parent Try

Parent node.

required
Source code in synt/stmt/try_catch.py
def __init__(self, ty: IntoExpression | None, is_group: bool, parent: Try):
    """Initialize a new exception handler builder.

    Args:
        ty: The type of exception to catch.
        is_group: Whether the exception handler is a group handler, aka `except*`.
        parent: Parent node.
    """
    if ty is not None:
        self.type = ty.into_expression()
    else:
        self.type = None
    self.asname = None
    self.is_group = is_group
    self.parent = parent

as_ ¤

as_(asname: Identifier) -> Self

Set the alias.

Parameters:

Name Type Description Default
asname Identifier

The alias name.

required
Source code in synt/stmt/try_catch.py
def as_(self, asname: Identifier) -> Self:
    """Set the alias.

    Args:
        asname: The alias name.
    """
    self.asname = asname
    return self

block ¤

block(*statements: Statement) -> Try

Set the block of the statement.

Parameters:

Name Type Description Default
statements Statement

The block of the statement.

()
Source code in synt/stmt/try_catch.py
def block(self, *statements: Statement) -> Try:
    """Set the block of the statement.

    Args:
        statements: The block of the statement.
    """
    handler = ExceptionHandler(
        self.type, self.is_group, self.asname, Block(*statements)
    )
    self.parent.handlers.append(handler)
    return self.parent

Try ¤

Bases: Statement

The try statement.

Notes

Python views except and except* as separate statement types, but Synt does view them as the same kind and a pair of different variations.

That means if you write except and except* statements together in a single Try, Synt won't complain about it, but the Python parser will reject it.

Examples:

try_block = try_(
                PASS
            ).except_(id_("ValueError")).block(
                PASS
            ).except_(id_("Exception")).as_(id_("e")).block(
                return_()
            ).except_().block(
                raise_()
            ).else_(
                PASS
            ).finally_(
                PASS
            )
assert try_block.into_code() == '''try:
    pass
except ValueError:
    pass
except Exception as e:
    return
except:
    raise
else:
    pass
finally:
    pass'''
# try:
#     pass
# except ValueError:
#     pass
# except Exception as e:
#     return
# except:
#     raise
# finally:
#     pass

try_block = try_(
                PASS
            ).except_star(id_("Exception")).block(
                PASS
            )
assert try_block.into_code() == "try:\n    pass\nexcept* Exception:\n    pass"
# try:
#     pass
# except* Exception:
#     pass
References

Try
TryStar

Source code in synt/stmt/try_catch.py
class Try(Statement):
    r"""The `try` statement.

    Notes:
        Python views `except` and `except*` as separate statement types,
        but Synt does view them as the same kind and a pair of different variations.

        That means if you write `except` and `except*` statements together in a single `Try`,
        Synt won't complain about it, but the Python parser will reject it.

    Examples:
        ```python
        try_block = try_(
                        PASS
                    ).except_(id_("ValueError")).block(
                        PASS
                    ).except_(id_("Exception")).as_(id_("e")).block(
                        return_()
                    ).except_().block(
                        raise_()
                    ).else_(
                        PASS
                    ).finally_(
                        PASS
                    )
        assert try_block.into_code() == '''try:
            pass
        except ValueError:
            pass
        except Exception as e:
            return
        except:
            raise
        else:
            pass
        finally:
            pass'''
        # try:
        #     pass
        # except ValueError:
        #     pass
        # except Exception as e:
        #     return
        # except:
        #     raise
        # finally:
        #     pass

        try_block = try_(
                        PASS
                    ).except_star(id_("Exception")).block(
                        PASS
                    )
        assert try_block.into_code() == "try:\n    pass\nexcept* Exception:\n    pass"
        # try:
        #     pass
        # except* Exception:
        #     pass
        ```

    References:
        [`Try`](https://docs.python.org/3/library/ast.html#ast.Try)<br/>
        [`TryStar`](https://docs.python.org/3/library/ast.html#ast.TryStar)
    """

    try_block: Block
    """The block to catch exceptions."""
    handlers: list[ExceptionHandler]
    """Exception handlers"""
    orelse: Block | None
    """Fallback handler, aka `else`."""
    final: Block | None
    """Final workaround body, aka `finally`."""

    def __init__(
        self,
        try_block: Block,
        handlers: list[ExceptionHandler],
        orelse: Block | None,
        final: Block | None,
    ):
        """Initialize a new `try` statement.

        **DO NOT USE THIS IN YOUR CODE!**

        Args:
            try_block: The block to catch exceptions.
            handlers: Exception handlers.
            orelse: Fallback handler, aka `else`.
            final: Final workaround body, aka `finally`.
        """
        self.try_block = try_block
        self.handlers = handlers
        self.orelse = orelse
        self.final = final

    def except_(self, ty: IntoExpression | None = None) -> ExceptionHandlerBuilder:
        """Append a new exception handler.

        Args:
            ty: The type of exception to catch.
        """
        return ExceptionHandlerBuilder(ty, False, self)

    def except_star(self, ty: IntoExpression | None) -> ExceptionHandlerBuilder:
        """Append a new group exception handler.

        Args:
            ty: The type of exception to catch.
        """
        return ExceptionHandlerBuilder(ty, True, self)

    def else_(self, *statements: Statement) -> Self:
        """Set the fallback handler.

        Args:
            statements: The statements in the fallback handler.
        """
        self.orelse = Block(*statements)
        return self

    def finally_(self, *statements: Statement) -> Self:
        """Set the final workaround body.

        Args:
            statements: The statements in the final workaround body.
        """
        self.final = Block(*statements)
        return self

    def indented(self, indent_width: int, indent_atom: str) -> str:
        indent = indent_atom * indent_width
        if len(self.handlers) > 0:
            handlers_text = "\n" + "\n".join(
                x.indented(indent_width, indent_atom) for x in self.handlers
            )
        else:
            handlers_text = ""
        if self.orelse is not None:
            orelse_text = f"\n{indent}else:\n{self.orelse.indented(indent_width + 1, indent_atom)}"
        else:
            orelse_text = ""
        if self.final is not None:
            final_text = f"\n{indent}finally:\n{self.final.indented(indent_width + 1, indent_atom)}"
        else:
            final_text = ""
        return (
            f"{indent}try:\n{self.try_block.indented(indent_width + 1, indent_atom)}"
            f"{handlers_text}{orelse_text}{final_text}"
        )

try_block instance-attribute ¤

try_block: Block = try_block

The block to catch exceptions.

handlers instance-attribute ¤

Exception handlers

orelse instance-attribute ¤

orelse: Block | None = orelse

Fallback handler, aka else.

final instance-attribute ¤

final: Block | None = final

Final workaround body, aka finally.

__init__ ¤

1
2
3
4
5
6
__init__(
    try_block: Block,
    handlers: list[ExceptionHandler],
    orelse: Block | None,
    final: Block | None,
)

Initialize a new try statement.

DO NOT USE THIS IN YOUR CODE!

Parameters:

Name Type Description Default
try_block Block

The block to catch exceptions.

required
handlers list[ExceptionHandler]

Exception handlers.

required
orelse Block | None

Fallback handler, aka else.

required
final Block | None

Final workaround body, aka finally.

required
Source code in synt/stmt/try_catch.py
def __init__(
    self,
    try_block: Block,
    handlers: list[ExceptionHandler],
    orelse: Block | None,
    final: Block | None,
):
    """Initialize a new `try` statement.

    **DO NOT USE THIS IN YOUR CODE!**

    Args:
        try_block: The block to catch exceptions.
        handlers: Exception handlers.
        orelse: Fallback handler, aka `else`.
        final: Final workaround body, aka `finally`.
    """
    self.try_block = try_block
    self.handlers = handlers
    self.orelse = orelse
    self.final = final

except_ ¤

1
2
3
except_(
    ty: IntoExpression | None = None,
) -> ExceptionHandlerBuilder

Append a new exception handler.

Parameters:

Name Type Description Default
ty IntoExpression | None

The type of exception to catch.

None
Source code in synt/stmt/try_catch.py
def except_(self, ty: IntoExpression | None = None) -> ExceptionHandlerBuilder:
    """Append a new exception handler.

    Args:
        ty: The type of exception to catch.
    """
    return ExceptionHandlerBuilder(ty, False, self)

except_star ¤

1
2
3
except_star(
    ty: IntoExpression | None,
) -> ExceptionHandlerBuilder

Append a new group exception handler.

Parameters:

Name Type Description Default
ty IntoExpression | None

The type of exception to catch.

required
Source code in synt/stmt/try_catch.py
def except_star(self, ty: IntoExpression | None) -> ExceptionHandlerBuilder:
    """Append a new group exception handler.

    Args:
        ty: The type of exception to catch.
    """
    return ExceptionHandlerBuilder(ty, True, self)

else_ ¤

else_(*statements: Statement) -> Self

Set the fallback handler.

Parameters:

Name Type Description Default
statements Statement

The statements in the fallback handler.

()
Source code in synt/stmt/try_catch.py
def else_(self, *statements: Statement) -> Self:
    """Set the fallback handler.

    Args:
        statements: The statements in the fallback handler.
    """
    self.orelse = Block(*statements)
    return self

finally_ ¤

finally_(*statements: Statement) -> Self

Set the final workaround body.

Parameters:

Name Type Description Default
statements Statement

The statements in the final workaround body.

()
Source code in synt/stmt/try_catch.py
def finally_(self, *statements: Statement) -> Self:
    """Set the final workaround body.

    Args:
        statements: The statements in the final workaround body.
    """
    self.final = Block(*statements)
    return self

indented ¤

indented(indent_width: int, indent_atom: str) -> str
Source code in synt/stmt/try_catch.py
def indented(self, indent_width: int, indent_atom: str) -> str:
    indent = indent_atom * indent_width
    if len(self.handlers) > 0:
        handlers_text = "\n" + "\n".join(
            x.indented(indent_width, indent_atom) for x in self.handlers
        )
    else:
        handlers_text = ""
    if self.orelse is not None:
        orelse_text = f"\n{indent}else:\n{self.orelse.indented(indent_width + 1, indent_atom)}"
    else:
        orelse_text = ""
    if self.final is not None:
        final_text = f"\n{indent}finally:\n{self.final.indented(indent_width + 1, indent_atom)}"
    else:
        final_text = ""
    return (
        f"{indent}try:\n{self.try_block.indented(indent_width + 1, indent_atom)}"
        f"{handlers_text}{orelse_text}{final_text}"
    )

try_ ¤

try_(*statement: Statement) -> Try

Initialize a try statement.

Parameters:

Name Type Description Default
statement Statement

The statements in the try block.

()
Source code in synt/stmt/try_catch.py
def try_(*statement: Statement) -> Try:
    r"""Initialize a `try` statement.

    Args:
        statement: The statements in the `try` block.
    """
    return Try(Block(*statement), [], None, None)