(zelf: &PyObject, vm: &VirtualMachine)
| 204 | |
| 205 | #[pyslot] |
| 206 | fn slot_repr(zelf: &PyObject, vm: &VirtualMachine) -> PyResult<PyStrRef> { |
| 207 | let zelf = zelf |
| 208 | .downcast_ref::<PyTuple>() |
| 209 | .ok_or_else(|| vm.new_type_error("unexpected payload for __repr__"))?; |
| 210 | |
| 211 | let field_names = Self::Data::REQUIRED_FIELD_NAMES; |
| 212 | let format_field = |(value, name): (&PyObject, _)| { |
| 213 | let s = value.repr(vm)?; |
| 214 | Ok(format!("{name}={s}")) |
| 215 | }; |
| 216 | let (body, suffix) = |
| 217 | if let Some(_guard) = rustpython_vm::recursion::ReprGuard::enter(vm, zelf.as_ref()) { |
| 218 | let fields: PyResult<Vec<_>> = zelf |
| 219 | .iter() |
| 220 | .map(|value| value.as_ref()) |
| 221 | .zip(field_names.iter().copied()) |
| 222 | .map(format_field) |
| 223 | .collect(); |
| 224 | (fields?.join(", "), "") |
| 225 | } else { |
| 226 | (String::new(), "...") |
| 227 | }; |
| 228 | // Build qualified name: if MODULE_NAME is already in TP_NAME, use it directly. |
| 229 | // Otherwise, check __module__ attribute (set by #[pymodule] at runtime). |
| 230 | let type_name = if Self::MODULE_NAME.is_some() { |
| 231 | alloc::borrow::Cow::Borrowed(Self::TP_NAME) |
| 232 | } else { |
| 233 | let typ = zelf.class(); |
| 234 | match typ.get_attr(identifier!(vm.ctx, __module__)) { |
| 235 | Some(module) if module.downcastable::<PyStr>() => { |
| 236 | let module_str = module.downcast_ref::<PyStr>().unwrap(); |
| 237 | alloc::borrow::Cow::Owned(format!("{}.{}", module_str.as_wtf8(), Self::NAME)) |
| 238 | } |
| 239 | _ => alloc::borrow::Cow::Borrowed(Self::TP_NAME), |
| 240 | } |
| 241 | }; |
| 242 | let repr_str = format!("{}({}{})", type_name, body, suffix); |
| 243 | Ok(vm.ctx.new_str(repr_str)) |
| 244 | } |
| 245 | |
| 246 | #[pymethod] |
| 247 | fn __replace__(zelf: PyRef<PyTuple>, args: FuncArgs, vm: &VirtualMachine) -> PyResult { |
nothing calls this directly
no test coverage detected