Skip to content

Commit cd61824

Browse files
committed
PyType takes part of pyTypeRef impl
1 parent 59723c7 commit cd61824

File tree

1 file changed

+54
-50
lines changed

1 file changed

+54
-50
lines changed

vm/src/obj/objtype.rs

Lines changed: 54 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -56,26 +56,26 @@ impl PyValue for PyType {
5656
}
5757
}
5858

59-
impl PyTypeRef {
60-
fn tp_name(zelf: Self, vm: &VirtualMachine) -> String {
61-
let opt_name = zelf.slots.name.read().clone();
59+
impl PyType {
60+
fn tp_name(&self, vm: &VirtualMachine) -> String {
61+
let opt_name = self.slots.name.read().clone();
6262
opt_name.unwrap_or_else(|| {
63-
let module = zelf.attributes.read().get("__module__").cloned();
63+
let module = self.attributes.read().get("__module__").cloned();
6464
let new_name = if let Some(module) = module {
6565
// FIXME: "unknown" case is a bug.
6666
let module_str = PyStrRef::try_from_object(vm, module)
6767
.map_or("<unknown>".to_owned(), |m| m.borrow_value().to_owned());
68-
format!("{}.{}", module_str, &zelf.name)
68+
format!("{}.{}", module_str, &self.name)
6969
} else {
70-
zelf.name.clone()
70+
self.name.clone()
7171
};
72-
*zelf.slots.name.write() = Some(new_name.clone());
72+
*self.slots.name.write() = Some(new_name.clone());
7373
new_name
7474
})
7575
}
7676

77-
pub fn iter_mro(&self) -> impl Iterator<Item = &PyTypeRef> + DoubleEndedIterator {
78-
std::iter::once(self).chain(self.mro.iter())
77+
pub fn iter_mro(&self) -> impl Iterator<Item = &PyType> + DoubleEndedIterator {
78+
std::iter::once(self).chain(self.mro.iter().map(|cls| cls.deref()))
7979
}
8080

8181
pub(crate) fn first_in_mro<F, R>(&self, f: F) -> Option<R>
@@ -87,27 +87,50 @@ impl PyTypeRef {
8787
if let Some(r) = f(self) {
8888
Some(r)
8989
} else {
90-
self.mro.iter().filter_map(|cls| f(cls)).next()
90+
self.mro.iter().find_map(|cls| f(&cls))
9191
}
9292
}
9393

94-
pub fn iter_base_chain(&self) -> impl Iterator<Item = &PyTypeRef> {
95-
std::iter::successors(Some(self), |cls| cls.base.as_ref())
96-
}
97-
9894
// This is used for class initialisation where the vm is not yet available.
9995
pub fn set_str_attr<V: Into<PyObjectRef>>(&self, attr_name: &str, value: V) {
10096
self.attributes
10197
.write()
10298
.insert(attr_name.to_owned(), value.into());
10399
}
104100

101+
/// This is the internal get_attr implementation for fast lookup on a class.
102+
pub fn get_attr(&self, attr_name: &str) -> Option<PyObjectRef> {
103+
flame_guard!(format!("class_get_attr({:?})", attr_name));
104+
105+
self.get_direct_attr(attr_name)
106+
.or_else(|| self.get_super_attr(attr_name))
107+
}
108+
109+
pub fn get_direct_attr(&self, attr_name: &str) -> Option<PyObjectRef> {
110+
self.attributes.read().get(attr_name).cloned()
111+
}
112+
113+
pub fn get_super_attr(&self, attr_name: &str) -> Option<PyObjectRef> {
114+
self.mro
115+
.iter()
116+
.find_map(|class| class.attributes.read().get(attr_name).cloned())
117+
}
118+
119+
// This is the internal has_attr implementation for fast lookup on a class.
120+
pub fn has_attr(&self, attr_name: &str) -> bool {
121+
self.attributes.read().contains_key(attr_name)
122+
|| self
123+
.mro
124+
.iter()
125+
.any(|c| c.attributes.read().contains_key(attr_name))
126+
}
127+
105128
pub fn get_attributes(&self) -> PyAttributes {
106129
// Gather all members here:
107130
let mut attributes = PyAttributes::new();
108131

109132
for bc in self.iter_mro().rev() {
110-
for (name, value) in bc.attributes.read().clone().iter() {
133+
for (name, value) in bc.attributes.read().iter() {
111134
attributes.insert(name.to_owned(), value.clone());
112135
}
113136
}
@@ -177,6 +200,16 @@ impl PyTypeRef {
177200
}
178201
}
179202

203+
impl PyTypeRef {
204+
pub fn iter_mro(&self) -> impl Iterator<Item = &PyTypeRef> + DoubleEndedIterator {
205+
std::iter::once(self).chain(self.mro.iter())
206+
}
207+
208+
pub fn iter_base_chain(&self) -> impl Iterator<Item = &PyTypeRef> {
209+
std::iter::successors(Some(self), |cls| cls.base.as_ref())
210+
}
211+
}
212+
180213
#[inline]
181214
fn get_class_magic(zelf: &PyObjectRef, name: &str) -> PyObjectRef {
182215
zelf.get_class_attr(name).unwrap()
@@ -237,8 +270,8 @@ impl PyType {
237270
}
238271

239272
#[pymethod(magic)]
240-
fn repr(zelf: PyRef<Self>, vm: &VirtualMachine) -> String {
241-
format!("<class '{}'>", PyRef::<Self>::tp_name(zelf, vm))
273+
fn repr(&self, vm: &VirtualMachine) -> String {
274+
format!("<class '{}'>", self.tp_name(vm))
242275
}
243276

244277
#[pyproperty(magic)]
@@ -471,8 +504,8 @@ impl PyType {
471504
}
472505

473506
impl SlotGetattro for PyType {
474-
fn getattro(zelf: PyRef<Self>, name_ref: PyStrRef, vm: &VirtualMachine) -> PyResult {
475-
let name = name_ref.borrow_value();
507+
fn getattro(zelf: PyRef<Self>, name_str: PyStrRef, vm: &VirtualMachine) -> PyResult {
508+
let name = name_str.borrow_value();
476509
vm_trace!("type.__getattribute__({:?}, {:?})", zelf, name);
477510
let mcl = zelf.lease_class();
478511

@@ -510,7 +543,7 @@ impl SlotGetattro for PyType {
510543
getter,
511544
vec![
512545
PyLease::into_pyref(mcl).into_object(),
513-
name_ref.into_object(),
546+
name_str.into_object(),
514547
],
515548
)
516549
} else {
@@ -638,7 +671,7 @@ fn call_tp_new(
638671
args: PyFuncArgs,
639672
vm: &VirtualMachine,
640673
) -> PyResult {
641-
for cls in typ.iter_mro() {
674+
for cls in typ.deref().iter_mro() {
642675
if let Some(new_meth) = cls.get_attr("__new__") {
643676
if !vm.ctx.is_tp_new_wrapper(&new_meth) {
644677
let new_meth = vm.call_if_get_descriptor(new_meth, typ.clone().into_object())?;
@@ -668,35 +701,6 @@ pub fn tp_new_wrapper(
668701
call_tp_new(zelf, cls, args, vm)
669702
}
670703

671-
impl PyType {
672-
/// This is the internal get_attr implementation for fast lookup on a class.
673-
pub fn get_attr(&self, attr_name: &str) -> Option<PyObjectRef> {
674-
flame_guard!(format!("class_get_attr({:?})", attr_name));
675-
676-
self.get_direct_attr(attr_name)
677-
.or_else(|| self.get_super_attr(attr_name))
678-
}
679-
680-
pub fn get_direct_attr(&self, attr_name: &str) -> Option<PyObjectRef> {
681-
self.attributes.read().get(attr_name).cloned()
682-
}
683-
684-
pub fn get_super_attr(&self, attr_name: &str) -> Option<PyObjectRef> {
685-
self.mro
686-
.iter()
687-
.find_map(|class| class.attributes.read().get(attr_name).cloned())
688-
}
689-
690-
// This is the internal has_attr implementation for fast lookup on a class.
691-
pub fn has_attr(&self, attr_name: &str) -> bool {
692-
self.attributes.read().contains_key(attr_name)
693-
|| self
694-
.mro
695-
.iter()
696-
.any(|c| c.attributes.read().contains_key(attr_name))
697-
}
698-
}
699-
700704
fn take_next_base(mut bases: Vec<Vec<PyTypeRef>>) -> (Option<PyTypeRef>, Vec<Vec<PyTypeRef>>) {
701705
bases = bases.into_iter().filter(|x| !x.is_empty()).collect();
702706

0 commit comments

Comments
 (0)