diff --git a/pyproject.toml b/pyproject.toml index 9b0bf87eff..cc006f60ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -269,6 +269,7 @@ dev = [ "boto3-stubs[s3,ses,sns,sqs]", "django-stubs", + "google-re2-stubs", "lxml-stubs", "SQLAlchemy[mypy]", "types-beautifulsoup4", @@ -408,7 +409,6 @@ module = [ "pyoembed.*", "pyuca.*", "pyvips.*", - "re2.*", "scim2_filter_parser.attr_paths", "social_django.*", "talon_core.*", diff --git a/uv.lock b/uv.lock index 24cd588570..8a35cbe1b3 100644 --- a/uv.lock +++ b/uv.lock @@ -1413,6 +1413,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ce/11/fd759e766f824ef55e743d9e6096a38500c9c3b40e614667ad259e11026f/google_re2-1.1.20240702-1-cp312-cp312-win_amd64.whl", hash = "sha256:a7e3129d31e12d51397d603adf45bd696135a5d9d61bc33643bc5d2e4366070b", size = 497133, upload-time = "2024-07-01T14:08:35.3Z" }, ] +[[package]] +name = "google-re2-stubs" +version = "0.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "google-re2" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e5/a4/d8d16007eb6a6eb137ec3b6344a67199837e14a73709efeaa7285d2660eb/google_re2_stubs-0.1.1.tar.gz", hash = "sha256:f5ebef2f4188957bf980a5ad88ab266589638e5090329e6a0fde99f6bb684657", size = 4009, upload-time = "2024-10-21T15:22:43.861Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/86/2134e8ff65a22e30883bfc38ac34c5c76fd88cc9cef02ff3561f05db2b68/google_re2_stubs-0.1.1-py3-none-any.whl", hash = "sha256:a82eb6c3accd20879d711cd38151583d8a154fcca755f43a5595143a484c8118", size = 3676, upload-time = "2024-10-21T15:22:43.08Z" }, +] + [[package]] name = "google-resumable-media" version = "2.7.2" @@ -5307,6 +5319,7 @@ dev = [ { name = "firebase-admin" }, { name = "gitlint-core" }, { name = "google-re2" }, + { name = "google-re2-stubs" }, { name = "greenlet" }, { name = "html2text" }, { name = "ipython" }, @@ -5529,6 +5542,7 @@ dev = [ { name = "firebase-admin" }, { name = "gitlint-core" }, { name = "google-re2" }, + { name = "google-re2-stubs" }, { name = "greenlet" }, { name = "html2text" }, { name = "ipython" }, diff --git a/version.py b/version.py index 47b960af58..8fb5574176 100644 --- a/version.py +++ b/version.py @@ -49,4 +49,4 @@ API_FEATURE_LEVEL = 405 # historical commits sharing the same major version, in which case a # minor version bump suffices. -PROVISION_VERSION = (333, 6) # bumped 2025-06-30 to add pynacl +PROVISION_VERSION = (333, 7) # bumped 2025-07-14 to add google-re2-stubs diff --git a/zerver/lib/markdown/__init__.py b/zerver/lib/markdown/__init__.py index c39975bf56..c6e119ec66 100644 --- a/zerver/lib/markdown/__init__.py +++ b/zerver/lib/markdown/__init__.py @@ -1460,11 +1460,15 @@ class InlineInterestingLinkProcessor(markdown.treeprocessors.Treeprocessor): class CompiledInlineProcessor(markdown.inlinepatterns.InlineProcessor): - def __init__(self, compiled_re: Pattern[str], zmd: "ZulipMarkdown") -> None: + def __init__( + self, compiled_re: "Pattern[str] | re2._Regexp[str]", zmd: "ZulipMarkdown" + ) -> None: # This is similar to the superclass's small __init__ function, # but we skip the compilation step and let the caller give us # a compiled regex. - self.compiled_re = compiled_re + self.compiled_re = cast( + Pattern[str], compiled_re + ) # Python-Markdown doesn't expect re2, but it works well enough self.md = zmd self.zmd = zmd diff --git a/zerver/models/linkifiers.py b/zerver/models/linkifiers.py index db3a69273a..bf271a3ad4 100644 --- a/zerver/models/linkifiers.py +++ b/zerver/models/linkifiers.py @@ -1,5 +1,3 @@ -from re import Pattern - import re2 import uri_template from django.core.exceptions import ValidationError @@ -19,7 +17,7 @@ from zerver.lib.types import LinkifierDict from zerver.models.realms import Realm -def filter_pattern_validator(value: str) -> Pattern[str]: +def filter_pattern_validator(value: str) -> "re2._Regexp[str]": try: # Do not write errors to stderr (this still raises exceptions) options = re2.Options()