In chapter 22 you mention that FrozenJSON.__getattr__() raising a KeyError is "not to confusing". However, today I discovered a side effect from this that is confusing: copy.copy(FrozenJSON({'name': 'Jim Bo', 'class': 1982})) raises a RecursionError.
Indeed the documentation states that an AttributeError should be raised (https://docs.python.org/3/reference/datamodel.html#object.__getattr__) and apparently this is relied upon in the stdlib. In the copy implementation a new instance of FrozenJSON is generated without the initializer being called. Then, when looking for some optional dunder methods (that are not found) the copy implementation triggers a __getattr__ call with self.__data not yet existing, triggering the recursion.
What I appreciate in your book is that you are always very precise about all types of unexpected side effects, so maybe you could consider spending some text on this in a future update.
Hi Luciano,
In chapter 22 you mention that
FrozenJSON.__getattr__()
raising aKeyError
is "not to confusing". However, today I discovered a side effect from this that is confusing:copy.copy(FrozenJSON({'name': 'Jim Bo', 'class': 1982}))
raises aRecursionError
.Indeed the documentation states that an
AttributeError
should be raised (https://docs.python.org/3/reference/datamodel.html#object.__getattr__) and apparently this is relied upon in the stdlib. In the copy implementation a new instance ofFrozenJSON
is generated without the initializer being called. Then, when looking for some optional dunder methods (that are not found) the copy implementation triggers a__getattr__
call withself.__data
not yet existing, triggering the recursion.What I appreciate in your book is that you are always very precise about all types of unexpected side effects, so maybe you could consider spending some text on this in a future update.
Best regards, Michiel