From c5f4eadbcd741164f39152960d3fba50ec2b3c13 Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Mon, 12 Jan 2026 14:17:13 +0000 Subject: [PATCH 1/5] Switch from docformatter to pydocstringformatter --- .pre-commit-config.yaml | 8 ++++---- pyproject.toml | 9 +++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1ed243a7..6b48bc64 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ ci: - check-manifest - deptry - doc8 - - docformatter + - pydocstringformatter - docs - interrogate - interrogate-docs @@ -104,9 +104,9 @@ repos: additional_dependencies: [uv==0.9.5] stages: [pre-commit] - - id: docformatter - name: docformatter - entry: uv run --extra=dev -m docformatter --in-place + - id: pydocstringformatter + name: pydocstringformatter + entry: uv run --extra=dev pydocstringformatter language: python types_or: [python] additional_dependencies: [uv==0.9.5] diff --git a/pyproject.toml b/pyproject.toml index 3f7f5df0..d4a6cbd2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,13 +42,13 @@ optional-dependencies.dev = [ "deptry==0.24.0", "doc8==2.0.0", "doccmd==2026.1.3.2", - "docformatter==1.7.7", "freezegun==1.5.5", "furo==2025.12.19", "interrogate==1.7.0", "mypy[faster-cache]==1.19.1", "mypy-strict-kwargs==2026.1.12", "prek==0.2.27", + "pydocstringformatter==0.7.3", "pydocstyle==6.3", "pygments==2.19.2", "pylint[spelling]==4.0.4", @@ -274,9 +274,6 @@ spelling-private-dict-file = 'spelling_private_dict.txt' # --spelling-private-dict-file option instead of raising a message. spelling-store-unknown-words = 'no' -[tool.docformatter] -make-summary-multi-line = true - [tool.check-manifest] ignore = [ @@ -346,6 +343,10 @@ enableTypeIgnoreComments = false reportUnnecessaryTypeIgnoreComment = true typeCheckingMode = "strict" +[tool.pydocstringformatter] +write = true +split-summary-body = false + [tool.interrogate] fail-under = 100 omit-covered-files = true From e4126ee5441f4afdae41339aad26f77c04bc4638 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Mon, 12 Jan 2026 14:18:45 +0000 Subject: [PATCH 2/5] [pre-commit.ci lite] apply automatic fixes --- conftest.py | 8 +- docs/source/__init__.py | 4 +- docs/source/conf.py | 4 +- src/vws/__init__.py | 4 +- src/vws/exceptions/__init__.py | 4 +- src/vws/exceptions/base_exceptions.py | 12 +-- src/vws/exceptions/cloud_reco_exceptions.py | 16 +--- src/vws/exceptions/custom_exceptions.py | 20 +--- src/vws/exceptions/vws_exceptions.py | 68 ++++--------- src/vws/include_target_data.py | 4 +- src/vws/query.py | 12 +-- src/vws/reports.py | 8 +- src/vws/response.py | 8 +- src/vws/vws.py | 12 +-- tests/__init__.py | 4 +- tests/conftest.py | 24 ++--- tests/test_cloud_reco_exceptions.py | 8 +- tests/test_query.py | 40 ++------ tests/test_vws.py | 100 +++++--------------- tests/test_vws_exceptions.py | 20 +--- 20 files changed, 100 insertions(+), 280 deletions(-) diff --git a/conftest.py b/conftest.py index 1d776f8d..0e579a4d 100644 --- a/conftest.py +++ b/conftest.py @@ -1,6 +1,4 @@ -""" -Setup for Sybil. -""" +"""Setup for Sybil.""" import io import uuid @@ -21,9 +19,7 @@ def pytest_collection_modifyitems(items: list[pytest.Item]) -> None: - """ - Apply the beartype decorator to all collected test functions. - """ + """Apply the beartype decorator to all collected test functions.""" for item in items: if isinstance(item, pytest.Function): item.obj = beartype(obj=item.obj) diff --git a/docs/source/__init__.py b/docs/source/__init__.py index b63eed5f..535ceb2e 100644 --- a/docs/source/__init__.py +++ b/docs/source/__init__.py @@ -1,3 +1 @@ -""" -Documentation. -""" +"""Documentation.""" diff --git a/docs/source/conf.py b/docs/source/conf.py index 914bcb88..920ba1a4 100755 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -1,7 +1,5 @@ #!/usr/bin/env python3 -""" -Configuration for Sphinx. -""" +"""Configuration for Sphinx.""" import importlib.metadata from pathlib import Path diff --git a/src/vws/__init__.py b/src/vws/__init__.py index 42788b92..bfd96d6c 100644 --- a/src/vws/__init__.py +++ b/src/vws/__init__.py @@ -1,6 +1,4 @@ -""" -A library for Vuforia Web Services. -""" +"""A library for Vuforia Web Services.""" from .query import CloudRecoService from .vws import VWS diff --git a/src/vws/exceptions/__init__.py b/src/vws/exceptions/__init__.py index a1e3cd91..7260ffdb 100644 --- a/src/vws/exceptions/__init__.py +++ b/src/vws/exceptions/__init__.py @@ -1,3 +1 @@ -""" -Custom exceptions raised by this package. -""" +"""Custom exceptions raised by this package.""" diff --git a/src/vws/exceptions/base_exceptions.py b/src/vws/exceptions/base_exceptions.py index 943323bf..c8608059 100644 --- a/src/vws/exceptions/base_exceptions.py +++ b/src/vws/exceptions/base_exceptions.py @@ -10,9 +10,7 @@ @beartype class CloudRecoError(Exception): - """ - Base class for Vuforia Cloud Recognition Web API exceptions. - """ + """Base class for Vuforia Cloud Recognition Web API exceptions.""" def __init__(self, response: Response) -> None: """ @@ -24,9 +22,7 @@ def __init__(self, response: Response) -> None: @property def response(self) -> Response: - """ - The response returned by Vuforia which included this error. - """ + """The response returned by Vuforia which included this error.""" return self._response @@ -48,7 +44,5 @@ def __init__(self, response: Response) -> None: @property def response(self) -> Response: - """ - The response returned by Vuforia which included this error. - """ + """The response returned by Vuforia which included this error.""" return self._response diff --git a/src/vws/exceptions/cloud_reco_exceptions.py b/src/vws/exceptions/cloud_reco_exceptions.py index ff5dde20..2b20a722 100644 --- a/src/vws/exceptions/cloud_reco_exceptions.py +++ b/src/vws/exceptions/cloud_reco_exceptions.py @@ -1,6 +1,4 @@ -""" -Exceptions which match errors raised by the Vuforia Cloud Recognition Web APIs. -""" +"""Exceptions which match errors raised by the Vuforia Cloud Recognition Web APIs.""" from beartype import beartype @@ -17,31 +15,27 @@ class MaxNumResultsOutOfRangeError(CloudRecoError): @beartype class InactiveProjectError(CloudRecoError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'InactiveProject'. """ @beartype class BadImageError(CloudRecoError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'BadImage'. """ @beartype class AuthenticationFailureError(CloudRecoError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'AuthenticationFailure'. """ @beartype class RequestTimeTooSkewedError(CloudRecoError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'RequestTimeTooSkewed'. """ diff --git a/src/vws/exceptions/custom_exceptions.py b/src/vws/exceptions/custom_exceptions.py index 694e98c3..466dfd1c 100644 --- a/src/vws/exceptions/custom_exceptions.py +++ b/src/vws/exceptions/custom_exceptions.py @@ -11,9 +11,7 @@ @beartype class RequestEntityTooLargeError(Exception): - """ - Exception raised when the given image is too large. - """ + """Exception raised when the given image is too large.""" def __init__(self, response: Response) -> None: """ @@ -25,24 +23,18 @@ def __init__(self, response: Response) -> None: @property def response(self) -> Response: - """ - The response returned by Vuforia which included this error. - """ + """The response returned by Vuforia which included this error.""" return self._response @beartype class TargetProcessingTimeoutError(Exception): - """ - Exception raised when waiting for a target to be processed times out. - """ + """Exception raised when waiting for a target to be processed times out.""" @beartype class ServerError(Exception): # pragma: no cover - """ - Exception raised when VWS returns a server error. - """ + """Exception raised when VWS returns a server error.""" def __init__(self, response: Response) -> None: """ @@ -54,7 +46,5 @@ def __init__(self, response: Response) -> None: @property def response(self) -> Response: - """ - The response returned by Vuforia which included this error. - """ + """The response returned by Vuforia which included this error.""" return self._response diff --git a/src/vws/exceptions/vws_exceptions.py b/src/vws/exceptions/vws_exceptions.py index 48222376..a25c2261 100644 --- a/src/vws/exceptions/vws_exceptions.py +++ b/src/vws/exceptions/vws_exceptions.py @@ -14,16 +14,13 @@ @beartype class UnknownTargetError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'UnknownTarget'. """ @property def target_id(self) -> str: - """ - The unknown target ID. - """ + """The unknown target ID.""" path = urlparse(url=self.response.url).path # Every HTTP path which can raise this error is in the format # `/something/{target_id}`. @@ -32,23 +29,19 @@ def target_id(self) -> str: @beartype class FailError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code 'Fail'. - """ + """Exception raised when Vuforia returns a response with a result code 'Fail'.""" @beartype class BadImageError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'BadImage'. """ @beartype class AuthenticationFailureError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'AuthenticationFailure'. """ @@ -56,24 +49,20 @@ class AuthenticationFailureError(VWSError): # See https://github.com/VWS-Python/vws-python/issues/822. @beartype class RequestQuotaReachedError(VWSError): # pragma: no cover - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'RequestQuotaReached'. """ @beartype class TargetStatusProcessingError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'TargetStatusProcessing'. """ @property def target_id(self) -> str: - """ - The processing target ID. - """ + """The processing target ID.""" path = urlparse(url=self.response.url).path # Every HTTP path which can raise this error is in the format # `/something/{target_id}`. @@ -83,8 +72,7 @@ def target_id(self) -> str: # This is not simulated by the mock. @beartype class DateRangeError(VWSError): # pragma: no cover - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'DateRangeError'. """ @@ -92,8 +80,7 @@ class DateRangeError(VWSError): # pragma: no cover # This is not simulated by the mock. @beartype class TargetQuotaReachedError(VWSError): # pragma: no cover - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'TargetQuotaReached'. """ @@ -101,8 +88,7 @@ class TargetQuotaReachedError(VWSError): # pragma: no cover # This is not simulated by the mock. @beartype class ProjectSuspendedError(VWSError): # pragma: no cover - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'ProjectSuspended'. """ @@ -110,48 +96,41 @@ class ProjectSuspendedError(VWSError): # pragma: no cover # This is not simulated by the mock. @beartype class ProjectHasNoAPIAccessError(VWSError): # pragma: no cover - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'ProjectHasNoAPIAccess'. """ @beartype class ProjectInactiveError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'ProjectInactive'. """ @beartype class MetadataTooLargeError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'MetadataTooLarge'. """ @beartype class RequestTimeTooSkewedError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'RequestTimeTooSkewed'. """ @beartype class TargetNameExistError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'TargetNameExist'. """ @property def target_name(self) -> str: - """ - The target name which already exists. - """ + """The target name which already exists.""" response_body = self.response.request_body or b"" request_json = json.loads(s=response_body) return str(object=request_json["name"]) @@ -159,24 +138,20 @@ def target_name(self) -> str: @beartype class ImageTooLargeError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'ImageTooLarge'. """ @beartype class TargetStatusNotSuccessError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'TargetStatusNotSuccess'. """ @property def target_id(self) -> str: - """ - The unknown target ID. - """ + """The unknown target ID.""" path = urlparse(url=self.response.url).path # Every HTTP path which can raise this error is in the format # `/something/{target_id}`. @@ -185,7 +160,6 @@ def target_id(self) -> str: @beartype class TooManyRequestsError(VWSError): # pragma: no cover - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'TooManyRequests'. """ diff --git a/src/vws/include_target_data.py b/src/vws/include_target_data.py index 37682e08..0692a1e4 100644 --- a/src/vws/include_target_data.py +++ b/src/vws/include_target_data.py @@ -1,6 +1,4 @@ -""" -Tools for managing ``CloudRecoService.query``'s ``include_target_data``. -""" +"""Tools for managing ``CloudRecoService.query``'s ``include_target_data``.""" from enum import StrEnum, auto, unique diff --git a/src/vws/query.py b/src/vws/query.py index 96122aa1..ab449c61 100644 --- a/src/vws/query.py +++ b/src/vws/query.py @@ -1,6 +1,4 @@ -""" -Tools for interacting with the Vuforia Cloud Recognition Web APIs. -""" +"""Tools for interacting with the Vuforia Cloud Recognition Web APIs.""" import datetime import io @@ -34,9 +32,7 @@ @beartype def _get_image_data(image: _ImageType) -> bytes: - """ - Get the data of an image file. - """ + """Get the data of an image file.""" original_tell = image.tell() image.seek(0) image_data = image.read() @@ -46,9 +42,7 @@ def _get_image_data(image: _ImageType) -> bytes: @beartype class CloudRecoService: - """ - An interface to the Vuforia Cloud Recognition Web APIs. - """ + """An interface to the Vuforia Cloud Recognition Web APIs.""" def __init__( self, diff --git a/src/vws/reports.py b/src/vws/reports.py index f6a77133..e59408aa 100644 --- a/src/vws/reports.py +++ b/src/vws/reports.py @@ -1,6 +1,4 @@ -""" -Classes for representing Vuforia reports. -""" +"""Classes for representing Vuforia reports.""" import datetime from dataclasses import dataclass @@ -86,9 +84,7 @@ class TargetRecord: @beartype @dataclass(frozen=True) class TargetData: - """ - The target data optionally included with a query match. - """ + """The target data optionally included with a query match.""" name: str application_metadata: str | None diff --git a/src/vws/response.py b/src/vws/response.py index 269f2e23..e2060cb9 100644 --- a/src/vws/response.py +++ b/src/vws/response.py @@ -1,6 +1,4 @@ -""" -Responses for requests to VWS and VWQ. -""" +"""Responses for requests to VWS and VWQ.""" from dataclasses import dataclass @@ -10,9 +8,7 @@ @dataclass(frozen=True) @beartype class Response: - """ - A response from a request. - """ + """A response from a request.""" text: str url: str diff --git a/src/vws/vws.py b/src/vws/vws.py index 8def19ed..1191ee7d 100644 --- a/src/vws/vws.py +++ b/src/vws/vws.py @@ -1,6 +1,4 @@ -""" -Tools for interacting with Vuforia APIs. -""" +"""Tools for interacting with Vuforia APIs.""" import base64 import io @@ -52,9 +50,7 @@ @beartype def _get_image_data(image: _ImageType) -> bytes: - """ - Get the data of an image file. - """ + """Get the data of an image file.""" original_tell = image.tell() image.seek(0) image_data = image.read() @@ -131,9 +127,7 @@ def _target_api_request( @beartype(conf=BeartypeConf(is_pep484_tower=True)) class VWS: - """ - An interface to Vuforia Web Services APIs. - """ + """An interface to Vuforia Web Services APIs.""" def __init__( self, diff --git a/tests/__init__.py b/tests/__init__.py index c7e38a86..3502d86d 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,3 +1 @@ -""" -Tests for ``vws``. -""" +"""Tests for ``vws``.""" diff --git a/tests/conftest.py b/tests/conftest.py index 74c6fc56..7c064778 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,4 @@ -""" -Configuration, plugins and fixtures for `pytest`. -""" +"""Configuration, plugins and fixtures for `pytest`.""" import io from collections.abc import Generator @@ -16,9 +14,7 @@ @pytest.fixture(name="_mock_database") def fixture_mock_database() -> Generator[VuforiaDatabase]: - """ - Yield a mock ``VuforiaDatabase``. - """ + """Yield a mock ``VuforiaDatabase``.""" # We use a low processing time so that tests run quickly. with MockVWS(processing_time_seconds=0.2) as mock: database = VuforiaDatabase() @@ -28,9 +24,7 @@ def fixture_mock_database() -> Generator[VuforiaDatabase]: @pytest.fixture def vws_client(_mock_database: VuforiaDatabase) -> VWS: - """ - A VWS client which connects to a mock database. - """ + """A VWS client which connects to a mock database.""" return VWS( server_access_key=_mock_database.server_access_key, server_secret_key=_mock_database.server_secret_key, @@ -39,9 +33,7 @@ def vws_client(_mock_database: VuforiaDatabase) -> VWS: @pytest.fixture def cloud_reco_client(_mock_database: VuforiaDatabase) -> CloudRecoService: - """ - A ``CloudRecoService`` client which connects to a mock database. - """ + """A ``CloudRecoService`` client which connects to a mock database.""" return CloudRecoService( client_access_key=_mock_database.client_access_key, client_secret_key=_mock_database.client_secret_key, @@ -54,9 +46,7 @@ def fixture_image_file( tmp_path: Path, request: pytest.FixtureRequest, ) -> Generator[BinaryIO]: - """ - An image file object. - """ + """An image file object.""" file = tmp_path / "image.jpg" buffer = high_quality_image.getvalue() file.write_bytes(data=buffer) @@ -71,9 +61,7 @@ def image( high_quality_image: io.BytesIO, image_file: BinaryIO, ) -> io.BytesIO | BinaryIO: - """ - An image in any of the types that the API accepts. - """ + """An image in any of the types that the API accepts.""" if request.param == "high_quality_image": return high_quality_image return image_file diff --git a/tests/test_cloud_reco_exceptions.py b/tests/test_cloud_reco_exceptions.py index 3515b0d2..d4c8cb0f 100644 --- a/tests/test_cloud_reco_exceptions.py +++ b/tests/test_cloud_reco_exceptions.py @@ -1,6 +1,4 @@ -""" -Tests for exceptions raised when using the CloudRecoService. -""" +"""Tests for exceptions raised when using the CloudRecoService.""" import io import uuid @@ -63,9 +61,7 @@ def test_image_too_large( def test_cloudrecoexception_inheritance() -> None: - """ - CloudRecoService-specific exceptions inherit from CloudRecoException. - """ + """CloudRecoService-specific exceptions inherit from CloudRecoException.""" subclasses = [ MaxNumResultsOutOfRangeError, InactiveProjectError, diff --git a/tests/test_query.py b/tests/test_query.py index e229cf95..11b803eb 100644 --- a/tests/test_query.py +++ b/tests/test_query.py @@ -1,6 +1,4 @@ -""" -Tests for the ``CloudRecoService`` querying functionality. -""" +"""Tests for the ``CloudRecoService`` querying functionality.""" import io import uuid @@ -14,18 +12,14 @@ class TestQuery: - """ - Tests for making image queries. - """ + """Tests for making image queries.""" @staticmethod def test_no_matches( cloud_reco_client: CloudRecoService, image: io.BytesIO | BinaryIO, ) -> None: - """ - An empty list is returned if there are no matches. - """ + """An empty list is returned if there are no matches.""" result = cloud_reco_client.query(image=image) assert result == [] @@ -35,9 +29,7 @@ def test_match( cloud_reco_client: CloudRecoService, image: io.BytesIO | BinaryIO, ) -> None: - """ - Details of matching targets are returned. - """ + """Details of matching targets are returned.""" target_id = vws_client.add_target( name="x", width=1, @@ -51,9 +43,7 @@ def test_match( class TestCustomBaseVWQURL: - """ - Tests for using a custom base VWQ URL. - """ + """Tests for using a custom base VWQ URL.""" @staticmethod def test_custom_base_url(image: io.BytesIO | BinaryIO) -> None: @@ -93,9 +83,7 @@ def test_custom_base_url(image: io.BytesIO | BinaryIO) -> None: class TestMaxNumResults: - """ - Tests for the ``max_num_results`` parameter of ``query``. - """ + """Tests for the ``max_num_results`` parameter of ``query``.""" @staticmethod def test_default( @@ -103,9 +91,7 @@ def test_default( cloud_reco_client: CloudRecoService, image: io.BytesIO | BinaryIO, ) -> None: - """ - By default the maximum number of results is 1. - """ + """By default the maximum number of results is 1.""" target_id = vws_client.add_target( name=uuid.uuid4().hex, width=1, @@ -131,9 +117,7 @@ def test_custom( cloud_reco_client: CloudRecoService, image: io.BytesIO | BinaryIO, ) -> None: - """ - It is possible to set a custom ``max_num_results``. - """ + """It is possible to set a custom ``max_num_results``.""" target_id = vws_client.add_target( name=uuid.uuid4().hex, width=1, @@ -167,9 +151,7 @@ def test_custom( class TestIncludeTargetData: - """ - Tests for the ``include_target_data`` parameter of ``query``. - """ + """Tests for the ``include_target_data`` parameter of ``query``.""" @staticmethod def test_default( @@ -177,9 +159,7 @@ def test_default( cloud_reco_client: CloudRecoService, image: io.BytesIO | BinaryIO, ) -> None: - """ - By default, target data is only returned in the top match. - """ + """By default, target data is only returned in the top match.""" target_id = vws_client.add_target( name=uuid.uuid4().hex, width=1, diff --git a/tests/test_vws.py b/tests/test_vws.py index e16eff55..d427e1c9 100644 --- a/tests/test_vws.py +++ b/tests/test_vws.py @@ -1,6 +1,4 @@ -""" -Tests for helper functions for managing a Vuforia database. -""" +"""Tests for helper functions for managing a Vuforia database.""" import base64 import datetime @@ -25,9 +23,7 @@ class TestAddTarget: - """ - Tests for adding a target. - """ + """Tests for adding a target.""" @staticmethod @pytest.mark.parametrize( @@ -43,9 +39,7 @@ def test_add_target( *, active_flag: bool, ) -> None: - """ - No exception is raised when adding one target. - """ + """No exception is raised when adding one target.""" name = "x" width = 1 if application_metadata is None: @@ -98,9 +92,7 @@ def test_add_two_targets( class TestCustomBaseVWSURL: - """ - Tests for using a custom base VWS URL. - """ + """Tests for using a custom base VWS URL.""" @staticmethod def test_custom_base_url(image: io.BytesIO | BinaryIO) -> None: @@ -128,18 +120,14 @@ def test_custom_base_url(image: io.BytesIO | BinaryIO) -> None: class TestListTargets: - """ - Tests for listing targets. - """ + """Tests for listing targets.""" @staticmethod def test_list_targets( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """ - It is possible to get a list of target IDs. - """ + """It is possible to get a list of target IDs.""" id_1 = vws_client.add_target( name="x", width=1, @@ -158,18 +146,14 @@ def test_list_targets( class TestDelete: - """ - Test for deleting a target. - """ + """Test for deleting a target.""" @staticmethod def test_delete_target( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """ - It is possible to delete a target. - """ + """It is possible to delete a target.""" target_id = vws_client.add_target( name="x", width=1, @@ -185,18 +169,14 @@ def test_delete_target( class TestGetTargetSummaryReport: - """ - Tests for getting a summary report for a target. - """ + """Tests for getting a summary report for a target.""" @staticmethod def test_get_target_summary_report( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """ - Details of a target are returned by ``get_target_summary_report``. - """ + """Details of a target are returned by ``get_target_summary_report``.""" date = "2018-04-25" target_name = uuid.uuid4().hex with freeze_time(time_to_freeze=date): @@ -240,15 +220,11 @@ def test_get_target_summary_report( class TestGetDatabaseSummaryReport: - """ - Tests for getting a summary report for a database. - """ + """Tests for getting a summary report for a database.""" @staticmethod def test_get_target(vws_client: VWS) -> None: - """ - Details of a database are returned by ``get_database_summary_report``. - """ + """Details of a database are returned by ``get_database_summary_report``.""" report = vws_client.get_database_summary_report() expected_report = DatabaseSummaryReport( @@ -287,18 +263,14 @@ def test_get_target(vws_client: VWS) -> None: class TestGetTargetRecord: - """ - Tests for getting a record of a target. - """ + """Tests for getting a record of a target.""" @staticmethod def test_get_target_record( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """ - Details of a target are returned by ``get_target_record``. - """ + """Details of a target are returned by ``get_target_record``.""" target_id = vws_client.add_target( name="x", width=1, @@ -344,9 +316,7 @@ def test_get_failed( vws_client: VWS, image_file_failed_state: io.BytesIO, ) -> None: - """ - Check that the report works with a failed target. - """ + """Check that the report works with a failed target.""" target_id = vws_client.add_target( name="x", width=1, @@ -362,18 +332,14 @@ def test_get_failed( class TestWaitForTargetProcessed: - """ - Tests for waiting for a target to be processed. - """ + """Tests for waiting for a target to be processed.""" @staticmethod def test_wait_for_target_processed( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """ - It is possible to wait until a target is processed. - """ + """It is possible to wait until a target is processed.""" target_id = vws_client.add_target( name="x", width=1, @@ -391,9 +357,7 @@ def test_wait_for_target_processed( def test_default_seconds_between_requests( image: io.BytesIO | BinaryIO, ) -> None: - """ - By default, 0.2 seconds are waited between polling requests. - """ + """By default, 0.2 seconds are waited between polling requests.""" with MockVWS(processing_time_seconds=0.5) as mock: database = VuforiaDatabase() mock.add_database(database=database) @@ -443,9 +407,7 @@ def test_default_seconds_between_requests( def test_custom_seconds_between_requests( image: io.BytesIO | BinaryIO, ) -> None: - """ - It is possible to customize the time waited between polling requests. - """ + """It is possible to customize the time waited between polling requests.""" with MockVWS(processing_time_seconds=0.5) as mock: database = VuforiaDatabase() mock.add_database(database=database) @@ -493,9 +455,7 @@ def test_custom_seconds_between_requests( @staticmethod def test_custom_timeout(image: io.BytesIO | BinaryIO) -> None: - """ - It is possible to set a maximum timeout. - """ + """It is possible to set a maximum timeout.""" with MockVWS(processing_time_seconds=0.5) as mock: database = VuforiaDatabase() mock.add_database(database=database) @@ -531,18 +491,14 @@ def test_custom_timeout(image: io.BytesIO | BinaryIO) -> None: class TestGetDuplicateTargets: - """ - Tests for getting duplicate targets. - """ + """Tests for getting duplicate targets.""" @staticmethod def test_get_duplicate_targets( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """ - It is possible to get the IDs of similar targets. - """ + """It is possible to get the IDs of similar targets.""" target_id = vws_client.add_target( name="x", width=1, @@ -565,9 +521,7 @@ def test_get_duplicate_targets( class TestUpdateTarget: - """ - Tests for updating a target. - """ + """Tests for updating a target.""" @staticmethod def test_update_target( @@ -576,9 +530,7 @@ def test_update_target( different_high_quality_image: io.BytesIO, cloud_reco_client: CloudRecoService, ) -> None: - """ - It is possible to update a target. - """ + """It is possible to update a target.""" old_name = uuid.uuid4().hex old_width = secrets.choice(seq=range(1, 5000)) / 100 target_id = vws_client.add_target( @@ -635,9 +587,7 @@ def test_no_fields_given( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """ - It is possible to give no update fields. - """ + """It is possible to give no update fields.""" target_id = vws_client.add_target( name="x", width=1, diff --git a/tests/test_vws_exceptions.py b/tests/test_vws_exceptions.py index 86da6604..eb5b12a6 100644 --- a/tests/test_vws_exceptions.py +++ b/tests/test_vws_exceptions.py @@ -1,6 +1,4 @@ -""" -Tests for VWS exceptions. -""" +"""Tests for VWS exceptions.""" import io import uuid @@ -98,9 +96,7 @@ def test_request_quota_reached() -> None: def test_fail(high_quality_image: io.BytesIO) -> None: - """ - A ``Fail`` exception is raised when the server access key does not exist. - """ + """A ``Fail`` exception is raised when the server access key does not exist.""" with MockVWS(): vws_client = VWS( server_access_key=uuid.uuid4().hex, @@ -120,9 +116,7 @@ def test_fail(high_quality_image: io.BytesIO) -> None: def test_bad_image(vws_client: VWS) -> None: - """ - A ``BadImage`` exception is raised when a non-image is given. - """ + """A ``BadImage`` exception is raised when a non-image is given.""" not_an_image = io.BytesIO(initial_bytes=b"Not an image") with pytest.raises(expected_exception=BadImageError) as exc: vws_client.add_target( @@ -325,9 +319,7 @@ def test_target_status_not_success( def test_vwsexception_inheritance() -> None: - """ - VWS-related exceptions should inherit from VWSException. - """ + """VWS-related exceptions should inherit from VWSException.""" subclasses = [ AuthenticationFailureError, BadImageError, @@ -354,9 +346,7 @@ def test_base_exception( vws_client: VWS, high_quality_image: io.BytesIO, ) -> None: - """ - ``VWSException``s has a response property. - """ + """``VWSException``s has a response property.""" with pytest.raises(expected_exception=VWSError) as exc: vws_client.get_target_record(target_id="a") From b57ba660dc68b9c917b91fe720d5bd223280745d Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Mon, 12 Jan 2026 14:23:57 +0000 Subject: [PATCH 3/5] Configure pydocstringformatter to make minimal changes --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index d4a6cbd2..f83bea5b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -346,6 +346,8 @@ typeCheckingMode = "strict" [tool.pydocstringformatter] write = true split-summary-body = false +beginning-quotes = false +closing-quotes = false [tool.interrogate] fail-under = 100 From 6c82f4a9543f22170b369090744d872742ae8630 Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Mon, 12 Jan 2026 14:24:43 +0000 Subject: [PATCH 4/5] Switch from pydocstringformatter --- conftest.py | 8 +- docs/source/__init__.py | 4 +- docs/source/conf.py | 4 +- pyproject.toml | 2 - src/vws/__init__.py | 4 +- src/vws/exceptions/__init__.py | 4 +- src/vws/exceptions/base_exceptions.py | 12 ++- src/vws/exceptions/cloud_reco_exceptions.py | 16 +++- src/vws/exceptions/custom_exceptions.py | 20 +++- src/vws/exceptions/vws_exceptions.py | 68 +++++++++---- src/vws/include_target_data.py | 4 +- src/vws/query.py | 12 ++- src/vws/reports.py | 8 +- src/vws/response.py | 8 +- src/vws/vws.py | 12 ++- tests/__init__.py | 4 +- tests/conftest.py | 24 +++-- tests/test_cloud_reco_exceptions.py | 8 +- tests/test_query.py | 40 ++++++-- tests/test_vws.py | 100 +++++++++++++++----- tests/test_vws_exceptions.py | 20 +++- 21 files changed, 280 insertions(+), 102 deletions(-) diff --git a/conftest.py b/conftest.py index 0e579a4d..1d776f8d 100644 --- a/conftest.py +++ b/conftest.py @@ -1,4 +1,6 @@ -"""Setup for Sybil.""" +""" +Setup for Sybil. +""" import io import uuid @@ -19,7 +21,9 @@ def pytest_collection_modifyitems(items: list[pytest.Item]) -> None: - """Apply the beartype decorator to all collected test functions.""" + """ + Apply the beartype decorator to all collected test functions. + """ for item in items: if isinstance(item, pytest.Function): item.obj = beartype(obj=item.obj) diff --git a/docs/source/__init__.py b/docs/source/__init__.py index 535ceb2e..b63eed5f 100644 --- a/docs/source/__init__.py +++ b/docs/source/__init__.py @@ -1 +1,3 @@ -"""Documentation.""" +""" +Documentation. +""" diff --git a/docs/source/conf.py b/docs/source/conf.py index 920ba1a4..914bcb88 100755 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 -"""Configuration for Sphinx.""" +""" +Configuration for Sphinx. +""" import importlib.metadata from pathlib import Path diff --git a/pyproject.toml b/pyproject.toml index f83bea5b..d4a6cbd2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -346,8 +346,6 @@ typeCheckingMode = "strict" [tool.pydocstringformatter] write = true split-summary-body = false -beginning-quotes = false -closing-quotes = false [tool.interrogate] fail-under = 100 diff --git a/src/vws/__init__.py b/src/vws/__init__.py index bfd96d6c..42788b92 100644 --- a/src/vws/__init__.py +++ b/src/vws/__init__.py @@ -1,4 +1,6 @@ -"""A library for Vuforia Web Services.""" +""" +A library for Vuforia Web Services. +""" from .query import CloudRecoService from .vws import VWS diff --git a/src/vws/exceptions/__init__.py b/src/vws/exceptions/__init__.py index 7260ffdb..a1e3cd91 100644 --- a/src/vws/exceptions/__init__.py +++ b/src/vws/exceptions/__init__.py @@ -1 +1,3 @@ -"""Custom exceptions raised by this package.""" +""" +Custom exceptions raised by this package. +""" diff --git a/src/vws/exceptions/base_exceptions.py b/src/vws/exceptions/base_exceptions.py index c8608059..943323bf 100644 --- a/src/vws/exceptions/base_exceptions.py +++ b/src/vws/exceptions/base_exceptions.py @@ -10,7 +10,9 @@ @beartype class CloudRecoError(Exception): - """Base class for Vuforia Cloud Recognition Web API exceptions.""" + """ + Base class for Vuforia Cloud Recognition Web API exceptions. + """ def __init__(self, response: Response) -> None: """ @@ -22,7 +24,9 @@ def __init__(self, response: Response) -> None: @property def response(self) -> Response: - """The response returned by Vuforia which included this error.""" + """ + The response returned by Vuforia which included this error. + """ return self._response @@ -44,5 +48,7 @@ def __init__(self, response: Response) -> None: @property def response(self) -> Response: - """The response returned by Vuforia which included this error.""" + """ + The response returned by Vuforia which included this error. + """ return self._response diff --git a/src/vws/exceptions/cloud_reco_exceptions.py b/src/vws/exceptions/cloud_reco_exceptions.py index 2b20a722..ff5dde20 100644 --- a/src/vws/exceptions/cloud_reco_exceptions.py +++ b/src/vws/exceptions/cloud_reco_exceptions.py @@ -1,4 +1,6 @@ -"""Exceptions which match errors raised by the Vuforia Cloud Recognition Web APIs.""" +""" +Exceptions which match errors raised by the Vuforia Cloud Recognition Web APIs. +""" from beartype import beartype @@ -15,27 +17,31 @@ class MaxNumResultsOutOfRangeError(CloudRecoError): @beartype class InactiveProjectError(CloudRecoError): - """Exception raised when Vuforia returns a response with a result code + """ + Exception raised when Vuforia returns a response with a result code 'InactiveProject'. """ @beartype class BadImageError(CloudRecoError): - """Exception raised when Vuforia returns a response with a result code + """ + Exception raised when Vuforia returns a response with a result code 'BadImage'. """ @beartype class AuthenticationFailureError(CloudRecoError): - """Exception raised when Vuforia returns a response with a result code + """ + Exception raised when Vuforia returns a response with a result code 'AuthenticationFailure'. """ @beartype class RequestTimeTooSkewedError(CloudRecoError): - """Exception raised when Vuforia returns a response with a result code + """ + Exception raised when Vuforia returns a response with a result code 'RequestTimeTooSkewed'. """ diff --git a/src/vws/exceptions/custom_exceptions.py b/src/vws/exceptions/custom_exceptions.py index 466dfd1c..694e98c3 100644 --- a/src/vws/exceptions/custom_exceptions.py +++ b/src/vws/exceptions/custom_exceptions.py @@ -11,7 +11,9 @@ @beartype class RequestEntityTooLargeError(Exception): - """Exception raised when the given image is too large.""" + """ + Exception raised when the given image is too large. + """ def __init__(self, response: Response) -> None: """ @@ -23,18 +25,24 @@ def __init__(self, response: Response) -> None: @property def response(self) -> Response: - """The response returned by Vuforia which included this error.""" + """ + The response returned by Vuforia which included this error. + """ return self._response @beartype class TargetProcessingTimeoutError(Exception): - """Exception raised when waiting for a target to be processed times out.""" + """ + Exception raised when waiting for a target to be processed times out. + """ @beartype class ServerError(Exception): # pragma: no cover - """Exception raised when VWS returns a server error.""" + """ + Exception raised when VWS returns a server error. + """ def __init__(self, response: Response) -> None: """ @@ -46,5 +54,7 @@ def __init__(self, response: Response) -> None: @property def response(self) -> Response: - """The response returned by Vuforia which included this error.""" + """ + The response returned by Vuforia which included this error. + """ return self._response diff --git a/src/vws/exceptions/vws_exceptions.py b/src/vws/exceptions/vws_exceptions.py index a25c2261..48222376 100644 --- a/src/vws/exceptions/vws_exceptions.py +++ b/src/vws/exceptions/vws_exceptions.py @@ -14,13 +14,16 @@ @beartype class UnknownTargetError(VWSError): - """Exception raised when Vuforia returns a response with a result code + """ + Exception raised when Vuforia returns a response with a result code 'UnknownTarget'. """ @property def target_id(self) -> str: - """The unknown target ID.""" + """ + The unknown target ID. + """ path = urlparse(url=self.response.url).path # Every HTTP path which can raise this error is in the format # `/something/{target_id}`. @@ -29,19 +32,23 @@ def target_id(self) -> str: @beartype class FailError(VWSError): - """Exception raised when Vuforia returns a response with a result code 'Fail'.""" + """ + Exception raised when Vuforia returns a response with a result code 'Fail'. + """ @beartype class BadImageError(VWSError): - """Exception raised when Vuforia returns a response with a result code + """ + Exception raised when Vuforia returns a response with a result code 'BadImage'. """ @beartype class AuthenticationFailureError(VWSError): - """Exception raised when Vuforia returns a response with a result code + """ + Exception raised when Vuforia returns a response with a result code 'AuthenticationFailure'. """ @@ -49,20 +56,24 @@ class AuthenticationFailureError(VWSError): # See https://github.com/VWS-Python/vws-python/issues/822. @beartype class RequestQuotaReachedError(VWSError): # pragma: no cover - """Exception raised when Vuforia returns a response with a result code + """ + Exception raised when Vuforia returns a response with a result code 'RequestQuotaReached'. """ @beartype class TargetStatusProcessingError(VWSError): - """Exception raised when Vuforia returns a response with a result code + """ + Exception raised when Vuforia returns a response with a result code 'TargetStatusProcessing'. """ @property def target_id(self) -> str: - """The processing target ID.""" + """ + The processing target ID. + """ path = urlparse(url=self.response.url).path # Every HTTP path which can raise this error is in the format # `/something/{target_id}`. @@ -72,7 +83,8 @@ def target_id(self) -> str: # This is not simulated by the mock. @beartype class DateRangeError(VWSError): # pragma: no cover - """Exception raised when Vuforia returns a response with a result code + """ + Exception raised when Vuforia returns a response with a result code 'DateRangeError'. """ @@ -80,7 +92,8 @@ class DateRangeError(VWSError): # pragma: no cover # This is not simulated by the mock. @beartype class TargetQuotaReachedError(VWSError): # pragma: no cover - """Exception raised when Vuforia returns a response with a result code + """ + Exception raised when Vuforia returns a response with a result code 'TargetQuotaReached'. """ @@ -88,7 +101,8 @@ class TargetQuotaReachedError(VWSError): # pragma: no cover # This is not simulated by the mock. @beartype class ProjectSuspendedError(VWSError): # pragma: no cover - """Exception raised when Vuforia returns a response with a result code + """ + Exception raised when Vuforia returns a response with a result code 'ProjectSuspended'. """ @@ -96,41 +110,48 @@ class ProjectSuspendedError(VWSError): # pragma: no cover # This is not simulated by the mock. @beartype class ProjectHasNoAPIAccessError(VWSError): # pragma: no cover - """Exception raised when Vuforia returns a response with a result code + """ + Exception raised when Vuforia returns a response with a result code 'ProjectHasNoAPIAccess'. """ @beartype class ProjectInactiveError(VWSError): - """Exception raised when Vuforia returns a response with a result code + """ + Exception raised when Vuforia returns a response with a result code 'ProjectInactive'. """ @beartype class MetadataTooLargeError(VWSError): - """Exception raised when Vuforia returns a response with a result code + """ + Exception raised when Vuforia returns a response with a result code 'MetadataTooLarge'. """ @beartype class RequestTimeTooSkewedError(VWSError): - """Exception raised when Vuforia returns a response with a result code + """ + Exception raised when Vuforia returns a response with a result code 'RequestTimeTooSkewed'. """ @beartype class TargetNameExistError(VWSError): - """Exception raised when Vuforia returns a response with a result code + """ + Exception raised when Vuforia returns a response with a result code 'TargetNameExist'. """ @property def target_name(self) -> str: - """The target name which already exists.""" + """ + The target name which already exists. + """ response_body = self.response.request_body or b"" request_json = json.loads(s=response_body) return str(object=request_json["name"]) @@ -138,20 +159,24 @@ def target_name(self) -> str: @beartype class ImageTooLargeError(VWSError): - """Exception raised when Vuforia returns a response with a result code + """ + Exception raised when Vuforia returns a response with a result code 'ImageTooLarge'. """ @beartype class TargetStatusNotSuccessError(VWSError): - """Exception raised when Vuforia returns a response with a result code + """ + Exception raised when Vuforia returns a response with a result code 'TargetStatusNotSuccess'. """ @property def target_id(self) -> str: - """The unknown target ID.""" + """ + The unknown target ID. + """ path = urlparse(url=self.response.url).path # Every HTTP path which can raise this error is in the format # `/something/{target_id}`. @@ -160,6 +185,7 @@ def target_id(self) -> str: @beartype class TooManyRequestsError(VWSError): # pragma: no cover - """Exception raised when Vuforia returns a response with a result code + """ + Exception raised when Vuforia returns a response with a result code 'TooManyRequests'. """ diff --git a/src/vws/include_target_data.py b/src/vws/include_target_data.py index 0692a1e4..37682e08 100644 --- a/src/vws/include_target_data.py +++ b/src/vws/include_target_data.py @@ -1,4 +1,6 @@ -"""Tools for managing ``CloudRecoService.query``'s ``include_target_data``.""" +""" +Tools for managing ``CloudRecoService.query``'s ``include_target_data``. +""" from enum import StrEnum, auto, unique diff --git a/src/vws/query.py b/src/vws/query.py index ab449c61..96122aa1 100644 --- a/src/vws/query.py +++ b/src/vws/query.py @@ -1,4 +1,6 @@ -"""Tools for interacting with the Vuforia Cloud Recognition Web APIs.""" +""" +Tools for interacting with the Vuforia Cloud Recognition Web APIs. +""" import datetime import io @@ -32,7 +34,9 @@ @beartype def _get_image_data(image: _ImageType) -> bytes: - """Get the data of an image file.""" + """ + Get the data of an image file. + """ original_tell = image.tell() image.seek(0) image_data = image.read() @@ -42,7 +46,9 @@ def _get_image_data(image: _ImageType) -> bytes: @beartype class CloudRecoService: - """An interface to the Vuforia Cloud Recognition Web APIs.""" + """ + An interface to the Vuforia Cloud Recognition Web APIs. + """ def __init__( self, diff --git a/src/vws/reports.py b/src/vws/reports.py index e59408aa..f6a77133 100644 --- a/src/vws/reports.py +++ b/src/vws/reports.py @@ -1,4 +1,6 @@ -"""Classes for representing Vuforia reports.""" +""" +Classes for representing Vuforia reports. +""" import datetime from dataclasses import dataclass @@ -84,7 +86,9 @@ class TargetRecord: @beartype @dataclass(frozen=True) class TargetData: - """The target data optionally included with a query match.""" + """ + The target data optionally included with a query match. + """ name: str application_metadata: str | None diff --git a/src/vws/response.py b/src/vws/response.py index e2060cb9..269f2e23 100644 --- a/src/vws/response.py +++ b/src/vws/response.py @@ -1,4 +1,6 @@ -"""Responses for requests to VWS and VWQ.""" +""" +Responses for requests to VWS and VWQ. +""" from dataclasses import dataclass @@ -8,7 +10,9 @@ @dataclass(frozen=True) @beartype class Response: - """A response from a request.""" + """ + A response from a request. + """ text: str url: str diff --git a/src/vws/vws.py b/src/vws/vws.py index 1191ee7d..8def19ed 100644 --- a/src/vws/vws.py +++ b/src/vws/vws.py @@ -1,4 +1,6 @@ -"""Tools for interacting with Vuforia APIs.""" +""" +Tools for interacting with Vuforia APIs. +""" import base64 import io @@ -50,7 +52,9 @@ @beartype def _get_image_data(image: _ImageType) -> bytes: - """Get the data of an image file.""" + """ + Get the data of an image file. + """ original_tell = image.tell() image.seek(0) image_data = image.read() @@ -127,7 +131,9 @@ def _target_api_request( @beartype(conf=BeartypeConf(is_pep484_tower=True)) class VWS: - """An interface to Vuforia Web Services APIs.""" + """ + An interface to Vuforia Web Services APIs. + """ def __init__( self, diff --git a/tests/__init__.py b/tests/__init__.py index 3502d86d..c7e38a86 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1 +1,3 @@ -"""Tests for ``vws``.""" +""" +Tests for ``vws``. +""" diff --git a/tests/conftest.py b/tests/conftest.py index 7c064778..74c6fc56 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,6 @@ -"""Configuration, plugins and fixtures for `pytest`.""" +""" +Configuration, plugins and fixtures for `pytest`. +""" import io from collections.abc import Generator @@ -14,7 +16,9 @@ @pytest.fixture(name="_mock_database") def fixture_mock_database() -> Generator[VuforiaDatabase]: - """Yield a mock ``VuforiaDatabase``.""" + """ + Yield a mock ``VuforiaDatabase``. + """ # We use a low processing time so that tests run quickly. with MockVWS(processing_time_seconds=0.2) as mock: database = VuforiaDatabase() @@ -24,7 +28,9 @@ def fixture_mock_database() -> Generator[VuforiaDatabase]: @pytest.fixture def vws_client(_mock_database: VuforiaDatabase) -> VWS: - """A VWS client which connects to a mock database.""" + """ + A VWS client which connects to a mock database. + """ return VWS( server_access_key=_mock_database.server_access_key, server_secret_key=_mock_database.server_secret_key, @@ -33,7 +39,9 @@ def vws_client(_mock_database: VuforiaDatabase) -> VWS: @pytest.fixture def cloud_reco_client(_mock_database: VuforiaDatabase) -> CloudRecoService: - """A ``CloudRecoService`` client which connects to a mock database.""" + """ + A ``CloudRecoService`` client which connects to a mock database. + """ return CloudRecoService( client_access_key=_mock_database.client_access_key, client_secret_key=_mock_database.client_secret_key, @@ -46,7 +54,9 @@ def fixture_image_file( tmp_path: Path, request: pytest.FixtureRequest, ) -> Generator[BinaryIO]: - """An image file object.""" + """ + An image file object. + """ file = tmp_path / "image.jpg" buffer = high_quality_image.getvalue() file.write_bytes(data=buffer) @@ -61,7 +71,9 @@ def image( high_quality_image: io.BytesIO, image_file: BinaryIO, ) -> io.BytesIO | BinaryIO: - """An image in any of the types that the API accepts.""" + """ + An image in any of the types that the API accepts. + """ if request.param == "high_quality_image": return high_quality_image return image_file diff --git a/tests/test_cloud_reco_exceptions.py b/tests/test_cloud_reco_exceptions.py index d4c8cb0f..3515b0d2 100644 --- a/tests/test_cloud_reco_exceptions.py +++ b/tests/test_cloud_reco_exceptions.py @@ -1,4 +1,6 @@ -"""Tests for exceptions raised when using the CloudRecoService.""" +""" +Tests for exceptions raised when using the CloudRecoService. +""" import io import uuid @@ -61,7 +63,9 @@ def test_image_too_large( def test_cloudrecoexception_inheritance() -> None: - """CloudRecoService-specific exceptions inherit from CloudRecoException.""" + """ + CloudRecoService-specific exceptions inherit from CloudRecoException. + """ subclasses = [ MaxNumResultsOutOfRangeError, InactiveProjectError, diff --git a/tests/test_query.py b/tests/test_query.py index 11b803eb..e229cf95 100644 --- a/tests/test_query.py +++ b/tests/test_query.py @@ -1,4 +1,6 @@ -"""Tests for the ``CloudRecoService`` querying functionality.""" +""" +Tests for the ``CloudRecoService`` querying functionality. +""" import io import uuid @@ -12,14 +14,18 @@ class TestQuery: - """Tests for making image queries.""" + """ + Tests for making image queries. + """ @staticmethod def test_no_matches( cloud_reco_client: CloudRecoService, image: io.BytesIO | BinaryIO, ) -> None: - """An empty list is returned if there are no matches.""" + """ + An empty list is returned if there are no matches. + """ result = cloud_reco_client.query(image=image) assert result == [] @@ -29,7 +35,9 @@ def test_match( cloud_reco_client: CloudRecoService, image: io.BytesIO | BinaryIO, ) -> None: - """Details of matching targets are returned.""" + """ + Details of matching targets are returned. + """ target_id = vws_client.add_target( name="x", width=1, @@ -43,7 +51,9 @@ def test_match( class TestCustomBaseVWQURL: - """Tests for using a custom base VWQ URL.""" + """ + Tests for using a custom base VWQ URL. + """ @staticmethod def test_custom_base_url(image: io.BytesIO | BinaryIO) -> None: @@ -83,7 +93,9 @@ def test_custom_base_url(image: io.BytesIO | BinaryIO) -> None: class TestMaxNumResults: - """Tests for the ``max_num_results`` parameter of ``query``.""" + """ + Tests for the ``max_num_results`` parameter of ``query``. + """ @staticmethod def test_default( @@ -91,7 +103,9 @@ def test_default( cloud_reco_client: CloudRecoService, image: io.BytesIO | BinaryIO, ) -> None: - """By default the maximum number of results is 1.""" + """ + By default the maximum number of results is 1. + """ target_id = vws_client.add_target( name=uuid.uuid4().hex, width=1, @@ -117,7 +131,9 @@ def test_custom( cloud_reco_client: CloudRecoService, image: io.BytesIO | BinaryIO, ) -> None: - """It is possible to set a custom ``max_num_results``.""" + """ + It is possible to set a custom ``max_num_results``. + """ target_id = vws_client.add_target( name=uuid.uuid4().hex, width=1, @@ -151,7 +167,9 @@ def test_custom( class TestIncludeTargetData: - """Tests for the ``include_target_data`` parameter of ``query``.""" + """ + Tests for the ``include_target_data`` parameter of ``query``. + """ @staticmethod def test_default( @@ -159,7 +177,9 @@ def test_default( cloud_reco_client: CloudRecoService, image: io.BytesIO | BinaryIO, ) -> None: - """By default, target data is only returned in the top match.""" + """ + By default, target data is only returned in the top match. + """ target_id = vws_client.add_target( name=uuid.uuid4().hex, width=1, diff --git a/tests/test_vws.py b/tests/test_vws.py index d427e1c9..e16eff55 100644 --- a/tests/test_vws.py +++ b/tests/test_vws.py @@ -1,4 +1,6 @@ -"""Tests for helper functions for managing a Vuforia database.""" +""" +Tests for helper functions for managing a Vuforia database. +""" import base64 import datetime @@ -23,7 +25,9 @@ class TestAddTarget: - """Tests for adding a target.""" + """ + Tests for adding a target. + """ @staticmethod @pytest.mark.parametrize( @@ -39,7 +43,9 @@ def test_add_target( *, active_flag: bool, ) -> None: - """No exception is raised when adding one target.""" + """ + No exception is raised when adding one target. + """ name = "x" width = 1 if application_metadata is None: @@ -92,7 +98,9 @@ def test_add_two_targets( class TestCustomBaseVWSURL: - """Tests for using a custom base VWS URL.""" + """ + Tests for using a custom base VWS URL. + """ @staticmethod def test_custom_base_url(image: io.BytesIO | BinaryIO) -> None: @@ -120,14 +128,18 @@ def test_custom_base_url(image: io.BytesIO | BinaryIO) -> None: class TestListTargets: - """Tests for listing targets.""" + """ + Tests for listing targets. + """ @staticmethod def test_list_targets( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """It is possible to get a list of target IDs.""" + """ + It is possible to get a list of target IDs. + """ id_1 = vws_client.add_target( name="x", width=1, @@ -146,14 +158,18 @@ def test_list_targets( class TestDelete: - """Test for deleting a target.""" + """ + Test for deleting a target. + """ @staticmethod def test_delete_target( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """It is possible to delete a target.""" + """ + It is possible to delete a target. + """ target_id = vws_client.add_target( name="x", width=1, @@ -169,14 +185,18 @@ def test_delete_target( class TestGetTargetSummaryReport: - """Tests for getting a summary report for a target.""" + """ + Tests for getting a summary report for a target. + """ @staticmethod def test_get_target_summary_report( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """Details of a target are returned by ``get_target_summary_report``.""" + """ + Details of a target are returned by ``get_target_summary_report``. + """ date = "2018-04-25" target_name = uuid.uuid4().hex with freeze_time(time_to_freeze=date): @@ -220,11 +240,15 @@ def test_get_target_summary_report( class TestGetDatabaseSummaryReport: - """Tests for getting a summary report for a database.""" + """ + Tests for getting a summary report for a database. + """ @staticmethod def test_get_target(vws_client: VWS) -> None: - """Details of a database are returned by ``get_database_summary_report``.""" + """ + Details of a database are returned by ``get_database_summary_report``. + """ report = vws_client.get_database_summary_report() expected_report = DatabaseSummaryReport( @@ -263,14 +287,18 @@ def test_get_target(vws_client: VWS) -> None: class TestGetTargetRecord: - """Tests for getting a record of a target.""" + """ + Tests for getting a record of a target. + """ @staticmethod def test_get_target_record( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """Details of a target are returned by ``get_target_record``.""" + """ + Details of a target are returned by ``get_target_record``. + """ target_id = vws_client.add_target( name="x", width=1, @@ -316,7 +344,9 @@ def test_get_failed( vws_client: VWS, image_file_failed_state: io.BytesIO, ) -> None: - """Check that the report works with a failed target.""" + """ + Check that the report works with a failed target. + """ target_id = vws_client.add_target( name="x", width=1, @@ -332,14 +362,18 @@ def test_get_failed( class TestWaitForTargetProcessed: - """Tests for waiting for a target to be processed.""" + """ + Tests for waiting for a target to be processed. + """ @staticmethod def test_wait_for_target_processed( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """It is possible to wait until a target is processed.""" + """ + It is possible to wait until a target is processed. + """ target_id = vws_client.add_target( name="x", width=1, @@ -357,7 +391,9 @@ def test_wait_for_target_processed( def test_default_seconds_between_requests( image: io.BytesIO | BinaryIO, ) -> None: - """By default, 0.2 seconds are waited between polling requests.""" + """ + By default, 0.2 seconds are waited between polling requests. + """ with MockVWS(processing_time_seconds=0.5) as mock: database = VuforiaDatabase() mock.add_database(database=database) @@ -407,7 +443,9 @@ def test_default_seconds_between_requests( def test_custom_seconds_between_requests( image: io.BytesIO | BinaryIO, ) -> None: - """It is possible to customize the time waited between polling requests.""" + """ + It is possible to customize the time waited between polling requests. + """ with MockVWS(processing_time_seconds=0.5) as mock: database = VuforiaDatabase() mock.add_database(database=database) @@ -455,7 +493,9 @@ def test_custom_seconds_between_requests( @staticmethod def test_custom_timeout(image: io.BytesIO | BinaryIO) -> None: - """It is possible to set a maximum timeout.""" + """ + It is possible to set a maximum timeout. + """ with MockVWS(processing_time_seconds=0.5) as mock: database = VuforiaDatabase() mock.add_database(database=database) @@ -491,14 +531,18 @@ def test_custom_timeout(image: io.BytesIO | BinaryIO) -> None: class TestGetDuplicateTargets: - """Tests for getting duplicate targets.""" + """ + Tests for getting duplicate targets. + """ @staticmethod def test_get_duplicate_targets( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """It is possible to get the IDs of similar targets.""" + """ + It is possible to get the IDs of similar targets. + """ target_id = vws_client.add_target( name="x", width=1, @@ -521,7 +565,9 @@ def test_get_duplicate_targets( class TestUpdateTarget: - """Tests for updating a target.""" + """ + Tests for updating a target. + """ @staticmethod def test_update_target( @@ -530,7 +576,9 @@ def test_update_target( different_high_quality_image: io.BytesIO, cloud_reco_client: CloudRecoService, ) -> None: - """It is possible to update a target.""" + """ + It is possible to update a target. + """ old_name = uuid.uuid4().hex old_width = secrets.choice(seq=range(1, 5000)) / 100 target_id = vws_client.add_target( @@ -587,7 +635,9 @@ def test_no_fields_given( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """It is possible to give no update fields.""" + """ + It is possible to give no update fields. + """ target_id = vws_client.add_target( name="x", width=1, diff --git a/tests/test_vws_exceptions.py b/tests/test_vws_exceptions.py index eb5b12a6..86da6604 100644 --- a/tests/test_vws_exceptions.py +++ b/tests/test_vws_exceptions.py @@ -1,4 +1,6 @@ -"""Tests for VWS exceptions.""" +""" +Tests for VWS exceptions. +""" import io import uuid @@ -96,7 +98,9 @@ def test_request_quota_reached() -> None: def test_fail(high_quality_image: io.BytesIO) -> None: - """A ``Fail`` exception is raised when the server access key does not exist.""" + """ + A ``Fail`` exception is raised when the server access key does not exist. + """ with MockVWS(): vws_client = VWS( server_access_key=uuid.uuid4().hex, @@ -116,7 +120,9 @@ def test_fail(high_quality_image: io.BytesIO) -> None: def test_bad_image(vws_client: VWS) -> None: - """A ``BadImage`` exception is raised when a non-image is given.""" + """ + A ``BadImage`` exception is raised when a non-image is given. + """ not_an_image = io.BytesIO(initial_bytes=b"Not an image") with pytest.raises(expected_exception=BadImageError) as exc: vws_client.add_target( @@ -319,7 +325,9 @@ def test_target_status_not_success( def test_vwsexception_inheritance() -> None: - """VWS-related exceptions should inherit from VWSException.""" + """ + VWS-related exceptions should inherit from VWSException. + """ subclasses = [ AuthenticationFailureError, BadImageError, @@ -346,7 +354,9 @@ def test_base_exception( vws_client: VWS, high_quality_image: io.BytesIO, ) -> None: - """``VWSException``s has a response property.""" + """ + ``VWSException``s has a response property. + """ with pytest.raises(expected_exception=VWSError) as exc: vws_client.get_target_record(target_id="a") From 848686798b4cd9b7617d973b77ef25fbdc69c10a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Mon, 12 Jan 2026 14:27:40 +0000 Subject: [PATCH 5/5] [pre-commit.ci lite] apply automatic fixes --- conftest.py | 8 +- docs/source/__init__.py | 4 +- docs/source/conf.py | 4 +- src/vws/__init__.py | 4 +- src/vws/exceptions/__init__.py | 4 +- src/vws/exceptions/base_exceptions.py | 12 +-- src/vws/exceptions/cloud_reco_exceptions.py | 16 +--- src/vws/exceptions/custom_exceptions.py | 20 +--- src/vws/exceptions/vws_exceptions.py | 68 ++++--------- src/vws/include_target_data.py | 4 +- src/vws/query.py | 12 +-- src/vws/reports.py | 8 +- src/vws/response.py | 8 +- src/vws/vws.py | 12 +-- tests/__init__.py | 4 +- tests/conftest.py | 24 ++--- tests/test_cloud_reco_exceptions.py | 8 +- tests/test_query.py | 40 ++------ tests/test_vws.py | 100 +++++--------------- tests/test_vws_exceptions.py | 20 +--- 20 files changed, 100 insertions(+), 280 deletions(-) diff --git a/conftest.py b/conftest.py index 1d776f8d..0e579a4d 100644 --- a/conftest.py +++ b/conftest.py @@ -1,6 +1,4 @@ -""" -Setup for Sybil. -""" +"""Setup for Sybil.""" import io import uuid @@ -21,9 +19,7 @@ def pytest_collection_modifyitems(items: list[pytest.Item]) -> None: - """ - Apply the beartype decorator to all collected test functions. - """ + """Apply the beartype decorator to all collected test functions.""" for item in items: if isinstance(item, pytest.Function): item.obj = beartype(obj=item.obj) diff --git a/docs/source/__init__.py b/docs/source/__init__.py index b63eed5f..535ceb2e 100644 --- a/docs/source/__init__.py +++ b/docs/source/__init__.py @@ -1,3 +1 @@ -""" -Documentation. -""" +"""Documentation.""" diff --git a/docs/source/conf.py b/docs/source/conf.py index 914bcb88..920ba1a4 100755 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -1,7 +1,5 @@ #!/usr/bin/env python3 -""" -Configuration for Sphinx. -""" +"""Configuration for Sphinx.""" import importlib.metadata from pathlib import Path diff --git a/src/vws/__init__.py b/src/vws/__init__.py index 42788b92..bfd96d6c 100644 --- a/src/vws/__init__.py +++ b/src/vws/__init__.py @@ -1,6 +1,4 @@ -""" -A library for Vuforia Web Services. -""" +"""A library for Vuforia Web Services.""" from .query import CloudRecoService from .vws import VWS diff --git a/src/vws/exceptions/__init__.py b/src/vws/exceptions/__init__.py index a1e3cd91..7260ffdb 100644 --- a/src/vws/exceptions/__init__.py +++ b/src/vws/exceptions/__init__.py @@ -1,3 +1 @@ -""" -Custom exceptions raised by this package. -""" +"""Custom exceptions raised by this package.""" diff --git a/src/vws/exceptions/base_exceptions.py b/src/vws/exceptions/base_exceptions.py index 943323bf..c8608059 100644 --- a/src/vws/exceptions/base_exceptions.py +++ b/src/vws/exceptions/base_exceptions.py @@ -10,9 +10,7 @@ @beartype class CloudRecoError(Exception): - """ - Base class for Vuforia Cloud Recognition Web API exceptions. - """ + """Base class for Vuforia Cloud Recognition Web API exceptions.""" def __init__(self, response: Response) -> None: """ @@ -24,9 +22,7 @@ def __init__(self, response: Response) -> None: @property def response(self) -> Response: - """ - The response returned by Vuforia which included this error. - """ + """The response returned by Vuforia which included this error.""" return self._response @@ -48,7 +44,5 @@ def __init__(self, response: Response) -> None: @property def response(self) -> Response: - """ - The response returned by Vuforia which included this error. - """ + """The response returned by Vuforia which included this error.""" return self._response diff --git a/src/vws/exceptions/cloud_reco_exceptions.py b/src/vws/exceptions/cloud_reco_exceptions.py index ff5dde20..2b20a722 100644 --- a/src/vws/exceptions/cloud_reco_exceptions.py +++ b/src/vws/exceptions/cloud_reco_exceptions.py @@ -1,6 +1,4 @@ -""" -Exceptions which match errors raised by the Vuforia Cloud Recognition Web APIs. -""" +"""Exceptions which match errors raised by the Vuforia Cloud Recognition Web APIs.""" from beartype import beartype @@ -17,31 +15,27 @@ class MaxNumResultsOutOfRangeError(CloudRecoError): @beartype class InactiveProjectError(CloudRecoError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'InactiveProject'. """ @beartype class BadImageError(CloudRecoError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'BadImage'. """ @beartype class AuthenticationFailureError(CloudRecoError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'AuthenticationFailure'. """ @beartype class RequestTimeTooSkewedError(CloudRecoError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'RequestTimeTooSkewed'. """ diff --git a/src/vws/exceptions/custom_exceptions.py b/src/vws/exceptions/custom_exceptions.py index 694e98c3..466dfd1c 100644 --- a/src/vws/exceptions/custom_exceptions.py +++ b/src/vws/exceptions/custom_exceptions.py @@ -11,9 +11,7 @@ @beartype class RequestEntityTooLargeError(Exception): - """ - Exception raised when the given image is too large. - """ + """Exception raised when the given image is too large.""" def __init__(self, response: Response) -> None: """ @@ -25,24 +23,18 @@ def __init__(self, response: Response) -> None: @property def response(self) -> Response: - """ - The response returned by Vuforia which included this error. - """ + """The response returned by Vuforia which included this error.""" return self._response @beartype class TargetProcessingTimeoutError(Exception): - """ - Exception raised when waiting for a target to be processed times out. - """ + """Exception raised when waiting for a target to be processed times out.""" @beartype class ServerError(Exception): # pragma: no cover - """ - Exception raised when VWS returns a server error. - """ + """Exception raised when VWS returns a server error.""" def __init__(self, response: Response) -> None: """ @@ -54,7 +46,5 @@ def __init__(self, response: Response) -> None: @property def response(self) -> Response: - """ - The response returned by Vuforia which included this error. - """ + """The response returned by Vuforia which included this error.""" return self._response diff --git a/src/vws/exceptions/vws_exceptions.py b/src/vws/exceptions/vws_exceptions.py index 48222376..a25c2261 100644 --- a/src/vws/exceptions/vws_exceptions.py +++ b/src/vws/exceptions/vws_exceptions.py @@ -14,16 +14,13 @@ @beartype class UnknownTargetError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'UnknownTarget'. """ @property def target_id(self) -> str: - """ - The unknown target ID. - """ + """The unknown target ID.""" path = urlparse(url=self.response.url).path # Every HTTP path which can raise this error is in the format # `/something/{target_id}`. @@ -32,23 +29,19 @@ def target_id(self) -> str: @beartype class FailError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code 'Fail'. - """ + """Exception raised when Vuforia returns a response with a result code 'Fail'.""" @beartype class BadImageError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'BadImage'. """ @beartype class AuthenticationFailureError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'AuthenticationFailure'. """ @@ -56,24 +49,20 @@ class AuthenticationFailureError(VWSError): # See https://github.com/VWS-Python/vws-python/issues/822. @beartype class RequestQuotaReachedError(VWSError): # pragma: no cover - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'RequestQuotaReached'. """ @beartype class TargetStatusProcessingError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'TargetStatusProcessing'. """ @property def target_id(self) -> str: - """ - The processing target ID. - """ + """The processing target ID.""" path = urlparse(url=self.response.url).path # Every HTTP path which can raise this error is in the format # `/something/{target_id}`. @@ -83,8 +72,7 @@ def target_id(self) -> str: # This is not simulated by the mock. @beartype class DateRangeError(VWSError): # pragma: no cover - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'DateRangeError'. """ @@ -92,8 +80,7 @@ class DateRangeError(VWSError): # pragma: no cover # This is not simulated by the mock. @beartype class TargetQuotaReachedError(VWSError): # pragma: no cover - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'TargetQuotaReached'. """ @@ -101,8 +88,7 @@ class TargetQuotaReachedError(VWSError): # pragma: no cover # This is not simulated by the mock. @beartype class ProjectSuspendedError(VWSError): # pragma: no cover - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'ProjectSuspended'. """ @@ -110,48 +96,41 @@ class ProjectSuspendedError(VWSError): # pragma: no cover # This is not simulated by the mock. @beartype class ProjectHasNoAPIAccessError(VWSError): # pragma: no cover - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'ProjectHasNoAPIAccess'. """ @beartype class ProjectInactiveError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'ProjectInactive'. """ @beartype class MetadataTooLargeError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'MetadataTooLarge'. """ @beartype class RequestTimeTooSkewedError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'RequestTimeTooSkewed'. """ @beartype class TargetNameExistError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'TargetNameExist'. """ @property def target_name(self) -> str: - """ - The target name which already exists. - """ + """The target name which already exists.""" response_body = self.response.request_body or b"" request_json = json.loads(s=response_body) return str(object=request_json["name"]) @@ -159,24 +138,20 @@ def target_name(self) -> str: @beartype class ImageTooLargeError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'ImageTooLarge'. """ @beartype class TargetStatusNotSuccessError(VWSError): - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'TargetStatusNotSuccess'. """ @property def target_id(self) -> str: - """ - The unknown target ID. - """ + """The unknown target ID.""" path = urlparse(url=self.response.url).path # Every HTTP path which can raise this error is in the format # `/something/{target_id}`. @@ -185,7 +160,6 @@ def target_id(self) -> str: @beartype class TooManyRequestsError(VWSError): # pragma: no cover - """ - Exception raised when Vuforia returns a response with a result code + """Exception raised when Vuforia returns a response with a result code 'TooManyRequests'. """ diff --git a/src/vws/include_target_data.py b/src/vws/include_target_data.py index 37682e08..0692a1e4 100644 --- a/src/vws/include_target_data.py +++ b/src/vws/include_target_data.py @@ -1,6 +1,4 @@ -""" -Tools for managing ``CloudRecoService.query``'s ``include_target_data``. -""" +"""Tools for managing ``CloudRecoService.query``'s ``include_target_data``.""" from enum import StrEnum, auto, unique diff --git a/src/vws/query.py b/src/vws/query.py index 96122aa1..ab449c61 100644 --- a/src/vws/query.py +++ b/src/vws/query.py @@ -1,6 +1,4 @@ -""" -Tools for interacting with the Vuforia Cloud Recognition Web APIs. -""" +"""Tools for interacting with the Vuforia Cloud Recognition Web APIs.""" import datetime import io @@ -34,9 +32,7 @@ @beartype def _get_image_data(image: _ImageType) -> bytes: - """ - Get the data of an image file. - """ + """Get the data of an image file.""" original_tell = image.tell() image.seek(0) image_data = image.read() @@ -46,9 +42,7 @@ def _get_image_data(image: _ImageType) -> bytes: @beartype class CloudRecoService: - """ - An interface to the Vuforia Cloud Recognition Web APIs. - """ + """An interface to the Vuforia Cloud Recognition Web APIs.""" def __init__( self, diff --git a/src/vws/reports.py b/src/vws/reports.py index f6a77133..e59408aa 100644 --- a/src/vws/reports.py +++ b/src/vws/reports.py @@ -1,6 +1,4 @@ -""" -Classes for representing Vuforia reports. -""" +"""Classes for representing Vuforia reports.""" import datetime from dataclasses import dataclass @@ -86,9 +84,7 @@ class TargetRecord: @beartype @dataclass(frozen=True) class TargetData: - """ - The target data optionally included with a query match. - """ + """The target data optionally included with a query match.""" name: str application_metadata: str | None diff --git a/src/vws/response.py b/src/vws/response.py index 269f2e23..e2060cb9 100644 --- a/src/vws/response.py +++ b/src/vws/response.py @@ -1,6 +1,4 @@ -""" -Responses for requests to VWS and VWQ. -""" +"""Responses for requests to VWS and VWQ.""" from dataclasses import dataclass @@ -10,9 +8,7 @@ @dataclass(frozen=True) @beartype class Response: - """ - A response from a request. - """ + """A response from a request.""" text: str url: str diff --git a/src/vws/vws.py b/src/vws/vws.py index 8def19ed..1191ee7d 100644 --- a/src/vws/vws.py +++ b/src/vws/vws.py @@ -1,6 +1,4 @@ -""" -Tools for interacting with Vuforia APIs. -""" +"""Tools for interacting with Vuforia APIs.""" import base64 import io @@ -52,9 +50,7 @@ @beartype def _get_image_data(image: _ImageType) -> bytes: - """ - Get the data of an image file. - """ + """Get the data of an image file.""" original_tell = image.tell() image.seek(0) image_data = image.read() @@ -131,9 +127,7 @@ def _target_api_request( @beartype(conf=BeartypeConf(is_pep484_tower=True)) class VWS: - """ - An interface to Vuforia Web Services APIs. - """ + """An interface to Vuforia Web Services APIs.""" def __init__( self, diff --git a/tests/__init__.py b/tests/__init__.py index c7e38a86..3502d86d 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,3 +1 @@ -""" -Tests for ``vws``. -""" +"""Tests for ``vws``.""" diff --git a/tests/conftest.py b/tests/conftest.py index 74c6fc56..7c064778 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,4 @@ -""" -Configuration, plugins and fixtures for `pytest`. -""" +"""Configuration, plugins and fixtures for `pytest`.""" import io from collections.abc import Generator @@ -16,9 +14,7 @@ @pytest.fixture(name="_mock_database") def fixture_mock_database() -> Generator[VuforiaDatabase]: - """ - Yield a mock ``VuforiaDatabase``. - """ + """Yield a mock ``VuforiaDatabase``.""" # We use a low processing time so that tests run quickly. with MockVWS(processing_time_seconds=0.2) as mock: database = VuforiaDatabase() @@ -28,9 +24,7 @@ def fixture_mock_database() -> Generator[VuforiaDatabase]: @pytest.fixture def vws_client(_mock_database: VuforiaDatabase) -> VWS: - """ - A VWS client which connects to a mock database. - """ + """A VWS client which connects to a mock database.""" return VWS( server_access_key=_mock_database.server_access_key, server_secret_key=_mock_database.server_secret_key, @@ -39,9 +33,7 @@ def vws_client(_mock_database: VuforiaDatabase) -> VWS: @pytest.fixture def cloud_reco_client(_mock_database: VuforiaDatabase) -> CloudRecoService: - """ - A ``CloudRecoService`` client which connects to a mock database. - """ + """A ``CloudRecoService`` client which connects to a mock database.""" return CloudRecoService( client_access_key=_mock_database.client_access_key, client_secret_key=_mock_database.client_secret_key, @@ -54,9 +46,7 @@ def fixture_image_file( tmp_path: Path, request: pytest.FixtureRequest, ) -> Generator[BinaryIO]: - """ - An image file object. - """ + """An image file object.""" file = tmp_path / "image.jpg" buffer = high_quality_image.getvalue() file.write_bytes(data=buffer) @@ -71,9 +61,7 @@ def image( high_quality_image: io.BytesIO, image_file: BinaryIO, ) -> io.BytesIO | BinaryIO: - """ - An image in any of the types that the API accepts. - """ + """An image in any of the types that the API accepts.""" if request.param == "high_quality_image": return high_quality_image return image_file diff --git a/tests/test_cloud_reco_exceptions.py b/tests/test_cloud_reco_exceptions.py index 3515b0d2..d4c8cb0f 100644 --- a/tests/test_cloud_reco_exceptions.py +++ b/tests/test_cloud_reco_exceptions.py @@ -1,6 +1,4 @@ -""" -Tests for exceptions raised when using the CloudRecoService. -""" +"""Tests for exceptions raised when using the CloudRecoService.""" import io import uuid @@ -63,9 +61,7 @@ def test_image_too_large( def test_cloudrecoexception_inheritance() -> None: - """ - CloudRecoService-specific exceptions inherit from CloudRecoException. - """ + """CloudRecoService-specific exceptions inherit from CloudRecoException.""" subclasses = [ MaxNumResultsOutOfRangeError, InactiveProjectError, diff --git a/tests/test_query.py b/tests/test_query.py index e229cf95..11b803eb 100644 --- a/tests/test_query.py +++ b/tests/test_query.py @@ -1,6 +1,4 @@ -""" -Tests for the ``CloudRecoService`` querying functionality. -""" +"""Tests for the ``CloudRecoService`` querying functionality.""" import io import uuid @@ -14,18 +12,14 @@ class TestQuery: - """ - Tests for making image queries. - """ + """Tests for making image queries.""" @staticmethod def test_no_matches( cloud_reco_client: CloudRecoService, image: io.BytesIO | BinaryIO, ) -> None: - """ - An empty list is returned if there are no matches. - """ + """An empty list is returned if there are no matches.""" result = cloud_reco_client.query(image=image) assert result == [] @@ -35,9 +29,7 @@ def test_match( cloud_reco_client: CloudRecoService, image: io.BytesIO | BinaryIO, ) -> None: - """ - Details of matching targets are returned. - """ + """Details of matching targets are returned.""" target_id = vws_client.add_target( name="x", width=1, @@ -51,9 +43,7 @@ def test_match( class TestCustomBaseVWQURL: - """ - Tests for using a custom base VWQ URL. - """ + """Tests for using a custom base VWQ URL.""" @staticmethod def test_custom_base_url(image: io.BytesIO | BinaryIO) -> None: @@ -93,9 +83,7 @@ def test_custom_base_url(image: io.BytesIO | BinaryIO) -> None: class TestMaxNumResults: - """ - Tests for the ``max_num_results`` parameter of ``query``. - """ + """Tests for the ``max_num_results`` parameter of ``query``.""" @staticmethod def test_default( @@ -103,9 +91,7 @@ def test_default( cloud_reco_client: CloudRecoService, image: io.BytesIO | BinaryIO, ) -> None: - """ - By default the maximum number of results is 1. - """ + """By default the maximum number of results is 1.""" target_id = vws_client.add_target( name=uuid.uuid4().hex, width=1, @@ -131,9 +117,7 @@ def test_custom( cloud_reco_client: CloudRecoService, image: io.BytesIO | BinaryIO, ) -> None: - """ - It is possible to set a custom ``max_num_results``. - """ + """It is possible to set a custom ``max_num_results``.""" target_id = vws_client.add_target( name=uuid.uuid4().hex, width=1, @@ -167,9 +151,7 @@ def test_custom( class TestIncludeTargetData: - """ - Tests for the ``include_target_data`` parameter of ``query``. - """ + """Tests for the ``include_target_data`` parameter of ``query``.""" @staticmethod def test_default( @@ -177,9 +159,7 @@ def test_default( cloud_reco_client: CloudRecoService, image: io.BytesIO | BinaryIO, ) -> None: - """ - By default, target data is only returned in the top match. - """ + """By default, target data is only returned in the top match.""" target_id = vws_client.add_target( name=uuid.uuid4().hex, width=1, diff --git a/tests/test_vws.py b/tests/test_vws.py index e16eff55..d427e1c9 100644 --- a/tests/test_vws.py +++ b/tests/test_vws.py @@ -1,6 +1,4 @@ -""" -Tests for helper functions for managing a Vuforia database. -""" +"""Tests for helper functions for managing a Vuforia database.""" import base64 import datetime @@ -25,9 +23,7 @@ class TestAddTarget: - """ - Tests for adding a target. - """ + """Tests for adding a target.""" @staticmethod @pytest.mark.parametrize( @@ -43,9 +39,7 @@ def test_add_target( *, active_flag: bool, ) -> None: - """ - No exception is raised when adding one target. - """ + """No exception is raised when adding one target.""" name = "x" width = 1 if application_metadata is None: @@ -98,9 +92,7 @@ def test_add_two_targets( class TestCustomBaseVWSURL: - """ - Tests for using a custom base VWS URL. - """ + """Tests for using a custom base VWS URL.""" @staticmethod def test_custom_base_url(image: io.BytesIO | BinaryIO) -> None: @@ -128,18 +120,14 @@ def test_custom_base_url(image: io.BytesIO | BinaryIO) -> None: class TestListTargets: - """ - Tests for listing targets. - """ + """Tests for listing targets.""" @staticmethod def test_list_targets( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """ - It is possible to get a list of target IDs. - """ + """It is possible to get a list of target IDs.""" id_1 = vws_client.add_target( name="x", width=1, @@ -158,18 +146,14 @@ def test_list_targets( class TestDelete: - """ - Test for deleting a target. - """ + """Test for deleting a target.""" @staticmethod def test_delete_target( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """ - It is possible to delete a target. - """ + """It is possible to delete a target.""" target_id = vws_client.add_target( name="x", width=1, @@ -185,18 +169,14 @@ def test_delete_target( class TestGetTargetSummaryReport: - """ - Tests for getting a summary report for a target. - """ + """Tests for getting a summary report for a target.""" @staticmethod def test_get_target_summary_report( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """ - Details of a target are returned by ``get_target_summary_report``. - """ + """Details of a target are returned by ``get_target_summary_report``.""" date = "2018-04-25" target_name = uuid.uuid4().hex with freeze_time(time_to_freeze=date): @@ -240,15 +220,11 @@ def test_get_target_summary_report( class TestGetDatabaseSummaryReport: - """ - Tests for getting a summary report for a database. - """ + """Tests for getting a summary report for a database.""" @staticmethod def test_get_target(vws_client: VWS) -> None: - """ - Details of a database are returned by ``get_database_summary_report``. - """ + """Details of a database are returned by ``get_database_summary_report``.""" report = vws_client.get_database_summary_report() expected_report = DatabaseSummaryReport( @@ -287,18 +263,14 @@ def test_get_target(vws_client: VWS) -> None: class TestGetTargetRecord: - """ - Tests for getting a record of a target. - """ + """Tests for getting a record of a target.""" @staticmethod def test_get_target_record( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """ - Details of a target are returned by ``get_target_record``. - """ + """Details of a target are returned by ``get_target_record``.""" target_id = vws_client.add_target( name="x", width=1, @@ -344,9 +316,7 @@ def test_get_failed( vws_client: VWS, image_file_failed_state: io.BytesIO, ) -> None: - """ - Check that the report works with a failed target. - """ + """Check that the report works with a failed target.""" target_id = vws_client.add_target( name="x", width=1, @@ -362,18 +332,14 @@ def test_get_failed( class TestWaitForTargetProcessed: - """ - Tests for waiting for a target to be processed. - """ + """Tests for waiting for a target to be processed.""" @staticmethod def test_wait_for_target_processed( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """ - It is possible to wait until a target is processed. - """ + """It is possible to wait until a target is processed.""" target_id = vws_client.add_target( name="x", width=1, @@ -391,9 +357,7 @@ def test_wait_for_target_processed( def test_default_seconds_between_requests( image: io.BytesIO | BinaryIO, ) -> None: - """ - By default, 0.2 seconds are waited between polling requests. - """ + """By default, 0.2 seconds are waited between polling requests.""" with MockVWS(processing_time_seconds=0.5) as mock: database = VuforiaDatabase() mock.add_database(database=database) @@ -443,9 +407,7 @@ def test_default_seconds_between_requests( def test_custom_seconds_between_requests( image: io.BytesIO | BinaryIO, ) -> None: - """ - It is possible to customize the time waited between polling requests. - """ + """It is possible to customize the time waited between polling requests.""" with MockVWS(processing_time_seconds=0.5) as mock: database = VuforiaDatabase() mock.add_database(database=database) @@ -493,9 +455,7 @@ def test_custom_seconds_between_requests( @staticmethod def test_custom_timeout(image: io.BytesIO | BinaryIO) -> None: - """ - It is possible to set a maximum timeout. - """ + """It is possible to set a maximum timeout.""" with MockVWS(processing_time_seconds=0.5) as mock: database = VuforiaDatabase() mock.add_database(database=database) @@ -531,18 +491,14 @@ def test_custom_timeout(image: io.BytesIO | BinaryIO) -> None: class TestGetDuplicateTargets: - """ - Tests for getting duplicate targets. - """ + """Tests for getting duplicate targets.""" @staticmethod def test_get_duplicate_targets( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """ - It is possible to get the IDs of similar targets. - """ + """It is possible to get the IDs of similar targets.""" target_id = vws_client.add_target( name="x", width=1, @@ -565,9 +521,7 @@ def test_get_duplicate_targets( class TestUpdateTarget: - """ - Tests for updating a target. - """ + """Tests for updating a target.""" @staticmethod def test_update_target( @@ -576,9 +530,7 @@ def test_update_target( different_high_quality_image: io.BytesIO, cloud_reco_client: CloudRecoService, ) -> None: - """ - It is possible to update a target. - """ + """It is possible to update a target.""" old_name = uuid.uuid4().hex old_width = secrets.choice(seq=range(1, 5000)) / 100 target_id = vws_client.add_target( @@ -635,9 +587,7 @@ def test_no_fields_given( vws_client: VWS, image: io.BytesIO | BinaryIO, ) -> None: - """ - It is possible to give no update fields. - """ + """It is possible to give no update fields.""" target_id = vws_client.add_target( name="x", width=1, diff --git a/tests/test_vws_exceptions.py b/tests/test_vws_exceptions.py index 86da6604..eb5b12a6 100644 --- a/tests/test_vws_exceptions.py +++ b/tests/test_vws_exceptions.py @@ -1,6 +1,4 @@ -""" -Tests for VWS exceptions. -""" +"""Tests for VWS exceptions.""" import io import uuid @@ -98,9 +96,7 @@ def test_request_quota_reached() -> None: def test_fail(high_quality_image: io.BytesIO) -> None: - """ - A ``Fail`` exception is raised when the server access key does not exist. - """ + """A ``Fail`` exception is raised when the server access key does not exist.""" with MockVWS(): vws_client = VWS( server_access_key=uuid.uuid4().hex, @@ -120,9 +116,7 @@ def test_fail(high_quality_image: io.BytesIO) -> None: def test_bad_image(vws_client: VWS) -> None: - """ - A ``BadImage`` exception is raised when a non-image is given. - """ + """A ``BadImage`` exception is raised when a non-image is given.""" not_an_image = io.BytesIO(initial_bytes=b"Not an image") with pytest.raises(expected_exception=BadImageError) as exc: vws_client.add_target( @@ -325,9 +319,7 @@ def test_target_status_not_success( def test_vwsexception_inheritance() -> None: - """ - VWS-related exceptions should inherit from VWSException. - """ + """VWS-related exceptions should inherit from VWSException.""" subclasses = [ AuthenticationFailureError, BadImageError, @@ -354,9 +346,7 @@ def test_base_exception( vws_client: VWS, high_quality_image: io.BytesIO, ) -> None: - """ - ``VWSException``s has a response property. - """ + """``VWSException``s has a response property.""" with pytest.raises(expected_exception=VWSError) as exc: vws_client.get_target_record(target_id="a")