On Wed, Mar 31, 2021 at 12:08 PM Mark Shannon <m...@hotpy.org> wrote:

> Hi Guido,
>
> On 31/03/2021 6:21 pm, Guido van Rossum wrote:
> > On Wed, Mar 31, 2021 at 2:30 AM Mark Shannon <m...@hotpy.org
> > <mailto:m...@hotpy.org>> wrote:
>


> [Brandt Bucher, earlier]
> >      > - 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
> >      >      ...
> >      > ```
>


> [Mark, in response]
> >     I don't like the way this need special inheritance rules, where
> >     inheriting one attribute mutates the value of another.
> >     It seems convoluted.
> >
> >     Consider:
> >
> >     class WhatIsIt(MySeq, MyMap):
> >           pass
> >
> >     With __match_container__ it works as expected with no special
> >     inheritance rules.
>

[me, responding to Mark]

> > Wait a minute, do you expect WhatIsIt to be a sequence but not a map?
> > *I* would expect that it is both, and that's exactly what Brandt's
> > proposal does. So I see this as a plus.
>

[Now back to Mark]

> Earlier you said:
>
>      Classes that are both mappings and sequences are ill-conceived.
>      Let's not compromise semantics or optimizability to support these.
>     (IOW I agree with Mark here.)
>

Ah, you caught me there. I do think that classes that combine both
characteristics are in troublesome water. I think we can get optimizability
either way, so I'll focus on semantics.

Brandt has demonstrated that it's ugly to write the code for a class that
in match statements behaves as either a sequence or a mapping (but not
both) while at the same time keeping the code compatible with Python 3.9 or
before. I also think that using flag attributes that are set to True or
False (instead of using a bitmap of flags, which is obscure to many Python
users) solves this problem nicely.

Using separate flag attributes happens to lead to different semantics than
the flags-bitmap approach in the case of multiple inheritance. Given that
one *can* inherit from both Sequence and Mapping, having separate flags
seems slightly better than the flags-bitmap approach. It wasn't enough to
convince me earlier, but the other advantage does convince me: separate
flag attributes are better than using a flags-bitmap.

Now, if it weren't for other issues, having no flags at all here but just
signalling the applicable pattern kinds through inheritance from
collections.abc.{Sequence,Mapping} would be even cleaner. But we do have
other issues: (a) the exceptions for str, bytes, bytearray, and (b) the
clumsiness of importing collections.abc (which is Python code) deep in the
ceval main loop. So some explicit form of signalling this is fine -- and
for classes that explicitly inherit from Sequence or Mapping will get it
for free that way.

>
> PEP 653 requires that:
> (__match_container__ & (MATCH_SEQUENCE | MATCH_MAPPING)) !=
> (MATCH_SEQUENCE | MATCH_MAPPING)
>
> Would you require that (__match_seq__ and __match_map__) is always false?
>

Nope.

If so, then what is the mechanism for handling the `WhatIsIt` class?
> If not, then you loose the ability to make a single test to determine
> which patterns can apply.
>

Translating the flag attributes to bits in tp_flags (or in a new flags
variable elsewhere in the type object) would still allow a pretty fast
test. And needing to support overlapping subsets of the cases is not unique
to this situation, after all a class may well be a sequence *and* have
attributes named x, y and z.


> >     I think we are close to agreement on the mechanism for selecting
> which
> >     pattern to match, but I still want the better defined semantics of
> >     PEP 653.
> >
> >
> > I don't know that PEP 653's semantics are better. Have you analyzed any
> > *differences* besides the proposal above? I've personally found reading
> > your pseudo-code very difficult, so I simply don't know.
>
> PEP 653 semantics are more precise. I think that is better :)
>

I wish I knew of a single instance where PEP 634 and PEP 653 actually
differ.


> Apart from that, I think the semantics are so similar once you've added
> __match_seq__/__match_map__  to PEP 634 that is hard to
> claim one is better than the other.
> My (unfinished) implementation of PEP 653 makes almost no changes to the
> test suite.
>

I'd like to see where those differences are -- then we can talk about which
is better. :-)


> The code in the examples is Python, not pseudo-code.
> That might be easier to follow.
>

-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*
<http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________
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/VBTHLNRUQUXVK73Q22R3ZP7VJGUVXKWG/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to