pythonmypypython-typingpython-re

Specialize the regex type re.Pattern


Specializing the type of re.Pattern to re.Pattern[bytes], mypy correctly detects the type error:

import re
REGEX: re.Pattern[bytes] = re.compile(b"\xab.{2}")
def check(pattern: str) -> bool:
    if str == "xyz":
        return REGEX.fullmatch(pattern) is not None
    return True
print(check("abcd"))

Type mismatch detected:

$ mypy ~/main.py 
/home/oren/main.py:5: error: Argument 1 to "fullmatch" of "Pattern" has incompatible type "str"; expected "bytes"
Found 1 error in 1 file (checked 1 source file)

However, when I try to actually run the code I get a weird (?) message:

$ python ~/main.py
Traceback (most recent call last):
  File "/home/oren/main.py", line 2, in <module>
    REGEX: re.Pattern[bytes] = re.compile(b"\xab.{2}")
TypeError: 'type' object is not subscriptable

How come the type annotation bothers Python?


Solution

  • The ability to specialize the generic re.Pattern and re.Match types using [str] or [bytes] was added in Python 3.9. It seems you are using an older Python version.

    For Python versions earlier than 3.8 the typing module provides a typing.re namespace which contains replacement types for this purpose.

    Since Python 3.8, they are directly available in the typing module and the typing.re namespace is deprecated (will be removed in Python 3.12).

    Reference: https://docs.python.org/3/library/typing.html#typing.Pattern

    Summary: