-
Notifications
You must be signed in to change notification settings - Fork 749
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
PyWeak<T>
: a weak Py<T>
reference which integrates with the weakref
Python module
#3134
Comments
I started working on this. It currently only does |
I'd say that depends on whether it is tied to the internals of |
Please note that #3205 may have impacts on the design of |
I've made a basic working version. However, I still have some design questions/problems:
What do you think? |
I agree with your last suggestion of having coexisting implementations. A python Then we could have (with the current API) These untyped versions are not as elegant for you as Building an implementation of For |
A way to allow for This might also allow for cyclic references. I will start to add the |
I (finally) had some spare time to add some of the features discussed. Currently, I might look into creating a Shall I already make a pull-request for this? |
@SuperJappie08 I think we can definitely review a PR for these types. Those new types being added to the The |
I think this can be closed because #3835 added the wrappers. That said, there's an issue with the API that was added that I think we should probably fix in the long term. Python 3.13 adds I think we can probably add a new API to replace |
Let's close this for now, can always revisit further later. |
Hi,
I'm working on python and rust library (Rust library & Rust library wrapped to a Python module) which uses a bidirectional unbalanced tree structure, where the nodes
NodeA
andNodeB
alternate.The trees also have a
HashMap
index per node type for easy look up, which containsWeak<NodeX>
Since I have multiple tree types with the same base functionality, the tree is actually stored in a private encapsulated
TreeData
struct which contains the root node and the index maps. As a result, the parent of the root node is such aWeak<TreeData>
.NodeA
is the only node type which can be the root, they can have 2 parent typesNodeB
orTreeData
.These nodes contain a method to get a reference to their parent in the rust library.
However, for the Python module I would like to return a reference to the encapsulated
TreeData
soTreeX
which is wrapped toPyTreeX
.These returned objects should not be clones due to the referencing nature of the data structure, and introducing a rust
Weak<TreeX>
in the wrapping makes error handling more complex.Therefore, I wanted to use the
weakref
python module to encapsulate aweakref.proxy
of the external python tree into the retrieved nodes to return instead of the actual rawTreeData
reference.There is currently no 'nice' rust centric way to do this with PyO3.
In my current solution, I import the
weakref
module and store aPyObject
which contains theweakref.proxy
Here is a code example:
So, I just import the
weakref
module and use it that way.This works, but is not as clear in Rust as it can be, since (to my current knowledge) I have to use the
PyObject
type.Proposal
Therefore, I propose a new python reference type related to
Py<T>
which would incorporate some of theweakref
functionality.This could look something like
PyWeak<T>
and corresponds with a pythonweakref.ref(T)
.This reference type could introduce a method which could look more like rust's
Weak::upgrade()
or python's way of working withweakref.ref()
.Such a
upgrade
/get
version could be implemented in 2 ways.PyWeak::ref(...) -> PyResult<T>
where the same Python exception is raised as if you are usingweakref.proxy
(orReferenceError
for Python >=3.10 orAtributeError
for earlier version)PyWeak::get() -> Option<T>
which behaves just like python'sweakref.ref
which needs to be called for it to return the object orNone
if it has been deallocated.PyWeak::upgrade(...) -> Option<Py<T>>
, this would be like rust'sRc::upgrade(...)
andArc::upgrade(...)
Something that would be really nice, which, I doubt, is possible, is something like rust's
Arc::new_cyclic()
to initialize cyclic references.The biggest advantage over the way this currently can be achieved, is the improved type safety in Rust and possibly some speed up due to not having to import
weakref
in the Rust code.Syntax example
The 'upgraded' version, of the previous example:
Feasibility
While looking more into the
weakref
modules, I noticed that there are C bindings available (in both Python's C-API andPyO3-ffi
).I'm not 100% sure if something like this is even possible.
I would love to help implement. However, my rust experience is very limited in this sector.
And I also need to finish the project which raised the question in the next month(s), so I am a bit preoccupied.
I wonder if something like this has been considered already, or if there already exists a 'better' way to do such things.
The text was updated successfully, but these errors were encountered: