-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Properly handles del val.__dict__
.
#5576
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
base: main
Are you sure you want to change the base?
Conversation
see also #5509 |
dbe0d21
to
16113a4
Compare
Thanks for that PR, I have updated the PR based on that. If everything is good I will try to make my PR on top of the original one. Its much easier for me to work with squashed commits but I don't want to lose the work of the original PR. |
@hbina Sure! That will be a good way. Thank you! |
16113a4
to
d964098
Compare
@@ -711,14 +712,37 @@ impl PyObject { | |||
|
|||
/// Set the dict field. Returns `Err(dict)` if this object does not have a dict field |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The doc-comment doesn't fit in actual implementation anymore
pub fn set_dict(&self, dict: PySetterValue<PyDictRef>) -> Option<()> { | ||
// NOTE(hanif) - So far, this is the only error condition that I know of so we can use Option | ||
// for now. | ||
if self.payload_is::<crate::builtins::function::PyFunction>() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am sorry. I don't get how PyFunction
specifically requires to be checked yet. Is this same in CPython?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because deleting dict of a function is not allowed.
I can't find the equivalent check inside of cpython...
class A:
pass
def ff():
return 0
# Deleting __dict__ of class is fine
a = A()
print(a.__dict__)
del a.__dict__
# Deleting __dict__ of function is not allowed
print(ff.__dict__)
del ff.__dict__
Yields
hbina085@akarin-thinkpad ~/g/RustPython (hbina-fix-issue-5355) [1]> python ggg_issue_5355.py (numbadev)
{}
{}
Traceback (most recent call last):
File "/home/hbina085/git/RustPython/ggg_issue_5355.py", line 16, in <module>
del ff.__dict__
^^^^^^^^^^^
TypeError: cannot delete __dict__
Perhaps I should have added comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of PyFunction, isn't it a similar, but different rule? e.g. static types, immutable types etc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe instant_dict()
can be simple None for those types.
// self.0.dict = Some(InstanceDict::new(dict)); | ||
unsafe { | ||
let ptr = self as *const _ as *mut PyObject; | ||
(*ptr).0.dict = Some(InstanceDict::new(dict)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this necessarily to be unsafe? Is this guaranteed to be actually safe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no idea how to implement this without unsafe...All the methods only have immutable access to self. Can't figure out the head or tails of PyObjectRef either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When it matched to None
, I guess this object never can have __dict__
. Then returning None
will fit to it.
This PR is based on the work by key262yek. The original PR is here: RustPython#5509
- Add support for deleting object dictionaries - Modify object_set_dict to handle dictionary deletion - Update setter value handling to support delete operations
- Simplify object_set_dict method in object.rs - Update set_dict method in core.rs to handle both assignment and deletion - Consolidate dictionary modification logic
- Modify set_dict method to allow assigning dict to objects without existing dict - Update error handling in object_set_dict to provide more precise error message - Refactor type module to correctly handle dictionary assignment
This PR is based on the work by key262yek. Signed-off-by: Hanif Ariffin <[email protected]>
Co-authored-by: Jeong, YunWon <[email protected]>
a693b3b
to
425fd4f
Compare
// self.0.dict = Some(InstanceDict::new(dict)); | ||
unsafe { | ||
let ptr = self as *const _ as *mut PyObject; | ||
(*ptr).0.dict = Some(InstanceDict::new(dict)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When it matched to None
, I guess this object never can have __dict__
. Then returning None
will fit to it.
(Some(_), PySetterValue::Delete) => { | ||
// self.0.dict = None; | ||
unsafe { | ||
let ptr = self as *const _ as *mut PyObject; | ||
(*ptr).0.dict = None; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Some(_), PySetterValue::Delete) => { | |
// self.0.dict = None; | |
unsafe { | |
let ptr = self as *const _ as *mut PyObject; | |
(*ptr).0.dict = None; | |
} | |
} | |
(Some(dict), PySetterValue::Delete) => { | |
dict.write().clear(); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't do this because it only have &self
.
pub fn set_dict(&self, dict: PySetterValue<PyDictRef>) -> Option<()> { | ||
// NOTE(hanif) - So far, this is the only error condition that I know of so we can use Option | ||
// for now. | ||
if self.payload_is::<crate::builtins::function::PyFunction>() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe instant_dict()
can be simple None for those types.
Fixes #5355