I was just working on some docs for Boost.Python and thought I'd write down what happens when you try to write to a read-only property (I use properties to expose C++ data members among other things). So: >>> class X(object): ... def get(self): return 'x' ... l = property(get) ... >>> x = X() >>> x.l 'x' >>> x.l = 1 Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: can't set attribute This struck me as a very poor error message, given that mechanism in Boost.Python v1 used to say: Traceback (innermost last): File "<string>", line 1, in ? AttributeError: 'l' attribute is read-only Is it worth doing something about this? -- David Abrahams * Boost Consulting dave@boost-consulting.com * http://www.boost-consulting.com
On Tue, Oct 08, 2002 at 11:37:46AM -0400, David Abrahams wrote: [...]
AttributeError: can't set attribute
This struck me as a very poor error message, given that mechanism in Boost.Python v1 used to say:
[...]
AttributeError: 'l' attribute is read-only
Is it worth doing something about this?
The following comes close, in Python, but requires a setter object for each attribute: class SetROProperty: def __init__(self, name): self.name = name def __call__(self, obj, val): raise AttributeError, "%r attribute is read-only" % self.name class X(object): def get(self): return 'x' l = property(get, SetROProperty('l')) >>> x = X() >>> x.l 'x' >>> x.l = 1 Traceback (most recent call last): File "<stdin>", line 1, in ? File "srop.py", line 5, in __call__ raise AttributeError, "%r attribute is read-only" % self.name AttributeError: 'l' attribute is read-only The key seems to be that property() doesn't know the name the property has. Jeff
The key seems to be that property() doesn't know the name the property has.
Oops, you're right. This makes it practically impossible to improve the error message (without the kind of trick that Jeff shows). --Guido van Rossum (home page: http://www.python.org/~guido/)
Guido van Rossum wrote:
The key seems to be that property() doesn't know the name the property has.
Oops, you're right. This makes it practically impossible to improve the error message (without the kind of trick that Jeff shows).
--Guido van Rossum (home page: http://www.python.org/~guido/)
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev
Why not have the property find its name in the class's __dict__, something like this: (in class property) def __set__(self, obj, value): if self.fset is not None: self.fset(obj, value) else: for key, value in type(obj).__dict__.iteritems(): if value is self: raise AttributeError, "Property '" + key + "' is read-only." # No name? Strange put possible I guess. raise AttributeError, "can't set property"
Why not have the property find its name in the class's __dict__, something like this:
(in class property) def __set__(self, obj, value): if self.fset is not None: self.fset(obj, value) else: for key, value in type(obj).__dict__.iteritems(): if value is self: raise AttributeError, "Property '" + key + "' is read-only." # No name? Strange put possible I guess. raise AttributeError, "can't set property"
You'd have to search base classes too, in MRO order. Doable, but makes AttributeError very expensive. (This can be a concern if it is in fact being caught.) It could also be misleading -- the same property object may occur more than once, and you don't know which one was being set. I think it's best to rely on the traceback. If the traceback looks like Traceback (most recent call last): File "foo.py", line 42, in bar self.foo = 42 AttributeError: can't set attribute the problem should be clear enough. --Guido van Rossum (home page: http://www.python.org/~guido/)
participants (4)
-
David Abrahams
-
Guido van Rossum
-
Jeff Epler
-
John Williams