PEP 622 authors,

Overall, the PEP describes the proposal quite nicely. However, I do indeed have concerns and questions, some of which I describe in this email.

(1) Class pattern that does isinstance and nothing else.

If I understand the proposed semantics correctly, `Class()` is equivalent to checking `isinstance(obj, Class)`, also when `__match_args__` is not present. However, if a future match protocol is allowed to override this behavior to mean something else, for example `Class() == obj`, then the plain isinstance checks won't work anymore! I do find `Class() == obj` to be a more intuitive and consistent meaning for `Class()` than plain `isinstance` is. 

Instead, the plain isinstance check would seem to be well described by a pattern like `Class(...)`. This would allow isinstance checks for any class, and there is even a workaround if you really want to refer to the Ellipsis object. This is also related to the following point.

(2) The meaning of e.g. `Class(x=1, y=_)` versus `Class(x=1)`

In the proposed semantics, cases like this are equivalent. I can see why that is desirable in many cases, although Class(x=1, ...)` would make it more clear. A possible improvement might be to add an optional element to  `__match_args__` that separates optional arguments from required ones (although "optional" is not the same as "don't care"). 

(3) Check for exhaustiveness at runtime

The PEP states:

Check exhaustiveness at runtime
The question is what to do if no case clause has a matching pattern, and there is no default case. An earlier version of the proposal specified that the behavior in this case would be to throw an exception rather than silently falling through.
The arguments back and forth were many, but in the end the EIBTI (Explicit Is Better Than Implicit) argument won out: it's better to have the programmer explicitly throw an exception if that is the behavior they want.
For cases such as sealed classes and enums, where the patterns are all known to be members of a discrete set, static checkers can warn about missing patterns.

I don't understand this argument. Would it not be more explicit to have an `else` or `case _` branch to say what should happen in that case?

(4) Check for exhaustiveness by static checkers

About this, the PEP states:

From a reliability perspective, experience shows that missing a case when dealing with a set of possible data values leads to hard to debug issues, thus forcing people to add safety asserts like this:
def get_first(data: Union[int, list[int]]) -> int:
    if isinstance(data, list) and data:
        return data[0]
    elif isinstance(data, int):
        return data
    else:
        assert False, "should never get here"
PEP 484 specifies that static type checkers should support exhaustiveness in conditional checks with respect to enum values. PEP 586 later generalized this requirement to literal types.
This PEP further generalizes this requirement to arbitrary patterns.

This seems reasonable. However, why is the standard for static and runtime different? The corresponding runtime check is extremely easy and efficient to do, so if this is an error according to static analysis, why not make it an error at runtime too?

—Koos