Here's a fun one. Start here
Lazy PyTwitter: Is there some way with typing/mypy to express that a type must be a 3-element numpy array of reals?— David Beazley (@dabeaz) June 21, 2018
This is a cool question.
Here's an essential clarification on what this structure is.
Sorry, but I'm not letting go of this. Suppose I write a function:— David Beazley (@dabeaz) June 22, 2018
def vec3(x:float, y:float, z:float):
I now use this to make "instances" of 3D vectors, which get passed around and used throughout my code.
How would I type hint all of that?
This is tricky and I think there are two reasons why it's hard.
1. We want to specify some details internal to instances of the np.array class.
2. We want to provide a size constraint, something that I don't think typing can do.
The size constraint may be handled by using Tuple, but it doesn't really fit in a general way. This three-tuple is Tuple[float, float, float]. You can see how that rapidly gets hideous for higher-dimension objects. You'd want Tuple[float*3], right?
The internal constrain, similarly, is challenging. However. An np.array() -- for the most part -- is a Sequence with extra features.
I have a suggestion.
1. A stubs/numpy.py file with this. I think this characterizes the array structure.
from typing import TypeVar, Sequence _Base = TypeVar("_Base") def array(*args: Sequence[_Base]) -> Sequence[_Base]: ...
2. Here's the target function.
import numpy as np from typing import Sequence Vector3 = Sequence[float] def vec3(x: float, y: float, z: float) -> Vector3: return np.array((x, y, z))
This seems to capture part of the type definition. It doesn't capture the 3-ness of the vector.