bslatkin / effectivepython

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

Item 51: Possible logic mistake, needs clarification #119

Closed kfreezen closed 1 month ago

kfreezen commented 1 month ago

I find the text "This fails because TraceMeta does not inherit from OtherMeta. In theory, I can use metaclass inheritance to solve this problem by having OtherMeta inherit from TraceMeta:" confusing.

class TraceMeta(type):
    pass # Elided more code

class OtherMeta(TraceMeta):
    pass

class SimpleDict(dict, metaclass=OtherMeta):
    pass

class TraceDict(SimpleDict, metaclass=TraceMeta):
    pass

If OtherMeta and SimpleDict are a third-party library, why couldn't TraceMeta just subclass OtherMeta? Wouldn't that take care of your meta class issue? Or is there some blindingly obvious issue I am overlooking?

bslatkin commented 1 month ago

That could potentially work if OtherMeta can be extended without breaking all of the assumptions TraceMeta already has about class objects. Given the complexity of metaclasses, I expect that won't be the case. But additionally the next part of the book says "But this won’t work if ... I want to use multiple utility metaclasses like TraceMeta at the same time". So if you have many metaclasses from many libraries you can't modify, there's no way to compose them together. Does that make sense?