Skip to content

Commit f93a4ef

Browse files
authored
Descriptor HowTo: Sync the error-messages with the C code. Add tests. (gh-112403)
1 parent 0303a9f commit f93a4ef

File tree

1 file changed

+40
-3
lines changed

1 file changed

+40
-3
lines changed

Doc/howto/descriptor.rst

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,17 +1013,23 @@ here is a pure Python equivalent:
10131013
if obj is None:
10141014
return self
10151015
if self.fget is None:
1016-
raise AttributeError(f"property '{self._name}' has no getter")
1016+
raise AttributeError(
1017+
f'property {self._name!r} of {type(obj).__name__!r} object has no getter'
1018+
)
10171019
return self.fget(obj)
10181020

10191021
def __set__(self, obj, value):
10201022
if self.fset is None:
1021-
raise AttributeError(f"property '{self._name}' has no setter")
1023+
raise AttributeError(
1024+
f'property {self._name!r} of {type(obj).__name__!r} object has no setter'
1025+
)
10221026
self.fset(obj, value)
10231027

10241028
def __delete__(self, obj):
10251029
if self.fdel is None:
1026-
raise AttributeError(f"property '{self._name}' has no deleter")
1030+
raise AttributeError(
1031+
f'property {self._name!r} of {type(obj).__name__!r} object has no deleter'
1032+
)
10271033
self.fdel(obj)
10281034

10291035
def getter(self, fget):
@@ -1054,6 +1060,11 @@ here is a pure Python equivalent:
10541060
def delx(self):
10551061
del self.__x
10561062
x = Property(getx, setx, delx, "I'm the 'x' property.")
1063+
no_getter = Property(None, setx, delx, "I'm the 'x' property.")
1064+
no_setter = Property(getx, None, delx, "I'm the 'x' property.")
1065+
no_deleter = Property(getx, setx, None, "I'm the 'x' property.")
1066+
no_doc = Property(getx, setx, delx, None)
1067+
10571068

10581069
# Now do it again but use the decorator style
10591070

@@ -1092,6 +1103,32 @@ here is a pure Python equivalent:
10921103
>>> hasattr(ccc, 'x')
10931104
False
10941105

1106+
>>> cc = CC()
1107+
>>> cc.x = 33
1108+
>>> try:
1109+
... cc.no_getter
1110+
... except AttributeError as e:
1111+
... e.args[0]
1112+
...
1113+
"property 'no_getter' of 'CC' object has no getter"
1114+
1115+
>>> try:
1116+
... cc.no_setter = 33
1117+
... except AttributeError as e:
1118+
... e.args[0]
1119+
...
1120+
"property 'no_setter' of 'CC' object has no setter"
1121+
1122+
>>> try:
1123+
... del cc.no_deleter
1124+
... except AttributeError as e:
1125+
... e.args[0]
1126+
...
1127+
"property 'no_deleter' of 'CC' object has no deleter"
1128+
1129+
>>> CC.no_doc.__doc__ is None
1130+
True
1131+
10951132
The :func:`property` builtin helps whenever a user interface has granted
10961133
attribute access and then subsequent changes require the intervention of a
10971134
method.

0 commit comments

Comments
 (0)