Guido van Rossum wrote: > On Wed, Mar 31, 2021 at 2:14 PM Brandt Bucher brandtbuc...@gmail.com > wrote: > > (One change from my last email: it doesn't allow `__match_map__` / > > `__match_seq__` to be set to `False`... only `True`. This prevents some > > otherwise tricky multiple-inheritance edge-cases present in both of our > > flagging systems that I discovered during testing. I don't think there are > > actual use-cases for unsetting the flags in subclasses, but we can revisit > > that later if needed.) > That's surprising to me. Just like we can have a class that inherits from > int but isn't hashable, and make that explicit by setting `__hash__ = > None`, why couldn't I have a class that inherits from something else that > happens to inherit from Sequence, and say "but I don't want it to match > like a sequence" by adding `__match_sequence__ = False`? AFAIK all Mark's > versions would support this by setting `__match_kind__ = 0`.
The issue isn't when *I* set `__match_seq__ = False` or `__match_container__ = 0`. It's when *one of my parents* does it that things become difficult. > Maybe you can show an example edge case where this would be undesirable? Good idea. I've probably been staring at this stuff for too long to figure it out myself. :) As far as I can tell, these surprising cases arise because a bit flag can only be either 0 or 1. For us, "not specified" is equivalent to 0, which can lead to ambiguity. Consider this case: ``` class Seq: __match_seq__ = True # or __match_container__ = MATCH_SEQUENCE class Parent: pass class Child(Parent, Seq): pass ``` Okay, cool. `Child` will match as a sequence, which seems correct. But what about this similar case? ``` class Seq: __match_seq__ = True # or __match_container__ = MATCH_SEQUENCE class Parent: __match_seq__ = False # or __match_container__ = 0 class Child(Parent, Seq): pass ``` Here, `Child` will *not* match as a sequence, even though it probably should. The only workarounds I've found (like allowing `None` to mean "this is unset, don't inherit me if another parent sets this flag", ditching tp_flags entirely, or not inheriting these attributes) feel a bit extreme just to allow some users to do the moral equivalent of un-subclassing `collections.abc.Sequence`. So, my current solution (seen on the branch linked in my earlier email) is: - Set the flag if the corresponding magic attribute is set to True in the class definition - Raise at class definition time if it's set to anything other than True - Otherwise, set the flag if any of the parents set have the flag set As far as I can tell, this leads to the expected (and current, as of 3.10.0a6) behavior in all cases. Plus, it doesn't break my mental model of how inheritance works. _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/R3BGDN6NINJMLUWBVMVYIGORSLPJOMJP/ Code of Conduct: http://python.org/psf/codeofconduct/