This commit is contained in:
Jeong YunWon
2025-12-24 17:48:41 +09:00
committed by Jeong, YunWon
parent 7c3bc5ed8d
commit a4e60f569e
3 changed files with 26 additions and 8 deletions

View File

@@ -7,7 +7,7 @@ use crate::{
function::{FuncArgs, PyMethodDef, PyMethodFlags, PySetterValue},
types::{
Callable, Comparable, GetDescriptor, HashFunc, Hashable, InitFunc, PyComparisonOp,
Representable,
Representable, StringifyFunc,
},
};
use rustpython_common::lock::PyRwLock;
@@ -398,6 +398,7 @@ pub fn init(ctx: &Context) {
pub enum SlotFunc {
Init(InitFunc),
Hash(HashFunc),
Repr(StringifyFunc),
}
impl std::fmt::Debug for SlotFunc {
@@ -405,6 +406,7 @@ impl std::fmt::Debug for SlotFunc {
match self {
SlotFunc::Init(_) => write!(f, "SlotFunc::Init(...)"),
SlotFunc::Hash(_) => write!(f, "SlotFunc::Hash(...)"),
SlotFunc::Repr(_) => write!(f, "SlotFunc::Repr(...)"),
}
}
}
@@ -426,6 +428,15 @@ impl SlotFunc {
let hash = func(&obj, vm)?;
Ok(vm.ctx.new_int(hash).into())
}
SlotFunc::Repr(func) => {
if !args.args.is_empty() || !args.kwargs.is_empty() {
return Err(
vm.new_type_error("__repr__() takes no arguments (1 given)".to_owned())
);
}
let s = func(&obj, vm)?;
Ok(s.into())
}
}
}
}
@@ -456,7 +467,6 @@ impl GetDescriptor for PySlotWrapper {
) -> PyResult {
match obj {
None => Ok(zelf),
Some(obj) if vm.is_none(&obj) => Ok(zelf),
Some(obj) => {
let zelf = zelf.downcast::<Self>().unwrap();
Ok(PyMethodWrapper { wrapper: zelf, obj }.into_pyobject(vm))

View File

@@ -174,6 +174,20 @@ pub trait PyClassImpl: PyClassDef {
class.set_attr(ctx.names.__hash__, ctx.none.clone().into());
}
// Add __repr__ slot wrapper if slot exists and not already in dict
if let Some(repr_func) = class.slots.repr.load() {
let repr_name = identifier!(ctx, __repr__);
if !class.attributes.read().contains_key(repr_name) {
let wrapper = PySlotWrapper {
typ: class,
name: ctx.intern_str("__repr__"),
wrapped: SlotFunc::Repr(repr_func),
doc: Some("Return repr(self)."),
};
class.set_attr(repr_name, wrapper.into_ref(ctx).into());
}
}
class.extend_methods(class.slots.methods, ctx);
}

View File

@@ -1114,12 +1114,6 @@ pub trait Representable: PyPayload {
Self::repr(zelf, vm)
}
#[inline]
#[pymethod]
fn __repr__(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyRef<PyStr>> {
Self::slot_repr(&zelf, vm)
}
#[inline]
fn repr(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyRef<PyStr>> {
let repr = Self::repr_str(zelf, vm)?;