New submission from Joshua Bronson <jabron...@gmail.com>: If I understand correctly, it should be an invariant that in the code below, for all "Parent" classes, for all "method"s, Child1.method should return the same result as Child2.method:
``` class Parent: def __init__(self, value): self._value = value def method(self): return self._value class Child1(Parent): pass c1 = Child1(42) result = c1.method() assert result == 42, result class Child2(Parent): def method(self): return super().method() c2 = Child2(42) result = c2.method() assert result == 42, result ``` But when "Parent" is "dict" and method is "__iter__", that is not the case: ``` SHOW_BUG = True class ChildDict1(dict): """Simplification of werkzeug.datastructures.MultiDict.""" def __init__(self): pass if not SHOW_BUG: def __iter__(self): return super().__iter__() def add(self, key, value): self.setdefault(key, []).append(value) def __setitem__(self, key, value): """Like add, but removes any existing key first.""" super().__setitem__(key, [value]) def getall(self, key) -> list: return super().__getitem__(key) def __getitem__(self, key): """Return the first value for this key.""" return self.getall(key)[0] def items(self, multi=False): for (key, values) in super().items(): if multi: yield from ((key, value) for value in values) else: yield key, values[0] def values(self): return (values[0] for values in super().values()) # Remaining overridden implementations of methods # inherited from dict are elided for brevity. cd1 = ChildDict1() assert dict(cd1) == {} cd1[1] = "one" cd1.add(1, "uno") assert cd1.getall(1) == ["one", "uno"] assert list(cd1.items()) == [(1, "one")] assert list(cd1.values()) == [ "one"] assert dict(cd1) == {1: "one"}, cd1 # XXX ``` If you run the above as-is, the line marked "XXX" will trigger an AssertionError demonstrating the unexpected behavior. If you change SHOW_BUG to False, it won’t. Is it intended that toggling the value of SHOW_BUG in this code causes different results? You can visit https://repl.it/@jab/dict-subclass-copy-surprise to run the examples above directly in your browser. ---------- messages: 387191 nosy: jab priority: normal severity: normal status: open title: Dict copy optimization violates subclass invariant type: behavior _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue43246> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com