Skip to content

Commit 2ff3ae8

Browse files
committed
getattr to take &Py<PyStr>
1 parent 906dfd3 commit 2ff3ae8

File tree

8 files changed

+50
-45
lines changed

8 files changed

+50
-45
lines changed

vm/src/builtins/genericalias.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ impl GetAttr for PyGenericAlias {
393393
fn getattro(zelf: &Py<Self>, attr: PyStrRef, vm: &VirtualMachine) -> PyResult {
394394
for exc in ATTR_EXCEPTIONS.iter() {
395395
if *(*exc) == attr.to_string() {
396-
return zelf.as_object().generic_getattr(attr, vm);
396+
return zelf.as_object().generic_getattr(&attr, vm);
397397
}
398398
}
399399
zelf.origin().get_attr(attr, vm)

vm/src/builtins/module.rs

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ pub struct ModuleInitArgs {
2626
doc: Option<PyStrRef>,
2727
}
2828

29-
#[pyclass(with(GetAttr, Initializer, Representable), flags(BASETYPE, HAS_DICT))]
3029
impl PyModule {
3130
// pub(crate) fn new(d: PyDictRef) -> Self {
3231
// PyModule { dict: d.into() }
@@ -37,49 +36,31 @@ impl PyModule {
3736
// self.dict.get()
3837
// }
3938

40-
#[pyslot]
41-
fn slot_new(cls: PyTypeRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult {
42-
PyModule {}.into_ref_with_type(vm, cls).map(Into::into)
43-
}
44-
4539
fn getattr_inner(zelf: &Py<Self>, name: PyStrRef, vm: &VirtualMachine) -> PyResult {
46-
if let Some(attr) = zelf
47-
.as_object()
48-
.generic_getattr_opt(name.clone(), None, vm)?
49-
{
40+
if let Some(attr) = zelf.as_object().generic_getattr_opt(&name, None, vm)? {
5041
return Ok(attr);
5142
}
5243
if let Ok(getattr) = zelf.dict().get_item(identifier!(vm, __getattr__), vm) {
5344
return getattr.call((name,), vm);
5445
}
55-
let module_name = if let Some(name) = Self::name(zelf.to_owned(), vm) {
46+
let module_name = if let Some(name) = zelf.name(vm) {
5647
format!(" '{name}'")
5748
} else {
5849
"".to_owned()
5950
};
6051
Err(vm.new_attribute_error(format!("module{module_name} has no attribute '{name}'")))
6152
}
53+
}
6254

63-
fn name(zelf: PyRef<Self>, vm: &VirtualMachine) -> Option<PyStrRef> {
64-
let name = zelf
55+
impl Py<PyModule> {
56+
fn name(&self, vm: &VirtualMachine) -> Option<PyStrRef> {
57+
let name = self
6558
.as_object()
66-
.generic_getattr_opt(identifier!(vm, __name__).to_owned(), None, vm)
59+
.generic_getattr_opt(identifier!(vm, __name__), None, vm)
6760
.unwrap_or_default()?;
6861
name.downcast::<PyStr>().ok()
6962
}
7063

71-
#[pymethod(magic)]
72-
fn dir(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<Vec<PyObjectRef>> {
73-
let dict = zelf
74-
.as_object()
75-
.dict()
76-
.ok_or_else(|| vm.new_value_error("module has no dict".to_owned()))?;
77-
let attrs = dict.into_iter().map(|(k, _v)| k).collect();
78-
Ok(attrs)
79-
}
80-
}
81-
82-
impl Py<PyModule> {
8364
// TODO: to be replaced by the commented-out dict method above once dictoffsets land
8465
pub fn dict(&self) -> PyDictRef {
8566
self.as_object().dict().unwrap()
@@ -117,6 +98,24 @@ impl Py<PyModule> {
11798
}
11899
}
119100

101+
#[pyclass(with(GetAttr, Initializer, Representable), flags(BASETYPE, HAS_DICT))]
102+
impl PyModule {
103+
#[pyslot]
104+
fn slot_new(cls: PyTypeRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult {
105+
PyModule {}.into_ref_with_type(vm, cls).map(Into::into)
106+
}
107+
108+
#[pymethod(magic)]
109+
fn dir(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<Vec<PyObjectRef>> {
110+
let dict = zelf
111+
.as_object()
112+
.dict()
113+
.ok_or_else(|| vm.new_value_error("module has no dict".to_owned()))?;
114+
let attrs = dict.into_iter().map(|(k, _v)| k).collect();
115+
Ok(attrs)
116+
}
117+
}
118+
120119
impl Initializer for PyModule {
121120
type Args = ModuleInitArgs;
122121

vm/src/builtins/object.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ impl PyBaseObject {
298298
#[pyslot]
299299
pub(crate) fn getattro(obj: &PyObject, name: PyStrRef, vm: &VirtualMachine) -> PyResult {
300300
vm_trace!("object.__getattribute__({:?}, {:?})", obj, name);
301-
obj.as_object().generic_getattr(name, vm)
301+
obj.as_object().generic_getattr(&name, vm)
302302
}
303303

304304
#[pymethod(magic)]

vm/src/builtins/super.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,13 @@ impl GetAttr for PySuper {
130130
let skip = |zelf: &Py<Self>, name| zelf.as_object().generic_getattr(name, vm);
131131
let (obj, start_type): (PyObjectRef, PyTypeRef) = match zelf.obj.clone() {
132132
Some(o) => o,
133-
None => return skip(zelf, name),
133+
None => return skip(zelf, &name),
134134
};
135135
// We want __class__ to return the class of the super object
136136
// (i.e. super, or a subclass), not the class of su->obj.
137137

138138
if name.as_str() == "__class__" {
139-
return skip(zelf, name);
139+
return skip(zelf, &name);
140140
}
141141

142142
if let Some(name) = vm.ctx.interned_str(&*name) {
@@ -159,7 +159,7 @@ impl GetAttr for PySuper {
159159
}
160160
}
161161
}
162-
skip(zelf, name)
162+
skip(zelf, &name)
163163
}
164164
}
165165

vm/src/builtins/union.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ impl GetAttr for PyUnion {
304304
fn getattro(zelf: &Py<Self>, attr: PyStrRef, vm: &VirtualMachine) -> PyResult {
305305
for &exc in CLS_ATTRS {
306306
if *exc == attr.to_string() {
307-
return zelf.as_object().generic_getattr(attr, vm);
307+
return zelf.as_object().generic_getattr(&attr, vm);
308308
}
309309
}
310310
zelf.as_object().to_pyobject(vm).get_attr(attr, vm)

vm/src/intern.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,13 @@ impl<T: PyPayload> std::hash::Hash for PyInterned<T> {
164164
}
165165
}
166166

167+
impl<T: PyPayload> AsRef<Py<T>> for PyInterned<T> {
168+
#[inline(always)]
169+
fn as_ref(&self) -> &Py<T> {
170+
&self.inner
171+
}
172+
}
173+
167174
impl<T: PyPayload> Deref for PyInterned<T> {
168175
type Target = Py<T>;
169176
#[inline(always)]

vm/src/protocol/object.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::{
1313
function::{Either, OptionalArg, PyArithmeticValue, PySetterValue},
1414
protocol::{PyIter, PyMapping, PySequence},
1515
types::{Constructor, PyComparisonOp},
16-
AsObject, PyObject, PyObjectRef, PyResult, TryFromObject, VirtualMachine,
16+
AsObject, Py, PyObject, PyObjectRef, PyResult, TryFromObject, VirtualMachine,
1717
};
1818

1919
// RustPython doesn't need these items
@@ -182,27 +182,26 @@ impl PyObject {
182182
}
183183
}
184184

185-
pub fn generic_getattr(&self, name: PyStrRef, vm: &VirtualMachine) -> PyResult {
186-
self.generic_getattr_opt(name.clone(), None, vm)?
187-
.ok_or_else(|| {
188-
vm.new_attribute_error(format!(
189-
"'{}' object has no attribute '{}'",
190-
self.class().name(),
191-
name
192-
))
193-
})
185+
pub fn generic_getattr(&self, name: &Py<PyStr>, vm: &VirtualMachine) -> PyResult {
186+
self.generic_getattr_opt(name, None, vm)?.ok_or_else(|| {
187+
vm.new_attribute_error(format!(
188+
"'{}' object has no attribute '{}'",
189+
self.class().name(),
190+
name
191+
))
192+
})
194193
}
195194

196195
/// CPython _PyObject_GenericGetAttrWithDict
197196
pub fn generic_getattr_opt(
198197
&self,
199-
name_str: PyStrRef,
198+
name_str: &Py<PyStr>,
200199
dict: Option<PyDictRef>,
201200
vm: &VirtualMachine,
202201
) -> PyResult<Option<PyObjectRef>> {
203202
let name = name_str.as_str();
204203
let obj_cls = self.class();
205-
let cls_attr_name = vm.ctx.interned_str(&*name_str);
204+
let cls_attr_name = vm.ctx.interned_str(name_str);
206205
let cls_attr = match cls_attr_name.and_then(|name| obj_cls.get_attr(name)) {
207206
Some(descr) => {
208207
let descr_cls = descr.class();

vm/src/stdlib/thread.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ pub(crate) mod _thread {
366366
Ok(ldict.into())
367367
} else {
368368
zelf.as_object()
369-
.generic_getattr_opt(attr.clone(), Some(ldict), vm)?
369+
.generic_getattr_opt(&attr, Some(ldict), vm)?
370370
.ok_or_else(|| {
371371
vm.new_attribute_error(format!(
372372
"{} has no attribute '{}'",

0 commit comments

Comments
 (0)