I am experimenting with the typing module and I wanted to know how to properly type something like a Nonagon (a 9 point polygon), which should be a Tuple and not a List because it should be immutable.
In 2D space, it would be something like this:
Point2D = Tuple[float, float]
Nonagon = Tuple[Point2D, Point2D, Point2D, Point2D, Point2D, Point2D, Point2D, Point2D, Point2D]
nine_points: Nonagon = (
(0.0, 0.0),
(6.0, 0.0),
(6.0, 2.0),
(2.0, 2.0),
(6.0, 5.0),
(2.0, 8.0),
(6.0, 8.0),
(6.0, 10.0),
(0.0, 10.0),
)
Is there any syntactic sugar available to make the Nonagon declaration shorter or easier to read?
This is not valid Python, but I am looking for something similar to this:
Nonagon = Tuple[*([Point2D] * 9)] # Not valid Python
Or using NamedTuple
# Not properly detected by static type analysers
Nonagon = NamedTuple('Nonagon', [(f"point_{i}", Point2D) for i in range(9)])
This is NOT what I want:
# Valid but allows for more and less than 9 points
Nonagon = Tuple[Point2D, ...]
I think the most adequate way would be something like:
from typing import Annotated
# Valid but needs MinMaxLen and checking logic to be defined from scratch
Nonagon = Annotated[Point2D, MinMaxLen(9, 9)]
You can use the types module. All type hints come from types.GenericAlias.
From the doc:
Represent a PEP 585 generic type
E.g. fort = list[int],t.__origin__islistandt.__args__is(int,).
This means that you can make your own type hinting by passing the type arguments to the class itself.
>>> Point2D = tuple[float, float]
>>> Nonagon = types.GenericAlias(tuple, (Point2D,)*9)
>>> Nonagon
tuple[tuple[float, float], tuple[float, float], tuple[float, float], tuple[float, float], tuple[float, float], tuple[float, float], tuple[float, float], tuple[float, float], tuple[float, float]]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With