Litmus test: Give someone who does not know Python this code example from the PEP and ask them what it does and why it does what it does:

match get_shape():
    case Line(start := Point(x, y), end) if start == end:
        print(f"Zero length line at {x}, {y}")
I expect confusion to be the result.  If they don't blindly assume the variables come from somewhere not shown to stop their anguish. 

With Python experience, my own reading is:
 * I see start actually being assigned.
 * I see nothing giving values to end, x, or y.
 * Line and Point are things being called, probably class constructions due to being Capitalized.
 * But where did the parameter values come from and why and how can end be referred to in a conditional when it doesn't exist yet?
   They appear to be magic!

Did get_shape() return these? (i think not).  Something magic and implicit rather than explicit happens in later lines.  The opposite of what Python is known for.

Where's the pseudo-code describing exactly what the above looks like logically speaking? (there's a TODO in the PEP for the __match__ protocol code so I assume it will come, thanks!).  I can guess _only_ after reading a bunch of these discussions and bits of the PEP.  Is it this?  I can't tell.

shape = get_shape()
values_or_none = Line.__match__(shape)
if values_or_none:
  start, end = values_or_none
  if start == end:
    if x, y := Point.__match__(shape):
      print(...)
      del x, y
  else:
    print(...)
  del start, end
else:
  # ... onto the next case: ?

Someone unfamiliar with Python wouldn't even have a chance of seeing that.  I had to rewrite the above many times, I'm probably still wrong.

That sample is very confusing code.  It makes me lean -1 on the PEP overall today.

This syntax does not lead to readable logically understandable code.  I wouldn't encourage anyone to write code that way because it is not understandable to others.  We must never assume others are experts in the language they are working on code in if we want it to be maintainable.  I wouldn't approve a code review containing that example.

It would help in part if ()s were not used to invoke the __match__ protocol.  I think a couple others also mentioned this earlier.  Don't make it look like a call.  Use different tokens than ().  Point{x, y} for example.  Or some way to use another token unused in that context in our toolbook such as @ to signify "get a matcher for this class" instead of "construct this class".  for example ClassName@() as our match protocol indicator, shown here with explicit assignments for clarity:

match get_shape() as shape:
  case start, end := Line@(shape):

no implicit assignments, it is clear where everything comes from.  it is clear it isn't a constructor call.

downside?  possibly a painful bug when someone forgets to type the @.  but the point of it not being construction needs to be made.  not using ()s but instead using ClassName@{} or just ClassName{} would prevent that.

The more nested things get with sub-patterns, the worse the confusion becomes.  The nesting sounds powerful but is frankly something I'd want to forbid anyone from using when the assignment consequences are implicit.  So why implement sub-patterns at all?  All I see right now is pain.

-gps