bslatkin / effectivepython

Effective Python: Second Edition — Source Code and Errata for the Book
https://effectivepython.com
2.24k stars 718 forks source link

Item #48: Example of __init_subclass__ inheriting from 2 classes. #67

Open almazkun opened 4 years ago

almazkun commented 4 years ago

Good day! Thank you you for your book. It is incredibly interesting and well written book.

There is a little confusion toward the end of the item 48. Where you describe how two validations classes with super().__init_subclass__ can be inherited by one class.

Yon stated in the paragraph that it will be inherited from BetterPolygon class defined earlier, but in the code example Polygon class is used, witch is an example of metaclass usage.

Here is the exact part from the book:

It’s even compatible with multiple inheritance. Here, I define a class to represent region fill color that can be composed with the BetterPolygon class from before:

class Filled:
    color = None # Must be specified by subclass
    def __init_subclass__(cls):
        super().__init_subclass__()
        if cls.color not in ("red", "green", "blue"):
                raise ValueError("Fills need a valid color")

I can inherit from both classes to define a new class. Both classes call super().__init_subclass__(), causing their corresponding validation logic to run when the subclass is created:

class RedTriangle(Filled, Polygon): # It seems like you meant to use `BetterPolygon`
    color = 'red'
    sides = 3

ruddy = RedTriangle()
assert isinstance(ruddy, Filled)
assert isinstance(ruddy, Polygon) # It seems like you meant to use `BetterPolygon`

Thank you!

bslatkin commented 4 years ago

Thanks for the report! You're right. This should be BetterPolygon in all of the references to Polygon that follow the Filled class definition. The resulting behavior and output doesn't change with that fix, since the Polygon metaclass implemented the same behavior. But this is an important detail.

bslatkin commented 4 months ago

Keeping this open for tracking purposes.