>> - Add new `__match_seq__` and `__match_map__` special attributes, 
>> corresponding to new public `Py_TPFLAGS_MATCH_SEQ` and 
>> `Py_TPFLAGS_MATCH_MAP` flags for use in `tp_flags`. When Python classes are 
>> defined with one or both of these attributes set to a boolean value, 
>> `type.__new__` will update the flags on the type to reflect the change 
>> (using a similar mechanism as `__slots__` definitions). They will be 
>> inherited otherwise. For convenience, `collections.abc.Sequence` will define 
>> `__match_seq__ = True`, and `collections.abc.Mapping` will define 
>> `__match_map__ = True`.
>> 
>> Using this in Python would look like:
>> 
>> ```
>> class MySeq:
>>      __match_seq__ = True
>>      ...
>> 
>> class MyMap:
>>      __match_map__ = True
>>      ...
>> ```
> 
> I don't like the way this need special inheritance rules, where inheriting 
> one attribute mutates the value of another. It seems convoluted.

Let me clarify: these two attributes do not interact with one another; each 
attribute only interacts with its own flag on the type. It is perfectly 
possible to do:

```
class WhatIsIt:
    __match_map__ = True
    __match_seq__ = True
```

This will set both flags, and this `WhatIsIt` will match as a mapping *and* a 
sequence. This is allowed and works in PEP 634, but like Guido I'm not entirely 
opposed to making the matching behavior of such a class undefined against 
sequence or mapping patterns. 

> Consider:
> 
> class WhatIsIt(MySeq, MyMap):
     pass
> 
> With __match_container__ it works as expected with no special inheritance 
> rules.

What *is* the expected behavior of this? Based on the current behavior of PEP 
634, I would expect the `__match_container__` of each base to be or'ed, and 
something like this to match as both a mapping and a sequence (which PEP 653 
says leads to undefined behavior). The actual behavior seems more like it will 
just be a sequence and not a mapping, since `__match_container__` would be 
inherited from `MySeq` and `MyMap` would be ignored.

In the interest of precision, here is an implementation of *exactly* what I am 
thinking:

`typeobject.c`: 
https://github.com/python/cpython/compare/master...brandtbucher:patma-flags#diff-1decebeef15f4e0b0ce106c665751ec55068d4d1d1825847925ad4f528b5b872

`ceval.c`: 
https://github.com/python/cpython/compare/master...brandtbucher:patma-flags#diff-c22186367cbe20233e843261998dc027ae5f1f8c0d2e778abfa454ae74cc59de

(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.)
_______________________________________________
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/S4KLVTEA4HYDCAER25DZMOUB6LN6K63P/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to