-
Notifications
You must be signed in to change notification settings - Fork 779
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
Extend Python Class from Rust #991
Comments
I had an initial idea of calling class A:
a = 13
class B:
b = 42
C = type("C", (A, B), {}) |
Interesting. You might find #1152 interesting which I think might use that or something similar (haven't had a chance to review it yet) |
Are there any existing examples that you can point me to of how this is done now? Thanks! |
I recently hit this and asked in gitter too
@davidhewitt I likely won't have time soon due to work so don't sweat it, but if you find some cycles and can throw some information here I can possibly take a crack at it in the future when work settles down. |
Potentially relevant: https://www.python.org/dev/peps/pep-0253/ |
I tried using class ChildVehicle(fsr.RustVehicle):
def get_veh_kg(self) -> float:
return self.veh_kg
veh = ChildVehicle.from_file(str(fsim.package_root() / 'resources/vehdb/2012_Ford_Fusion.yaml'))
veh.get_veh_kg() this happened: ---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In [12], line 7
3 return self.veh_kg
5 veh = ChildVehicle.from_file(str(fsim.package_root() / 'resources/vehdb/2012_Ford_Fusion.yaml'))
----> 7 veh.get_veh_kg()
AttributeError: 'fastsimrust.RustVehicle' object has no attribute 'get_veh_kg' Note that on the Rust side, we use a proc macro to add the pyo3 attributes so it'll look a little wonky to anyone who looks into the Rust code. |
@calbaker please open this as a separate discussion/issue - this issue is about extending the other way. |
I had this issue about half a year ago, and came up with an idea (link to pydantic-core issue) where we use BaseModel from Pydantic as an interface between the two languages. Half a year later, I need this feature again in a completely different project; sad to see it being so far away (very understandable). A big +1 from me. |
How could this be implemented? Wouldn't it require evaluating the python code with an Or would the macro generate the equivalent CPython commands to import the class and then subclass it dynamically, thus making the code unsafe? |
You are welcome to join the discussion @LoveIsGrief |
Just a dump of my thoughts @nekitdev already found it, but classes / types in python can be created dynamically #991 (comment). (relevant python doc). They generate a PyTypeObject (documentation on creating new types in C). So it should be possible to dynamically create types in rust from imported python classes. The downside is they will be dynamic / at runtime and thus cannot be used for static typing elsewhere in Rust code. As a first step, that might be OK and it might even already be possible (still have to try it out to confirm). Making it static though would be the most difficult, I imagine. One would have to somehow evaluate the python code before compilation or during compilation to generate either:
@caniko I'm not sure why this should be dependent on pydantic. Could shed some light on that? Shouldn't PyO3 be independent of third-party python libs? |
@LoveIsGrief, you are already thinking about the issue. The Pydantic way would make it static. 👬 |
@LoveIsGrief agreed that making dynamic subtyping is a fine first step, I think all we would need to do to achieve that is give To make it static I think we can borrow inspiration from Duchess which has a @caniko I think the pydantic approach you propose may be suitable for some use-cases but I don't think it's necessary for a barebones implementation here. |
I have a similar issue, however mine might be even more complex. import abc as _abc
class Entity(_abc.ABC):
"""An entity"""
@_abc.abstractproperty
def uuid(self) -> str:
"""Unique ID of this entity"""
... And then I also have implementations of that class (also in Edit: |
@davidhewitt time flew by! A quick click through the |
In my case I'm generating Rust-facing wrappers via macro anyway, so the boilerplate being boilerplatey is less of an issue than the lack of documentation on what it needs to be: I've narrowed it down to needing |
…tion (#103) - Introduce new customize point for using custom artifact implementation. - This is new feature in Python SDK. Bump up its version to 1.1.0 - Since PyO3 does not support inheriting Python class in Rust side, I create wrapper classes in Python layer. PyO3/pyo3#991
A user asked a question on Gitter just now about extending a Python class from Rust.
While I think it's possible to do this by hand with a lot of unsafe code by implementing
PyTypeInfo
for the base type manually, it's pretty complicated.This is an issue to think one day about how to make this easier. Possibly it's good enough to document the current process, or maybe there are design changes we can make internally.
The text was updated successfully, but these errors were encountered: