-
Notifications
You must be signed in to change notification settings - Fork 162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add __class_getitem__
to generic classes
#1345
Comments
Thanks for opening this. I will give some context that: So rustworkx tries to mimic a Python implementations the most possible despite being written in Rust. But some more advanced features are missing. I agree that this should be available and I will try to implement it. I will also accept PRs if someone wants to do it before I do. The NumPy code is a good starting point. In the meantime, we will keep suggesting users to stick with temporary fix n. 3 that is |
#1348 will add the support for I still need to figure out how to implement this for the Custom Return Types as not all of them can be parametrized |
Very cool and fast handling! I skimmed the PR. I was kind of let down by the fact the graph = PyGraph[int, str]() which will need to import from __future__ import annotations
graph: PyGraph[int, str] = PyGraph() But I don't think its too bad either way. |
I need to open an issue in PyO3 asking for the Py_GenericAlias binding to Rust. It would save us one Python import, which can have a positive performance impact as you mentioned. However at the moment I think it is a reasonable fix as it is not a breaking change. Code without |
I noticed that despite the
PyGraph
,PyDiGraph
andPyDAG
classes being typed as generic over node payload and edge payload type the classes cannot be typed in runtime because the do not implement the__class_getitem__
class method.This means that using them in annotations requires one of the following: (1) use forward reference (i.e. put them quotation marks); (2) be enclosed in an
if TYPE_CHECKING:
block; (3) havefrom __future__ import annotations
used in the module; (4) used only in.pyi
files. (5) use thetype
statement in python>=3.12 instead ofTypeAlias
(which does lazy evaluation).These are a bit of a hassle but not too troubling, but this has another implication: these type annotations cannot be inspected at runtime.
Runtime inspection is something that packages like
pydantic
,attrs
do (even the standard librarydataclasses
module does a bit of it).I suggest adding a
__class_getitem__
classmethod for these classes. In python its easy to do (although I'm not suggesting implementing this in python):This should probably be implemented in rust via PyO3. The
GenericAlias
class has a python-stable ABI counterpartPy_GenericAlias
and I assume that it's supported by PyO3 (but haven't checked).For reference you can look at
numpy
C-implementation, where they do minimal check that thekey
is either a tuple of length 1 or 2 or any other python object (thePy_GenericAlias
converts it to a one-tuple in that case): https://github.com/numpy/numpy/blob/ebbd9442e9ccd2508979d58354d16e3eeca96d9c/numpy/_core/src/multiarray/methods.c#L2805If you do add the
__class_getitem__
method, then its probably also best to add its signature to thepyi
files:The text was updated successfully, but these errors were encountered: