Skip to content

Commit ab1de29

Browse files
committed
type.__name__ & getattr optimization
1 parent 2ff3ae8 commit ab1de29

36 files changed

+485
-379
lines changed

src/shell/helper.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ impl<'vm> ShellHelper<'vm> {
7878
let mut current = self.globals.get_item_opt(first.as_str(), self.vm).ok()??;
7979

8080
for attr in parents {
81-
current = current.get_attr(attr.as_str(), self.vm).ok()?;
81+
let attr = self.vm.ctx.new_str(attr.as_str());
82+
current = current.get_attr(&attr, self.vm).ok()?;
8283
}
8384

8485
let current_iter = str_iter_method(current, identifier!(self.vm, __dir__)).ok()?;

stdlib/src/ssl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ mod _ssl {
230230
/// SSL/TLS connection terminated abruptly.
231231
#[pyattr(name = "SSLEOFError", once)]
232232
fn ssl_eof_error(vm: &VirtualMachine) -> PyTypeRef {
233-
PyType::new_simple_ref("ssl.SSLEOFError", &ssl_error(vm), &vm.ctx).unwrap()
233+
PyType::new_simple_heap("ssl.SSLEOFError", &ssl_error(vm), &vm.ctx).unwrap()
234234
}
235235

236236
type OpensslVersionInfo = (u8, u8, u8, u8, u8);

vm/src/builtins/builtin_func.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ impl PyBuiltinMethod {
259259
vm: &VirtualMachine,
260260
) -> (Option<PyObjectRef>, (Option<PyObjectRef>, PyStrRef)) {
261261
let builtins_getattr = vm.builtins.get_attr("getattr", vm).ok();
262-
let classname = vm.builtins.get_attr(self.class.name().to_string(), vm).ok();
262+
let classname = vm.builtins.get_attr(&self.class.__name__(vm), vm).ok();
263263
(builtins_getattr, (classname, self.value.name.clone()))
264264
}
265265
}

vm/src/builtins/function.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -501,10 +501,10 @@ impl Comparable for PyBoundMethod {
501501
}
502502

503503
impl GetAttr for PyBoundMethod {
504-
fn getattro(zelf: &Py<Self>, name: PyStrRef, vm: &VirtualMachine) -> PyResult {
504+
fn getattro(zelf: &Py<Self>, name: &Py<PyStr>, vm: &VirtualMachine) -> PyResult {
505505
let class_attr = vm
506506
.ctx
507-
.interned_str(&*name)
507+
.interned_str(name)
508508
.and_then(|attr_name| zelf.get_class_attr(attr_name));
509509
if let Some(obj) = class_attr {
510510
return vm.call_if_get_descriptor(obj, zelf.to_owned().into());

vm/src/builtins/genericalias.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use once_cell::sync::Lazy;
33
use super::type_;
44
use crate::{
55
atomic_func,
6-
builtins::{PyList, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, PyTypeRef},
6+
builtins::{PyList, PyStr, PyTuple, PyTupleRef, PyType, PyTypeRef},
77
class::PyClassImpl,
88
common::hash,
99
convert::ToPyObject,
@@ -216,7 +216,7 @@ impl PyGenericAlias {
216216

217217
fn is_typevar(obj: &PyObjectRef, vm: &VirtualMachine) -> bool {
218218
let class = obj.class();
219-
class.slot_name() == "TypeVar"
219+
"TypeVar" == &*class.slot_name()
220220
&& class
221221
.get_attr(identifier!(vm, __module__))
222222
.and_then(|o| o.downcast_ref::<PyStr>().map(|s| s.as_str() == "typing"))
@@ -390,10 +390,10 @@ impl Hashable for PyGenericAlias {
390390
}
391391

392392
impl GetAttr for PyGenericAlias {
393-
fn getattro(zelf: &Py<Self>, attr: PyStrRef, vm: &VirtualMachine) -> PyResult {
393+
fn getattro(zelf: &Py<Self>, attr: &Py<PyStr>, 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: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::pystr::IntoPyStrRef;
22
use super::{PyDictRef, PyStr, PyStrRef, PyType, PyTypeRef};
33
use crate::{
4-
builtins::PyStrInterned,
4+
builtins::{pystr::AsPyStr, PyStrInterned},
55
class::PyClassImpl,
66
convert::ToPyObject,
77
function::FuncArgs,
@@ -30,29 +30,24 @@ impl PyModule {
3030
// pub(crate) fn new(d: PyDictRef) -> Self {
3131
// PyModule { dict: d.into() }
3232
// }
33+
}
3334

34-
// #[inline]
35-
// pub fn dict(&self) -> PyDictRef {
36-
// self.dict.get()
37-
// }
38-
39-
fn getattr_inner(zelf: &Py<Self>, name: PyStrRef, vm: &VirtualMachine) -> PyResult {
40-
if let Some(attr) = zelf.as_object().generic_getattr_opt(&name, None, vm)? {
35+
impl Py<PyModule> {
36+
fn getattr_inner(&self, name: &Py<PyStr>, vm: &VirtualMachine) -> PyResult {
37+
if let Some(attr) = self.as_object().generic_getattr_opt(name, None, vm)? {
4138
return Ok(attr);
4239
}
43-
if let Ok(getattr) = zelf.dict().get_item(identifier!(vm, __getattr__), vm) {
44-
return getattr.call((name,), vm);
40+
if let Ok(getattr) = self.dict().get_item(identifier!(vm, __getattr__), vm) {
41+
return getattr.call((name.to_owned(),), vm);
4542
}
46-
let module_name = if let Some(name) = zelf.name(vm) {
43+
let module_name = if let Some(name) = self.name(vm) {
4744
format!(" '{name}'")
4845
} else {
4946
"".to_owned()
5047
};
5148
Err(vm.new_attribute_error(format!("module{module_name} has no attribute '{name}'")))
5249
}
53-
}
5450

55-
impl Py<PyModule> {
5651
fn name(&self, vm: &VirtualMachine) -> Option<PyStrRef> {
5752
let name = self
5853
.as_object()
@@ -85,9 +80,10 @@ impl Py<PyModule> {
8580
.expect("Failed to set __spec__ on module");
8681
}
8782

88-
pub fn get_attr(&self, attr_name: impl IntoPyStrRef, vm: &VirtualMachine) -> PyResult {
89-
PyModule::getattr_inner(self, attr_name.into_pystr_ref(vm), vm)
83+
pub fn get_attr<'a>(&self, attr_name: impl AsPyStr<'a>, vm: &VirtualMachine) -> PyResult {
84+
self.getattr_inner(attr_name.as_pystr(&vm.ctx), vm)
9085
}
86+
9187
pub fn set_attr(
9288
&self,
9389
attr_name: impl IntoPyStrRef,
@@ -135,8 +131,8 @@ impl Initializer for PyModule {
135131
}
136132

137133
impl GetAttr for PyModule {
138-
fn getattro(zelf: &Py<Self>, name: PyStrRef, vm: &VirtualMachine) -> PyResult {
139-
Self::getattr_inner(zelf, name, vm)
134+
fn getattro(zelf: &Py<Self>, name: &Py<PyStr>, vm: &VirtualMachine) -> PyResult {
135+
zelf.getattr_inner(name, vm)
140136
}
141137
}
142138

vm/src/builtins/namespace.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ impl Representable for PyNamespace {
8282
let name = if o.class().is(vm.ctx.types.namespace_type) {
8383
"namespace".to_owned()
8484
} else {
85-
o.class().slot_name()
85+
o.class().slot_name().to_owned()
8686
};
8787

8888
let repr = if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) {

vm/src/builtins/object.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -296,14 +296,14 @@ impl PyBaseObject {
296296

297297
/// Return getattr(self, name).
298298
#[pyslot]
299-
pub(crate) fn getattro(obj: &PyObject, name: PyStrRef, vm: &VirtualMachine) -> PyResult {
299+
pub(crate) fn getattro(obj: &PyObject, name: &Py<PyStr>, 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)]
305305
fn getattribute(obj: PyObjectRef, name: PyStrRef, vm: &VirtualMachine) -> PyResult {
306-
Self::getattro(&obj, name, vm)
306+
Self::getattro(&obj, &name, vm)
307307
}
308308

309309
#[pymethod(magic)]

vm/src/builtins/str.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,42 @@ impl IntoPyStrRef for &'static PyStrInterned {
189189
}
190190
}
191191

192+
pub trait AsPyStr<'a>
193+
where
194+
Self: 'a,
195+
{
196+
#[allow(clippy::wrong_self_convention)] // to implement on refs
197+
fn as_pystr(self, ctx: &Context) -> &'a Py<PyStr>;
198+
}
199+
200+
impl<'a> AsPyStr<'a> for &'a Py<PyStr> {
201+
#[inline]
202+
fn as_pystr(self, _ctx: &Context) -> &'a Py<PyStr> {
203+
self
204+
}
205+
}
206+
207+
impl<'a> AsPyStr<'a> for &'a PyStrRef {
208+
#[inline]
209+
fn as_pystr(self, _ctx: &Context) -> &'a Py<PyStr> {
210+
self
211+
}
212+
}
213+
214+
impl AsPyStr<'static> for &'static str {
215+
#[inline]
216+
fn as_pystr(self, ctx: &Context) -> &'static Py<PyStr> {
217+
ctx.intern_str(self)
218+
}
219+
}
220+
221+
impl<'a> AsPyStr<'a> for &'a PyStrInterned {
222+
#[inline]
223+
fn as_pystr(self, _ctx: &Context) -> &'a Py<PyStr> {
224+
self
225+
}
226+
}
227+
192228
#[pyclass(module = false, name = "str_iterator")]
193229
#[derive(Debug)]
194230
pub struct PyStrIterator {

vm/src/builtins/super.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
See also [CPython source code.](https://github.com/python/cpython/blob/50b48572d9a90c5bb36e2bef6179548ea927a35a/Objects/typeobject.c#L7663)
44
*/
55

6-
use super::{PyStrRef, PyType, PyTypeRef};
6+
use super::{PyStr, PyType, PyTypeRef};
77
use crate::{
88
class::PyClassImpl,
99
function::{IntoFuncArgs, OptionalArg},
@@ -126,20 +126,20 @@ impl PySuper {
126126
}
127127

128128
impl GetAttr for PySuper {
129-
fn getattro(zelf: &Py<Self>, name: PyStrRef, vm: &VirtualMachine) -> PyResult {
129+
fn getattro(zelf: &Py<Self>, name: &Py<PyStr>, vm: &VirtualMachine) -> PyResult {
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

142-
if let Some(name) = vm.ctx.interned_str(&*name) {
142+
if let Some(name) = vm.ctx.interned_str(name) {
143143
// skip the classes in start_type.mro up to and including zelf.typ
144144
let mro: Vec<_> = start_type
145145
.iter_mro()
@@ -159,7 +159,7 @@ impl GetAttr for PySuper {
159159
}
160160
}
161161
}
162-
skip(zelf, &name)
162+
skip(zelf, name)
163163
}
164164
}
165165

0 commit comments

Comments
 (0)