Skip to content

Improved typing for __array__#138

Open
kylebarron wants to merge 3 commits intorasterio:mainfrom
kylebarron:kyle/__array__-typing
Open

Improved typing for __array__#138
kylebarron wants to merge 3 commits intorasterio:mainfrom
kylebarron:kyle/__array__-typing

Conversation

@kylebarron
Copy link

Similar in spirit to #137 for for the __array__ conversion to numpy.

This one is less important than #137 so it's ok if you reject it for complexity:

Before:

image

After:

image
  • This effectively just changes the behavior of np.asarray when no explicit dtype is provided (assuming users call np.asarray and not Affine.__array__)
  • I like to have "complete" typing like this, but compared to Implement typing overloads for (matrix) multiplication #137 it's not as crucial to have the type checker know that the array is a float64 array specifically.

@mwtoews
Copy link
Contributor

mwtoews commented Feb 1, 2026

numpy is not a project dependency. It's currently an optional dependency for "test". Is there a way to make numpy types optional?

@kylebarron
Copy link
Author

Anything inside of if TYPE_CHECKING: doesn't get evaluated at runtime. So if the user doesn't have numpy installed and they call __array__ directly, their type checker will just infer Any / Unknown

image

@sgillies
Copy link
Member

sgillies commented Feb 2, 2026

@kylebarron thank you, but this kind of complicated typing makes me depressed.

Instead, I'm inclined to deprecate __array__ and remove the conditional numpy dependency. Instead, we could use Numpy's array interface like this:

>>> import array
>>> class Foo:
...     __array_interface__ = {"shape": (2, 2), "typestr": "d", "data": array.array("d", [1,2,3,4]), "version": 3}
... 
>>> import numpy
>>> numpy.array(Foo())
array([[1., 2.],
       [3., 4.]])

The data key properly constructing a 1-D buffer from the Affine attributes, of course. The type annotation for this should be simpler, all of the types in the array interface items being fixed, yes?

@kylebarron
Copy link
Author

kylebarron commented Feb 3, 2026

I pushed another option, which hard-codes np.float64. This will be wrong if users ever call __array__ directly, but provides correct typing for np.array and np.asarray (since numpy overrides the inferred type if an explicit dtype is provided):

image

So it's a viable option if you don't expect users to call __array__ directly.

@kylebarron thank you, but this kind of complicated typing makes me depressed.

To be clear, this is pretty low value for me, so it's totally fine if you want to reject it for complexity. (I think #137 is much higher value, since matrix multiplication is probably much more common, and the typing pain of the currently-inferred union is much worse)

Instead, I'm inclined to deprecate __array__ and remove the conditional numpy dependency. Instead, we could use Numpy's array interface like this:

I don't know enough about pros and cons of __array__ and the array interface. But they both seem like perfectly valid ways to export to Numpy.

I don't think it's possible to type that array interface because the type checker isn't able to statically match the typestr: d with an np.float64.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants