Skip to content
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

Some safe functions are marked unsafe? #1389

Closed
nw0 opened this issue Jan 16, 2021 · 6 comments · Fixed by #1404
Closed

Some safe functions are marked unsafe? #1389

nw0 opened this issue Jan 16, 2021 · 6 comments · Fixed by #1404

Comments

@nw0
Copy link
Contributor

nw0 commented Jan 16, 2021

When I was looking at the remaining unsafe functions without safety notes for #698, I noticed that a couple of functions didn't seem to be unsafe at all.

This issue is about whether these functions should be safe to call (i.e. no need to be marked unsafe) because they wrap up the unsafety, or aren't actually unsafe.

  1. PyLayout::py_init. This function takes ownership of a value: T, which could be leaked in the worst case, but leaking memory is considered safe Rust. For reference, both implementations don't use any unsafe code.

    unsafe fn py_init(&mut self, _value: T) {}

  2. PyClassDict::clear_dict. In this case the implementation calls the FFI function PyDict_Clear, which seems to be safe as it operates solely on the refcounted contents of the class dict.

    unsafe fn clear_dict(&mut self, _py: Python) {}

  3. PyClassAlloc::new. This feels like implementations should encapsulate any unsafety, but I'm not sure.

    pub trait PyClassAlloc: PyTypeInfo + Sized {

Opening this issue as suggested in #1388 (comment), even if it's not obvious that we want to change the unsafe marking on any of the functions. I realise that most of these APIs are probably only used internally.

@davidhewitt
Copy link
Member

I agree with 1 + 2 being needlessly unsafe, good catch. I'm in favour of removing unsafe from these APIs.

PyClassAlloc::new should continue to be unsafe to call, because it takes a raw pointer and so has to derefence it, which is unsafe.

@nw0
Copy link
Contributor Author

nw0 commented Jan 18, 2021

PyClassAlloc::new should continue to be unsafe to call, because it takes a raw pointer and so has to derefence it, which is unsafe.

Oops, yes, of course.

  1. opt_to_pyobj only gets the pointers to a PyObj, or None, which is itself safe (as it doesn't actually use the pointers).
    unsafe fn opt_to_pyobj(py: Python, opt: Option<&PyObject>) -> *mut ffi::PyObject {

I've briefly looked at all the unsafe fns in PyO3, and the rest seem bona fide unsafe as they are currently defined. I can file a PR to change 1 and 2 (and 4?), if you'd like.

@davidhewitt
Copy link
Member

Agreed that opt_to_pyobj is also safe.

I can file a PR to change 1 and 2 (and 4?), if you'd like.

If you're willing, that'd be very much appreciated! It'd technically be breaking so I probably wouldn't be able to merge the PR for a little bit until we're ready to merge all the breaking changes that will go into 0.14.

@nw0
Copy link
Contributor Author

nw0 commented Feb 19, 2021

Sorry to post on an old issue: I think clear_weakrefs is another of these actually safe functions.

https://github.com/PyO3/pyo3/blob/master/src/pyclass_slots.rs#L69

PyObject_ClearWeakRefs clears the remaining weak references to the object. A weak reference (another PyObject)

[...] will allow access to the referenced object if it hasn't been collected and to determine if the object still exists in memory. Retrieving the referent is done by calling the reference object. If the referent is no longer alive, this will return None instead. (PEP 205)

I believe it's safe to clear weak references, as their being cleared "unexpectedly" is explicitly why weak references exist. If not, I suppose I'm about to learn what remark should be put into the "Safety" docstring... (#698)

@birkenfeld
Copy link
Member

I don't think this can be safe as long as it takes a raw pointer, since there is no guarantee that it points to a valid PyObject.

@nw0
Copy link
Contributor Author

nw0 commented Feb 19, 2021

Ah, of course -- my bad

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 a pull request may close this issue.

3 participants