fluentpython / example-code-2e

Example code for Fluent Python, 2nd edition (O'Reilly 2022)
https://amzn.to/3J48u2J
MIT License
3.26k stars 919 forks source link

Side effect of FrozenJSON.__getattr__ not raising KeyError #46

Open hayemj opened 3 months ago

hayemj commented 3 months ago

Hi Luciano,

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.

Best regards, Michiel