From 5d99494042e9cb28c907e62b6f136b2f2dcf38ca Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Mon, 20 Jul 2026 19:53:42 +0200 Subject: [PATCH 1/6] feat: warn if unexpected-error-in-is_valid_syntax Signed-off-by: Jan Kowalleck --- src/rfc3987_syntax2/syntax_helpers.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/rfc3987_syntax2/syntax_helpers.py b/src/rfc3987_syntax2/syntax_helpers.py index dc51199..6d6f8bd 100644 --- a/src/rfc3987_syntax2/syntax_helpers.py +++ b/src/rfc3987_syntax2/syntax_helpers.py @@ -5,6 +5,7 @@ from pathlib import Path from threading import Lock from typing import Any, Callable, Optional, TYPE_CHECKING, Literal +from warnings import warn from lark import Lark, ParseTree, exceptions @@ -120,9 +121,16 @@ def parse(term: _SYNTAX_PARSER_TERM, value: str) -> 'ParseTree': def is_valid_syntax(term: _SYNTAX_PARSER_TERM, value: str) -> bool: try: parse(term=term, value=value) - return True - except exceptions.LarkError: + except exceptions.UnexpectedInput: + return False + except exceptions.LarkError as err: + warn("Unexpected LarkError (non-UnexpectedInput) " + f"for term={term!r}: {type(err).__name__}: {err}", + RuntimeWarning, + stacklevel=2) return False + else: + return True _T_SYNTAX_VALIDATOR = Callable[[str], bool] @@ -139,9 +147,10 @@ def syntax_validator(text: str) -> bool: parser=RFC3987_SYNTAX_PARSER_TYPE) try: parser.parse(text) - return True - except exceptions.LarkError: + except exceptions.UnexpectedInput: return False + else: + return True return syntax_validator From 290c0dc12991ce50ae8915af4fd03d5e3e59f2ed Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Mon, 20 Jul 2026 19:56:13 +0200 Subject: [PATCH 2/6] docs Signed-off-by: Jan Kowalleck --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e10efcb..d2eb741 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ All notable changes to this project will be documented in this file. * Function `is_valid_syntax_non_zero` (via [#48]) * Function `is_valid_syntax_pct_encoded` (via [#48]) * Dict `RFC3987_SYNTAX_TERM_VALIDATORS` mapping `RFC3987_SYNTAX_TERMS` to validator function (via [#49]) + * Function `is_valid_syntax` issues a warning if an unexpected error occurred (via [#51]) * Performance * Public symbols use lazy loading (via [#43]) * Tests @@ -33,6 +34,7 @@ All notable changes to this project will be documented in this file. [#48]: https://github.com/jkowalleck/rfc3987-syntax2/pull/48 [#49]: https://github.com/jkowalleck/rfc3987-syntax2/pull/49 [#50]: https://github.com/jkowalleck/rfc3987-syntax2/pull/50 +[#51]: https://github.com/jkowalleck/rfc3987-syntax2/pull/51 ## v1.2.0 - 2026-07-16 From 0a3e845c7f39f157b9b5776da4f7fcdfdbb6e457 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Jul 2026 17:56:15 +0000 Subject: [PATCH 3/6] test: add test for RuntimeWarning in is_valid_syntax --- tests/test_is_valid_syntax_warning.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/test_is_valid_syntax_warning.py diff --git a/tests/test_is_valid_syntax_warning.py b/tests/test_is_valid_syntax_warning.py new file mode 100644 index 0000000..78f7664 --- /dev/null +++ b/tests/test_is_valid_syntax_warning.py @@ -0,0 +1,21 @@ +# Copyright (c) 2026 Jan Kowalleck - modifications and maintenance +# SPDX-License-Identifier: MIT + +import pytest +from unittest.mock import patch + +from lark import exceptions + +import rfc3987_syntax2.syntax_helpers as sut + + +def _raise_lark_error(*args: object, **kwargs: object) -> None: + raise exceptions.LarkError("unexpected test error") + + +@pytest.mark.parametrize("term", ["iri", "iri_reference", "absolute_iri"]) +def test_is_valid_syntax_warns_on_unexpected_lark_error(term: str) -> None: + with patch.object(sut, "parse", side_effect=_raise_lark_error): + with pytest.warns(RuntimeWarning, match=r"Unexpected LarkError"): + result = sut.is_valid_syntax(term=term, value="any-value") + assert result is False From 466bfdff63bd496ec4750c7390acd0d0dc14d585 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Mon, 20 Jul 2026 20:00:22 +0200 Subject: [PATCH 4/6] tests Signed-off-by: Jan Kowalleck --- tests/test_is_valid_syntax_warning.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/test_is_valid_syntax_warning.py b/tests/test_is_valid_syntax_warning.py index 78f7664..b7c5054 100644 --- a/tests/test_is_valid_syntax_warning.py +++ b/tests/test_is_valid_syntax_warning.py @@ -13,9 +13,10 @@ def _raise_lark_error(*args: object, **kwargs: object) -> None: raise exceptions.LarkError("unexpected test error") -@pytest.mark.parametrize("term", ["iri", "iri_reference", "absolute_iri"]) -def test_is_valid_syntax_warns_on_unexpected_lark_error(term: str) -> None: +def test_is_valid_syntax_warns_on_unexpected_lark_error() -> None: with patch.object(sut, "parse", side_effect=_raise_lark_error): with pytest.warns(RuntimeWarning, match=r"Unexpected LarkError"): - result = sut.is_valid_syntax(term=term, value="any-value") + result = sut.is_valid_syntax( + term='unsupported-term', # type: ignore[arg-type] # on purpose + value="any-value") assert result is False From 7122fa9f7fef6d1907c394293f9f8d7cecc47a3a Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Mon, 20 Jul 2026 20:01:46 +0200 Subject: [PATCH 5/6] dings Signed-off-by: Jan Kowalleck --- src/rfc3987_syntax2/syntax_helpers.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/rfc3987_syntax2/syntax_helpers.py b/src/rfc3987_syntax2/syntax_helpers.py index 6d6f8bd..63ab839 100644 --- a/src/rfc3987_syntax2/syntax_helpers.py +++ b/src/rfc3987_syntax2/syntax_helpers.py @@ -122,15 +122,16 @@ def is_valid_syntax(term: _SYNTAX_PARSER_TERM, value: str) -> bool: try: parse(term=term, value=value) except exceptions.UnexpectedInput: + # from Lark.parse() return False except exceptions.LarkError as err: + # from Lark() warn("Unexpected LarkError (non-UnexpectedInput) " f"for term={term!r}: {type(err).__name__}: {err}", RuntimeWarning, stacklevel=2) return False - else: - return True + return True _T_SYNTAX_VALIDATOR = Callable[[str], bool] From e324137ac6cfcea8a9a01b82ae6f6d7f7e2be201 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Mon, 20 Jul 2026 20:11:10 +0200 Subject: [PATCH 6/6] dings Signed-off-by: Jan Kowalleck --- src/rfc3987_syntax2/syntax_helpers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rfc3987_syntax2/syntax_helpers.py b/src/rfc3987_syntax2/syntax_helpers.py index 8f8a828..fd1ebda 100644 --- a/src/rfc3987_syntax2/syntax_helpers.py +++ b/src/rfc3987_syntax2/syntax_helpers.py @@ -125,7 +125,7 @@ def is_valid_syntax(term: _T_SYNTAX_PARSER_TERM, value: str) -> bool: # from Lark.parse() return False except exceptions.LarkError as err: - # from Lark() + # from Lark internals / initialization (non-UnexpectedInput) warn("Unexpected LarkError (non-UnexpectedInput) " f"for term={term!r}: {type(err).__name__}: {err}", RuntimeWarning, @@ -148,7 +148,7 @@ def syntax_validator(text: str) -> bool: parser=RFC3987_SYNTAX_PARSER_TYPE) try: parser.parse(text) - except exceptions.UnexpectedInput: + except exceptions.LarkError: return False else: return True