|
1 | 1 | use crate::{
|
2 |
| - AsObject, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, |
3 |
| - builtins::{PyBaseExceptionRef, PyTuple, PyTupleRef, PyType}, |
| 2 | + AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, |
| 3 | + builtins::{PyBaseExceptionRef, PyStrRef, PyTuple, PyTupleRef, PyType}, |
4 | 4 | class::{PyClassImpl, StaticType},
|
5 | 5 | vm::Context,
|
6 | 6 | };
|
@@ -47,31 +47,40 @@ pub trait PyStructSequence: StaticType + PyClassImpl + Sized + 'static {
|
47 | 47 | Ok(seq)
|
48 | 48 | }
|
49 | 49 |
|
50 |
| - #[pymethod] |
51 |
| - fn __repr__(zelf: PyRef<PyTuple>, vm: &VirtualMachine) -> PyResult<String> { |
| 50 | + #[pyslot] |
| 51 | + fn slot_repr(zelf: &PyObject, vm: &VirtualMachine) -> PyResult<PyStrRef> { |
| 52 | + let zelf = zelf |
| 53 | + .downcast_ref::<PyTuple>() |
| 54 | + .ok_or_else(|| vm.new_type_error("unexpected payload for __repr__"))?; |
| 55 | + |
52 | 56 | let format_field = |(value, name): (&PyObjectRef, _)| {
|
53 | 57 | let s = value.repr(vm)?;
|
54 | 58 | Ok(format!("{name}={s}"))
|
55 | 59 | };
|
56 |
| - let (body, suffix) = if let Some(_guard) = |
57 |
| - rustpython_vm::recursion::ReprGuard::enter(vm, zelf.as_object()) |
58 |
| - { |
59 |
| - if Self::REQUIRED_FIELD_NAMES.len() == 1 { |
60 |
| - let value = zelf.first().unwrap(); |
61 |
| - let formatted = format_field((value, Self::REQUIRED_FIELD_NAMES[0]))?; |
62 |
| - (formatted, ",") |
| 60 | + let (body, suffix) = |
| 61 | + if let Some(_guard) = rustpython_vm::recursion::ReprGuard::enter(vm, zelf.as_ref()) { |
| 62 | + if Self::REQUIRED_FIELD_NAMES.len() == 1 { |
| 63 | + let value = zelf.first().unwrap(); |
| 64 | + let formatted = format_field((value, Self::REQUIRED_FIELD_NAMES[0]))?; |
| 65 | + (formatted, ",") |
| 66 | + } else { |
| 67 | + let fields: PyResult<Vec<_>> = zelf |
| 68 | + .iter() |
| 69 | + .zip(Self::REQUIRED_FIELD_NAMES.iter().copied()) |
| 70 | + .map(format_field) |
| 71 | + .collect(); |
| 72 | + (fields?.join(", "), "") |
| 73 | + } |
63 | 74 | } else {
|
64 |
| - let fields: PyResult<Vec<_>> = zelf |
65 |
| - .iter() |
66 |
| - .zip(Self::REQUIRED_FIELD_NAMES.iter().copied()) |
67 |
| - .map(format_field) |
68 |
| - .collect(); |
69 |
| - (fields?.join(", "), "") |
70 |
| - } |
71 |
| - } else { |
72 |
| - (String::new(), "...") |
73 |
| - }; |
74 |
| - Ok(format!("{}({}{})", Self::TP_NAME, body, suffix)) |
| 75 | + (String::new(), "...") |
| 76 | + }; |
| 77 | + let repr_str = format!("{}({}{})", Self::TP_NAME, body, suffix); |
| 78 | + Ok(vm.ctx.new_str(repr_str)) |
| 79 | + } |
| 80 | + |
| 81 | + #[pymethod] |
| 82 | + fn __repr__(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyStrRef> { |
| 83 | + Self::slot_repr(&zelf, vm) |
75 | 84 | }
|
76 | 85 |
|
77 | 86 | #[pymethod]
|
|
0 commit comments