From c0574b6f35002f1f3f18335397e374d1a01950d5 Mon Sep 17 00:00:00 2001 From: Claudio Matsuoka Date: Sat, 9 Sep 2023 17:26:42 -0300 Subject: [PATCH] ci(linters): address more pyright warnings Signed-off-by: Claudio Matsuoka --- craft_application/application.py | 4 +-- craft_application/models/project.py | 3 +-- tests/conftest.py | 6 ++--- tests/integration/services/test_provider.py | 3 ++- tests/unit/models/test_project.py | 28 ++++++++------------- tests/unit/test_application.py | 15 ++++++----- 6 files changed, 28 insertions(+), 31 deletions(-) diff --git a/craft_application/application.py b/craft_application/application.py index 5411313e..10b6e6fb 100644 --- a/craft_application/application.py +++ b/craft_application/application.py @@ -47,7 +47,7 @@ class _Dispatcher(craft_cli.Dispatcher): @property def parsed_args(self) -> argparse.Namespace: """The map of parsed command-line arguments.""" - return self._parsed_command_args + return self._parsed_command_args or argparse.Namespace() @final @@ -129,7 +129,7 @@ def cache_dir(self) -> str: # xdg types: https://github.com/python/typeshed/pull/10163 return save_cache_path(self.app.name) # type: ignore[no-any-return] - def _configure_services(self, build_for: str) -> None: + def _configure_services(self, build_for: str | None) -> None: """Configure additional keyword arguments for any service classes. Any child classes that override this must either call this directly or must diff --git a/craft_application/models/project.py b/craft_application/models/project.py index c9c0cd45..8643bce4 100644 --- a/craft_application/models/project.py +++ b/craft_application/models/project.py @@ -17,7 +17,6 @@ This defines the structure of the input file (e.g. snapcraft.yaml) """ -import abc import dataclasses from typing import Any, Dict, List, Optional, Union @@ -80,6 +79,6 @@ def effective_base(self) -> Any: # noqa: ANN401 app specific classes can improv return self.base raise RuntimeError("Could not determine effective base") - @abc.abstractmethod def get_build_plan(self) -> List[BuildInfo]: """Obtain the list of architectures and bases from the project file.""" + raise NotImplementedError diff --git a/tests/conftest.py b/tests/conftest.py index fc689113..b54ac301 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -31,9 +31,9 @@ from collections.abc import Iterator -class MyProject(craft_application.models.Project): +class MyProject(models.Project): def get_build_plan(self) -> list[models.BuildInfo]: - arch = craft_application.util.get_host_architecture() + arch = util.get_host_architecture() return [models.BuildInfo(arch, arch, bases.BaseName("ubuntu", "22.04"))] @@ -50,7 +50,7 @@ def app_metadata() -> craft_application.AppMetadata: @pytest.fixture() -def fake_project() -> MyProject: +def fake_project() -> models.Project: return MyProject( name="full-project", # pyright: ignore[reportGeneralTypeIssues] title="A fully-defined project", # pyright: ignore[reportGeneralTypeIssues] diff --git a/tests/integration/services/test_provider.py b/tests/integration/services/test_provider.py index a89b88a1..8a7c660b 100644 --- a/tests/integration/services/test_provider.py +++ b/tests/integration/services/test_provider.py @@ -21,6 +21,7 @@ import pytest from craft_application.models import BuildInfo from craft_application.util import get_host_architecture +from craft_providers import bases @pytest.mark.parametrize( @@ -57,7 +58,7 @@ def test_provider_lifecycle( provider_service.get_provider(name) arch = get_host_architecture() - build_info = BuildInfo(arch, arch, craft_providers.bases.BaseName(*base_name)) + build_info = BuildInfo(arch, arch, bases.BaseName(*base_name)) instance = provider_service.instance(build_info, work_dir=snap_safe_tmp_path) executor = None try: diff --git a/tests/unit/models/test_project.py b/tests/unit/models/test_project.py index 8895b044..d8155094 100644 --- a/tests/unit/models/test_project.py +++ b/tests/unit/models/test_project.py @@ -16,23 +16,17 @@ """Tests for BaseProject""" import pathlib from textwrap import dedent -from typing import List, Optional +from typing import Optional import pytest from craft_application.errors import CraftValidationError -from craft_application.models import BuildInfo, Project - - -class MyProject(Project): - def get_build_plan(self) -> List[BuildInfo]: - return [] - +from craft_application.models import Project PROJECTS_DIR = pathlib.Path(__file__).parent / "project_models" PARTS_DICT = {"my-part": {"plugin": "nil"}} # pyright doesn't like these types and doesn't have a pydantic plugin like mypy. # Because of this, we need to silence several errors in these constants. -BASIC_PROJECT = MyProject( +BASIC_PROJECT = Project( name="project-name", # pyright: ignore[reportGeneralTypeIssues] version="1.0", # pyright: ignore[reportGeneralTypeIssues] parts=PARTS_DICT, @@ -42,7 +36,7 @@ def get_build_plan(self) -> List[BuildInfo]: "version": "1.0", "parts": PARTS_DICT, } -FULL_PROJECT = MyProject( +FULL_PROJECT = Project( name="full-project", # pyright: ignore[reportGeneralTypeIssues] title="A fully-defined project", # pyright: ignore[reportGeneralTypeIssues] base="core24", @@ -88,23 +82,23 @@ def test_marshal(project, project_dict): [(BASIC_PROJECT, BASIC_PROJECT_DICT), (FULL_PROJECT, FULL_PROJECT_DICT)], ) def test_unmarshal_success(project, project_dict): - assert MyProject.unmarshal(project_dict) == project + assert Project.unmarshal(project_dict) == project @pytest.mark.parametrize("data", [None, [], (), 0, ""]) def test_unmarshal_error(data): with pytest.raises(TypeError): - MyProject.unmarshal(data) + Project.unmarshal(data) @pytest.mark.parametrize("project", [BASIC_PROJECT, FULL_PROJECT]) def test_marshal_then_unmarshal(project): - assert MyProject.unmarshal(project.marshal()) == project + assert Project.unmarshal(project.marshal()) == project @pytest.mark.parametrize("project_dict", [BASIC_PROJECT_DICT, FULL_PROJECT_DICT]) def test_unmarshal_then_marshal(project_dict): - assert MyProject.unmarshal(project_dict).marshal() == project_dict + assert Project.unmarshal(project_dict).marshal() == project_dict @pytest.mark.parametrize( @@ -116,7 +110,7 @@ def test_unmarshal_then_marshal(project_dict): ) def test_from_yaml_file_success(project_file, expected): with project_file.open(): - actual = MyProject.from_yaml_file(project_file) + actual = Project.from_yaml_file(project_file) assert expected == actual @@ -130,7 +124,7 @@ def test_from_yaml_file_success(project_file, expected): ) def test_from_yaml_file_failure(project_file, error_class): with pytest.raises(error_class): - MyProject.from_yaml_file(project_file) + Project.from_yaml_file(project_file) @pytest.mark.parametrize( @@ -153,7 +147,7 @@ def test_effective_base_is_base(project): assert project.effective_base == project.base -class FakeBuildBaseProject(MyProject): +class FakeBuildBaseProject(Project): build_base: Optional[str] diff --git a/tests/unit/test_application.py b/tests/unit/test_application.py index f62f213c..dfd50029 100644 --- a/tests/unit/test_application.py +++ b/tests/unit/test_application.py @@ -28,6 +28,9 @@ import pytest_check from craft_application import application, commands, services from craft_application.models import BuildInfo +from craft_application.util import ( + get_host_architecture, # pyright: ignore[reportGeneralTypeIssues] +) from craft_providers import bases EMPTY_COMMAND_GROUP = craft_cli.CommandGroup("FakeCommands", []) @@ -48,7 +51,7 @@ def app(app_metadata, fake_services): @pytest.fixture() def mock_dispatcher(monkeypatch): - dispatcher = mock.Mock(spec_set=craft_application.application._Dispatcher) + dispatcher = mock.Mock(spec_set=application._Dispatcher) monkeypatch.setattr( "craft_application.application._Dispatcher", mock.Mock(return_value=dispatcher) ) @@ -101,7 +104,7 @@ def test_run_managed_success(app, fake_project, emitter): app.services.provider = mock_provider app.project = fake_project - arch = craft_application.util.get_host_architecture() + arch = get_host_architecture() app.run_managed(arch) emitter.assert_debug(f"Running testcraft in {arch} instance...") @@ -115,7 +118,7 @@ def test_run_managed_failure(app, fake_project): app.project = fake_project with pytest.raises(craft_providers.ProviderError) as exc_info: - app.run_managed(craft_application.util.get_host_architecture()) + app.run_managed(get_host_architecture()) assert exc_info.value.brief == "Failed to execute testcraft in instance." @@ -125,7 +128,7 @@ def test_run_managed_multiple(app, fake_project, emitter, monkeypatch): app.services.provider = mock_provider app.project = fake_project - arch = craft_application.util.get_host_architecture() + arch = get_host_architecture() monkeypatch.setattr( app.project.__class__, "get_build_plan", @@ -145,7 +148,7 @@ def test_run_managed_specified(app, fake_project, emitter, monkeypatch): app.services.provider = mock_provider app.project = fake_project - arch = craft_application.util.get_host_architecture() + arch = get_host_architecture() monkeypatch.setattr( app.project.__class__, "get_build_plan", @@ -242,7 +245,7 @@ def test_run_success_managed(monkeypatch, app, fake_project): def test_run_success_managed_with_arch(monkeypatch, app, fake_project): app.project = fake_project app.run_managed = mock.Mock() - arch = craft_application.util.get_host_architecture() + arch = get_host_architecture() monkeypatch.setattr(sys, "argv", ["testcraft", "pull", f"--build-for={arch}"]) pytest_check.equal(app.run(), 0)