From fd66cb9624c2aa03cd17b94468776468bf4ddcb5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 13 May 2023 20:10:05 +0000 Subject: [PATCH 1/2] Bump pyright from 1.1.304 to 1.1.308 Bumps [pyright](https://github.com/RobertCraigie/pyright-python) from 1.1.304 to 1.1.308. - [Release notes](https://github.com/RobertCraigie/pyright-python/releases) - [Commits](https://github.com/RobertCraigie/pyright-python/compare/v1.1.304...v1.1.308) --- updated-dependencies: - dependency-name: pyright dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7a5b802e7..3aec3bcfb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -294,7 +294,7 @@ dev = [ "pydocstyle==6.3.0", "pyenchant==3.2.2", "pylint==2.17.4", - "pyright==1.1.304", + "pyright==1.1.308", "pyroma==4.2", "pytest-cov==4.0.0", "pytest==7.3.1", From e41290b6e1ac33a0941afa8c3c904b18366460f1 Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Mon, 15 May 2023 00:43:25 +0100 Subject: [PATCH 2/2] Fix or disable pyright issues --- pyproject.toml | 2 ++ spelling_private_dict.txt | 1 + src/mock_vws/_query_tools.py | 4 ++- .../_query_validators/image_validators.py | 24 +++++++++----- src/mock_vws/target_raters.py | 8 ++++- tests/mock_vws/test_docker.py | 32 +++++++++++++++---- 6 files changed, 54 insertions(+), 17 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 3aec3bcfb..d7bb5636d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -144,6 +144,7 @@ module = [ "cv2", "docker", "docker.errors", + "docker.models.containers", "docker.models.networks", "multipart", "sybil", @@ -211,6 +212,7 @@ ignore = [ # Ignore "too-many-*" errors as they seem to get in the way more than # helping. "PLR0913", + "PLR0915", # Allow 'assert' in tests as it is the standard for pytest. # Also, allow 'assert' in other code as it is the standard for Python type hint # narrowing - see diff --git a/spelling_private_dict.txt b/spelling_private_dict.txt index 828179b7e..682f20923 100644 --- a/spelling_private_dict.txt +++ b/spelling_private_dict.txt @@ -80,6 +80,7 @@ recognitions refactoring regex reimplementation +reportGeneralTypeIssues repr reqheader reqjson diff --git a/src/mock_vws/_query_tools.py b/src/mock_vws/_query_tools.py index 722133ba5..7b8467cfd 100644 --- a/src/mock_vws/_query_tools.py +++ b/src/mock_vws/_query_tools.py @@ -84,7 +84,9 @@ def get_query_match_response_text( else: include_target_data = parsed_include_target_data.value.lower() - image_value = parsed.get("image").raw + image_part = parsed.get("image") + assert image_part is not None + image_value = image_part.raw gmt = ZoneInfo("GMT") now = datetime.datetime.now(tz=gmt) diff --git a/src/mock_vws/_query_validators/image_validators.py b/src/mock_vws/_query_validators/image_validators.py index d845aedcc..84f4887e1 100644 --- a/src/mock_vws/_query_validators/image_validators.py +++ b/src/mock_vws/_query_validators/image_validators.py @@ -67,7 +67,9 @@ def validate_image_file_size( boundary = email_message.get_boundary() assert isinstance(boundary, str) parsed = multipart.MultipartParser(stream=body_file, boundary=boundary) - image = parsed.get("image").raw + image_part = parsed.get("image") + assert image_part is not None + image_value = image_part.raw # This is the documented maximum size of a PNG as per. # https://library.vuforia.com/web-api/vuforia-query-web-api. @@ -77,7 +79,7 @@ def validate_image_file_size( # Ignore coverage on this as there is a bug in urllib3 which means that we # do not trigger this exception. # See https://github.com/urllib3/urllib3/issues/2733. - if len(image) > max_bytes: # pragma: no cover + if len(image_value) > max_bytes: # pragma: no cover _LOGGER.warning(msg="The image file size is too large.") raise RequestEntityTooLarge @@ -104,8 +106,10 @@ def validate_image_dimensions( boundary = email_message.get_boundary() assert isinstance(boundary, str) parsed = multipart.MultipartParser(stream=body_file, boundary=boundary) - image = parsed.get("image").raw - image_file = io.BytesIO(image) + image_part = parsed.get("image") + assert image_part is not None + image_value = image_part.raw + image_file = io.BytesIO(image_value) pil_image = Image.open(image_file) max_width = 30000 max_height = 30000 @@ -137,9 +141,11 @@ def validate_image_format( boundary = email_message.get_boundary() assert isinstance(boundary, str) parsed = multipart.MultipartParser(stream=body_file, boundary=boundary) - image = parsed.get("image").raw + image_part = parsed.get("image") + assert image_part is not None + image_value = image_part.raw - image_file = io.BytesIO(image) + image_file = io.BytesIO(image_value) pil_image = Image.open(image_file) if pil_image.format in {"PNG", "JPEG"}: @@ -170,9 +176,11 @@ def validate_image_is_image( boundary = email_message.get_boundary() assert isinstance(boundary, str) parsed = multipart.MultipartParser(stream=body_file, boundary=boundary) - image = parsed.get("image").raw + image_part = parsed.get("image") + assert image_part is not None + image_value = image_part.raw - image_file = io.BytesIO(image) + image_file = io.BytesIO(image_value) try: Image.open(image_file) diff --git a/src/mock_vws/target_raters.py b/src/mock_vws/target_raters.py index 451ca32ee..7f1cd786d 100644 --- a/src/mock_vws/target_raters.py +++ b/src/mock_vws/target_raters.py @@ -11,6 +11,12 @@ import numpy as np from PIL import Image +# cv2 errors cannot be inferred without type stubs. +# See https://github.com/opencv/opencv/issues/14590. +_CV2_ERROR = ( + cv2.error # pyright: ignore[reportGeneralTypeIssues] # noqa: E501 # pylint: disable=no-member +) + @functools.cache def _get_brisque_target_tracking_rating(image_content: bytes) -> int: @@ -32,7 +38,7 @@ def _get_brisque_target_tracking_rating(image_content: bytes) -> int: with np.errstate(divide="ignore", invalid="ignore"): try: score = brisque_obj.score(img=image_array) - except (cv2.error, ValueError): # pylint: disable=no-member + except (_CV2_ERROR, ValueError): return 0 if math.isnan(score): return 0 diff --git a/tests/mock_vws/test_docker.py b/tests/mock_vws/test_docker.py index 37ccd0949..b8ccab4dd 100644 --- a/tests/mock_vws/test_docker.py +++ b/tests/mock_vws/test_docker.py @@ -13,7 +13,9 @@ import docker import pytest import requests -from docker.errors import BuildError +from docker.errors import BuildError, NotFound +from docker.models.containers import Container +from docker.models.networks import Network from mock_vws.database import VuforiaDatabase from vws import VWS, CloudRecoService @@ -21,8 +23,6 @@ import io from collections.abc import Iterator - from docker.models.networks import Network - # We do not cover this function because hitting particular branches depends on # timing. @@ -72,13 +72,15 @@ def fixture_custom_bridge_network() -> Iterator[Network]: name="test-vws-bridge-" + uuid.uuid4().hex, driver="bridge", ) - except docker.errors.NotFound: + except NotFound: # On Windows the "bridge" network driver is not available and we use # the "nat" driver instead. network = client.networks.create( name="test-vws-bridge-" + uuid.uuid4().hex, driver="nat", ) + + assert isinstance(network, Network) try: yield network finally: @@ -115,7 +117,7 @@ def test_build_and_run( vwq_tag = f"vws-mock-vwq:latest-{random}" try: - target_manager_image, _ = client.images.build( + target_manager_build_result = client.images.build( path=str(repository_root), dockerfile=str(target_manager_dockerfile), tag=target_manager_tag, @@ -133,16 +135,23 @@ def test_build_and_run( reason = "We do not currently support using Windows containers." pytest.skip(reason) - vws_image, _ = client.images.build( + assert isinstance(target_manager_build_result, tuple) + target_manager_image, _ = target_manager_build_result + + vws_build_result = client.images.build( path=str(repository_root), dockerfile=str(vws_dockerfile), tag=vws_tag, ) - vwq_image, _ = client.images.build( + assert isinstance(vws_build_result, tuple) + vws_image, _ = vws_build_result + vwq_build_result = client.images.build( path=str(repository_root), dockerfile=str(vwq_dockerfile), tag=vwq_tag, ) + assert isinstance(vwq_build_result, tuple) + vwq_image, _ = vwq_build_result database = VuforiaDatabase() target_manager_container_name = "vws-mock-target-manager-" + random @@ -178,9 +187,16 @@ def test_build_and_run( }, ) + assert isinstance(target_manager_container, Container) + assert isinstance(vws_container, Container) + assert isinstance(vwq_container, Container) for container in (target_manager_container, vws_container, vwq_container): container.reload() + assert isinstance(target_manager_container.attrs, dict) + target_manager_port_attrs = target_manager_container.attrs[ + "NetworkSettings" + ]["Ports"] target_manager_port_attrs = target_manager_container.attrs[ "NetworkSettings" ]["Ports"] @@ -189,10 +205,12 @@ def test_build_and_run( "HostPort" ] + assert isinstance(vws_container.attrs, dict) vws_port_attrs = vws_container.attrs["NetworkSettings"]["Ports"] vws_host_ip = vws_port_attrs["5000/tcp"][0]["HostIp"] vws_host_port = vws_port_attrs["5000/tcp"][0]["HostPort"] + assert isinstance(vwq_container.attrs, dict) vwq_port_attrs = vwq_container.attrs["NetworkSettings"]["Ports"] vwq_host_ip = vwq_port_attrs["5000/tcp"][0]["HostIp"] vwq_host_port = vwq_port_attrs["5000/tcp"][0]["HostPort"]