Skip to content

Refactor Mapping Protocol and Item Protocol #3462

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

Merged
merged 9 commits into from
Dec 3, 2021

Conversation

qingshi163
Copy link
Contributor

@Snowapril
Copy link
Contributor

Snowapril commented Nov 28, 2021

Oh yes. ItemProtocol was one of stuffs that should be moved to object protocol. Refactored mapping protocol also seems better than before.

@youknowone
Copy link
Member

@Snowapril could you review this PR?

self.methods(vm).subscript.is_some()
}

pub fn obj_as<T: PyObjectPayload>(&self) -> &PyObjectView<T> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this safe function? It looks like to take random T but in that case it will not be always safe.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This helper function is used to downcast the object to the type who provide the methods and should not used by any case if the type is not certain. maybe add the comment will be better than mark it unsafe because it is used in each methods to get the instance of Self?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds like this method is strictly required to be call like obj_as::<Self> always. In that case, the function is unsafe beacuse the guarantee of Self came from user, not from automatic constraints.
If you want to have a safe version of the function, I think a trait can wrap it safely. Maybe AsMapping can be the place.

trait AsMapping {
    fn mapping_as(mapping: ...) -> &PyObjectView<Self> {
        unsafe { mapping.obj_as::<Self>() }
    }
   ...
}

Comment on lines +100 to +105
pub fn from_dict_exact(dict: PyDictRef) -> Self {
Self {
obj: dict.into(),
mapping_methods: PyDict::MAPPING_METHODS,
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe impl From<PyDictRef>?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is PyDictRef means exact PyDict not the subclass?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, i am sorry. exact meant that exact.

@youknowone
Copy link
Member

does PyMapping and ArgMapping separated to keep PyObjectRef in ArgMapping?

@qingshi163
Copy link
Contributor Author

does PyMapping and ArgMapping separated to keep PyObjectRef in ArgMapping?

PyMapping do not take the ownership, it bind the lifetime to &PyObject. ArgMapping keeps PyObjectRef and the cached methods to avoid mro search.

Comment on lines 64 to 66
pub fn has_protocol(&self, vm: &VirtualMachine) -> bool {
self.methods(vm).subscript.is_some()
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about just using check? PyIter also adopt check for PyIter::Check

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sense, but I think I'd like to keep fn try_protocol() as it is more rust style.

Comment on lines 467 to 468
if let Ok(mapping) = PyMapping::try_protocol(self, vm) {
mapping.ass_subscript(&needle, Some(value), vm)
Copy link
Contributor

@Snowapril Snowapril Dec 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to cpython code, they check ass_subscript exist then call it, otherwise pass. For now, It seems we just check only mapping & subscript and call ass_subscript

Comment on lines 494 to 496
if let Ok(mapping) = PyMapping::try_protocol(self, vm) {
mapping.ass_subscript(&needle, None, vm)
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same with set_item. We must check ass_subscript exist before calling it

@qingshi163 qingshi163 requested a review from youknowone December 2, 2021 16:06
@youknowone youknowone merged commit 38513cb into RustPython:main Dec 3, 2021
@qingshi163 qingshi163 deleted the mapping-protocol2 branch May 11, 2022 17:20
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 this pull request may close these issues.

3 participants