Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ min_python_version = 3.6.0
max-line-length = 88
ban-relative-imports = true
inline-quotes = double
# Allow omission of a return type hint for __init__ if at least one argument is annotated
# used by flake8-annotations
mypy-init-return = true
enable-extensions = TC, TC2
type-checking-exempt-modules = typing, typing-extensions
extend-ignore =
Expand All @@ -12,10 +15,17 @@ extend-ignore =
E203,
# SIM106: Handle error-cases first
SIM106,
# ANN101: Missing type annotation for self in method
ANN101,
Comment thread
neersighted marked this conversation as resolved.
Resolved
# ANN102: Missing type annotation for cls in classmethod
ANN102,
per-file-ignores =
# F401: Module imported by unused (non-implicit modules)
# TC002: Move third-party import '...' into a type-checking block
__init__.py:F401,TC002,
# ANN201: Missing return type annotation for public function
tests/test_*:ANN201
Comment thread
neersighted marked this conversation as resolved.
Resolved
tests/**/test_*:ANN201
extend-exclude =
# Frozen and not subject to change in this repo:
get-poetry.py,
Expand Down
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ repos:
hooks:
- id: yesqa
additional_dependencies: &flake8_deps
- flake8-annotations==2.7.0
- flake8-broken-line==0.4.0
- flake8-bugbear==21.9.2
- flake8-comprehensions==3.7.0
Expand Down
2 changes: 1 addition & 1 deletion src/poetry/installation/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ def execute(self, operations: List["OperationTypes"]) -> int:
return 1 if self._shutdown else 0

@staticmethod
def _get_max_workers(desired_max_workers: Optional[int] = None):
def _get_max_workers(desired_max_workers: Optional[int] = None) -> int:
# This should be directly handled by ThreadPoolExecutor
# however, on some systems the number of CPUs cannot be determined
# (it raises a NotImplementedError), so, in this case, we assume
Expand Down
74 changes: 48 additions & 26 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
from pathlib import Path
from typing import TYPE_CHECKING
from typing import Any
from typing import Callable
from typing import Dict
from typing import Iterator
from typing import List
from typing import Optional
from typing import TextIO
from typing import Tuple
from typing import Type

Expand Down Expand Up @@ -42,8 +43,15 @@


if TYPE_CHECKING:
from pytest_mock import MockerFixture

from poetry.installation.executor import Executor
from poetry.poetry import Poetry
from poetry.utils.env import Env
from poetry.utils.env import MockEnv
from tests.helpers import PoetryTestApplication
from tests.types import CommandTesterFactory
from tests.types import FixtureDirGetter
from tests.types import ProjectFactory


Expand All @@ -68,41 +76,43 @@ def all(self) -> Dict[str, Any]:


class DummyBackend(KeyringBackend):
def __init__(self):
def __init__(self) -> None:
self._passwords = {}

@classmethod
def priority(cls):
def priority(cls) -> int:
return 42

def set_password(self, service, username, password):
def set_password(
self, service: str, username: Optional[str], password: Any
) -> None:
self._passwords[service] = {username: password}

def get_password(self, service, username):
def get_password(self, service: str, username: Optional[str]) -> Any:
return self._passwords.get(service, {}).get(username)

def get_credential(self, service, username):
def get_credential(self, service: str, username: Optional[str]) -> Any:
return self._passwords.get(service, {}).get(username)

def delete_password(self, service, username):
def delete_password(self, service: str, username: Optional[str]) -> None:
if service in self._passwords and username in self._passwords[service]:
del self._passwords[service][username]


@pytest.fixture()
def dummy_keyring():
def dummy_keyring() -> DummyBackend:
return DummyBackend()


@pytest.fixture()
def with_simple_keyring(dummy_keyring):
def with_simple_keyring(dummy_keyring: DummyBackend) -> None:
import keyring

keyring.set_keyring(dummy_keyring)


@pytest.fixture()
def with_fail_keyring():
def with_fail_keyring() -> None:
import keyring

from keyring.backends.fail import Keyring
Expand All @@ -111,7 +121,7 @@ def with_fail_keyring():


@pytest.fixture()
def with_chained_keyring(mocker):
def with_chained_keyring(mocker: "MockerFixture") -> None:
from keyring.backends.fail import Keyring

mocker.patch("keyring.backend.get_all_keyring", [Keyring()])
Expand All @@ -130,12 +140,12 @@ def config_cache_dir(tmp_dir: str) -> Path:


@pytest.fixture
def config_virtualenvs_path(config_cache_dir):
def config_virtualenvs_path(config_cache_dir: Path) -> Path:
return config_cache_dir / "virtualenvs"


@pytest.fixture
def config_source(config_cache_dir):
def config_source(config_cache_dir: Path) -> DictConfigSource:
source = DictConfigSource()
source.add_property("cache-dir", str(config_cache_dir))

Expand All @@ -150,7 +160,11 @@ def auth_config_source() -> DictConfigSource:


@pytest.fixture
def config(config_source, auth_config_source, mocker) -> Config:
def config(
config_source: DictConfigSource,
auth_config_source: DictConfigSource,
mocker: "MockerFixture",
) -> Config:
import keyring

from keyring.backends.fail import Keyring
Expand All @@ -169,7 +183,7 @@ def config(config_source, auth_config_source, mocker) -> Config:


@pytest.fixture(autouse=True)
def mock_user_config_dir(mocker):
def mock_user_config_dir(mocker: "MockerFixture") -> Iterator[None]:
config_dir = tempfile.mkdtemp(prefix="poetry_config_")
mocker.patch("poetry.locations.CONFIG_DIR", new=config_dir)
mocker.patch("poetry.factory.CONFIG_DIR", new=config_dir)
Expand All @@ -178,17 +192,17 @@ def mock_user_config_dir(mocker):


@pytest.fixture(autouse=True)
def download_mock(mocker):
def download_mock(mocker: "MockerFixture") -> None:
# Patch download to not download anything but to just copy from fixtures
mocker.patch("poetry.utils.helpers.download_file", new=mock_download)
mocker.patch("poetry.puzzle.provider.download_file", new=mock_download)
mocker.patch("poetry.repositories.pypi_repository.download_file", new=mock_download)


@pytest.fixture(autouse=True)
def pep517_metadata_mock(mocker):
def pep517_metadata_mock(mocker: "MockerFixture") -> None:
@classmethod
def _pep517_metadata(cls, path):
def _pep517_metadata(cls: PackageInfo, path: Path) -> PackageInfo:
with suppress(PackageInfoError):
return PackageInfo.from_setup_files(path)
return PackageInfo(name="demo", version="0.1.2")
Expand All @@ -210,7 +224,7 @@ def environ() -> Iterator[None]:


@pytest.fixture(autouse=True)
def git_mock(mocker):
def git_mock(mocker: "MockerFixture") -> None:
# Patch git module to not actually clone projects
mocker.patch("poetry.core.vcs.git.Git.clone", new=mock_clone)
mocker.patch("poetry.core.vcs.git.Git.checkout", new=lambda *_: None)
Expand All @@ -235,8 +249,8 @@ def fixture_base() -> Path:


@pytest.fixture
def fixture_dir(fixture_base: Path) -> Callable[[str], Path]:
def _fixture_dir(name: str):
def fixture_dir(fixture_base: Path) -> "FixtureDirGetter":
def _fixture_dir(name: str) -> Path:
return fixture_base / name

return _fixture_dir
Expand All @@ -252,18 +266,18 @@ def tmp_dir() -> Iterator[str]:


@pytest.fixture
def mocked_open_files(mocker):
def mocked_open_files(mocker: "MockerFixture") -> List:
files = []
original = Path.open

def mocked_open(self, *args, **kwargs):
def mocked_open(self: Path, *args: Any, **kwargs: Any) -> TextIO:
if self.name in {"pyproject.toml"}:
return mocker.MagicMock()
return original(self, *args, **kwargs)

mocker.patch("pathlib.Path.open", mocked_open)

yield files
return files


@pytest.fixture
Expand Down Expand Up @@ -376,8 +390,16 @@ def _factory(


@pytest.fixture
def command_tester_factory(app, env) -> "CommandTesterFactory":
def _tester(command, poetry=None, installer=None, executor=None, environment=None):
def command_tester_factory(
app: "PoetryTestApplication", env: "MockEnv"
) -> "CommandTesterFactory":
def _tester(
command: str,
poetry: Optional["Poetry"] = None,
installer: Optional[Installer] = None,
executor: Optional["Executor"] = None,
environment: Optional["Env"] = None,
) -> CommandTester:
command = app.find(command)
tester = CommandTester(command)

Expand Down
4 changes: 2 additions & 2 deletions tests/console/commands/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import os

from typing import TYPE_CHECKING
from typing import Callable

import pytest

Expand All @@ -20,6 +19,7 @@
from poetry.config.dict_config_source import DictConfigSource
from tests.conftest import Config
from tests.types import CommandTesterFactory
from tests.types import FixtureDirGetter


@pytest.fixture()
Expand Down Expand Up @@ -98,7 +98,7 @@ def test_display_single_setting(tester: "CommandTester", config: "Config"):


def test_display_single_local_setting(
command_tester_factory: "CommandTesterFactory", fixture_dir: Callable[[str], "Path"]
command_tester_factory: "CommandTesterFactory", fixture_dir: "FixtureDirGetter"
):
tester = command_tester_factory(
"config", poetry=Factory().create_poetry(fixture_dir("with_local_config"))
Expand Down
8 changes: 4 additions & 4 deletions tests/console/commands/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

from pathlib import Path
from typing import TYPE_CHECKING
from typing import Callable
from typing import Iterator

import pytest
Expand All @@ -22,6 +21,7 @@

from poetry.poetry import Poetry
from tests.helpers import TestRepository
from tests.types import FixtureDirGetter


@pytest.fixture
Expand Down Expand Up @@ -339,7 +339,7 @@ def test_interactive_with_directory_dependency(
tester: CommandTester,
repo: "TestRepository",
source_dir: Path,
fixture_dir: Callable[[str], Path],
fixture_dir: "FixtureDirGetter",
):
repo.add_package(get_package("pendulum", "2.0.0"))
repo.add_package(get_package("pytest", "3.6.0"))
Expand Down Expand Up @@ -390,7 +390,7 @@ def test_interactive_with_directory_dependency_and_other_name(
tester: CommandTester,
repo: "TestRepository",
source_dir: Path,
fixture_dir: Callable[[str], Path],
fixture_dir: "FixtureDirGetter",
):
repo.add_package(get_package("pendulum", "2.0.0"))
repo.add_package(get_package("pytest", "3.6.0"))
Expand Down Expand Up @@ -442,7 +442,7 @@ def test_interactive_with_file_dependency(
tester: CommandTester,
repo: "TestRepository",
source_dir: Path,
fixture_dir: Callable[[str], Path],
fixture_dir: "FixtureDirGetter",
):
repo.add_package(get_package("pendulum", "2.0.0"))
repo.add_package(get_package("pytest", "3.6.0"))
Expand Down
10 changes: 5 additions & 5 deletions tests/console/commands/test_lock.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from pathlib import Path
from typing import TYPE_CHECKING
from typing import Callable
from typing import Type

import pytest
Expand All @@ -17,6 +16,7 @@
from poetry.poetry import Poetry
from tests.helpers import TestRepository
from tests.types import CommandTesterFactory
from tests.types import FixtureDirGetter
from tests.types import ProjectFactory


Expand All @@ -33,7 +33,7 @@ def tester(command_tester_factory: "CommandTesterFactory") -> "CommandTester":
def _project_factory(
fixture_name: str,
project_factory: "ProjectFactory",
fixture_dir: Callable[[str], Path],
fixture_dir: "FixtureDirGetter",
) -> "Poetry":
source = fixture_dir(fixture_name)
pyproject_content = (source / "pyproject.toml").read_text(encoding="utf-8")
Expand All @@ -47,21 +47,21 @@ def _project_factory(

@pytest.fixture
def poetry_with_outdated_lockfile(
project_factory: "ProjectFactory", fixture_dir: Callable[[str], Path]
project_factory: "ProjectFactory", fixture_dir: "FixtureDirGetter"
) -> "Poetry":
return _project_factory("outdated_lock", project_factory, fixture_dir)


@pytest.fixture
def poetry_with_up_to_date_lockfile(
project_factory: "ProjectFactory", fixture_dir: Callable[[str], Path]
project_factory: "ProjectFactory", fixture_dir: "FixtureDirGetter"
) -> "Poetry":
return _project_factory("up_to_date_lock", project_factory, fixture_dir)


@pytest.fixture
def poetry_with_old_lockfile(
project_factory: "ProjectFactory", fixture_dir: Callable[[str], Path]
project_factory: "ProjectFactory", fixture_dir: "FixtureDirGetter"
) -> "Poetry":
return _project_factory("old_lock", project_factory, fixture_dir)

Expand Down
Loading