[Python-Dev] Arbitrary non-identifier string keys when using **kwargs (original) (raw)

Stephen J. Turnbull turnbull.stephen.fw at u.tsukuba.ac.jp
Sun Oct 7 22:22:32 EDT 2018


Terry Reedy writes:

When this behavior of set/getattr was discussed a decade or so ago, Guido said not to disable it, but I believe he said it should not be considered a language feature. There are other situations where CPython is 'looser' than the spec.

I'm pretty sure that all of these mappings that create namespaces are not specified to be dicts. globals() and locals() need to return something, and dict is the only builtin mapping. On the other hand, it is explicit that changes to these dicts need not be reflected in the namespace.

Note that the namespace defined by a class is not a dict, it's a union (it may be a dict, or it may be slots):

>>> class Foo:
...  __slots__ = ('a')
...  def __init__(self, x):
...   self.a = x
...   self.b = (x,)
... 
>>> fu = Foo(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in __init__
AttributeError: 'Foo' object has no attribute 'c'
>>> class Foo:
...  __slots__ = ('a')
...  def __init__(self, x):
...   self.a = x
... 
>>> fu = Foo(1)
>>> print(fu.a)
1
>>> print(fu.__dict__)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute '__dict__'

This is a useful optimization if there are a lot of Foo objects, and is somewhat faster. As I understand it, while nobody has yet found a reason to optimize other namespaces in such a way (or extend them in some way, for that matter), the option is intentionally open.

Steve



More information about the Python-Dev mailing list