mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
PropertyArgs declared a fifth positional-or-keyword field, name, so the
derived arity was 0..=5 and property(None, None, None, None, None) built
a property object with the fifth argument stored in the __name__ slot.
CPython's property.__init__ is Argument Clinic generated with maxpos = 4
and the keyword list {fget, fset, fdel, doc}, so it rejects both that call
and property(name='x').
Drop the field. Nothing passed it: clone_property_with always supplied
None and copies the name separately, and the name slot is still filled by
__set_name__ and the __name__ setter.
Assisted-by: Claude Code:claude-opus-5
95 lines
1.8 KiB
Python
95 lines
1.8 KiB
Python
from testutils import assert_raises
|
|
|
|
|
|
class Fubar:
|
|
def __init__(self):
|
|
self.x = 100
|
|
|
|
@property
|
|
def foo(self):
|
|
value = self.x
|
|
self.x += 1
|
|
return value
|
|
|
|
|
|
f = Fubar()
|
|
assert f.foo == 100
|
|
assert f.foo == 101
|
|
|
|
assert type(Fubar.foo) is property
|
|
|
|
|
|
class Bar:
|
|
def __init__(self):
|
|
self.a = 0
|
|
|
|
@property
|
|
def foo(self):
|
|
return self.a
|
|
|
|
@foo.setter
|
|
def foo(self, value):
|
|
self.a += value
|
|
|
|
@foo.deleter
|
|
def foo(self):
|
|
self.a -= 1
|
|
|
|
|
|
bar = Bar()
|
|
assert bar.foo == 0
|
|
bar.foo = 5
|
|
assert bar.a == 5
|
|
del bar.foo
|
|
assert bar.a == 4
|
|
del bar.foo
|
|
assert bar.a == 3
|
|
|
|
|
|
null_property = property()
|
|
assert type(null_property) is property
|
|
|
|
p = property(lambda x: x[0])
|
|
assert p.__get__((2,), tuple) == 2
|
|
assert p.__get__((2,)) == 2
|
|
|
|
with assert_raises(AttributeError):
|
|
null_property.__get__((), tuple)
|
|
|
|
with assert_raises(TypeError):
|
|
property.__new__(object)
|
|
|
|
assert p.__doc__ is None
|
|
|
|
# Test property instance __doc__ attribute:
|
|
p.__doc__ = "222"
|
|
assert p.__doc__ == "222"
|
|
|
|
|
|
p1 = property("a", "b", "c")
|
|
|
|
assert p1.fget == "a"
|
|
assert p1.fset == "b"
|
|
assert p1.fdel == "c"
|
|
|
|
assert p1.getter(1).fget == 1
|
|
assert p1.setter(2).fset == 2
|
|
assert p1.deleter(3).fdel == 3
|
|
|
|
assert p1.getter(None).fget == "a"
|
|
assert p1.setter(None).fset == "b"
|
|
assert p1.deleter(None).fdel == "c"
|
|
|
|
assert p1.__get__(None, object) is p1
|
|
# assert p1.__doc__ is 'a'.__doc__
|
|
|
|
p2 = property("a", doc="pdoc")
|
|
# assert p2.__doc__ == 'pdoc'
|
|
|
|
|
|
# property() takes at most four arguments, and `name` is not one of them:
|
|
# the name slot is filled by __set_name__ and the __name__ setter instead.
|
|
assert_raises(TypeError, property, None, None, None, None, None)
|
|
assert_raises(TypeError, property, "a", "b", "c", "d", "e")
|
|
assert_raises(TypeError, property, name="x")
|