On 2/13/22, Christopher Barker <python...@gmail.com> wrote: > > Telling newbies that that means that it's either a property with no setter, > or am object without a __dict__, or one with __slots__ defined is not > really very helpful.
The __slots__ case is due to the lack of a __dict__ slot. It can be manually added in __slots__ (though adding __dict__ back is uncommon), along with the __weakref__ slot. The exception message when there's no __dict__ is generally good enough. For example: >>> (1).x = None Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'int' object has no attribute 'x' It's clear that the object has no __dict__ and no descriptor named "x". However, the message gets confusing with partially implemented magic attributes. For example, implement __getattr__(), but not __setattr__() or __delattr__(): class C: __slots__ = () def __getattr__(self, name): class_name = self.__class__.__name__ if name == 'x': return 42 raise AttributeError(f'{class_name!r} object has no ' f'attribute {name!r}') >>> c = C() >>> c.x 42 >>> c.x = None Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'C' object has no attribute 'x' Add __setattr__(): def __setattr__(self, name, value): class_name = self.__class__.__name__ if name == 'x': raise AttributeError(f'attribute {name!r} of {class_name!r} ' 'objects is not writable') raise AttributeError(f'{class_name!r} object has no ' f'attribute {name!r}') >>> c = C() >>> c.x = None Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 12, in __setattr__ AttributeError: attribute 'x' of 'C' objects is not writable >>> del c.x Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'C' object has no attribute 'x' Add __delattr__(): def __delattr__(self, name): class_name = self.__class__.__name__ if name == 'x': raise AttributeError(f'attribute {name!r} of {class_name!r} ' 'objects is not writable') raise AttributeError(f'{class_name!r} object has no ' f'attribute {name!r}') >>> c = C() >>> c.x 42 >>> c.x = None Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 12, in __setattr__ AttributeError: attribute 'x' of 'C' objects is not writable >>> del c.x Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 19, in __delattr__ AttributeError: attribute 'x' of 'C' objects is not writable _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/3S2KW3O7O7KKBQD2FVW6NG3CISNHF745/ Code of Conduct: http://python.org/psf/codeofconduct/