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.
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.
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.
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.
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.
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.
Is this necessarily to be unsafe? Is this guaranteed to be actually safe?
There was a problem hiding this comment.
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.
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 <hanif.ariffin.4326@gmail.com>
Co-authored-by: Jeong, YunWon <69878+youknowone@users.noreply.github.com>
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.
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.
| (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.
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.
Maybe instant_dict() can be simple None for those types.
Fixes #5355