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
This commit is contained in:
Hanjeong Lee authored and GitHub committed 2026-09-10 15:45:54 +09:00
1 parent 5afe140abd
commit 616cc259a8
3 files changed
+8 -7

No files matched your search

+4 -3
View File
@@ -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<String>
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() {
+2 -2
View File
@@ -252,8 +252,8 @@ impl PyByteArray {
}
#[pystaticmethod]
fn maketrans(from: PyBytesInner, to: PyBytesInner, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
PyBytesInner::maketrans(from, to, vm)
fn maketrans(frm: PyBytesInner, to: PyBytesInner, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
PyBytesInner::maketrans(frm, to, vm)
}
#[pymethod]
+2 -2
View File
@@ -250,8 +250,8 @@ impl PyBytes {
}
#[pystaticmethod]
fn maketrans(from: PyBytesInner, to: PyBytesInner, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
PyBytesInner::maketrans(from, to, vm)
fn maketrans(frm: PyBytesInner, to: PyBytesInner, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
PyBytesInner::maketrans(frm, to, vm)
}
fn __getitem__(&self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult {