From 8b380c1e10f83fc0ec9b4306036742ff6ad840eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jan 2026 07:54:31 +0000 Subject: [PATCH 01/10] Bump sphinx from 8.2.3 to 9.1.0 Bumps [sphinx](https://github.com/sphinx-doc/sphinx) from 8.2.3 to 9.1.0. - [Release notes](https://github.com/sphinx-doc/sphinx/releases) - [Changelog](https://github.com/sphinx-doc/sphinx/blob/master/CHANGES.rst) - [Commits](https://github.com/sphinx-doc/sphinx/compare/v8.2.3...v9.1.0) --- updated-dependencies: - dependency-name: sphinx dependency-version: 9.1.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 80b92dbbd..e30d29f39 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -85,7 +85,7 @@ optional-dependencies.dev = [ # use it to lint shell commands in GitHub workflow files. "shellcheck-py==0.11.0.1", "shfmt-py==3.12.0.2", - "sphinx==8.2.3", + "sphinx==9.1.0", "sphinx-copybutton==0.5.2", "sphinx-lint==1.0.2", "sphinx-paramlinks==0.6", From 84db2aa6137df7b3421f069201807d632f3131c3 Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Mon, 19 Jan 2026 08:08:52 +0000 Subject: [PATCH 02/10] Bump doc8 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e30d29f39..5d5a3ec41 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,7 +55,7 @@ optional-dependencies.dev = [ "coverage==7.13.1", "deptry==0.24.0", "dirty-equals==0.11", - "doc8==1.1.1", + "doc8==2.0.0", "doccmd==2026.1.18", "docformatter==1.7.7", "docker==7.1.0", From cf32a769682835e41edb667b59f84a61215742fd Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Tue, 27 Jan 2026 04:31:49 +0000 Subject: [PATCH 03/10] Support Python 3.14 --- .github/workflows/lint.yml | 2 +- .github/workflows/test.yml | 6 +++--- pyproject.toml | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 12b738ab7..e242f57b1 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -18,7 +18,7 @@ jobs: build: strategy: matrix: - python-version: ['3.13'] + python-version: ['3.13', '3.14'] platform: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.platform }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 386db8031..d4905c548 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,7 +25,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ['3.13'] + python-version: ['3.13', '3.14'] ci_pattern: - tests/mock_vws/test_query.py::TestContentType - tests/mock_vws/test_query.py::TestSuccess @@ -185,7 +185,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.13'] + python-version: ['3.13', '3.14'] platform: [ubuntu-latest] steps: @@ -231,7 +231,7 @@ jobs: runs-on: windows-latest strategy: matrix: - python-version: ['3.13'] + python-version: ['3.13', '3.14'] steps: - uses: actions/checkout@v6 diff --git a/pyproject.toml b/pyproject.toml index 5d5a3ec41..6d09f8cf9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,6 +29,7 @@ classifiers = [ "Operating System :: POSIX", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", ] dynamic = [ "version", @@ -345,7 +346,7 @@ DEP002 = [ [tool.pyproject-fmt] indent = 4 keep_full_version = true -max_supported_python = "3.13" +max_supported_python = "3.14" [tool.pytest.ini_options] From 8d494ba158a953956fe1cd5b21ba45b6f833c474 Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Tue, 27 Jan 2026 14:13:15 +0000 Subject: [PATCH 04/10] Don't bump Sphinx --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index cf3a90601..a58c38d42 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -86,7 +86,7 @@ optional-dependencies.dev = [ # use it to lint shell commands in GitHub workflow files. "shellcheck-py==0.11.0.1", "shfmt-py==3.12.0.2", - "sphinx==9.1.0", + "sphinx==8.2.3", "sphinx-copybutton==0.5.2", "sphinx-lint==1.0.2", "sphinx-paramlinks==0.6", From 06424724dc287c7290838ae2108c65d672f6bc25 Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Tue, 27 Jan 2026 14:20:28 +0000 Subject: [PATCH 05/10] Fix secrets file lookup for multi-Python matrix Use modulo arithmetic to map job index to secrets file index, ensuring that adding Python versions to the matrix doesn't break the secrets file lookup. Each test pattern maps to the same secrets file regardless of Python version. The number of secrets files is determined dynamically from the extracted tarball. --- .github/workflows/test.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d4905c548..4c5502e78 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -133,7 +133,12 @@ jobs: # See the "CI Setup" document for details of how this was set up. ci/decrypt_secret.sh tar xvf "${HOME}"/secrets/secrets.tar - cp ./ci_secrets/vuforia_secrets_${{ strategy.job-index }}.env ./vuforia_secrets.env + # Use modulo to map job index to secrets file index. + # This ensures all Python versions for the same test pattern + # use the same secrets file. + NUM_SECRETS_FILES=$(find ./ci_secrets -name 'vuforia_secrets_*.env' | wc -l) + SECRETS_INDEX=$(( ${{ strategy.job-index }} % NUM_SECRETS_FILES )) + cp ./ci_secrets/vuforia_secrets_${SECRETS_INDEX}.env ./vuforia_secrets.env env: CI_PATTERN: ${{ matrix.ci_pattern }} ENCRYPTED_FILE: secrets.tar.gpg From bfc5cf0c61d5f594389668ac76d6d6dd757667f8 Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Tue, 27 Jan 2026 14:51:56 +0000 Subject: [PATCH 06/10] Support only 3.14 --- .github/workflows/lint.yml | 2 +- .github/workflows/publish-site.yml | 2 +- .github/workflows/test.yml | 13 ++++--------- README.rst | 2 +- pyproject.toml | 3 +-- src/mock_vws/_flask_server/Dockerfile | 2 +- 6 files changed, 9 insertions(+), 15 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index a1ea33a58..e76d18673 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -18,7 +18,7 @@ jobs: build: strategy: matrix: - python-version: ['3.13', '3.14'] + python-version: ['3.14'] platform: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.platform }} diff --git a/.github/workflows/publish-site.yml b/.github/workflows/publish-site.yml index 4ca927ccb..8172787fb 100644 --- a/.github/workflows/publish-site.yml +++ b/.github/workflows/publish-site.yml @@ -22,6 +22,6 @@ jobs: with: documentation_path: docs/source pyproject_extras: dev - python_version: '3.13' + python_version: '3.14' sphinx_build_options: -W publish: ${{ github.ref_name == 'main' }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4c5502e78..5cf316b52 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,7 +25,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ['3.13', '3.14'] + python-version: ['3.14'] ci_pattern: - tests/mock_vws/test_query.py::TestContentType - tests/mock_vws/test_query.py::TestSuccess @@ -133,12 +133,7 @@ jobs: # See the "CI Setup" document for details of how this was set up. ci/decrypt_secret.sh tar xvf "${HOME}"/secrets/secrets.tar - # Use modulo to map job index to secrets file index. - # This ensures all Python versions for the same test pattern - # use the same secrets file. - NUM_SECRETS_FILES=$(find ./ci_secrets -name 'vuforia_secrets_*.env' | wc -l) - SECRETS_INDEX=$(( ${{ strategy.job-index }} % NUM_SECRETS_FILES )) - cp ./ci_secrets/vuforia_secrets_${SECRETS_INDEX}.env ./vuforia_secrets.env + cp ./ci_secrets/vuforia_secrets_${{ strategy.job-index }}.env ./vuforia_secrets.env env: CI_PATTERN: ${{ matrix.ci_pattern }} ENCRYPTED_FILE: secrets.tar.gpg @@ -190,7 +185,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.13', '3.14'] + python-version: ['3.14'] platform: [ubuntu-latest] steps: @@ -236,7 +231,7 @@ jobs: runs-on: windows-latest strategy: matrix: - python-version: ['3.13', '3.14'] + python-version: ['3.14'] steps: - uses: actions/checkout@v6 diff --git a/README.rst b/README.rst index cd8434d30..ac98fab1f 100644 --- a/README.rst +++ b/README.rst @@ -58,4 +58,4 @@ This includes details on how to use the mock, options, and details of the differ :target: https://github.com/VWS-Python/vws-python-mock/actions .. |PyPI| image:: https://badge.fury.io/py/VWS-Python-Mock.svg :target: https://badge.fury.io/py/VWS-Python-Mock -.. |minimum-python-version| replace:: 3.13 +.. |minimum-python-version| replace:: 3.14 diff --git a/pyproject.toml b/pyproject.toml index a58c38d42..501e9a974 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ license = "MIT" authors = [ { name = "Adam Dangoor", email = "adamdangoor@gmail.com" }, ] -requires-python = ">=3.13" +requires-python = ">=3.14" classifiers = [ "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", @@ -28,7 +28,6 @@ classifiers = [ "Operating System :: Microsoft :: Windows", "Operating System :: POSIX", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", ] dynamic = [ diff --git a/src/mock_vws/_flask_server/Dockerfile b/src/mock_vws/_flask_server/Dockerfile index a08e67063..68aaa0656 100644 --- a/src/mock_vws/_flask_server/Dockerfile +++ b/src/mock_vws/_flask_server/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.13-slim AS base +FROM python:3.14-slim AS base # We set this pretend version as we do not have Git in our path, and we do # not care enough about having the version correct inside the Docker container # to install it. From 9a342f4fca65057fed2911553986affd84f92d0d Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Tue, 27 Jan 2026 14:55:03 +0000 Subject: [PATCH 07/10] Fix ruff --- ci/test_custom_linters.py | 2 +- src/mock_vws/_database_matchers.py | 7 +++++-- src/mock_vws/_mock_common.py | 6 ++++-- src/mock_vws/_query_tools.py | 11 +++++++---- src/mock_vws/_query_validators/__init__.py | 9 ++++++--- .../_query_validators/accept_header_validators.py | 5 ++++- src/mock_vws/_query_validators/auth_validators.py | 8 ++++++-- .../_query_validators/content_length_validators.py | 5 ++++- .../_query_validators/content_type_validators.py | 5 ++++- src/mock_vws/_query_validators/date_validators.py | 5 ++++- src/mock_vws/_query_validators/exceptions.py | 5 ++++- src/mock_vws/_query_validators/fields_validators.py | 5 ++++- src/mock_vws/_query_validators/image_validators.py | 5 ++++- .../include_target_data_validators.py | 5 ++++- .../_query_validators/num_results_validators.py | 5 ++++- .../_query_validators/project_state_validators.py | 8 ++++++-- src/mock_vws/_requests_mock_server/decorators.py | 3 ++- .../_requests_mock_server/mock_web_query_api.py | 11 +++++++---- .../_requests_mock_server/mock_web_services_api.py | 13 ++++++++----- src/mock_vws/_services_validators/__init__.py | 9 ++++++--- .../_services_validators/auth_validators.py | 8 ++++++-- .../content_length_validators.py | 5 ++++- .../_services_validators/content_type_validators.py | 5 ++++- .../_services_validators/date_validators.py | 5 ++++- src/mock_vws/_services_validators/exceptions.py | 5 ++++- src/mock_vws/_services_validators/key_validators.py | 5 ++++- .../_services_validators/name_validators.py | 8 ++++++-- .../project_state_validators.py | 8 ++++++-- .../_services_validators/target_validators.py | 8 ++++++-- src/mock_vws/database.py | 6 ++++-- src/mock_vws/target_manager.py | 4 ++-- tests/conftest.py | 9 ++++++--- tests/mock_vws/fixtures/prepared_requests.py | 12 ++++++++---- tests/mock_vws/fixtures/vuforia_backends.py | 5 ++++- tests/mock_vws/test_add_target.py | 8 +++++--- tests/mock_vws/test_authorization_header.py | 8 ++++++-- tests/mock_vws/test_database_summary.py | 5 ++++- tests/mock_vws/test_delete_target.py | 5 ++++- tests/mock_vws/test_docker.py | 9 +++++---- tests/mock_vws/test_flask_app_usage.py | 5 ++++- tests/mock_vws/test_get_duplicates.py | 5 ++++- tests/mock_vws/test_get_target.py | 8 ++++++-- tests/mock_vws/test_invalid_given_id.py | 8 ++++++-- tests/mock_vws/test_query.py | 6 ++++-- tests/mock_vws/test_target_list.py | 6 +++++- tests/mock_vws/test_target_raters.py | 5 ++++- tests/mock_vws/test_target_summary.py | 10 +++++++--- tests/mock_vws/test_update_target.py | 8 +++++--- tests/mock_vws/utils/__init__.py | 8 +++++--- tests/mock_vws/utils/assertions.py | 7 +++++-- tests/mock_vws/utils/too_many_requests.py | 5 ++++- tests/mock_vws/utils/usage_test_helpers.py | 7 +++++-- 52 files changed, 250 insertions(+), 98 deletions(-) diff --git a/ci/test_custom_linters.py b/ci/test_custom_linters.py index c25260b46..ed3683f61 100644 --- a/ci/test_custom_linters.py +++ b/ci/test_custom_linters.py @@ -1,6 +1,5 @@ """Custom lint tests.""" -from pathlib import Path from typing import TYPE_CHECKING import pytest @@ -9,6 +8,7 @@ if TYPE_CHECKING: from collections.abc import Iterable + from pathlib import Path @beartype diff --git a/src/mock_vws/_database_matchers.py b/src/mock_vws/_database_matchers.py index 899cf71b2..6995fe6f0 100644 --- a/src/mock_vws/_database_matchers.py +++ b/src/mock_vws/_database_matchers.py @@ -1,11 +1,14 @@ """Helpers for getting databases which match keys given in requests.""" -from collections.abc import Iterable, Mapping +from typing import TYPE_CHECKING from beartype import beartype from vws_auth_tools import authorization_header -from mock_vws.database import VuforiaDatabase +if TYPE_CHECKING: + from collections.abc import Iterable, Mapping + + from mock_vws.database import VuforiaDatabase @beartype diff --git a/src/mock_vws/_mock_common.py b/src/mock_vws/_mock_common.py index 0ebbd379b..8b7c1c347 100644 --- a/src/mock_vws/_mock_common.py +++ b/src/mock_vws/_mock_common.py @@ -1,12 +1,14 @@ """Common utilities for creating mock routes.""" import json -from collections.abc import Iterable from dataclasses import dataclass -from typing import Any +from typing import TYPE_CHECKING, Any from beartype import beartype +if TYPE_CHECKING: + from collections.abc import Iterable + @dataclass(frozen=True) class Route: diff --git a/src/mock_vws/_query_tools.py b/src/mock_vws/_query_tools.py index b73f6c616..47cb3f6e0 100644 --- a/src/mock_vws/_query_tools.py +++ b/src/mock_vws/_query_tools.py @@ -3,9 +3,8 @@ import base64 import io import uuid -from collections.abc import Iterable, Mapping from email.message import EmailMessage -from typing import Any +from typing import TYPE_CHECKING, Any from beartype import beartype from werkzeug.formparser import MultiPartParser @@ -14,8 +13,12 @@ from mock_vws._constants import ResultCodes, TargetStatuses from mock_vws._database_matchers import get_database_matching_client_keys from mock_vws._mock_common import json_dump -from mock_vws.database import VuforiaDatabase -from mock_vws.image_matchers import ImageMatcher + +if TYPE_CHECKING: + from collections.abc import Iterable, Mapping + + from mock_vws.database import VuforiaDatabase + from mock_vws.image_matchers import ImageMatcher @beartype diff --git a/src/mock_vws/_query_validators/__init__.py b/src/mock_vws/_query_validators/__init__.py index 54e458e80..51c9b9002 100644 --- a/src/mock_vws/_query_validators/__init__.py +++ b/src/mock_vws/_query_validators/__init__.py @@ -1,11 +1,9 @@ """Input validators to use in the mock query API.""" -from collections.abc import Iterable, Mapping +from typing import TYPE_CHECKING from beartype import beartype -from mock_vws.database import VuforiaDatabase - from .accept_header_validators import validate_accept_header from .auth_validators import ( validate_auth_header_exists, @@ -37,6 +35,11 @@ from .num_results_validators import validate_max_num_results from .project_state_validators import validate_project_state +if TYPE_CHECKING: + from collections.abc import Iterable, Mapping + + from mock_vws.database import VuforiaDatabase + @beartype def run_query_validators( diff --git a/src/mock_vws/_query_validators/accept_header_validators.py b/src/mock_vws/_query_validators/accept_header_validators.py index fe3e966f6..5322d975e 100644 --- a/src/mock_vws/_query_validators/accept_header_validators.py +++ b/src/mock_vws/_query_validators/accept_header_validators.py @@ -1,12 +1,15 @@ """Validators for the ``Accept`` header.""" import logging -from collections.abc import Mapping +from typing import TYPE_CHECKING from beartype import beartype from mock_vws._query_validators.exceptions import InvalidAcceptHeaderError +if TYPE_CHECKING: + from collections.abc import Mapping + _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_query_validators/auth_validators.py b/src/mock_vws/_query_validators/auth_validators.py index a90273909..0d7b031a6 100644 --- a/src/mock_vws/_query_validators/auth_validators.py +++ b/src/mock_vws/_query_validators/auth_validators.py @@ -1,7 +1,7 @@ """Authorization validators to use in the mock query API.""" import logging -from collections.abc import Iterable, Mapping +from typing import TYPE_CHECKING from beartype import beartype @@ -11,7 +11,11 @@ AuthHeaderMissingError, MalformedAuthHeaderError, ) -from mock_vws.database import VuforiaDatabase + +if TYPE_CHECKING: + from collections.abc import Iterable, Mapping + + from mock_vws.database import VuforiaDatabase _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_query_validators/content_length_validators.py b/src/mock_vws/_query_validators/content_length_validators.py index 4cb799fb5..8282ee5ae 100644 --- a/src/mock_vws/_query_validators/content_length_validators.py +++ b/src/mock_vws/_query_validators/content_length_validators.py @@ -1,7 +1,7 @@ """Content-Length header validators to use in the mock.""" import logging -from collections.abc import Mapping +from typing import TYPE_CHECKING from beartype import beartype @@ -11,6 +11,9 @@ ContentLengthHeaderTooLargeError, ) +if TYPE_CHECKING: + from collections.abc import Mapping + _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_query_validators/content_type_validators.py b/src/mock_vws/_query_validators/content_type_validators.py index 3e7dc4792..d72306f3a 100644 --- a/src/mock_vws/_query_validators/content_type_validators.py +++ b/src/mock_vws/_query_validators/content_type_validators.py @@ -1,8 +1,8 @@ """Validators for the ``Content-Type`` header.""" import logging -from collections.abc import Mapping from email.message import EmailMessage +from typing import TYPE_CHECKING from beartype import beartype @@ -13,6 +13,9 @@ UnsupportedMediaTypeError, ) +if TYPE_CHECKING: + from collections.abc import Mapping + _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_query_validators/date_validators.py b/src/mock_vws/_query_validators/date_validators.py index 4151b0d31..24186f8b2 100644 --- a/src/mock_vws/_query_validators/date_validators.py +++ b/src/mock_vws/_query_validators/date_validators.py @@ -3,7 +3,7 @@ import contextlib import datetime import logging -from collections.abc import Mapping +from typing import TYPE_CHECKING from zoneinfo import ZoneInfo from beartype import beartype @@ -14,6 +14,9 @@ RequestTimeTooSkewedError, ) +if TYPE_CHECKING: + from collections.abc import Mapping + _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_query_validators/exceptions.py b/src/mock_vws/_query_validators/exceptions.py index 6417595f4..528356a2c 100644 --- a/src/mock_vws/_query_validators/exceptions.py +++ b/src/mock_vws/_query_validators/exceptions.py @@ -3,14 +3,17 @@ import email.utils import textwrap import uuid -from collections.abc import Mapping from http import HTTPStatus +from typing import TYPE_CHECKING from beartype import beartype from mock_vws._constants import ResultCodes from mock_vws._mock_common import json_dump +if TYPE_CHECKING: + from collections.abc import Mapping + @beartype class ValidatorError(Exception): diff --git a/src/mock_vws/_query_validators/fields_validators.py b/src/mock_vws/_query_validators/fields_validators.py index b9e78fecd..ae41f3bf8 100644 --- a/src/mock_vws/_query_validators/fields_validators.py +++ b/src/mock_vws/_query_validators/fields_validators.py @@ -2,14 +2,17 @@ import io import logging -from collections.abc import Mapping from email.message import EmailMessage +from typing import TYPE_CHECKING from beartype import beartype from werkzeug.formparser import MultiPartParser from mock_vws._query_validators.exceptions import UnknownParametersError +if TYPE_CHECKING: + from collections.abc import Mapping + _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_query_validators/image_validators.py b/src/mock_vws/_query_validators/image_validators.py index 827c636d2..c68a0943b 100644 --- a/src/mock_vws/_query_validators/image_validators.py +++ b/src/mock_vws/_query_validators/image_validators.py @@ -2,8 +2,8 @@ import io import logging -from collections.abc import Mapping from email.message import EmailMessage +from typing import TYPE_CHECKING from beartype import beartype from PIL import Image @@ -15,6 +15,9 @@ RequestEntityTooLargeError, ) +if TYPE_CHECKING: + from collections.abc import Mapping + _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_query_validators/include_target_data_validators.py b/src/mock_vws/_query_validators/include_target_data_validators.py index b3719aad8..eff2bfe6b 100644 --- a/src/mock_vws/_query_validators/include_target_data_validators.py +++ b/src/mock_vws/_query_validators/include_target_data_validators.py @@ -2,14 +2,17 @@ import io import logging -from collections.abc import Mapping from email.message import EmailMessage +from typing import TYPE_CHECKING from beartype import beartype from werkzeug.formparser import MultiPartParser from mock_vws._query_validators.exceptions import InvalidIncludeTargetDataError +if TYPE_CHECKING: + from collections.abc import Mapping + _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_query_validators/num_results_validators.py b/src/mock_vws/_query_validators/num_results_validators.py index 31ead620b..2d44141f4 100644 --- a/src/mock_vws/_query_validators/num_results_validators.py +++ b/src/mock_vws/_query_validators/num_results_validators.py @@ -2,8 +2,8 @@ import io import logging -from collections.abc import Mapping from email.message import EmailMessage +from typing import TYPE_CHECKING from beartype import beartype from werkzeug.formparser import MultiPartParser @@ -13,6 +13,9 @@ MaxNumResultsOutOfRangeError, ) +if TYPE_CHECKING: + from collections.abc import Mapping + _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_query_validators/project_state_validators.py b/src/mock_vws/_query_validators/project_state_validators.py index 5a3517bde..a424927f9 100644 --- a/src/mock_vws/_query_validators/project_state_validators.py +++ b/src/mock_vws/_query_validators/project_state_validators.py @@ -1,15 +1,19 @@ """Validators for the project state.""" import logging -from collections.abc import Iterable, Mapping +from typing import TYPE_CHECKING from beartype import beartype from mock_vws._database_matchers import get_database_matching_client_keys from mock_vws._query_validators.exceptions import InactiveProjectError -from mock_vws.database import VuforiaDatabase from mock_vws.states import States +if TYPE_CHECKING: + from collections.abc import Iterable, Mapping + + from mock_vws.database import VuforiaDatabase + _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_requests_mock_server/decorators.py b/src/mock_vws/_requests_mock_server/decorators.py index 6572d593d..dcbeadc22 100644 --- a/src/mock_vws/_requests_mock_server/decorators.py +++ b/src/mock_vws/_requests_mock_server/decorators.py @@ -8,7 +8,6 @@ from beartype import BeartypeConf, beartype from responses import RequestsMock -from mock_vws.database import VuforiaDatabase from mock_vws.image_matchers import ( ImageMatcher, StructuralSimilarityMatcher, @@ -25,6 +24,8 @@ if TYPE_CHECKING: from collections.abc import Iterable + from mock_vws.database import VuforiaDatabase + _STRUCTURAL_SIMILARITY_MATCHER = StructuralSimilarityMatcher() _BRISQUE_TRACKING_RATER = BrisqueTargetTrackingRater() diff --git a/src/mock_vws/_requests_mock_server/mock_web_query_api.py b/src/mock_vws/_requests_mock_server/mock_web_query_api.py index 8206a6d10..da28d920b 100644 --- a/src/mock_vws/_requests_mock_server/mock_web_query_api.py +++ b/src/mock_vws/_requests_mock_server/mock_web_query_api.py @@ -7,10 +7,9 @@ import email.utils from collections.abc import Callable, Iterable, Mapping from http import HTTPMethod, HTTPStatus -from typing import ParamSpec, Protocol, runtime_checkable +from typing import TYPE_CHECKING, ParamSpec, Protocol, runtime_checkable from beartype import beartype -from requests.models import PreparedRequest from mock_vws._mock_common import Route from mock_vws._query_tools import ( @@ -20,8 +19,12 @@ from mock_vws._query_validators.exceptions import ( ValidatorError, ) -from mock_vws.image_matchers import ImageMatcher -from mock_vws.target_manager import TargetManager + +if TYPE_CHECKING: + from requests.models import PreparedRequest + + from mock_vws.image_matchers import ImageMatcher + from mock_vws.target_manager import TargetManager _ROUTES: set[Route] = set() diff --git a/src/mock_vws/_requests_mock_server/mock_web_services_api.py b/src/mock_vws/_requests_mock_server/mock_web_services_api.py index ddee6ef03..b2a3e78aa 100644 --- a/src/mock_vws/_requests_mock_server/mock_web_services_api.py +++ b/src/mock_vws/_requests_mock_server/mock_web_services_api.py @@ -12,11 +12,10 @@ import uuid from collections.abc import Callable, Iterable, Mapping from http import HTTPMethod, HTTPStatus -from typing import Any, ParamSpec, Protocol, runtime_checkable +from typing import TYPE_CHECKING, Any, ParamSpec, Protocol, runtime_checkable from zoneinfo import ZoneInfo from beartype import BeartypeConf, beartype -from requests.models import PreparedRequest from mock_vws._constants import ResultCodes, TargetStatuses from mock_vws._database_matchers import get_database_matching_server_keys @@ -28,10 +27,14 @@ TargetStatusProcessingError, ValidatorError, ) -from mock_vws.image_matchers import ImageMatcher from mock_vws.target import Target -from mock_vws.target_manager import TargetManager -from mock_vws.target_raters import TargetTrackingRater + +if TYPE_CHECKING: + from requests.models import PreparedRequest + + from mock_vws.image_matchers import ImageMatcher + from mock_vws.target_manager import TargetManager + from mock_vws.target_raters import TargetTrackingRater _TARGET_ID_PATTERN = "[A-Za-z0-9]+" diff --git a/src/mock_vws/_services_validators/__init__.py b/src/mock_vws/_services_validators/__init__.py index 44487b365..f3765f451 100644 --- a/src/mock_vws/_services_validators/__init__.py +++ b/src/mock_vws/_services_validators/__init__.py @@ -1,8 +1,6 @@ """Input validators to use in the mock.""" -from collections.abc import Iterable, Mapping - -from mock_vws.database import VuforiaDatabase +from typing import TYPE_CHECKING from .active_flag_validators import validate_active_flag from .auth_validators import ( @@ -49,6 +47,11 @@ from .target_validators import validate_target_id_exists from .width_validators import validate_width +if TYPE_CHECKING: + from collections.abc import Iterable, Mapping + + from mock_vws.database import VuforiaDatabase + def run_services_validators( request_path: str, diff --git a/src/mock_vws/_services_validators/auth_validators.py b/src/mock_vws/_services_validators/auth_validators.py index f47164085..9e1d8a89e 100644 --- a/src/mock_vws/_services_validators/auth_validators.py +++ b/src/mock_vws/_services_validators/auth_validators.py @@ -1,8 +1,8 @@ """Authorization header validators to use in the mock.""" import logging -from collections.abc import Iterable, Mapping from http import HTTPStatus +from typing import TYPE_CHECKING from beartype import beartype @@ -11,7 +11,11 @@ AuthenticationFailureError, FailError, ) -from mock_vws.database import VuforiaDatabase + +if TYPE_CHECKING: + from collections.abc import Iterable, Mapping + + from mock_vws.database import VuforiaDatabase _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_services_validators/content_length_validators.py b/src/mock_vws/_services_validators/content_length_validators.py index eaa41b2af..0b41dad79 100644 --- a/src/mock_vws/_services_validators/content_length_validators.py +++ b/src/mock_vws/_services_validators/content_length_validators.py @@ -1,7 +1,7 @@ """Content-Length header validators to use in the mock.""" import logging -from collections.abc import Mapping +from typing import TYPE_CHECKING from beartype import beartype @@ -11,6 +11,9 @@ ContentLengthHeaderTooLargeError, ) +if TYPE_CHECKING: + from collections.abc import Mapping + _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_services_validators/content_type_validators.py b/src/mock_vws/_services_validators/content_type_validators.py index 12913fa6f..088f26a60 100644 --- a/src/mock_vws/_services_validators/content_type_validators.py +++ b/src/mock_vws/_services_validators/content_type_validators.py @@ -1,13 +1,16 @@ """Content-Type header validators to use in the mock.""" import logging -from collections.abc import Mapping from http import HTTPMethod +from typing import TYPE_CHECKING from beartype import beartype from mock_vws._services_validators.exceptions import AuthenticationFailureError +if TYPE_CHECKING: + from collections.abc import Mapping + _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_services_validators/date_validators.py b/src/mock_vws/_services_validators/date_validators.py index f5f773d97..2c7e08c7a 100644 --- a/src/mock_vws/_services_validators/date_validators.py +++ b/src/mock_vws/_services_validators/date_validators.py @@ -2,8 +2,8 @@ import datetime import logging -from collections.abc import Mapping from http import HTTPStatus +from typing import TYPE_CHECKING from zoneinfo import ZoneInfo from beartype import beartype @@ -13,6 +13,9 @@ RequestTimeTooSkewedError, ) +if TYPE_CHECKING: + from collections.abc import Mapping + _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_services_validators/exceptions.py b/src/mock_vws/_services_validators/exceptions.py index 4bbc5dab8..688546eca 100644 --- a/src/mock_vws/_services_validators/exceptions.py +++ b/src/mock_vws/_services_validators/exceptions.py @@ -3,14 +3,17 @@ import email.utils import textwrap import uuid -from collections.abc import Mapping from http import HTTPStatus +from typing import TYPE_CHECKING from beartype import beartype from mock_vws._constants import ResultCodes from mock_vws._mock_common import json_dump +if TYPE_CHECKING: + from collections.abc import Mapping + @beartype class ValidatorError(Exception): diff --git a/src/mock_vws/_services_validators/key_validators.py b/src/mock_vws/_services_validators/key_validators.py index b07533fe0..c66e4ee13 100644 --- a/src/mock_vws/_services_validators/key_validators.py +++ b/src/mock_vws/_services_validators/key_validators.py @@ -3,14 +3,17 @@ import json import logging import re -from collections.abc import Iterable from dataclasses import dataclass from http import HTTPMethod, HTTPStatus +from typing import TYPE_CHECKING from beartype import beartype from .exceptions import FailError +if TYPE_CHECKING: + from collections.abc import Iterable + _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_services_validators/name_validators.py b/src/mock_vws/_services_validators/name_validators.py index 37e511931..40e066449 100644 --- a/src/mock_vws/_services_validators/name_validators.py +++ b/src/mock_vws/_services_validators/name_validators.py @@ -2,8 +2,8 @@ import json import logging -from collections.abc import Iterable, Mapping from http import HTTPMethod, HTTPStatus +from typing import TYPE_CHECKING from beartype import beartype @@ -12,7 +12,11 @@ FailError, TargetNameExistError, ) -from mock_vws.database import VuforiaDatabase + +if TYPE_CHECKING: + from collections.abc import Iterable, Mapping + + from mock_vws.database import VuforiaDatabase _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_services_validators/project_state_validators.py b/src/mock_vws/_services_validators/project_state_validators.py index 468e6188a..e16e50206 100644 --- a/src/mock_vws/_services_validators/project_state_validators.py +++ b/src/mock_vws/_services_validators/project_state_validators.py @@ -1,16 +1,20 @@ """Validators for the project state.""" import logging -from collections.abc import Iterable, Mapping from http import HTTPMethod +from typing import TYPE_CHECKING from beartype import beartype from mock_vws._database_matchers import get_database_matching_server_keys from mock_vws._services_validators.exceptions import ProjectInactiveError -from mock_vws.database import VuforiaDatabase from mock_vws.states import States +if TYPE_CHECKING: + from collections.abc import Iterable, Mapping + + from mock_vws.database import VuforiaDatabase + _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_services_validators/target_validators.py b/src/mock_vws/_services_validators/target_validators.py index 4dbee04b1..3113e47a4 100644 --- a/src/mock_vws/_services_validators/target_validators.py +++ b/src/mock_vws/_services_validators/target_validators.py @@ -1,13 +1,17 @@ """Validators for given target IDs.""" import logging -from collections.abc import Iterable, Mapping +from typing import TYPE_CHECKING from beartype import beartype from mock_vws._database_matchers import get_database_matching_server_keys from mock_vws._services_validators.exceptions import UnknownTargetError -from mock_vws.database import VuforiaDatabase + +if TYPE_CHECKING: + from collections.abc import Iterable, Mapping + + from mock_vws.database import VuforiaDatabase _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/database.py b/src/mock_vws/database.py index 2e28a9f61..342b9a164 100644 --- a/src/mock_vws/database.py +++ b/src/mock_vws/database.py @@ -1,9 +1,8 @@ """Utilities for managing mock Vuforia databases.""" import uuid -from collections.abc import Iterable from dataclasses import dataclass, field -from typing import Self, TypedDict +from typing import TYPE_CHECKING, Self, TypedDict from beartype import beartype @@ -11,6 +10,9 @@ from mock_vws.states import States from mock_vws.target import Target, TargetDict +if TYPE_CHECKING: + from collections.abc import Iterable + @beartype class DatabaseDict(TypedDict): diff --git a/src/mock_vws/target_manager.py b/src/mock_vws/target_manager.py index 8042f588e..b4daa2e0a 100644 --- a/src/mock_vws/target_manager.py +++ b/src/mock_vws/target_manager.py @@ -4,11 +4,11 @@ from beartype import beartype -from mock_vws.database import VuforiaDatabase - if TYPE_CHECKING: from collections.abc import Iterable + from mock_vws.database import VuforiaDatabase + @beartype class TargetManager: diff --git a/tests/conftest.py b/tests/conftest.py index 64ef1427f..e4d740490 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,14 +2,17 @@ import base64 import binascii -import io import uuid +from typing import TYPE_CHECKING import pytest from vws import VWS, CloudRecoService -from mock_vws.database import VuforiaDatabase -from tests.mock_vws.utils import Endpoint +if TYPE_CHECKING: + import io + + from mock_vws.database import VuforiaDatabase + from tests.mock_vws.utils import Endpoint pytest_plugins = [ "tests.mock_vws.fixtures.prepared_requests", diff --git a/tests/mock_vws/fixtures/prepared_requests.py b/tests/mock_vws/fixtures/prepared_requests.py index 6a1d93aa8..8372f320d 100644 --- a/tests/mock_vws/fixtures/prepared_requests.py +++ b/tests/mock_vws/fixtures/prepared_requests.py @@ -1,21 +1,25 @@ """Fixtures which prepare requests.""" import base64 -import io import json from http import HTTPMethod, HTTPStatus -from typing import Any +from typing import TYPE_CHECKING, Any import pytest from urllib3.filepost import encode_multipart_formdata -from vws import VWS from vws_auth_tools import authorization_header, rfc_1123_date from mock_vws._constants import ResultCodes -from mock_vws.database import VuforiaDatabase from tests.mock_vws.utils import Endpoint from tests.mock_vws.utils.retries import RETRY_ON_TOO_MANY_REQUESTS +if TYPE_CHECKING: + import io + + from vws import VWS + + from mock_vws.database import VuforiaDatabase + VWS_HOST = "https://vws.vuforia.com" VWQ_HOST = "https://cloudreco.vuforia.com" diff --git a/tests/mock_vws/fixtures/vuforia_backends.py b/tests/mock_vws/fixtures/vuforia_backends.py index 39013b5b9..a2022304e 100644 --- a/tests/mock_vws/fixtures/vuforia_backends.py +++ b/tests/mock_vws/fixtures/vuforia_backends.py @@ -2,8 +2,8 @@ import contextlib import logging -from collections.abc import Generator from enum import Enum +from typing import TYPE_CHECKING import pytest import requests @@ -23,6 +23,9 @@ from mock_vws.states import States from tests.mock_vws.utils.retries import RETRY_ON_TOO_MANY_REQUESTS +if TYPE_CHECKING: + from collections.abc import Generator + LOGGER = logging.getLogger(name=__name__) LOGGER.setLevel(level=logging.DEBUG) diff --git a/tests/mock_vws/test_add_target.py b/tests/mock_vws/test_add_target.py index d732dc94f..f51ffc1b5 100644 --- a/tests/mock_vws/test_add_target.py +++ b/tests/mock_vws/test_add_target.py @@ -5,11 +5,10 @@ import json from http import HTTPMethod, HTTPStatus from string import hexdigits -from typing import Any, Final +from typing import TYPE_CHECKING, Any, Final import pytest from beartype import beartype -from vws import VWS from vws.exceptions.custom_exceptions import ( ServerError, ) @@ -22,7 +21,6 @@ ProjectInactiveError, TargetNameExistError, ) -from vws.response import Response from mock_vws._constants import ResultCodes from tests.mock_vws.utils import make_image_file @@ -31,6 +29,10 @@ assert_vws_response, ) +if TYPE_CHECKING: + from vws import VWS + from vws.response import Response + _MAX_METADATA_BYTES: Final[int] = 1024 * 1024 - 1 diff --git a/tests/mock_vws/test_authorization_header.py b/tests/mock_vws/test_authorization_header.py index c017c41ad..868fea3f6 100644 --- a/tests/mock_vws/test_authorization_header.py +++ b/tests/mock_vws/test_authorization_header.py @@ -1,9 +1,9 @@ """Tests for the `Authorization` header.""" -import io import json import uuid from http import HTTPStatus +from typing import TYPE_CHECKING from urllib.parse import urlparse import pytest @@ -13,7 +13,6 @@ from vws_auth_tools import rfc_1123_date from mock_vws._constants import ResultCodes -from mock_vws.database import VuforiaDatabase from tests.mock_vws.utils import Endpoint from tests.mock_vws.utils.assertions import ( assert_valid_transaction_id, @@ -22,6 +21,11 @@ ) from tests.mock_vws.utils.too_many_requests import handle_server_errors +if TYPE_CHECKING: + import io + + from mock_vws.database import VuforiaDatabase + @pytest.mark.usefixtures("verify_mock_vuforia") class TestAuthorizationHeader: diff --git a/tests/mock_vws/test_database_summary.py b/tests/mock_vws/test_database_summary.py index e0220319f..e3cf49121 100644 --- a/tests/mock_vws/test_database_summary.py +++ b/tests/mock_vws/test_database_summary.py @@ -1,9 +1,9 @@ """Tests for the mock of the database summary endpoint.""" -import io import logging import uuid from http import HTTPStatus +from typing import TYPE_CHECKING import pytest from beartype import beartype @@ -17,6 +17,9 @@ from mock_vws import MockVWS from mock_vws.database import VuforiaDatabase +if TYPE_CHECKING: + import io + LOGGER = logging.getLogger(name=__name__) LOGGER.setLevel(level=logging.DEBUG) diff --git a/tests/mock_vws/test_delete_target.py b/tests/mock_vws/test_delete_target.py index 9c3f68d1e..bfeb4ed5b 100644 --- a/tests/mock_vws/test_delete_target.py +++ b/tests/mock_vws/test_delete_target.py @@ -1,9 +1,9 @@ """Tests for deleting targets.""" from http import HTTPStatus +from typing import TYPE_CHECKING import pytest -from vws import VWS from vws.exceptions.vws_exceptions import ( ProjectInactiveError, TargetStatusProcessingError, @@ -13,6 +13,9 @@ from mock_vws._constants import ResultCodes from tests.mock_vws.utils.assertions import assert_vws_failure +if TYPE_CHECKING: + from vws import VWS + @pytest.mark.usefixtures("verify_mock_vuforia") class TestDelete: diff --git a/tests/mock_vws/test_docker.py b/tests/mock_vws/test_docker.py index 0484cb253..0ad24a9bc 100644 --- a/tests/mock_vws/test_docker.py +++ b/tests/mock_vws/test_docker.py @@ -1,8 +1,6 @@ """Tests for running the mock server in Docker.""" -import io import uuid -from collections.abc import Iterable, Iterator from http import HTTPStatus from typing import TYPE_CHECKING @@ -11,8 +9,6 @@ import requests from beartype import beartype from docker.errors import BuildError, NotFound -from docker.models.containers import Container -from docker.models.networks import Network from tenacity import retry from tenacity.retry import retry_if_exception_type from tenacity.stop import stop_after_delay @@ -22,7 +18,12 @@ from mock_vws.database import VuforiaDatabase if TYPE_CHECKING: + import io + from collections.abc import Iterable, Iterator + + from docker.models.containers import Container from docker.models.images import Image + from docker.models.networks import Network @retry( diff --git a/tests/mock_vws/test_flask_app_usage.py b/tests/mock_vws/test_flask_app_usage.py index fffd06804..6e8394b41 100644 --- a/tests/mock_vws/test_flask_app_usage.py +++ b/tests/mock_vws/test_flask_app_usage.py @@ -3,8 +3,8 @@ import io import json import uuid -from collections.abc import Iterator from http import HTTPStatus +from typing import TYPE_CHECKING import pytest import requests @@ -21,6 +21,9 @@ processing_time_seconds, ) +if TYPE_CHECKING: + from collections.abc import Iterator + _EXAMPLE_URL_FOR_TARGET_MANAGER = "http://" + uuid.uuid4().hex + ".com" diff --git a/tests/mock_vws/test_get_duplicates.py b/tests/mock_vws/test_get_duplicates.py index 5634e8737..9f326a94c 100644 --- a/tests/mock_vws/test_get_duplicates.py +++ b/tests/mock_vws/test_get_duplicates.py @@ -3,13 +3,16 @@ import copy import io import uuid +from typing import TYPE_CHECKING import pytest from PIL import Image -from vws import VWS from vws.exceptions.vws_exceptions import ProjectInactiveError from vws.reports import TargetStatuses +if TYPE_CHECKING: + from vws import VWS + @pytest.mark.usefixtures("verify_mock_vuforia") class TestDuplicates: diff --git a/tests/mock_vws/test_get_target.py b/tests/mock_vws/test_get_target.py index e0d22f634..a545273ae 100644 --- a/tests/mock_vws/test_get_target.py +++ b/tests/mock_vws/test_get_target.py @@ -3,14 +3,18 @@ https://developer.vuforia.com/library/web-api/cloud-targets-web-services-api#target-record """ -import io import uuid +from typing import TYPE_CHECKING import pytest -from vws import VWS from vws.exceptions.vws_exceptions import UnknownTargetError from vws.reports import TargetRecord, TargetStatuses +if TYPE_CHECKING: + import io + + from vws import VWS + @pytest.mark.usefixtures("verify_mock_vuforia") class TestGetRecord: diff --git a/tests/mock_vws/test_invalid_given_id.py b/tests/mock_vws/test_invalid_given_id.py index 067867f75..beceedef3 100644 --- a/tests/mock_vws/test_invalid_given_id.py +++ b/tests/mock_vws/test_invalid_given_id.py @@ -5,15 +5,19 @@ """ from http import HTTPStatus +from typing import TYPE_CHECKING import pytest -from vws import VWS from mock_vws._constants import ResultCodes -from tests.mock_vws.utils import Endpoint from tests.mock_vws.utils.assertions import assert_vws_failure from tests.mock_vws.utils.too_many_requests import handle_server_errors +if TYPE_CHECKING: + from vws import VWS + + from tests.mock_vws.utils import Endpoint + @pytest.mark.usefixtures("verify_mock_vuforia") class TestInvalidGivenID: diff --git a/tests/mock_vws/test_query.py b/tests/mock_vws/test_query.py index 49151ccdb..51f8109cd 100644 --- a/tests/mock_vws/test_query.py +++ b/tests/mock_vws/test_query.py @@ -26,7 +26,6 @@ from tenacity.stop import stop_after_delay from tenacity.wait import wait_fixed from urllib3.filepost import encode_multipart_formdata -from vws import VWS, CloudRecoService from vws.exceptions.cloud_reco_exceptions import ( BadImageError, InactiveProjectError, @@ -37,7 +36,6 @@ from vws.response import Response from vws_auth_tools import authorization_header, rfc_1123_date -from mock_vws.database import VuforiaDatabase from tests.mock_vws.utils import make_image_file from tests.mock_vws.utils.assertions import ( assert_query_success, @@ -49,6 +47,10 @@ if TYPE_CHECKING: from collections.abc import Iterable + from vws import VWS, CloudRecoService + + from mock_vws.database import VuforiaDatabase + VWQ_HOST = "https://cloudreco.vuforia.com" _JETTY_CONTENT_TYPE_ERROR = textwrap.dedent( diff --git a/tests/mock_vws/test_target_list.py b/tests/mock_vws/test_target_list.py index b83db3dfd..2c21960cb 100644 --- a/tests/mock_vws/test_target_list.py +++ b/tests/mock_vws/test_target_list.py @@ -1,7 +1,11 @@ """Tests for the mock of the target list endpoint.""" +from typing import TYPE_CHECKING + import pytest -from vws import VWS + +if TYPE_CHECKING: + from vws import VWS @pytest.mark.usefixtures("verify_mock_vuforia") diff --git a/tests/mock_vws/test_target_raters.py b/tests/mock_vws/test_target_raters.py index 27dbc8cb4..b0541d51b 100644 --- a/tests/mock_vws/test_target_raters.py +++ b/tests/mock_vws/test_target_raters.py @@ -1,6 +1,6 @@ """Tests for target quality raters.""" -import io +from typing import TYPE_CHECKING import pytest @@ -10,6 +10,9 @@ RandomTargetTrackingRater, ) +if TYPE_CHECKING: + import io + def test_random_target_tracking_rater() -> None: """ diff --git a/tests/mock_vws/test_target_summary.py b/tests/mock_vws/test_target_summary.py index 61fbd76ce..531b76a75 100644 --- a/tests/mock_vws/test_target_summary.py +++ b/tests/mock_vws/test_target_summary.py @@ -1,16 +1,20 @@ """Tests for the mock of the target summary endpoint.""" import datetime -import io import uuid +from typing import TYPE_CHECKING from zoneinfo import ZoneInfo import pytest -from vws import VWS, CloudRecoService from vws.exceptions.vws_exceptions import UnknownTargetError from vws.reports import TargetStatuses -from mock_vws.database import VuforiaDatabase +if TYPE_CHECKING: + import io + + from vws import VWS, CloudRecoService + + from mock_vws.database import VuforiaDatabase @pytest.mark.usefixtures("verify_mock_vuforia") diff --git a/tests/mock_vws/test_update_target.py b/tests/mock_vws/test_update_target.py index 1dddaffcc..82a1ac072 100644 --- a/tests/mock_vws/test_update_target.py +++ b/tests/mock_vws/test_update_target.py @@ -5,10 +5,9 @@ import json import uuid from http import HTTPMethod, HTTPStatus -from typing import Any, Final +from typing import TYPE_CHECKING, Any, Final import pytest -from vws import VWS from vws.exceptions.base_exceptions import VWSError from vws.exceptions.vws_exceptions import ( AuthenticationFailureError, @@ -21,7 +20,6 @@ TargetStatusNotSuccessError, ) from vws.reports import TargetStatuses -from vws.response import Response from mock_vws._constants import ResultCodes from tests.mock_vws.utils import make_image_file @@ -30,6 +28,10 @@ assert_vws_response, ) +if TYPE_CHECKING: + from vws import VWS + from vws.response import Response + _MAX_METADATA_BYTES: Final[int] = 1024 * 1024 - 1 diff --git a/tests/mock_vws/utils/__init__.py b/tests/mock_vws/utils/__init__.py index c554e4571..1f797659a 100644 --- a/tests/mock_vws/utils/__init__.py +++ b/tests/mock_vws/utils/__init__.py @@ -2,9 +2,8 @@ import io import secrets -from collections.abc import Mapping from dataclasses import dataclass -from typing import Literal +from typing import TYPE_CHECKING, Literal from urllib.parse import urljoin import requests @@ -12,7 +11,10 @@ from requests.structures import CaseInsensitiveDict from vws.response import Response -from mock_vws._constants import ResultCodes +if TYPE_CHECKING: + from collections.abc import Mapping + + from mock_vws._constants import ResultCodes @dataclass(frozen=True) diff --git a/tests/mock_vws/utils/assertions.py b/tests/mock_vws/utils/assertions.py index e026fed02..1aa9cadf0 100644 --- a/tests/mock_vws/utils/assertions.py +++ b/tests/mock_vws/utils/assertions.py @@ -6,12 +6,15 @@ import json from http import HTTPStatus from string import hexdigits +from typing import TYPE_CHECKING from zoneinfo import ZoneInfo from beartype import beartype -from vws.response import Response -from mock_vws._constants import ResultCodes +if TYPE_CHECKING: + from vws.response import Response + + from mock_vws._constants import ResultCodes @beartype diff --git a/tests/mock_vws/utils/too_many_requests.py b/tests/mock_vws/utils/too_many_requests.py index c35cb54d1..5be8559d7 100644 --- a/tests/mock_vws/utils/too_many_requests.py +++ b/tests/mock_vws/utils/too_many_requests.py @@ -1,11 +1,14 @@ """Helpers for handling too many requests errors.""" from http import HTTPStatus +from typing import TYPE_CHECKING from beartype import beartype from vws.exceptions.custom_exceptions import ServerError from vws.exceptions.vws_exceptions import TooManyRequestsError -from vws.response import Response + +if TYPE_CHECKING: + from vws.response import Response @beartype diff --git a/tests/mock_vws/utils/usage_test_helpers.py b/tests/mock_vws/utils/usage_test_helpers.py index 6c85dc0f6..c5bc94762 100644 --- a/tests/mock_vws/utils/usage_test_helpers.py +++ b/tests/mock_vws/utils/usage_test_helpers.py @@ -1,12 +1,15 @@ """Helpers for testing the usage of the mocks.""" import datetime -import io +from typing import TYPE_CHECKING from vws import VWS from vws.reports import TargetStatuses -from mock_vws.database import VuforiaDatabase +if TYPE_CHECKING: + import io + + from mock_vws.database import VuforiaDatabase def processing_time_seconds( From 6276f378b4fcf3ea73fc1b7b31d0fe82efb090a3 Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Wed, 28 Jan 2026 08:11:22 +0000 Subject: [PATCH 08/10] Revert "Fix ruff" This reverts commit 9a342f4fca65057fed2911553986affd84f92d0d. --- ci/test_custom_linters.py | 2 +- src/mock_vws/_database_matchers.py | 7 ++----- src/mock_vws/_mock_common.py | 6 ++---- src/mock_vws/_query_tools.py | 11 ++++------- src/mock_vws/_query_validators/__init__.py | 9 +++------ .../_query_validators/accept_header_validators.py | 5 +---- src/mock_vws/_query_validators/auth_validators.py | 8 ++------ .../_query_validators/content_length_validators.py | 5 +---- .../_query_validators/content_type_validators.py | 5 +---- src/mock_vws/_query_validators/date_validators.py | 5 +---- src/mock_vws/_query_validators/exceptions.py | 5 +---- src/mock_vws/_query_validators/fields_validators.py | 5 +---- src/mock_vws/_query_validators/image_validators.py | 5 +---- .../include_target_data_validators.py | 5 +---- .../_query_validators/num_results_validators.py | 5 +---- .../_query_validators/project_state_validators.py | 8 ++------ src/mock_vws/_requests_mock_server/decorators.py | 3 +-- .../_requests_mock_server/mock_web_query_api.py | 11 ++++------- .../_requests_mock_server/mock_web_services_api.py | 13 +++++-------- src/mock_vws/_services_validators/__init__.py | 9 +++------ .../_services_validators/auth_validators.py | 8 ++------ .../content_length_validators.py | 5 +---- .../_services_validators/content_type_validators.py | 5 +---- .../_services_validators/date_validators.py | 5 +---- src/mock_vws/_services_validators/exceptions.py | 5 +---- src/mock_vws/_services_validators/key_validators.py | 5 +---- .../_services_validators/name_validators.py | 8 ++------ .../project_state_validators.py | 8 ++------ .../_services_validators/target_validators.py | 8 ++------ src/mock_vws/database.py | 6 ++---- src/mock_vws/target_manager.py | 4 ++-- tests/conftest.py | 9 +++------ tests/mock_vws/fixtures/prepared_requests.py | 12 ++++-------- tests/mock_vws/fixtures/vuforia_backends.py | 5 +---- tests/mock_vws/test_add_target.py | 8 +++----- tests/mock_vws/test_authorization_header.py | 8 ++------ tests/mock_vws/test_database_summary.py | 5 +---- tests/mock_vws/test_delete_target.py | 5 +---- tests/mock_vws/test_docker.py | 9 ++++----- tests/mock_vws/test_flask_app_usage.py | 5 +---- tests/mock_vws/test_get_duplicates.py | 5 +---- tests/mock_vws/test_get_target.py | 8 ++------ tests/mock_vws/test_invalid_given_id.py | 8 ++------ tests/mock_vws/test_query.py | 6 ++---- tests/mock_vws/test_target_list.py | 6 +----- tests/mock_vws/test_target_raters.py | 5 +---- tests/mock_vws/test_target_summary.py | 10 +++------- tests/mock_vws/test_update_target.py | 8 +++----- tests/mock_vws/utils/__init__.py | 8 +++----- tests/mock_vws/utils/assertions.py | 7 ++----- tests/mock_vws/utils/too_many_requests.py | 5 +---- tests/mock_vws/utils/usage_test_helpers.py | 7 ++----- 52 files changed, 98 insertions(+), 250 deletions(-) diff --git a/ci/test_custom_linters.py b/ci/test_custom_linters.py index ed3683f61..c25260b46 100644 --- a/ci/test_custom_linters.py +++ b/ci/test_custom_linters.py @@ -1,5 +1,6 @@ """Custom lint tests.""" +from pathlib import Path from typing import TYPE_CHECKING import pytest @@ -8,7 +9,6 @@ if TYPE_CHECKING: from collections.abc import Iterable - from pathlib import Path @beartype diff --git a/src/mock_vws/_database_matchers.py b/src/mock_vws/_database_matchers.py index 6995fe6f0..899cf71b2 100644 --- a/src/mock_vws/_database_matchers.py +++ b/src/mock_vws/_database_matchers.py @@ -1,14 +1,11 @@ """Helpers for getting databases which match keys given in requests.""" -from typing import TYPE_CHECKING +from collections.abc import Iterable, Mapping from beartype import beartype from vws_auth_tools import authorization_header -if TYPE_CHECKING: - from collections.abc import Iterable, Mapping - - from mock_vws.database import VuforiaDatabase +from mock_vws.database import VuforiaDatabase @beartype diff --git a/src/mock_vws/_mock_common.py b/src/mock_vws/_mock_common.py index 8b7c1c347..0ebbd379b 100644 --- a/src/mock_vws/_mock_common.py +++ b/src/mock_vws/_mock_common.py @@ -1,14 +1,12 @@ """Common utilities for creating mock routes.""" import json +from collections.abc import Iterable from dataclasses import dataclass -from typing import TYPE_CHECKING, Any +from typing import Any from beartype import beartype -if TYPE_CHECKING: - from collections.abc import Iterable - @dataclass(frozen=True) class Route: diff --git a/src/mock_vws/_query_tools.py b/src/mock_vws/_query_tools.py index 47cb3f6e0..b73f6c616 100644 --- a/src/mock_vws/_query_tools.py +++ b/src/mock_vws/_query_tools.py @@ -3,8 +3,9 @@ import base64 import io import uuid +from collections.abc import Iterable, Mapping from email.message import EmailMessage -from typing import TYPE_CHECKING, Any +from typing import Any from beartype import beartype from werkzeug.formparser import MultiPartParser @@ -13,12 +14,8 @@ from mock_vws._constants import ResultCodes, TargetStatuses from mock_vws._database_matchers import get_database_matching_client_keys from mock_vws._mock_common import json_dump - -if TYPE_CHECKING: - from collections.abc import Iterable, Mapping - - from mock_vws.database import VuforiaDatabase - from mock_vws.image_matchers import ImageMatcher +from mock_vws.database import VuforiaDatabase +from mock_vws.image_matchers import ImageMatcher @beartype diff --git a/src/mock_vws/_query_validators/__init__.py b/src/mock_vws/_query_validators/__init__.py index 51c9b9002..54e458e80 100644 --- a/src/mock_vws/_query_validators/__init__.py +++ b/src/mock_vws/_query_validators/__init__.py @@ -1,9 +1,11 @@ """Input validators to use in the mock query API.""" -from typing import TYPE_CHECKING +from collections.abc import Iterable, Mapping from beartype import beartype +from mock_vws.database import VuforiaDatabase + from .accept_header_validators import validate_accept_header from .auth_validators import ( validate_auth_header_exists, @@ -35,11 +37,6 @@ from .num_results_validators import validate_max_num_results from .project_state_validators import validate_project_state -if TYPE_CHECKING: - from collections.abc import Iterable, Mapping - - from mock_vws.database import VuforiaDatabase - @beartype def run_query_validators( diff --git a/src/mock_vws/_query_validators/accept_header_validators.py b/src/mock_vws/_query_validators/accept_header_validators.py index 5322d975e..fe3e966f6 100644 --- a/src/mock_vws/_query_validators/accept_header_validators.py +++ b/src/mock_vws/_query_validators/accept_header_validators.py @@ -1,15 +1,12 @@ """Validators for the ``Accept`` header.""" import logging -from typing import TYPE_CHECKING +from collections.abc import Mapping from beartype import beartype from mock_vws._query_validators.exceptions import InvalidAcceptHeaderError -if TYPE_CHECKING: - from collections.abc import Mapping - _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_query_validators/auth_validators.py b/src/mock_vws/_query_validators/auth_validators.py index 0d7b031a6..a90273909 100644 --- a/src/mock_vws/_query_validators/auth_validators.py +++ b/src/mock_vws/_query_validators/auth_validators.py @@ -1,7 +1,7 @@ """Authorization validators to use in the mock query API.""" import logging -from typing import TYPE_CHECKING +from collections.abc import Iterable, Mapping from beartype import beartype @@ -11,11 +11,7 @@ AuthHeaderMissingError, MalformedAuthHeaderError, ) - -if TYPE_CHECKING: - from collections.abc import Iterable, Mapping - - from mock_vws.database import VuforiaDatabase +from mock_vws.database import VuforiaDatabase _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_query_validators/content_length_validators.py b/src/mock_vws/_query_validators/content_length_validators.py index 8282ee5ae..4cb799fb5 100644 --- a/src/mock_vws/_query_validators/content_length_validators.py +++ b/src/mock_vws/_query_validators/content_length_validators.py @@ -1,7 +1,7 @@ """Content-Length header validators to use in the mock.""" import logging -from typing import TYPE_CHECKING +from collections.abc import Mapping from beartype import beartype @@ -11,9 +11,6 @@ ContentLengthHeaderTooLargeError, ) -if TYPE_CHECKING: - from collections.abc import Mapping - _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_query_validators/content_type_validators.py b/src/mock_vws/_query_validators/content_type_validators.py index d72306f3a..3e7dc4792 100644 --- a/src/mock_vws/_query_validators/content_type_validators.py +++ b/src/mock_vws/_query_validators/content_type_validators.py @@ -1,8 +1,8 @@ """Validators for the ``Content-Type`` header.""" import logging +from collections.abc import Mapping from email.message import EmailMessage -from typing import TYPE_CHECKING from beartype import beartype @@ -13,9 +13,6 @@ UnsupportedMediaTypeError, ) -if TYPE_CHECKING: - from collections.abc import Mapping - _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_query_validators/date_validators.py b/src/mock_vws/_query_validators/date_validators.py index 24186f8b2..4151b0d31 100644 --- a/src/mock_vws/_query_validators/date_validators.py +++ b/src/mock_vws/_query_validators/date_validators.py @@ -3,7 +3,7 @@ import contextlib import datetime import logging -from typing import TYPE_CHECKING +from collections.abc import Mapping from zoneinfo import ZoneInfo from beartype import beartype @@ -14,9 +14,6 @@ RequestTimeTooSkewedError, ) -if TYPE_CHECKING: - from collections.abc import Mapping - _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_query_validators/exceptions.py b/src/mock_vws/_query_validators/exceptions.py index 528356a2c..6417595f4 100644 --- a/src/mock_vws/_query_validators/exceptions.py +++ b/src/mock_vws/_query_validators/exceptions.py @@ -3,17 +3,14 @@ import email.utils import textwrap import uuid +from collections.abc import Mapping from http import HTTPStatus -from typing import TYPE_CHECKING from beartype import beartype from mock_vws._constants import ResultCodes from mock_vws._mock_common import json_dump -if TYPE_CHECKING: - from collections.abc import Mapping - @beartype class ValidatorError(Exception): diff --git a/src/mock_vws/_query_validators/fields_validators.py b/src/mock_vws/_query_validators/fields_validators.py index ae41f3bf8..b9e78fecd 100644 --- a/src/mock_vws/_query_validators/fields_validators.py +++ b/src/mock_vws/_query_validators/fields_validators.py @@ -2,17 +2,14 @@ import io import logging +from collections.abc import Mapping from email.message import EmailMessage -from typing import TYPE_CHECKING from beartype import beartype from werkzeug.formparser import MultiPartParser from mock_vws._query_validators.exceptions import UnknownParametersError -if TYPE_CHECKING: - from collections.abc import Mapping - _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_query_validators/image_validators.py b/src/mock_vws/_query_validators/image_validators.py index c68a0943b..827c636d2 100644 --- a/src/mock_vws/_query_validators/image_validators.py +++ b/src/mock_vws/_query_validators/image_validators.py @@ -2,8 +2,8 @@ import io import logging +from collections.abc import Mapping from email.message import EmailMessage -from typing import TYPE_CHECKING from beartype import beartype from PIL import Image @@ -15,9 +15,6 @@ RequestEntityTooLargeError, ) -if TYPE_CHECKING: - from collections.abc import Mapping - _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_query_validators/include_target_data_validators.py b/src/mock_vws/_query_validators/include_target_data_validators.py index eff2bfe6b..b3719aad8 100644 --- a/src/mock_vws/_query_validators/include_target_data_validators.py +++ b/src/mock_vws/_query_validators/include_target_data_validators.py @@ -2,17 +2,14 @@ import io import logging +from collections.abc import Mapping from email.message import EmailMessage -from typing import TYPE_CHECKING from beartype import beartype from werkzeug.formparser import MultiPartParser from mock_vws._query_validators.exceptions import InvalidIncludeTargetDataError -if TYPE_CHECKING: - from collections.abc import Mapping - _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_query_validators/num_results_validators.py b/src/mock_vws/_query_validators/num_results_validators.py index 2d44141f4..31ead620b 100644 --- a/src/mock_vws/_query_validators/num_results_validators.py +++ b/src/mock_vws/_query_validators/num_results_validators.py @@ -2,8 +2,8 @@ import io import logging +from collections.abc import Mapping from email.message import EmailMessage -from typing import TYPE_CHECKING from beartype import beartype from werkzeug.formparser import MultiPartParser @@ -13,9 +13,6 @@ MaxNumResultsOutOfRangeError, ) -if TYPE_CHECKING: - from collections.abc import Mapping - _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_query_validators/project_state_validators.py b/src/mock_vws/_query_validators/project_state_validators.py index a424927f9..5a3517bde 100644 --- a/src/mock_vws/_query_validators/project_state_validators.py +++ b/src/mock_vws/_query_validators/project_state_validators.py @@ -1,19 +1,15 @@ """Validators for the project state.""" import logging -from typing import TYPE_CHECKING +from collections.abc import Iterable, Mapping from beartype import beartype from mock_vws._database_matchers import get_database_matching_client_keys from mock_vws._query_validators.exceptions import InactiveProjectError +from mock_vws.database import VuforiaDatabase from mock_vws.states import States -if TYPE_CHECKING: - from collections.abc import Iterable, Mapping - - from mock_vws.database import VuforiaDatabase - _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_requests_mock_server/decorators.py b/src/mock_vws/_requests_mock_server/decorators.py index dcbeadc22..6572d593d 100644 --- a/src/mock_vws/_requests_mock_server/decorators.py +++ b/src/mock_vws/_requests_mock_server/decorators.py @@ -8,6 +8,7 @@ from beartype import BeartypeConf, beartype from responses import RequestsMock +from mock_vws.database import VuforiaDatabase from mock_vws.image_matchers import ( ImageMatcher, StructuralSimilarityMatcher, @@ -24,8 +25,6 @@ if TYPE_CHECKING: from collections.abc import Iterable - from mock_vws.database import VuforiaDatabase - _STRUCTURAL_SIMILARITY_MATCHER = StructuralSimilarityMatcher() _BRISQUE_TRACKING_RATER = BrisqueTargetTrackingRater() diff --git a/src/mock_vws/_requests_mock_server/mock_web_query_api.py b/src/mock_vws/_requests_mock_server/mock_web_query_api.py index da28d920b..8206a6d10 100644 --- a/src/mock_vws/_requests_mock_server/mock_web_query_api.py +++ b/src/mock_vws/_requests_mock_server/mock_web_query_api.py @@ -7,9 +7,10 @@ import email.utils from collections.abc import Callable, Iterable, Mapping from http import HTTPMethod, HTTPStatus -from typing import TYPE_CHECKING, ParamSpec, Protocol, runtime_checkable +from typing import ParamSpec, Protocol, runtime_checkable from beartype import beartype +from requests.models import PreparedRequest from mock_vws._mock_common import Route from mock_vws._query_tools import ( @@ -19,12 +20,8 @@ from mock_vws._query_validators.exceptions import ( ValidatorError, ) - -if TYPE_CHECKING: - from requests.models import PreparedRequest - - from mock_vws.image_matchers import ImageMatcher - from mock_vws.target_manager import TargetManager +from mock_vws.image_matchers import ImageMatcher +from mock_vws.target_manager import TargetManager _ROUTES: set[Route] = set() diff --git a/src/mock_vws/_requests_mock_server/mock_web_services_api.py b/src/mock_vws/_requests_mock_server/mock_web_services_api.py index b2a3e78aa..ddee6ef03 100644 --- a/src/mock_vws/_requests_mock_server/mock_web_services_api.py +++ b/src/mock_vws/_requests_mock_server/mock_web_services_api.py @@ -12,10 +12,11 @@ import uuid from collections.abc import Callable, Iterable, Mapping from http import HTTPMethod, HTTPStatus -from typing import TYPE_CHECKING, Any, ParamSpec, Protocol, runtime_checkable +from typing import Any, ParamSpec, Protocol, runtime_checkable from zoneinfo import ZoneInfo from beartype import BeartypeConf, beartype +from requests.models import PreparedRequest from mock_vws._constants import ResultCodes, TargetStatuses from mock_vws._database_matchers import get_database_matching_server_keys @@ -27,14 +28,10 @@ TargetStatusProcessingError, ValidatorError, ) +from mock_vws.image_matchers import ImageMatcher from mock_vws.target import Target - -if TYPE_CHECKING: - from requests.models import PreparedRequest - - from mock_vws.image_matchers import ImageMatcher - from mock_vws.target_manager import TargetManager - from mock_vws.target_raters import TargetTrackingRater +from mock_vws.target_manager import TargetManager +from mock_vws.target_raters import TargetTrackingRater _TARGET_ID_PATTERN = "[A-Za-z0-9]+" diff --git a/src/mock_vws/_services_validators/__init__.py b/src/mock_vws/_services_validators/__init__.py index f3765f451..44487b365 100644 --- a/src/mock_vws/_services_validators/__init__.py +++ b/src/mock_vws/_services_validators/__init__.py @@ -1,6 +1,8 @@ """Input validators to use in the mock.""" -from typing import TYPE_CHECKING +from collections.abc import Iterable, Mapping + +from mock_vws.database import VuforiaDatabase from .active_flag_validators import validate_active_flag from .auth_validators import ( @@ -47,11 +49,6 @@ from .target_validators import validate_target_id_exists from .width_validators import validate_width -if TYPE_CHECKING: - from collections.abc import Iterable, Mapping - - from mock_vws.database import VuforiaDatabase - def run_services_validators( request_path: str, diff --git a/src/mock_vws/_services_validators/auth_validators.py b/src/mock_vws/_services_validators/auth_validators.py index 9e1d8a89e..f47164085 100644 --- a/src/mock_vws/_services_validators/auth_validators.py +++ b/src/mock_vws/_services_validators/auth_validators.py @@ -1,8 +1,8 @@ """Authorization header validators to use in the mock.""" import logging +from collections.abc import Iterable, Mapping from http import HTTPStatus -from typing import TYPE_CHECKING from beartype import beartype @@ -11,11 +11,7 @@ AuthenticationFailureError, FailError, ) - -if TYPE_CHECKING: - from collections.abc import Iterable, Mapping - - from mock_vws.database import VuforiaDatabase +from mock_vws.database import VuforiaDatabase _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_services_validators/content_length_validators.py b/src/mock_vws/_services_validators/content_length_validators.py index 0b41dad79..eaa41b2af 100644 --- a/src/mock_vws/_services_validators/content_length_validators.py +++ b/src/mock_vws/_services_validators/content_length_validators.py @@ -1,7 +1,7 @@ """Content-Length header validators to use in the mock.""" import logging -from typing import TYPE_CHECKING +from collections.abc import Mapping from beartype import beartype @@ -11,9 +11,6 @@ ContentLengthHeaderTooLargeError, ) -if TYPE_CHECKING: - from collections.abc import Mapping - _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_services_validators/content_type_validators.py b/src/mock_vws/_services_validators/content_type_validators.py index 088f26a60..12913fa6f 100644 --- a/src/mock_vws/_services_validators/content_type_validators.py +++ b/src/mock_vws/_services_validators/content_type_validators.py @@ -1,16 +1,13 @@ """Content-Type header validators to use in the mock.""" import logging +from collections.abc import Mapping from http import HTTPMethod -from typing import TYPE_CHECKING from beartype import beartype from mock_vws._services_validators.exceptions import AuthenticationFailureError -if TYPE_CHECKING: - from collections.abc import Mapping - _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_services_validators/date_validators.py b/src/mock_vws/_services_validators/date_validators.py index 2c7e08c7a..f5f773d97 100644 --- a/src/mock_vws/_services_validators/date_validators.py +++ b/src/mock_vws/_services_validators/date_validators.py @@ -2,8 +2,8 @@ import datetime import logging +from collections.abc import Mapping from http import HTTPStatus -from typing import TYPE_CHECKING from zoneinfo import ZoneInfo from beartype import beartype @@ -13,9 +13,6 @@ RequestTimeTooSkewedError, ) -if TYPE_CHECKING: - from collections.abc import Mapping - _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_services_validators/exceptions.py b/src/mock_vws/_services_validators/exceptions.py index 688546eca..4bbc5dab8 100644 --- a/src/mock_vws/_services_validators/exceptions.py +++ b/src/mock_vws/_services_validators/exceptions.py @@ -3,17 +3,14 @@ import email.utils import textwrap import uuid +from collections.abc import Mapping from http import HTTPStatus -from typing import TYPE_CHECKING from beartype import beartype from mock_vws._constants import ResultCodes from mock_vws._mock_common import json_dump -if TYPE_CHECKING: - from collections.abc import Mapping - @beartype class ValidatorError(Exception): diff --git a/src/mock_vws/_services_validators/key_validators.py b/src/mock_vws/_services_validators/key_validators.py index c66e4ee13..b07533fe0 100644 --- a/src/mock_vws/_services_validators/key_validators.py +++ b/src/mock_vws/_services_validators/key_validators.py @@ -3,17 +3,14 @@ import json import logging import re +from collections.abc import Iterable from dataclasses import dataclass from http import HTTPMethod, HTTPStatus -from typing import TYPE_CHECKING from beartype import beartype from .exceptions import FailError -if TYPE_CHECKING: - from collections.abc import Iterable - _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_services_validators/name_validators.py b/src/mock_vws/_services_validators/name_validators.py index 40e066449..37e511931 100644 --- a/src/mock_vws/_services_validators/name_validators.py +++ b/src/mock_vws/_services_validators/name_validators.py @@ -2,8 +2,8 @@ import json import logging +from collections.abc import Iterable, Mapping from http import HTTPMethod, HTTPStatus -from typing import TYPE_CHECKING from beartype import beartype @@ -12,11 +12,7 @@ FailError, TargetNameExistError, ) - -if TYPE_CHECKING: - from collections.abc import Iterable, Mapping - - from mock_vws.database import VuforiaDatabase +from mock_vws.database import VuforiaDatabase _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_services_validators/project_state_validators.py b/src/mock_vws/_services_validators/project_state_validators.py index e16e50206..468e6188a 100644 --- a/src/mock_vws/_services_validators/project_state_validators.py +++ b/src/mock_vws/_services_validators/project_state_validators.py @@ -1,20 +1,16 @@ """Validators for the project state.""" import logging +from collections.abc import Iterable, Mapping from http import HTTPMethod -from typing import TYPE_CHECKING from beartype import beartype from mock_vws._database_matchers import get_database_matching_server_keys from mock_vws._services_validators.exceptions import ProjectInactiveError +from mock_vws.database import VuforiaDatabase from mock_vws.states import States -if TYPE_CHECKING: - from collections.abc import Iterable, Mapping - - from mock_vws.database import VuforiaDatabase - _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/_services_validators/target_validators.py b/src/mock_vws/_services_validators/target_validators.py index 3113e47a4..4dbee04b1 100644 --- a/src/mock_vws/_services_validators/target_validators.py +++ b/src/mock_vws/_services_validators/target_validators.py @@ -1,17 +1,13 @@ """Validators for given target IDs.""" import logging -from typing import TYPE_CHECKING +from collections.abc import Iterable, Mapping from beartype import beartype from mock_vws._database_matchers import get_database_matching_server_keys from mock_vws._services_validators.exceptions import UnknownTargetError - -if TYPE_CHECKING: - from collections.abc import Iterable, Mapping - - from mock_vws.database import VuforiaDatabase +from mock_vws.database import VuforiaDatabase _LOGGER = logging.getLogger(name=__name__) diff --git a/src/mock_vws/database.py b/src/mock_vws/database.py index 342b9a164..2e28a9f61 100644 --- a/src/mock_vws/database.py +++ b/src/mock_vws/database.py @@ -1,8 +1,9 @@ """Utilities for managing mock Vuforia databases.""" import uuid +from collections.abc import Iterable from dataclasses import dataclass, field -from typing import TYPE_CHECKING, Self, TypedDict +from typing import Self, TypedDict from beartype import beartype @@ -10,9 +11,6 @@ from mock_vws.states import States from mock_vws.target import Target, TargetDict -if TYPE_CHECKING: - from collections.abc import Iterable - @beartype class DatabaseDict(TypedDict): diff --git a/src/mock_vws/target_manager.py b/src/mock_vws/target_manager.py index b4daa2e0a..8042f588e 100644 --- a/src/mock_vws/target_manager.py +++ b/src/mock_vws/target_manager.py @@ -4,11 +4,11 @@ from beartype import beartype +from mock_vws.database import VuforiaDatabase + if TYPE_CHECKING: from collections.abc import Iterable - from mock_vws.database import VuforiaDatabase - @beartype class TargetManager: diff --git a/tests/conftest.py b/tests/conftest.py index e4d740490..64ef1427f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,17 +2,14 @@ import base64 import binascii +import io import uuid -from typing import TYPE_CHECKING import pytest from vws import VWS, CloudRecoService -if TYPE_CHECKING: - import io - - from mock_vws.database import VuforiaDatabase - from tests.mock_vws.utils import Endpoint +from mock_vws.database import VuforiaDatabase +from tests.mock_vws.utils import Endpoint pytest_plugins = [ "tests.mock_vws.fixtures.prepared_requests", diff --git a/tests/mock_vws/fixtures/prepared_requests.py b/tests/mock_vws/fixtures/prepared_requests.py index 8372f320d..6a1d93aa8 100644 --- a/tests/mock_vws/fixtures/prepared_requests.py +++ b/tests/mock_vws/fixtures/prepared_requests.py @@ -1,25 +1,21 @@ """Fixtures which prepare requests.""" import base64 +import io import json from http import HTTPMethod, HTTPStatus -from typing import TYPE_CHECKING, Any +from typing import Any import pytest from urllib3.filepost import encode_multipart_formdata +from vws import VWS from vws_auth_tools import authorization_header, rfc_1123_date from mock_vws._constants import ResultCodes +from mock_vws.database import VuforiaDatabase from tests.mock_vws.utils import Endpoint from tests.mock_vws.utils.retries import RETRY_ON_TOO_MANY_REQUESTS -if TYPE_CHECKING: - import io - - from vws import VWS - - from mock_vws.database import VuforiaDatabase - VWS_HOST = "https://vws.vuforia.com" VWQ_HOST = "https://cloudreco.vuforia.com" diff --git a/tests/mock_vws/fixtures/vuforia_backends.py b/tests/mock_vws/fixtures/vuforia_backends.py index a2022304e..39013b5b9 100644 --- a/tests/mock_vws/fixtures/vuforia_backends.py +++ b/tests/mock_vws/fixtures/vuforia_backends.py @@ -2,8 +2,8 @@ import contextlib import logging +from collections.abc import Generator from enum import Enum -from typing import TYPE_CHECKING import pytest import requests @@ -23,9 +23,6 @@ from mock_vws.states import States from tests.mock_vws.utils.retries import RETRY_ON_TOO_MANY_REQUESTS -if TYPE_CHECKING: - from collections.abc import Generator - LOGGER = logging.getLogger(name=__name__) LOGGER.setLevel(level=logging.DEBUG) diff --git a/tests/mock_vws/test_add_target.py b/tests/mock_vws/test_add_target.py index f51ffc1b5..d732dc94f 100644 --- a/tests/mock_vws/test_add_target.py +++ b/tests/mock_vws/test_add_target.py @@ -5,10 +5,11 @@ import json from http import HTTPMethod, HTTPStatus from string import hexdigits -from typing import TYPE_CHECKING, Any, Final +from typing import Any, Final import pytest from beartype import beartype +from vws import VWS from vws.exceptions.custom_exceptions import ( ServerError, ) @@ -21,6 +22,7 @@ ProjectInactiveError, TargetNameExistError, ) +from vws.response import Response from mock_vws._constants import ResultCodes from tests.mock_vws.utils import make_image_file @@ -29,10 +31,6 @@ assert_vws_response, ) -if TYPE_CHECKING: - from vws import VWS - from vws.response import Response - _MAX_METADATA_BYTES: Final[int] = 1024 * 1024 - 1 diff --git a/tests/mock_vws/test_authorization_header.py b/tests/mock_vws/test_authorization_header.py index 868fea3f6..c017c41ad 100644 --- a/tests/mock_vws/test_authorization_header.py +++ b/tests/mock_vws/test_authorization_header.py @@ -1,9 +1,9 @@ """Tests for the `Authorization` header.""" +import io import json import uuid from http import HTTPStatus -from typing import TYPE_CHECKING from urllib.parse import urlparse import pytest @@ -13,6 +13,7 @@ from vws_auth_tools import rfc_1123_date from mock_vws._constants import ResultCodes +from mock_vws.database import VuforiaDatabase from tests.mock_vws.utils import Endpoint from tests.mock_vws.utils.assertions import ( assert_valid_transaction_id, @@ -21,11 +22,6 @@ ) from tests.mock_vws.utils.too_many_requests import handle_server_errors -if TYPE_CHECKING: - import io - - from mock_vws.database import VuforiaDatabase - @pytest.mark.usefixtures("verify_mock_vuforia") class TestAuthorizationHeader: diff --git a/tests/mock_vws/test_database_summary.py b/tests/mock_vws/test_database_summary.py index e3cf49121..e0220319f 100644 --- a/tests/mock_vws/test_database_summary.py +++ b/tests/mock_vws/test_database_summary.py @@ -1,9 +1,9 @@ """Tests for the mock of the database summary endpoint.""" +import io import logging import uuid from http import HTTPStatus -from typing import TYPE_CHECKING import pytest from beartype import beartype @@ -17,9 +17,6 @@ from mock_vws import MockVWS from mock_vws.database import VuforiaDatabase -if TYPE_CHECKING: - import io - LOGGER = logging.getLogger(name=__name__) LOGGER.setLevel(level=logging.DEBUG) diff --git a/tests/mock_vws/test_delete_target.py b/tests/mock_vws/test_delete_target.py index bfeb4ed5b..9c3f68d1e 100644 --- a/tests/mock_vws/test_delete_target.py +++ b/tests/mock_vws/test_delete_target.py @@ -1,9 +1,9 @@ """Tests for deleting targets.""" from http import HTTPStatus -from typing import TYPE_CHECKING import pytest +from vws import VWS from vws.exceptions.vws_exceptions import ( ProjectInactiveError, TargetStatusProcessingError, @@ -13,9 +13,6 @@ from mock_vws._constants import ResultCodes from tests.mock_vws.utils.assertions import assert_vws_failure -if TYPE_CHECKING: - from vws import VWS - @pytest.mark.usefixtures("verify_mock_vuforia") class TestDelete: diff --git a/tests/mock_vws/test_docker.py b/tests/mock_vws/test_docker.py index 0ad24a9bc..0484cb253 100644 --- a/tests/mock_vws/test_docker.py +++ b/tests/mock_vws/test_docker.py @@ -1,6 +1,8 @@ """Tests for running the mock server in Docker.""" +import io import uuid +from collections.abc import Iterable, Iterator from http import HTTPStatus from typing import TYPE_CHECKING @@ -9,6 +11,8 @@ import requests from beartype import beartype from docker.errors import BuildError, NotFound +from docker.models.containers import Container +from docker.models.networks import Network from tenacity import retry from tenacity.retry import retry_if_exception_type from tenacity.stop import stop_after_delay @@ -18,12 +22,7 @@ from mock_vws.database import VuforiaDatabase if TYPE_CHECKING: - import io - from collections.abc import Iterable, Iterator - - from docker.models.containers import Container from docker.models.images import Image - from docker.models.networks import Network @retry( diff --git a/tests/mock_vws/test_flask_app_usage.py b/tests/mock_vws/test_flask_app_usage.py index 6e8394b41..fffd06804 100644 --- a/tests/mock_vws/test_flask_app_usage.py +++ b/tests/mock_vws/test_flask_app_usage.py @@ -3,8 +3,8 @@ import io import json import uuid +from collections.abc import Iterator from http import HTTPStatus -from typing import TYPE_CHECKING import pytest import requests @@ -21,9 +21,6 @@ processing_time_seconds, ) -if TYPE_CHECKING: - from collections.abc import Iterator - _EXAMPLE_URL_FOR_TARGET_MANAGER = "http://" + uuid.uuid4().hex + ".com" diff --git a/tests/mock_vws/test_get_duplicates.py b/tests/mock_vws/test_get_duplicates.py index 9f326a94c..5634e8737 100644 --- a/tests/mock_vws/test_get_duplicates.py +++ b/tests/mock_vws/test_get_duplicates.py @@ -3,16 +3,13 @@ import copy import io import uuid -from typing import TYPE_CHECKING import pytest from PIL import Image +from vws import VWS from vws.exceptions.vws_exceptions import ProjectInactiveError from vws.reports import TargetStatuses -if TYPE_CHECKING: - from vws import VWS - @pytest.mark.usefixtures("verify_mock_vuforia") class TestDuplicates: diff --git a/tests/mock_vws/test_get_target.py b/tests/mock_vws/test_get_target.py index a545273ae..e0d22f634 100644 --- a/tests/mock_vws/test_get_target.py +++ b/tests/mock_vws/test_get_target.py @@ -3,18 +3,14 @@ https://developer.vuforia.com/library/web-api/cloud-targets-web-services-api#target-record """ +import io import uuid -from typing import TYPE_CHECKING import pytest +from vws import VWS from vws.exceptions.vws_exceptions import UnknownTargetError from vws.reports import TargetRecord, TargetStatuses -if TYPE_CHECKING: - import io - - from vws import VWS - @pytest.mark.usefixtures("verify_mock_vuforia") class TestGetRecord: diff --git a/tests/mock_vws/test_invalid_given_id.py b/tests/mock_vws/test_invalid_given_id.py index beceedef3..067867f75 100644 --- a/tests/mock_vws/test_invalid_given_id.py +++ b/tests/mock_vws/test_invalid_given_id.py @@ -5,19 +5,15 @@ """ from http import HTTPStatus -from typing import TYPE_CHECKING import pytest +from vws import VWS from mock_vws._constants import ResultCodes +from tests.mock_vws.utils import Endpoint from tests.mock_vws.utils.assertions import assert_vws_failure from tests.mock_vws.utils.too_many_requests import handle_server_errors -if TYPE_CHECKING: - from vws import VWS - - from tests.mock_vws.utils import Endpoint - @pytest.mark.usefixtures("verify_mock_vuforia") class TestInvalidGivenID: diff --git a/tests/mock_vws/test_query.py b/tests/mock_vws/test_query.py index 51f8109cd..49151ccdb 100644 --- a/tests/mock_vws/test_query.py +++ b/tests/mock_vws/test_query.py @@ -26,6 +26,7 @@ from tenacity.stop import stop_after_delay from tenacity.wait import wait_fixed from urllib3.filepost import encode_multipart_formdata +from vws import VWS, CloudRecoService from vws.exceptions.cloud_reco_exceptions import ( BadImageError, InactiveProjectError, @@ -36,6 +37,7 @@ from vws.response import Response from vws_auth_tools import authorization_header, rfc_1123_date +from mock_vws.database import VuforiaDatabase from tests.mock_vws.utils import make_image_file from tests.mock_vws.utils.assertions import ( assert_query_success, @@ -47,10 +49,6 @@ if TYPE_CHECKING: from collections.abc import Iterable - from vws import VWS, CloudRecoService - - from mock_vws.database import VuforiaDatabase - VWQ_HOST = "https://cloudreco.vuforia.com" _JETTY_CONTENT_TYPE_ERROR = textwrap.dedent( diff --git a/tests/mock_vws/test_target_list.py b/tests/mock_vws/test_target_list.py index 2c21960cb..b83db3dfd 100644 --- a/tests/mock_vws/test_target_list.py +++ b/tests/mock_vws/test_target_list.py @@ -1,11 +1,7 @@ """Tests for the mock of the target list endpoint.""" -from typing import TYPE_CHECKING - import pytest - -if TYPE_CHECKING: - from vws import VWS +from vws import VWS @pytest.mark.usefixtures("verify_mock_vuforia") diff --git a/tests/mock_vws/test_target_raters.py b/tests/mock_vws/test_target_raters.py index b0541d51b..27dbc8cb4 100644 --- a/tests/mock_vws/test_target_raters.py +++ b/tests/mock_vws/test_target_raters.py @@ -1,6 +1,6 @@ """Tests for target quality raters.""" -from typing import TYPE_CHECKING +import io import pytest @@ -10,9 +10,6 @@ RandomTargetTrackingRater, ) -if TYPE_CHECKING: - import io - def test_random_target_tracking_rater() -> None: """ diff --git a/tests/mock_vws/test_target_summary.py b/tests/mock_vws/test_target_summary.py index 531b76a75..61fbd76ce 100644 --- a/tests/mock_vws/test_target_summary.py +++ b/tests/mock_vws/test_target_summary.py @@ -1,20 +1,16 @@ """Tests for the mock of the target summary endpoint.""" import datetime +import io import uuid -from typing import TYPE_CHECKING from zoneinfo import ZoneInfo import pytest +from vws import VWS, CloudRecoService from vws.exceptions.vws_exceptions import UnknownTargetError from vws.reports import TargetStatuses -if TYPE_CHECKING: - import io - - from vws import VWS, CloudRecoService - - from mock_vws.database import VuforiaDatabase +from mock_vws.database import VuforiaDatabase @pytest.mark.usefixtures("verify_mock_vuforia") diff --git a/tests/mock_vws/test_update_target.py b/tests/mock_vws/test_update_target.py index 82a1ac072..1dddaffcc 100644 --- a/tests/mock_vws/test_update_target.py +++ b/tests/mock_vws/test_update_target.py @@ -5,9 +5,10 @@ import json import uuid from http import HTTPMethod, HTTPStatus -from typing import TYPE_CHECKING, Any, Final +from typing import Any, Final import pytest +from vws import VWS from vws.exceptions.base_exceptions import VWSError from vws.exceptions.vws_exceptions import ( AuthenticationFailureError, @@ -20,6 +21,7 @@ TargetStatusNotSuccessError, ) from vws.reports import TargetStatuses +from vws.response import Response from mock_vws._constants import ResultCodes from tests.mock_vws.utils import make_image_file @@ -28,10 +30,6 @@ assert_vws_response, ) -if TYPE_CHECKING: - from vws import VWS - from vws.response import Response - _MAX_METADATA_BYTES: Final[int] = 1024 * 1024 - 1 diff --git a/tests/mock_vws/utils/__init__.py b/tests/mock_vws/utils/__init__.py index 1f797659a..c554e4571 100644 --- a/tests/mock_vws/utils/__init__.py +++ b/tests/mock_vws/utils/__init__.py @@ -2,8 +2,9 @@ import io import secrets +from collections.abc import Mapping from dataclasses import dataclass -from typing import TYPE_CHECKING, Literal +from typing import Literal from urllib.parse import urljoin import requests @@ -11,10 +12,7 @@ from requests.structures import CaseInsensitiveDict from vws.response import Response -if TYPE_CHECKING: - from collections.abc import Mapping - - from mock_vws._constants import ResultCodes +from mock_vws._constants import ResultCodes @dataclass(frozen=True) diff --git a/tests/mock_vws/utils/assertions.py b/tests/mock_vws/utils/assertions.py index 1aa9cadf0..e026fed02 100644 --- a/tests/mock_vws/utils/assertions.py +++ b/tests/mock_vws/utils/assertions.py @@ -6,15 +6,12 @@ import json from http import HTTPStatus from string import hexdigits -from typing import TYPE_CHECKING from zoneinfo import ZoneInfo from beartype import beartype +from vws.response import Response -if TYPE_CHECKING: - from vws.response import Response - - from mock_vws._constants import ResultCodes +from mock_vws._constants import ResultCodes @beartype diff --git a/tests/mock_vws/utils/too_many_requests.py b/tests/mock_vws/utils/too_many_requests.py index 5be8559d7..c35cb54d1 100644 --- a/tests/mock_vws/utils/too_many_requests.py +++ b/tests/mock_vws/utils/too_many_requests.py @@ -1,14 +1,11 @@ """Helpers for handling too many requests errors.""" from http import HTTPStatus -from typing import TYPE_CHECKING from beartype import beartype from vws.exceptions.custom_exceptions import ServerError from vws.exceptions.vws_exceptions import TooManyRequestsError - -if TYPE_CHECKING: - from vws.response import Response +from vws.response import Response @beartype diff --git a/tests/mock_vws/utils/usage_test_helpers.py b/tests/mock_vws/utils/usage_test_helpers.py index c5bc94762..6c85dc0f6 100644 --- a/tests/mock_vws/utils/usage_test_helpers.py +++ b/tests/mock_vws/utils/usage_test_helpers.py @@ -1,15 +1,12 @@ """Helpers for testing the usage of the mocks.""" import datetime -from typing import TYPE_CHECKING +import io from vws import VWS from vws.reports import TargetStatuses -if TYPE_CHECKING: - import io - - from mock_vws.database import VuforiaDatabase +from mock_vws.database import VuforiaDatabase def processing_time_seconds( From 8514ff24b1d5a1cf2f3a2cdba5b0db0de0e2dcfa Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Wed, 28 Jan 2026 08:11:58 +0000 Subject: [PATCH 09/10] Ignore ruff TC rules until beartype supports TYPE_CHECKING Beartype requires imports to be available at runtime, not just under `if TYPE_CHECKING`. See https://github.com/beartype/beartype/discussions/594 for when beartype 0.23 will add support for TYPE_CHECKING imports. Co-Authored-By: Claude Opus 4.5 --- pyproject.toml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 501e9a974..29d2574bb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -162,6 +162,12 @@ lint.ignore = [ # Ignore "too-many-*" errors as they seem to get in the way more than # helping. "PLR0913", + # Beartype requires imports to be available at runtime, not just for type + # checking. See https://github.com/beartype/beartype/discussions/594 + # for when beartype will support `if TYPE_CHECKING` imports. + "TC001", + "TC002", + "TC003", ] lint.per-file-ignores."ci/test_custom_linters.py" = [ From 152c09a2ff3467c9f2c95894d99cb5483e7970f7 Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Wed, 28 Jan 2026 08:35:59 +0000 Subject: [PATCH 10/10] Remove runtime beartype application to test functions Python 3.14's deferred annotation evaluation (PEP 649) causes `_Stringifier.__format__` to raise a TypeError when beartype inspects function signatures at test collection time. This is a workaround until beartype 0.23 is released with full Python 3.14 support. See: - https://github.com/beartype/beartype/discussions/594 - https://github.com/beartype/beartype/pull/440 Co-Authored-By: Claude Opus 4.5 --- conftest.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/conftest.py b/conftest.py index 93484cd3e..8862c2d77 100644 --- a/conftest.py +++ b/conftest.py @@ -1,4 +1,11 @@ -"""Setup for Sybil.""" +""" +Setup for Sybil. + +Beartype is not applied to test functions because of a Python 3.14 +annotation issue. See: +- https://github.com/beartype/beartype/discussions/594 +- https://github.com/beartype/beartype/pull/440 +""" from doctest import ELLIPSIS @@ -12,15 +19,6 @@ from tests.mock_vws.utils.retries import RETRY_EXCEPTIONS - -@beartype -def pytest_collection_modifyitems(items: list[pytest.Item]) -> None: - """Apply the beartype decorator to all collected test functions.""" - for item in items: - if isinstance(item, pytest.Function): - item.obj = beartype(obj=item.obj) - - pytest_collect_file = Sybil( parsers=[ DocTestParser(optionflags=ELLIPSIS),