This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: match case does not support regex
Type: enhancement Stage:
Components: Interpreter Core, Regular Expressions Versions: Python 3.11
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: AliRn, eric.smith, ezio.melotti, mrabarnett, xtreak
Priority: normal Keywords:

Created on 2022-02-09 12:23 by AliRn, last changed 2022-04-11 14:59 by admin.

Messages (5)
msg412904 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2022-02-09 14:03
You need to provide more information.

Is your concern that re.match objects aren't matched like dicts are, despite looking like a mapping?

import re

def f(map):
    print(f'input={m["one"]} {m["two"]}')
    match map:
        case {'one': x, 'two': y}:
            print(f"match {x} {y}")
        case _:
            print("no match")

m = re.match("(?P<one>a)b(?P<two>c)", "abc")
d = {'one':0, 'two':1}
f(d)
f(m)

produces:
input=a c
match 0 1
input=a c
no match

I assume you're not reporting a bug, so I'm going to mark this as a feature request.
msg412905 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2022-02-09 14:13
Oops, slight bug in my code. Use this:

import re

def f(map):
    print(f'input={map["one"]} {map["two"]}')
    match map:
        case {'one': x, 'two': y}:
            print(f"match {x} {y}")
        case _:
            print("no match")

d = {'one':0, 'two':1}
f(d)
m = re.match("(?P<one>a)b(?P<two>c)", "abc")
f(m)

With this output:
input=0 1
match 0 1
input=a c
no match
msg412914 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2022-02-09 15:32
Looking at PEP 634, the obvious way to add support for this is to have the re.Match object specify Py_TPFLAGS_MAPPING. But I tried that, and then I get this error when using an re.Match object in a match statement:

    case {'one': x, 'two': y}:
         ^^^^^^^^^^^^^^^^^^^^
TypeError: object of type 're.Match' has no len()


Add len() to re.Match objects was rejected when __getitem__ was added to re.Match, in issue 24454.

I haven't explored other ways to support re.Match objects in the match statement.
msg412921 - (view) Author: Karthikeyan Singaravelan (xtreak) * (Python committer) Date: 2022-02-09 17:02
> There were ideas for exotic matchers such as IsInstance(), InRange(), RegexMatchingGroup() and so on.

https://www.python.org/dev/peps/pep-0622/#custom-matching-protocol

The PEP has some mention about a similar use case in custom match protocol section.
msg412924 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2022-02-09 17:12
Good catch, @xtreak. I think something like the discussed (but not implemented) custom matching protocol would be required here. __match_args__ won't work, because it's a special attribute only checked on classes, not instances.

Of course, I'm still not sure this is what the original poster is requesting!

But assuming so, this would require a PEP, and should be discussed with the PEP 634 authors.
History
Date User Action Args
2022-04-11 14:59:56adminsetgithub: 90850
2022-02-09 17:12:50eric.smithsetmessages: + msg412924
2022-02-09 17:02:29xtreaksetnosy: + xtreak
messages: + msg412921
2022-02-09 15:32:46eric.smithsetmessages: + msg412914
2022-02-09 14:13:51eric.smithsetmessages: + msg412905
2022-02-09 14:03:43eric.smithsetcomponents: + Interpreter Core
2022-02-09 14:03:31eric.smithsetversions: - Python 3.10
nosy: + eric.smith

messages: + msg412904

type: behavior -> enhancement
2022-02-09 12:23:52AliRncreate