@@ -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+
10951132The :func: `property ` builtin helps whenever a user interface has granted
10961133attribute access and then subsequent changes require the intervention of a
10971134method.
0 commit comments