Skip to content

Commit 7ff974e

Browse files
authored
Merge pull request RustPython#3261 from Snowapril/fix-issue-3232
Modify `PyType::name` method to return `BorrowedValue<str>`
2 parents 5db4a23 + f85ffd2 commit 7ff974e

File tree

12 files changed

+56
-22
lines changed

12 files changed

+56
-22
lines changed

common/src/borrow.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ use crate::lock::{
22
MapImmutable, PyImmutableMappedMutexGuard, PyMappedMutexGuard, PyMappedRwLockReadGuard,
33
PyMappedRwLockWriteGuard, PyMutexGuard, PyRwLockReadGuard, PyRwLockWriteGuard,
44
};
5-
use std::ops::{Deref, DerefMut};
5+
use std::{
6+
fmt,
7+
ops::{Deref, DerefMut},
8+
};
69

710
macro_rules! impl_from {
811
($lt:lifetime, $gen:ident, $t:ty, $($var:ident($from:ty),)*) => {
@@ -64,6 +67,12 @@ impl<T: ?Sized> Deref for BorrowedValue<'_, T> {
6467
}
6568
}
6669

70+
impl fmt::Display for BorrowedValue<'_, str> {
71+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72+
fmt::Display::fmt(self.deref(), f)
73+
}
74+
}
75+
6776
#[derive(Debug)]
6877
pub enum BorrowedValueMut<'a, T: ?Sized> {
6978
RefMut(&'a mut T),

stdlib/src/array.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1036,7 +1036,8 @@ mod array {
10361036

10371037
#[pymethod(magic)]
10381038
fn repr(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<String> {
1039-
let class_name = zelf.class().name();
1039+
let class = zelf.class();
1040+
let class_name = class.name();
10401041
if zelf.read().typecode() == 'u' {
10411042
if zelf.len() == 0 {
10421043
return Ok(format!("{}('u')", class_name));

vm/src/builtins/bytearray.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ impl PyByteArray {
128128

129129
#[pymethod(magic)]
130130
fn repr(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyResult<String> {
131-
let class_name = zelf.class().name();
131+
let class = zelf.class();
132+
let class_name = class.name();
132133
let s = zelf.inner().repr(Some(&class_name));
133134
Ok(s)
134135
}

vm/src/builtins/object.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,8 @@ impl PyBaseObject {
254254
Ok(())
255255
}
256256
Err(value) => {
257-
let type_repr = &value.class().name();
257+
let value_class = value.class();
258+
let type_repr = &value_class.name();
258259
Err(vm.new_type_error(format!(
259260
"__class__ must be set to a class, not '{}' object",
260261
type_repr

vm/src/builtins/pybool.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ impl SlotConstructor for PyBool {
9797

9898
fn py_new(zelf: PyTypeRef, x: Self::Args, vm: &VirtualMachine) -> PyResult {
9999
if !zelf.isinstance(&vm.ctx.types.type_type) {
100-
let actual_type = &zelf.class().name();
100+
let actual_class = zelf.class();
101+
let actual_type = &actual_class.name();
101102
return Err(vm.new_type_error(format!(
102103
"requires a 'type' object but received a '{}'",
103104
actual_type

vm/src/builtins/pystr.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1463,6 +1463,7 @@ fn char_is_printable(c: char) -> bool {
14631463
mod tests {
14641464
use super::*;
14651465
use crate::Interpreter;
1466+
use std::ops::Deref;
14661467

14671468
#[test]
14681469
fn str_title() {
@@ -1531,7 +1532,7 @@ mod tests {
15311532
assert_eq!(translated, "🎅xda".to_owned());
15321533
let translated = text.translate(vm.ctx.new_int(3), &vm);
15331534
assert_eq!(
1534-
translated.unwrap_err().class().name(),
1535+
translated.unwrap_err().class().name().deref(),
15351536
"TypeError".to_owned()
15361537
);
15371538
})

vm/src/builtins/pytype.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ use super::{
22
mappingproxy::PyMappingProxy, object, PyClassMethod, PyDictRef, PyInt, PyList, PyStaticMethod,
33
PyStr, PyStrRef, PyTuple, PyTupleRef, PyWeak,
44
};
5-
use crate::common::{ascii, lock::PyRwLock};
5+
use crate::common::{
6+
ascii,
7+
borrow::BorrowedValue,
8+
lock::{PyRwLock, PyRwLockReadGuard},
9+
};
610
use crate::{
711
function::{FuncArgs, KwArgs, OptionalArg},
812
protocol::{PyIterReturn, PyMappingMethods},
@@ -400,9 +404,16 @@ impl PyType {
400404
vm.ctx.not_implemented()
401405
}
402406

403-
#[pyproperty(magic)]
404-
pub fn name(&self) -> String {
405-
self.slot_name().rsplit('.').next().unwrap().to_string()
407+
#[pyproperty]
408+
fn __name__(&self) -> String {
409+
self.name().to_string()
410+
}
411+
412+
pub fn name(&self) -> BorrowedValue<str> {
413+
PyRwLockReadGuard::map(self.slots.name.read(), |slot_name| {
414+
slot_name.as_ref().unwrap().rsplit('.').next().unwrap()
415+
})
416+
.into()
406417
}
407418

408419
#[pymethod(magic)]
@@ -440,7 +451,7 @@ impl PyType {
440451
Some(found)
441452
}
442453
})
443-
.unwrap_or_else(|| vm.ctx.new_utf8_str(self.name()))
454+
.unwrap_or_else(|| vm.ctx.new_utf8_str(self.name().deref()))
444455
}
445456

446457
#[pyproperty(magic)]
@@ -653,7 +664,7 @@ impl PyType {
653664
fn text_signature(&self) -> Option<String> {
654665
self.slots
655666
.doc
656-
.and_then(|doc| get_text_signature_from_internal_doc(self.name().as_str(), doc))
667+
.and_then(|doc| get_text_signature_from_internal_doc(&self.name(), doc))
657668
.map(|signature| signature.to_string())
658669
}
659670
}

vm/src/builtins/set.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::{
1515
IdProtocol, PyClassImpl, PyComparisonValue, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
1616
TryFromObject, TypeProtocol,
1717
};
18-
use std::fmt;
18+
use std::{fmt, ops::Deref};
1919

2020
pub type SetContentType = dictdatatype::Dict<()>;
2121

@@ -512,12 +512,14 @@ impl PySet {
512512

513513
#[pymethod(magic)]
514514
fn repr(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult {
515-
let class_name = zelf.class().name();
515+
let class = zelf.class();
516+
let borrowed_name = class.name();
517+
let class_name = borrowed_name.deref();
516518
let s = if zelf.inner.len() == 0 {
517519
format!("{}()", class_name)
518520
} else if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) {
519521
let name = if class_name != "set" {
520-
Some(class_name.as_str())
522+
Some(class_name)
521523
} else {
522524
None
523525
};
@@ -790,7 +792,8 @@ impl PyFrozenSet {
790792
#[pymethod(magic)]
791793
fn repr(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult {
792794
let inner = &zelf.inner;
793-
let class_name = zelf.class().name();
795+
let class = zelf.class();
796+
let class_name = class.name();
794797
let s = if inner.len() == 0 {
795798
format!("{}()", class_name)
796799
} else if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) {

vm/src/exceptions.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use itertools::Itertools;
1515
use std::{
1616
collections::HashSet,
1717
io::{self, BufRead, BufReader},
18+
ops::Deref,
1819
};
1920

2021
impl std::fmt::Debug for PyBaseException {
@@ -175,7 +176,8 @@ pub fn write_exception_inner<W: Write>(
175176
let varargs = exc.args();
176177
let args_repr = exception_args_as_string(vm, varargs, true);
177178

178-
let exc_name = exc.class().name();
179+
let exc_class = exc.class();
180+
let exc_name = exc_class.name();
179181
match args_repr.len() {
180182
0 => writeln!(output, "{}", exc_name),
181183
1 => writeln!(output, "{}: {}", exc_name, args_repr[0]),
@@ -878,7 +880,7 @@ impl serde::Serialize for SerializeException<'_> {
878880
use serde::ser::*;
879881

880882
let mut struc = s.serialize_struct("PyBaseException", 7)?;
881-
struc.serialize_field("exc_type", &self.exc.class().name())?;
883+
struc.serialize_field("exc_type", self.exc.class().name().deref())?;
882884
let tbs = {
883885
struct Tracebacks(PyTracebackRef);
884886
impl serde::Serialize for Tracebacks {
@@ -956,6 +958,7 @@ pub(super) mod types {
956958
PyObjectRef, PyRef, PyResult, VirtualMachine,
957959
};
958960
use crossbeam_utils::atomic::AtomicCell;
961+
use std::ops::Deref;
959962

960963
// This module is designed to be used as `use builtins::*;`.
961964
// Do not add any pub symbols not included in builtins module.
@@ -1209,7 +1212,7 @@ pub(super) mod types {
12091212
// We need this method, because of how `CPython` copies `init`
12101213
// from `BaseException` in `SimpleExtendsException` macro.
12111214
// See: `BaseException_new`
1212-
if cls.name() == vm.ctx.exceptions.os_error.name() {
1215+
if cls.name().deref() == vm.ctx.exceptions.os_error.name().deref() {
12131216
match os_error_optional_new(args.args.to_vec(), vm) {
12141217
Some(error) => error.unwrap().into_pyresult(vm),
12151218
None => PyBaseException::slot_new(cls, args, vm),

vm/src/function.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,8 @@ impl FuncArgs {
182182
Ok(Some(kwarg))
183183
} else {
184184
let expected_ty_name = &ty.name();
185-
let actual_ty_name = &kwarg.class().name();
185+
let kwarg_class = kwarg.class();
186+
let actual_ty_name = &kwarg_class.name();
186187
Err(vm.new_type_error(format!(
187188
"argument of type {} is required for named parameter `{}` (got: {})",
188189
expected_ty_name, key, actual_ty_name

vm/src/pyobject.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,8 @@ pub(crate) fn pyref_type_error(
442442
obj: impl std::borrow::Borrow<PyObjectRef>,
443443
) -> PyBaseExceptionRef {
444444
let expected_type = &*class.name();
445-
let actual_type = &*obj.borrow().class().name();
445+
let actual_class = obj.borrow().class();
446+
let actual_type = &*actual_class.name();
446447
vm.new_type_error(format!(
447448
"Expected type '{}', not '{}'",
448449
expected_type, actual_type,

vm/src/stdlib/posix.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,8 +492,9 @@ pub mod module {
492492
))]
493493
fn try_to_libc(&self, vm: &VirtualMachine) -> PyResult<libc::sched_param> {
494494
use crate::TypeProtocol;
495+
let priority_class = self.sched_priority.class();
496+
let priority_type = priority_class.name();
495497
let priority = self.sched_priority.clone();
496-
let priority_type = priority.class().name();
497498
let value = priority.downcast::<PyInt>().map_err(|_| {
498499
vm.new_type_error(format!(
499500
"an integer is required (got type {})",

0 commit comments

Comments
 (0)