diff --git a/Makefile b/Makefile index 964d2bc6..828ac40d 100644 --- a/Makefile +++ b/Makefile @@ -53,12 +53,6 @@ format: install $(BIN)/buf $(BIN)/license-header ## Format code .PHONY: test test: generate install gettestdata ## Run unit tests uv run -- python -m unittest - $(MAKE) testextra - -.PHONY: testextra -testextra: - uv sync --extra re2 - uv run -- python -m unittest .PHONY: conformance conformance: $(BIN)/protovalidate-conformance generate install ## Run conformance tests diff --git a/README.md b/README.md index 85f8b908..e68f365b 100644 --- a/README.md +++ b/README.md @@ -52,12 +52,6 @@ To install the package, use `pip`: pip install protovalidate ``` -Protovalidate also has an optional dependency on [google-re2](https://pypi.org/project/google-re2/). If you require re2 syntax for your regular expressions, install the extra dep as follows: - -```shell -pip install protovalidate[re2] -``` - ## Documentation Comprehensive documentation for Protovalidate is available at [protovalidate.com][protovalidate]. diff --git a/protovalidate/internal/extra_func.py b/protovalidate/internal/extra_func.py index 386020ee..40bb677e 100644 --- a/protovalidate/internal/extra_func.py +++ b/protovalidate/internal/extra_func.py @@ -18,17 +18,12 @@ from urllib import parse as urlparse import celpy +import re2 from celpy import celtypes from protovalidate.internal import string_format from protovalidate.internal.rules import MessageType, field_to_cel -_USE_RE2 = True -try: - import re2 -except ImportError: - _USE_RE2 = False - # See https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address _email_regex = re.compile( r"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$" @@ -1559,16 +1554,7 @@ def __peek(self, char: str) -> bool: return self._index < len(self._string) and self._string[self._index] == char -def cel_matches_re(text: str, pattern: str) -> celpy.Result: - try: - m = re.search(pattern, text) - except re.error as ex: - return celpy.CELEvalError("match error", ex.__class__, ex.args) - - return celtypes.BoolType(m is not None) - - -def cel_matches_re2(text: str, pattern: str) -> celpy.Result: +def cel_matches(text: str, pattern: str) -> celpy.Result: try: m = re2.search(pattern, text) except re2.error as ex: @@ -1577,9 +1563,6 @@ def cel_matches_re2(text: str, pattern: str) -> celpy.Result: return celtypes.BoolType(m is not None) -cel_matches = cel_matches_re2 if _USE_RE2 else cel_matches_re - - def make_extra_funcs() -> dict[str, celpy.CELFunction]: string_fmt = string_format.StringFormat() return { diff --git a/pyproject.toml b/pyproject.toml index e7dd82c8..a7b7f9a3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,9 +24,6 @@ dynamic = ["version"] dependencies = [ "protobuf>=5", "cel-python==0.2.*", -] -[project.optional-dependencies] -re2 = [ # We need at least this version, which started publishing wheels for Python 3.13. # Ref: https://github.com/google/re2/issues/516 "google-re2>=1.1.20250722; python_version == '3.13'", diff --git a/test/test_matches.py b/test/test_matches.py index 3accacdf..6c0b3641 100644 --- a/test/test_matches.py +++ b/test/test_matches.py @@ -12,33 +12,18 @@ # See the License for the specific language governing permissions and # limitations under the License. -import importlib.util import unittest import celpy from celpy import celtypes -from protovalidate.internal.extra_func import cel_matches_re, cel_matches_re2 - -_USE_RE2 = True -spec = importlib.util.find_spec("re2") -if spec is None: - _USE_RE2 = False +from protovalidate.internal.extra_func import cel_matches class TestCollectViolations(unittest.TestCase): - @unittest.skipUnless(_USE_RE2, "Requires 're2'") def test_function_matches_re2(self): empty_string = celtypes.StringType("") # \z is valid re2 syntax for end of text - self.assertTrue(cel_matches_re2(empty_string, "^\\z")) + self.assertTrue(cel_matches(empty_string, "^\\z")) # \Z is invalid re2 syntax - self.assertIsInstance(cel_matches_re2(empty_string, "^\\Z"), celpy.CELEvalError) - - @unittest.skipUnless(_USE_RE2 is False, "Requires 're'") - def test_function_matches_re(self): - empty_string = celtypes.StringType("") - # \z is invalid re syntax - self.assertIsInstance(cel_matches_re(empty_string, "^\\z"), celpy.CELEvalError) - # \Z is valid re syntax for end of text - self.assertTrue(cel_matches_re(empty_string, "^\\Z")) + self.assertIsInstance(cel_matches(empty_string, "^\\Z"), celpy.CELEvalError) diff --git a/uv.lock b/uv.lock index a5020b96..70816d10 100644 --- a/uv.lock +++ b/uv.lock @@ -205,12 +205,8 @@ name = "protovalidate" source = { editable = "." } dependencies = [ { name = "cel-python" }, - { name = "protobuf" }, -] - -[package.optional-dependencies] -re2 = [ { name = "google-re2" }, + { name = "protobuf" }, ] [package.dev-dependencies] @@ -224,12 +220,11 @@ dev = [ [package.metadata] requires-dist = [ { name = "cel-python", specifier = "==0.2.*" }, - { name = "google-re2", marker = "python_full_version == '3.12.*' and extra == 're2'", specifier = ">=1.1" }, - { name = "google-re2", marker = "python_full_version == '3.13.*' and extra == 're2'", specifier = ">=1.1.20250722" }, - { name = "google-re2", marker = "extra == 're2'", specifier = ">=1" }, + { name = "google-re2", specifier = ">=1" }, + { name = "google-re2", marker = "python_full_version == '3.12.*'", specifier = ">=1.1" }, + { name = "google-re2", marker = "python_full_version == '3.13.*'", specifier = ">=1.1.20250722" }, { name = "protobuf", specifier = ">=5" }, ] -provides-extras = ["re2"] [package.metadata.requires-dev] dev = [