Mandatory patterns for easier destructuring

I’ve been wanting to use the destructuring syntax of match statements a lot. For instance, say I know that obj should be a Widget whose x attribute is a mapping, and I want to capture the value of obj.x["item"]; but if any of those assumptions doesn’t hold, I want an exception. I have been writing code like this:

match obj:
    case Widget(x={'item': my_value}):
    case _:
        raise ValueError("Something wrong's not right")

# ... use my_value

I think this is a lot of boilerplate. Is there a clearer/more idiomatic way of achieving the same thing?

I was thinking, what if there was syntax for that? Maybe something like:

match obj with Widget(x={'item': my_value})
# ... use my_value

That first line could be called a “simple match statement” (since it’s not the same thing as the existing compound match statement), and it would raise an AssertionError (or something else more appropriate) if the pattern doesn’t match.

Does anybody have opinions on that? It would be so useful in unit tests.

There’ve been other proposals for a “single match” action, including (if I’m recalling correctly) something like this:

Widget(x={'item': my_value}) = match obj

(For the record, I think ValueError or TypeError would be appropriate if it doesn’t match, rather than AssertionError.)

There’s been some mild interest but no syntax overwhelmingly appeals to people. You can probably search this forum for a few other proposals and pick and choose syntax elements to come up with something good.

1 Like

Yeah, I don’t like TypeError here (since correct types could still fail pattern matches), but ValueError makes sense.

By the way, I like that the assingment syntax you mentioned places the pattern correctly on the left hand side of the equals sign; however, there might be zero assigned variables in the pattern:

Widget() = match obj  # same as assert isinstance(obj, Widget)

which would make the assignment syntax very awkward.

I can’t think of any downsides to match EXPR with PATTERN.