diff --git a/api/src/contract/common.py b/api/src/contract/common.py index 9534d2e..75dce31 100644 --- a/api/src/contract/common.py +++ b/api/src/contract/common.py @@ -36,7 +36,7 @@ RESULT_SCHEMA_VERSION_PATTERN = r"^\d+\.\d+$" # recognition-result-message.resu T = TypeVar("T") -_VERSION_RE = re.compile(r"(\d+)\.\d+", re.ASCII) +_SUPPORTED_VERSION_RE = re.compile(SCHEMA_VERSION_PATTERN, re.ASCII) # ровно шаблон схемы, без int() def is_supported_major(schema_version: object) -> bool: @@ -46,8 +46,8 @@ def is_supported_major(schema_version: object) -> bool: """ if not isinstance(schema_version, str): return False - match = _VERSION_RE.fullmatch(schema_version) - return match is not None and int(match.group(1)) == SUPPORTED_MAJOR + # `$` Python допускает перевод строки в конце, `fullmatch` — нет; шаблон — тот же, что у схемы и модели + return _SUPPORTED_VERSION_RE.fullmatch(schema_version) is not None class _NotNull: diff --git a/api/tests/unit/test_contract.py b/api/tests/unit/test_contract.py index cf90984..7799b78 100644 --- a/api/tests/unit/test_contract.py +++ b/api/tests/unit/test_contract.py @@ -669,6 +669,8 @@ def test_integer_valued_float_is_normalized_to_int() -> None: ("2.0", False), ("0.9", False), ("10.0", False), + ("01.0", False), # шаблон схемы `^1\\.\\d+$`: ведущий ноль в MAJOR недопустим + ("9" * 5000 + ".0", False), # длиннее лимита int() (4300 цифр): без исключения ("11.0", False), ("1", False), ("1.", False), @@ -691,7 +693,7 @@ def test_supported_major_is_one() -> None: assert SUPPORTED_MAJOR == 1 -@pytest.mark.parametrize("version", ["1.0", "1.7", "2.0", "1", "1.0.1", "0.9"]) +@pytest.mark.parametrize("version", ["1.0", "1.7", "2.0", "1", "1.0.1", "0.9", "01.0", "9" * 5000 + ".0"]) def test_is_supported_major_agrees_with_schema_pattern(version: str) -> None: """Проверка MAJOR совпадает с `schema_version` запроса по схеме (pattern `^1\\.\\d+$`).""" payload = _example("request-image.json")