Descriptor HowTo: Sync the error-messages with the C code. Add tests. (gh-112403)

This commit is contained in:
Raymond Hettinger 2023-11-25 16:18:00 -06:00 committed by GitHub
parent 0303a9fa79
commit f93a4ef7a9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1013,17 +1013,23 @@ here is a pure Python equivalent:
if obj is None:
return self
if self.fget is None:
raise AttributeError(f"property '{self._name}' has no getter")
raise AttributeError(
f'property {self._name!r} of {type(obj).__name__!r} object has no getter'
)
return self.fget(obj)
def __set__(self, obj, value):
if self.fset is None:
raise AttributeError(f"property '{self._name}' has no setter")
raise AttributeError(
f'property {self._name!r} of {type(obj).__name__!r} object has no setter'
)
self.fset(obj, value)
def __delete__(self, obj):
if self.fdel is None:
raise AttributeError(f"property '{self._name}' has no deleter")
raise AttributeError(
f'property {self._name!r} of {type(obj).__name__!r} object has no deleter'
)
self.fdel(obj)
def getter(self, fget):
@ -1054,6 +1060,11 @@ here is a pure Python equivalent:
def delx(self):
del self.__x
x = Property(getx, setx, delx, "I'm the 'x' property.")
no_getter = Property(None, setx, delx, "I'm the 'x' property.")
no_setter = Property(getx, None, delx, "I'm the 'x' property.")
no_deleter = Property(getx, setx, None, "I'm the 'x' property.")
no_doc = Property(getx, setx, delx, None)
# Now do it again but use the decorator style
@ -1092,6 +1103,32 @@ here is a pure Python equivalent:
>>> hasattr(ccc, 'x')
False
>>> cc = CC()
>>> cc.x = 33
>>> try:
... cc.no_getter
... except AttributeError as e:
... e.args[0]
...
"property 'no_getter' of 'CC' object has no getter"
>>> try:
... cc.no_setter = 33
... except AttributeError as e:
... e.args[0]
...
"property 'no_setter' of 'CC' object has no setter"
>>> try:
... del cc.no_deleter
... except AttributeError as e:
... e.args[0]
...
"property 'no_deleter' of 'CC' object has no deleter"
>>> CC.no_doc.__doc__ is None
True
The :func:`property` builtin helps whenever a user interface has granted
attribute access and then subsequent changes require the intervention of a
method.