Bug? Feature? setattr(foo, '3', 4) works!

Ned Batchelder ned at nedbatchelder.com
Fri Dec 19 07:24:50 EST 2014


On 12/19/14 6:40 AM, Cem Karan wrote:
> I'm bringing this discussion over from the python-ideas mailing list to see what people think. I accidentally discovered that the following works, at least in Python 3.4.2:
>
>>>> class foo(object):
> ...     pass
> ...
>>>> setattr(foo, '3', 4)
>>>> dir(foo)
> ['3', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
>>>> getattr(foo, '3')
> 4
>>>> bar = foo()
>>>> dir(bar)
> ['3', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
>>>> getattr(bar, '3')
> 4
>>>> hasattr(foo, '3')
> True
>>>> hasattr(bar, '3')
> True
>
> However, the following doesn't work:
>
>>>> foo.3
>   File "<stdin>", line 1
>     foo.3
>         ^
> SyntaxError: invalid syntax
>>>> bar.3
>   File "<stdin>", line 1
>     bar.3
>         ^
> SyntaxError: invalid syntax
>
> I'd like to suggest that getattr(), setattr(), and hasattr() all be modified so that syntactically invalid statements raise SyntaxErrors. In messages on python-ideas, Nick Coghlan mentioned that since a Namespace is just a dictionary, the normal error raised would be TypeError and not SyntaxError; I'd like to suggest special-casing this so that using getattr(), setattr(), and hasattr() in this way raise SyntaxError instead as I think that will be less astonishing.
>
> Thoughts?
>
> Thanks,
> Cem Karan
>

Can you explain why you think it is important that setattr(obj, '3', 3) 
raise an error at all?  Yes, it surprised you, but there are many 
aspects of Python that are surprising. That's not a bad thing in and of 
itself.

Did this cause a real problem in your code?  Is there a way that 
allowing non-identifier attribute names will be harmful?

-- 
Ned Batchelder, http://nedbatchelder.com




More information about the Python-list mailing list