From 616cc259a88a461af60a339f4b3cf25bfadd9f2f Mon Sep 17 00:00:00 2001 From: Hanjeong Lee Date: Thu, 10 Sep 2026 15:45:54 +0900 Subject: [PATCH] Stop generating a `__text_signature__` that `inspect` cannot parse (#8681) * Leave Callee out of a generated __text_signature__ The interpreter supplies `callee` the way it supplies `vm`, but only `vm` was filtered, so the argument surfaced as a Python parameter and left a string inspect cannot parse: >>> object.__getstate__.__text_signature__ '(*args, **kwargs, callee)' >>> inspect.signature(object.__getstate__) ValueError: builtin has invalid signature Filter it in `func_sig`, and in `infer_native_call_flags`, which counted it as a fixed positional argument. `object.__getstate__` is the only #[pymethod] taking one today, inherited by 95 types. Assisted-by: Claude Code:claude-opus-5 * Rename maketrans's first parameter to frm `from` is a Python keyword, so the generated signature could not be parsed: >>> bytes.maketrans.__text_signature__ '(from, to, /)' >>> inspect.signature(bytes.maketrans) ValueError: builtin has invalid signature CPython's Argument Clinic spells it `frm` for the same reason. Both parameters are positional-only, so the name is documentation only. `bytes.maketrans` and `bytearray.maketrans` now report what CPython reports, `(frm, to, /)`. Assisted-by: Claude Code:claude-opus-5 --- crates/derive-impl/src/util.rs | 7 ++++--- crates/vm/src/builtins/bytearray.rs | 4 ++-- crates/vm/src/builtins/bytes.rs | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/crates/derive-impl/src/util.rs b/crates/derive-impl/src/util.rs index cae12d3c3..a3b751bd9 100644 --- a/crates/derive-impl/src/util.rs +++ b/crates/derive-impl/src/util.rs @@ -768,8 +768,9 @@ pub(crate) fn infer_native_call_flags(sig: &Signature, drop_first_typed: usize) }; let ty_tokens = &typed.ty; let ty = quote!(#ty_tokens).to_string().replace(' ', ""); - // `vm: &VirtualMachine` is not a Python-level argument. - if ty.starts_with('&') && ty.ends_with("VirtualMachine") { + // The interpreter supplies `vm` and `callee`; a Python call never + // passes them. + if (ty.starts_with('&') && ty.ends_with("VirtualMachine")) || ty.ends_with("Callee") { continue; } typed_args.push(ty); @@ -853,7 +854,7 @@ fn func_sig(sig: &Signature, mut implicit_self: Option<&str>) -> Option params.push("*args, **kwargs".to_owned()); continue; } - if ty.starts_with('&') && ty.ends_with("VirtualMachine") { + if (ty.starts_with('&') && ty.ends_with("VirtualMachine")) || ty.ends_with("Callee") { continue; } if let Some(marker) = implicit_self.take() { diff --git a/crates/vm/src/builtins/bytearray.rs b/crates/vm/src/builtins/bytearray.rs index f42dc7a85..ce8425f68 100644 --- a/crates/vm/src/builtins/bytearray.rs +++ b/crates/vm/src/builtins/bytearray.rs @@ -252,8 +252,8 @@ impl PyByteArray { } #[pystaticmethod] - fn maketrans(from: PyBytesInner, to: PyBytesInner, vm: &VirtualMachine) -> PyResult> { - PyBytesInner::maketrans(from, to, vm) + fn maketrans(frm: PyBytesInner, to: PyBytesInner, vm: &VirtualMachine) -> PyResult> { + PyBytesInner::maketrans(frm, to, vm) } #[pymethod] diff --git a/crates/vm/src/builtins/bytes.rs b/crates/vm/src/builtins/bytes.rs index bd132eb15..ab18cf636 100644 --- a/crates/vm/src/builtins/bytes.rs +++ b/crates/vm/src/builtins/bytes.rs @@ -250,8 +250,8 @@ impl PyBytes { } #[pystaticmethod] - fn maketrans(from: PyBytesInner, to: PyBytesInner, vm: &VirtualMachine) -> PyResult> { - PyBytesInner::maketrans(from, to, vm) + fn maketrans(frm: PyBytesInner, to: PyBytesInner, vm: &VirtualMachine) -> PyResult> { + PyBytesInner::maketrans(frm, to, vm) } fn __getitem__(&self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult {