summaryrefslogtreecommitdiffstats
path: root/Doc/howto
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2023-11-25 22:24:43 (GMT)
committerGitHub <noreply@github.com>2023-11-25 22:24:43 (GMT)
commit2199cebd0ff1f252ed8a817824d8901f4c68a001 (patch)
tree7d0ed1c748b483a339c6a30a4abdb6ab7884560f /Doc/howto
parent8b3c66bb90397499061b9d72ee09a127522c2be1 (diff)
downloadcpython-2199cebd0ff1f252ed8a817824d8901f4c68a001.zip
cpython-2199cebd0ff1f252ed8a817824d8901f4c68a001.tar.gz
cpython-2199cebd0ff1f252ed8a817824d8901f4c68a001.tar.bz2
[3.12] Descriptor HowTo: Sync the error-messages with the C code. Add tests. (gh-112403) (gh-112411)
Diffstat (limited to 'Doc/howto')
-rw-r--r--Doc/howto/descriptor.rst43
1 files changed, 40 insertions, 3 deletions
diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst
index ec7d99b..e5964ba 100644
--- a/Doc/howto/descriptor.rst
+++ b/Doc/howto/descriptor.rst
@@ -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.