Repository navigation
Match CPython Clinic layout for 56 raw text signatures - #9758
youknowdot wants to merge 5 commits into
Conversation
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: truePre-merge checks:
|
b6884be to
8c7ecd1
Compare
youknowone
left a comment
There was a problem hiding this comment.
The shared renderer change looks right. RustPython's derive-generated signatures are the counterpart of Clinic-generated ones, so applying Clinic's wrapping rule (chunks including the trailing comma, wrap at 72 columns, indent by name() in the one shared const renderer is the right place for it. It runs at compile time and only changes the raw __text_signature__ layout; __doc__ and inspect.signature are unaffected, as the PR states. Example with CPython 3.15.1:
binascii.a2b_base64.__text_signature__
before: '($module, data, /, *, strict_mode=<unrepresentable>, padded=True, alphabet=BASE64_ALPHABET, ignorechars=<unrepresentable>, canonical=False)'
after: '($module, data, /, *, strict_mode=<unrepresentable>,\n padded=True, alphabet=BASE64_ALPHABET,\n ignorechars=<unrepresentable>, canonical=False)'
Minor: total_tokens comes from a second dry run of write_args over an empty buffer. It is correct, but the renderer now runs twice per signature, which is worth a short comment.
The binascii hunk shows a structural problem
The three ItemDoc::static_text("a2b_base*(...)") strings had to be wrapped by hand because they bypass the renderer. Every future renderer change will need the same manual edit, and nothing catches a miss. The information is also duplicated: A2bBase64Args already carries the full signature metadata (py_default = "BASE64_ALPHABET", etc.).
These are hand-built PyMethodDefs only because the functions take their defining module:
fn a2b_base64(module: PyRef<PyModule>, args: A2bBase64Args, vm: &VirtualMachine)and #[pyfunction] has no way to receive that; no existing #[pyfunction] does. Every C module function receives PyObject *module, so the structural fix is for #[pyfunction] to recognize a leading module: &Py<PyModule> / PyRef<PyModule> parameter, pass the bound __self__, and leave it out of the signature, just as vm is left out. Then the manual definitions and the module_exec registration loop go away, the signatures are generated from A2bBase64Args, and this PR's wrapping applies automatically.
The other hand-written signature texts are the same kind of thing: __new__($type, *args, **kwargs) in vm/context.rs, __replace__($self, /, **fields) in _ast/python.rs, and __reduce__($self, /) in types/structseq.rs and stdlib/_thread.rs. They are closures or out-of-class PyMethodDefs that cannot go through the macros. They are short, so wrapping does not affect them today, but a const helper that builds an ItemDoc from typed signature metadata would remove them too. The static_text uses in crates/capi carry C-provided text and are fine.
Not blocking for this PR. Please note the binascii edit as a stopgap; module-parameter support in #[pyfunction] can follow separately (or land first, making the hunk unnecessary).
— commented by Claude
3d7cb99 to
6b4d65a
Compare
| canonical: OptionalArg<PyObjectRef>, | ||
| } | ||
|
|
||
| /// Decode a line of base64 data. |
There was a problem hiding this comment.
don't add this. it must be retrived from rustpython-doc
6b4d65a to
e88e190
Compare
|
@youknowdot Please replace the WhyIn CPython every module-level C function receives its module as the first C argument ( Design
Must stay identical
ValidationWorkspace and CAPI tests, strict Clippy for both, the existing signature/binascii snippets on CPython 3.15 and RustPython, and — commented by Claude |
Assisted-by: OpenAI Codex:GPT-6.1
Assisted-by: OpenAI Codex
Add explicit pyfunction(with_module) support for a leading PyRef<PyModule> or &Py<PyModule>, reusing the existing bound native call path. Keep this opt-in: _imp.exec_builtin and exec_dynamic take ordinary module arguments of the same type. Generate binascii decoder signatures from FromArgs metadata, preserve their docs, and remove manual registration. Assisted-by: Codex:unknown
Remove the three inline docstring overrides from the module-bound decoder functions. Import their complete CPython 3.15.1 documentation into the shared database, including the missing base32 and base85 entries, and cover the parameter documentation in the existing binascii snippet. Assisted-by: Codex:unknown
Replace the with_module opt-in and BIND_MODULE flag with a structural module receiver carried in Callee. Infer leading owned or borrowed module parameters in pyfunction through a distinct adapter, and keep one typed receiver in PyNativeFunction while preserving positional method binding. Update C-API adapters and _imp target-module calls, document the canonical receiver spelling, and cover module injection and callable metadata. The binascii decoders retain generated signatures and rustpython-doc bodies. Assisted-by: Codex:unknown
34ce070 to
1ca28a0
Compare
Summary
Match CPython 3.15 Argument Clinic's raw signature wrapping at compile time. Complete parameter chunks, including
/,*, defaults, and trailing commas, wrap at 72 columns; continuation indentation and Unicode character counting follow Clinic. Exact fixtures cover the original 56 layout discrepancies.The module-receiver implementation has been rebuilt following review:
zelfreceiver.module_object,with_module_object,BIND_MODULE, and thewith_moduleattribute option are removed.Callee, outsideFuncArgs. Ordinary functions incur no receiver prepend, clone, or downcast. Bound methods retain positional receiver binding.#[pyfunction]recognizes a leadingPyRef<PyModule>or&Py<PyModule>syntactically, uses a distinct adapter kind, and omits that receiver from Python's arguments. Canonical spelling and alias limitations are documented;PyModuleRefis explicitly rejected._imp.exec_builtinand_imp.exec_dynamicdeclare a defining-module receiver before their Python-visible target module. C-API adapters consume the separate receiver without changing method calls.#[pyfunction]registration and obtain their full CPython documentation fromrustpython-doc, not duplicated Rust docstrings.Rebased independently onto main
c07e0bc954; not stacked on another open PR. No new dependencies or changes toLib/test.Validation
-D warnings) passes.test_binascii test_inspect test_builtin test_importlib: 1,994 tests, 132 skipped; all four modules pass.extra_testspytest: 495 passed, 20 failed on both baseline and changed builds, with exactly the same failing cases. These cover sandbox IPC/socket/OS limitations, disabled SQLite, and existing standalone-CPython/test compatibility differences. Additional profiler tests likewise reproduce only the baseline forkserver permission failure.math.sqrttight loop, same optimized build settings, CPU-pinned alternating runs, 9 samples of 3 million calls per build: median 424.8 → 421.2 ns/call (-0.84%, within run-to-run variation). No increased call cost was observed.Hosted CI: pending for
1ca28a0d49769ad6cd25cb777ec70fb19a92984b.AI assistance: OpenAI Codex assisted with implementation, regression tests, review, and validation.