Feature
property(None, None, None, None, None) constructs a property object in RustPython, but CPython raises TypeError because property() takes at most four arguments.
Reproduction
print(type(property(None, None, None, None, None)))
RustPython:
CPython:
TypeError: property() takes at most 4 arguments (5 given)
Root cause
PropertyArgs declares a fifth #[pyarg(any, default)] field, name, and compute_arity_bounds counts every positional-or-keyword field toward the maximum arity, so PropertyArgs::arity() is 0..=5 and the leftover-positional check in FuncArgs::bind passes for five arguments; Initializer::init then stores the fifth one in the __name__ slot. CPython's property.__init__ is Argument Clinic generated with maxpos = 4 and the keyword list {fget, fset, fdel, doc}, so _PyArg_UnpackKeywords rejects the fifth argument before property_init_impl runs. The same field also makes RustPython accept property(name='x'), which is not in CPython's keyword list either.
Fix
Remove the name field from PropertyArgs and the assignment that consumes it in Initializer::init, which drops the derived arity back to 0..=4. No caller passes it: clone_property_with already passes name: None and copies the name separately, and the PyProperty name slot stays filled by __set_name__ and the __name__ setter.
Environment
- RustPython d248a04 (Python 3.14.0), also reproduced on 0.5.0
- CPython v3.14.3
- OS: Debian 12
Python Documentation or reference to CPython source code
-
CPython property_init: Objects/clinic/descrobject.c.h#L133-L150 — the Argument Clinic generated parser fixes the keyword list at four entries and passes maxpos = 4:
static const char * const _keywords[] = {"fget", "fset", "fdel", "doc", NULL};
static _PyArg_Parser _parser = {
.keywords = _keywords,
.fname = "property",
.kwtuple = KWTUPLE,
};
...
fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser,
/*minpos*/ 0, /*maxpos*/ 4, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
-
CPython _PyArg_UnpackKeywords: Python/getargs.c#L2429-L2441 — raises the TypeError once the argument count exceeds maxargs, before the implementation function is reached:
if (!varpos && nargs + nkwargs > maxargs) {
/* Adding "keyword" (when nargs == 0) prevents producing wrong error
messages in some special cases (see bpo-31229). */
PyErr_Format(PyExc_TypeError,
"%.200s%s takes at most %d %sargument%s (%zd given)",
(parser->fname == NULL) ? "function" : parser->fname,
(parser->fname == NULL) ? "" : "()",
maxargs,
(nargs == 0) ? "keyword " : "",
(maxargs == 1) ? "" : "s",
nargs + nkwargs);
return NULL;
}
-
Documentation: property, whose signature is property(fget=None, fset=None, fdel=None, doc=None).
Related arity-validation gaps in other builtin constructors: #8461, #8462.
AI disclosure: this report was drafted with Claude Code (claude-opus-5) and reviewed by me before submission. The divergence comes from a differential-testing run against CPython 3.14.3, and every source reference above was checked against the linked revisions.
Feature
property(None, None, None, None, None)constructs apropertyobject in RustPython, but CPython raisesTypeErrorbecauseproperty()takes at most four arguments.Reproduction
RustPython:
CPython:
Root cause
PropertyArgsdeclares a fifth#[pyarg(any, default)]field,name, andcompute_arity_boundscounts every positional-or-keyword field toward the maximum arity, soPropertyArgs::arity()is0..=5and the leftover-positional check inFuncArgs::bindpasses for five arguments;Initializer::initthen stores the fifth one in the__name__slot. CPython'sproperty.__init__is Argument Clinic generated withmaxpos = 4and the keyword list{fget, fset, fdel, doc}, so_PyArg_UnpackKeywordsrejects the fifth argument beforeproperty_init_implruns. The same field also makes RustPython acceptproperty(name='x'), which is not in CPython's keyword list either.Fix
Remove the
namefield fromPropertyArgsand the assignment that consumes it inInitializer::init, which drops the derived arity back to0..=4. No caller passes it:clone_property_withalready passesname: Noneand copies the name separately, and thePyPropertynameslot stays filled by__set_name__and the__name__setter.Environment
Python Documentation or reference to CPython source code
CPython
property_init:Objects/clinic/descrobject.c.h#L133-L150— the Argument Clinic generated parser fixes the keyword list at four entries and passesmaxpos = 4:CPython
_PyArg_UnpackKeywords:Python/getargs.c#L2429-L2441— raises theTypeErroronce the argument count exceedsmaxargs, before the implementation function is reached:Documentation:
property, whose signature isproperty(fget=None, fset=None, fdel=None, doc=None).Related arity-validation gaps in other builtin constructors: #8461, #8462.
AI disclosure: this report was drafted with Claude Code (claude-opus-5) and reviewed by me before submission. The divergence comes from a differential-testing run against CPython 3.14.3, and every source reference above was checked against the linked revisions.