Since we are talking about namedtuple and implementation, I just noticed: In [22]: Point = namedtuple('Point', ['x', 'y']) In [23]: p = Point(2,3) In [24]: p.x = 5 --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-24-328d3fab3e30> in <module>() ----> 1 p.x = 5 AttributeError: can't set attribute OK -- that makes sense. but then, if you try: In [25]: p.z = 5 --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-25-625ed954d865> in <module>() ----> 1 p.z = 5 AttributeError: 'Point' object has no attribute 'z' I think this should be a different message -- key here is that you can't set a new attribute, not that one doesn't exist. Maybe: "AttributeError: can't set new attribute" -CHB -- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov
This error message is the same for types with __slots__, and probably it is indeed a bit too terse. -- Ivan On 27 July 2017 at 18:26, Chris Barker <chris.barker@noaa.gov> wrote:
Since we are talking about namedtuple and implementation, I just noticed:
In [22]: Point = namedtuple('Point', ['x', 'y']) In [23]: p = Point(2,3)
In [24]: p.x = 5 ------------------------------------------------------------ --------------- AttributeError Traceback (most recent call last) <ipython-input-24-328d3fab3e30> in <module>() ----> 1 p.x = 5 AttributeError: can't set attribute
OK -- that makes sense. but then, if you try:
In [25]: p.z = 5 ------------------------------------------------------------ --------------- AttributeError Traceback (most recent call last) <ipython-input-25-625ed954d865> in <module>() ----> 1 p.z = 5 AttributeError: 'Point' object has no attribute 'z'
I think this should be a different message -- key here is that you can't set a new attribute, not that one doesn't exist. Maybe:
"AttributeError: can't set new attribute"
-CHB
--
Christopher Barker, Ph.D. Oceanographer
Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception
Chris.Barker@noaa.gov
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
I've never liked that error message either: >>> object().foo = 'bar' Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'object' object has no attribute 'foo' Should say the "object is immutable," not writable, or something of the sort. On 2017-07-27 09:26, Chris Barker wrote:
Since we are talking about namedtuple and implementation, I just noticed:
On Fri, Jul 28, 2017 at 10:09 AM, Mike Miller <python-ideas@mgmiller.net> wrote:
I've never liked that error message either:
>>> object().foo = 'bar' Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'object' object has no attribute 'foo'
Should say the "object is immutable," not writable, or something of the sort.
As Ivan said, this is to do with __slots__. It's nothing to do with immutability:
class Demo: ... __slots__ = 'spam' ... x = Demo() x.spam = 1 x.ham = 2 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Demo' object has no attribute 'ham'
If the object has a __dict__, any unknown attributes go into there:
class Demo2(Demo): pass ... y = Demo2() y.ham = 2 y.spam = 3 y.__dict__ {'ham': 2}
which prevents that "has no attribute" error. ChrisA
On 2017-07-27 18:02, Chris Angelico wrote:
As Ivan said, this is to do with __slots__. It's nothing to do with immutability:
object().__slots__ Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'object' object has no attribute '__slots__'
object().__dict__ Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'object' object has no attribute '__dict__'
If an object has no slots or dict and does not accept attribute assignment, is it not effectively immutable? -Mike
If an object has no slots or dict and does not accept attribute assignment, is it not effectively immutable?
No, not necessarily. class A(list): __slots__ = () 2017-07-28 10:00 GMT+02:00 Mike Miller <python-ideas@mgmiller.net>:
On 2017-07-27 18:02, Chris Angelico wrote:
As Ivan said, this is to do with __slots__. It's nothing to do with immutability:
object().__slots__ Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'object' object has no attribute '__slots__'
object().__dict__ Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'object' object has no attribute '__dict__'
If an object has no slots or dict and does not accept attribute assignment, is it not effectively immutable?
-Mike
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
-- Antoine Rozo
That's a subclass. Also:
class A(list): __slots__ = () ...
a = A() a.foo = 'bar' Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'A' object has no attribute 'foo'
-Mike On 2017-07-28 01:06, Antoine Rozo wrote:
If an object has no slots or dict and does not accept attribute assignment, is it not effectively immutable?
No, not necessarily.
class A(list): __slots__ = ()
Yes, but A objects have no slots, no dict, do not accept attribute assignment, but are mutable.
a = A() a [] a.__slots__ () a.__dict__ Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'A' object has no attribute '__dict__' a.append(1) a.append(2) a [1, 2]
2017-07-28 20:23 GMT+02:00 Mike Miller <python-ideas@mgmiller.net>:
That's a subclass. Also:
class A(list): __slots__ = () ...
a = A() a.foo = 'bar' Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'A' object has no attribute 'foo'
-Mike
On 2017-07-28 01:06, Antoine Rozo wrote:
If an object has no slots or dict and does not accept attribute assignment, is it not effectively immutable?
No, not necessarily.
class A(list): __slots__ = ()
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
-- Antoine Rozo
Nice. Ok, so there are different dimensions of mutability. Still, haven't found any "backdoors" to object(), the one I claimed was immutable. -Mike
On 29 July 2017 at 04:56, Mike Miller <python-ideas@mgmiller.net> wrote:
Nice. Ok, so there are different dimensions of mutability.
Still, haven't found any "backdoors" to object(), the one I claimed was immutable.
It's possible to write builtin types that are truly immutable, and there are several examples of that (direct instances of object, tuple instances, instances of the builtin numeric types), but it isn't particularly straightforward to make Python defined classes truly immutable. While this gets close for stateless instances (akin to instantiating object() directly): >>> class MostlyImmutable: ... __slots__ = () ... @property ... def __class__(self): ... return type(self) ... It's far more difficult to actually store any meaningful state without making it open to mutation in some way (since it needs to settable from __new__, and Python doesn't provide any inherent mechanism from distinguishing those cases from post-creation modifications). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
On Sat, Jul 29, 2017 at 6:49 AM, Nick Coghlan <ncoghlan@gmail.com> wrote:
It's possible to write builtin types that are truly immutable, and there are several examples of that (direct instances of object, tuple instances, instances of the builtin numeric types),
Maybe this is an argument for namedtuple to be a "proper" builtin. Though, as the names have to be defined at run time, I suppose that isn't possible. -CHB -- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov
On Thu, Jul 27, 2017 at 05:09:56PM -0700, Mike Miller wrote:
I've never liked that error message either:
>>> object().foo = 'bar' Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'object' object has no attribute 'foo'
Should say the "object is immutable," not writable, or something of the sort.
Then put in a feature request on the bug tracker. It shouldn't require a week's discussion on Python-Ideas to improve an error message. -- Steve
participants (7)
-
Antoine Rozo -
Chris Angelico -
Chris Barker -
Ivan Levkivskyi -
Mike Miller -
Nick Coghlan -
Steven D'Aprano