[Python-Dev] Arbitrary non-identifier string keys when using **kwargs

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