Skip to content

Implement mapping trait for GenericAlias #3374

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 3 commits into from
Oct 26, 2021

Conversation

Snowapril
Copy link
Contributor

@Snowapril Snowapril commented Oct 25, 2021

This revision implements mapping trait for GenericAlias

Although this is not included in #3244, actually GenericAlias provide mapping protocol interface.
(https://github.com/python/cpython/blob/main/Objects/genericaliasobject.c#L376)

Reference

Comment on lines 198 to 202
for idx in 0..tuple.len() {
if tuple.fast_getitem(idx).is(item) {
return Some(idx);
}
}
Copy link
Member

Choose a reason for hiding this comment

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

PyTuple is immutable so it doesn't have a lock.

Suggested change
for idx in 0..tuple.len() {
if tuple.fast_getitem(idx).is(item) {
return Some(idx);
}
}
params.as_slice().position(|p| p.is(arg))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah.. I agree with that. Thanks!

@@ -1,10 +1,12 @@
use crate::{
builtins::tuple::IntoPyTuple,
Copy link
Member

Choose a reason for hiding this comment

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

This is not intended to be used as an API. I'd better to hide this better than now. vm.ctx.new_tuple or PyTuple::new_ref will suggest more consistent way like other types.

}
}

let newargs = newargs.into_pytuple(vm);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
let newargs = newargs.into_pytuple(vm);
let newargs = newargs.into();

Into is enough to convert from PyRef to PyObjectRef

@Snowapril Snowapril force-pushed the ga_mapping_protocol branch 2 times, most recently from 0cf8b3a to 9870276 Compare October 25, 2021 14:04
Comment on lines 210 to 226
if let Ok(sub_params) = PyTupleRef::try_from_object(vm, sub_params) {
let sub_args = sub_params
.as_slice()
.iter()
.map(|arg| {
if let Some(idx) = tuple_index(params, arg) {
argitems[idx].clone()
} else {
arg.clone()
}
})
.collect::<Vec<_>>();
let sub_args: PyObjectRef = PyTuple::new_ref(sub_args, &vm.ctx).into();
Some(obj.get_item(sub_args, vm))
} else {
None
}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if let Ok(sub_params) = PyTupleRef::try_from_object(vm, sub_params) {
let sub_args = sub_params
.as_slice()
.iter()
.map(|arg| {
if let Some(idx) = tuple_index(params, arg) {
argitems[idx].clone()
} else {
arg.clone()
}
})
.collect::<Vec<_>>();
let sub_args: PyObjectRef = PyTuple::new_ref(sub_args, &vm.ctx).into();
Some(obj.get_item(sub_args, vm))
} else {
None
}
PyTupleRef::try_from_object(vm, sub_params).ok().map(|sub_params| {
let sub_args = sub_params
.as_slice()
.iter()
.map(|arg| {
if let Some(idx) = tuple_index(params, arg) {
argitems[idx].clone()
} else {
arg.clone()
}
})
.collect::<Vec<_>>();
let sub_args: PyObjectRef = PyTuple::new_ref(sub_args, &vm.ctx).into();
Some(obj.get_item(sub_args, vm))
})

Comment on lines 275 to 283
let mut new_args: Vec<PyObjectRef> = Vec::with_capacity(zelf.args.len());
for arg in zelf.args.as_slice().iter() {
if is_typevar(arg) {
let idx = tuple_index(&zelf.parameters, arg).unwrap();
new_args.push(arg_items[idx].clone());
} else {
new_args.push(subs_tvars(arg.clone(), &zelf.parameters, arg_items, vm)?);
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
let mut new_args: Vec<PyObjectRef> = Vec::with_capacity(zelf.args.len());
for arg in zelf.args.as_slice().iter() {
if is_typevar(arg) {
let idx = tuple_index(&zelf.parameters, arg).unwrap();
new_args.push(arg_items[idx].clone());
} else {
new_args.push(subs_tvars(arg.clone(), &zelf.parameters, arg_items, vm)?);
}
}
let new_args = zelf.args.as_slice().iter().map(|arg| {
if is_typevar(arg) {
let idx = tuple_index(&zelf.parameters, arg).unwrap();
Ok(arg_items[idx].clone())
} else {
subs_tvars(arg.clone(), &zelf.parameters, arg_items, vm)
}
}).collect::<Result<Vec<_>, _>>()?;

with_capacity is inferred through iterator

Copy link
Contributor Author

@Snowapril Snowapril Oct 26, 2021

Choose a reason for hiding this comment

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

wow.. collect::<Result<Vec<_>, _>> seems great. I didn't know that Vec<Result> can be converted like that

@Snowapril Snowapril force-pushed the ga_mapping_protocol branch from 9870276 to 4705b04 Compare October 26, 2021 01:15
Signed-off-by: snowapril <sinjihng@gmail.com>
Signed-off-by: snowapril <sinjihng@gmail.com>
Signed-off-by: snowapril <sinjihng@gmail.com>
@Snowapril Snowapril force-pushed the ga_mapping_protocol branch from 4705b04 to 795bfeb Compare October 26, 2021 01:15
@Snowapril
Copy link
Contributor Author

I add extra test that didn't caught by unittest

from typing import TypeVar
Y = TypeVar('Y')
assert dict[str,Y][int] == dict[str, int]

@youknowone youknowone merged commit c414da1 into RustPython:main Oct 26, 2021
@youknowone
Copy link
Member

Thanks!

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.

2 participants