Dan Snider <mr.assume.a...@gmail.com> added the comment:
It's working as intended. locals() and vars() simply returns the current frame's f_locals. In functions, modifying this usually accomplishes nothing useful because the code object has OPTIMIZED and NEWLOCALS flags set, meaning local variables are looked up or set via the LOAD_FAST and STORE_FAST opcodes (respectively) which doesn't even look in the f_locals mapping. In this case, vars() and locals() will build a new dict[*] and fill it with the frame's fastlocals and unpack any closure cells into it. The code object used for class bodies however is special and actually *does* use the mapping in f_locals, which for for classes ultimately built by builtins.__build_class__ (aka classes built with a `class` statement) will be whatever the metaclass's __prepare__ returns, which in the case of enums is an enum._EnumDict instance. So that's why metaclasses are so powerful. You don't even need to use a dictionary subclass as the class namespace, since the STORE_NAME opcode will use PyObject_SetItem; however type.__new__ will make you cast it to a dict, and even the dict that is wrapped by a MappingProxy after the class has been created will be a copy anyway. So anyway, there's nothing actually wrong with the current behavior. dict.update never calls `self.__getitem__`, and since `_EnumDict.__setitem__` is where all of the magic happens regular dict.update won't trigger it. I agree though that adding an update method would be nice though and can be done in just a few lines of code. import enum import sys def local_update(it=(), **kws): self = sys._getframe(1).f_locals d = dict(it, **kws) for k, v in d.items(): self[k] = v class MyEnum(enum.Enum): local_update(a=1, b=2) assert MyEnum.a.value == 1 [*] it doesn't actually build a new one every time but the only practical purpose with the NEWLOCALS code.co_code flag set is for introspection with vars(), locals(), and sys._getframe ---------- nosy: +bup _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue34750> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com