Skip to content

Commit

Permalink
Merge pull request #98 from enpaul/enp/refactor
Browse files Browse the repository at this point in the history
Overhaul for stable
  • Loading branch information
enpaul authored Aug 20, 2024
2 parents e875008 + bbb075a commit 536fd65
Show file tree
Hide file tree
Showing 23 changed files with 1,643 additions and 2,099 deletions.
1 change: 0 additions & 1 deletion .github/scripts/setup-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ poetry --version --no-ansi;
poetry run pip --version;

poetry install \
--extras poetry \
--quiet \
--remove-untracked \
--no-ansi;
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ jobs:
strategy:
matrix:
python:
- version: "3.7"
toxenv: py37
- version: "3.8"
toxenv: py38
- version: "3.9"
Expand All @@ -22,6 +20,8 @@ jobs:
toxenv: py310
- version: "3.11"
toxenv: py311
- version: "3.12"
toxenv: py312
fail-fast: true
steps:
- name: Checkout
Expand Down
7 changes: 4 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,13 @@ repos:

- id: reorder-python-imports
name: reorder-python-imports
entry: reorder-python-imports
entry: isort
language: system
args:
- "--unclassifiable-application-module=tox_poetry_installer"
require_serial: true
types:
- python
args:
- "--filter-files"

- id: black
name: black
Expand Down
1 change: 0 additions & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
# --disable=W"
disable=logging-fstring-interpolation
,logging-format-interpolation
,bad-continuation
,line-too-long
,ungrouped-imports
,typecheck
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,6 @@ error will be set to one of the "Status" values below to indicate what the error
| `LockedDepNotFoundError` | Indicates that an item specified in the `locked_deps` config option does not match the name of a package in the Poetry lockfile. |
| `LockedDepsRequiredError` | Indicates that a test environment with the `require_locked_deps` config option set to `true` also specified unlocked dependencies using the [`deps`](https://tox.readthedocs.io/en/latest/config.html#conf-deps) config option. |
| `PoetryNotInstalledError` | Indicates that the `poetry` module could not be imported under the current runtime environment, and `require_poetry = true` was specified. |
| `RequiresUnsafeDepError` | Indicates that the package-under-test depends on a package that Poetry has classified as unsafe and cannot be installed. |

> ℹ️ **Note:** One or more of these errors can be caused by the `pyproject.toml` being out
> of sync with the Poetry lockfile. If this is the case, than a warning will be logged
Expand Down
2,775 changes: 1,186 additions & 1,589 deletions poetry.lock

Large diffs are not rendered by default.

51 changes: 26 additions & 25 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,45 +23,46 @@ classifiers = [
"Natural Language :: English",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: Implementation :: CPython",
]

[tool.poetry.plugins.tox]
poetry_installer = "tox_poetry_installer"

[tool.poetry.extras]
poetry = ["poetry", "cleo"]

[tool.poetry.dependencies]
python = "^3.7"
cleo = {version = ">=1.0,<3.0", optional = true}
poetry = {version = "^1.5.0", optional = true}
python = "^3.8"
cleo = ">=1.0,<3.0"
poetry = "^1.5.0"
poetry-core = "^1.1.0"
tox = "^4"
tox = "^4.1"

[tool.poetry.group.dev.dependencies]
bandit = "^1.6.2"
black = "^22.3.0"
blacken-docs = "^1.8.0"
ipython = {version = "^8.10.1", python = "^3.8"}
mdformat = "^0.7"
mdformat-gfm = "^0.3"
mypy = "^0.930"
pre-commit = "^2.7.1"
pre-commit-hooks = "^3.3.0"
pylint = "^2.13.0"
pytest = "^6.0.2"
pytest-cov = "^2.10.1"
reorder-python-imports = "^2.3.5"
safety = "^2.2.0"
toml = "^0.10.1"
tox = "^4"
types-toml = "^0.10.1"
bandit = {version = "^1.7.7", python = "^3.10"}
black = {version = "^24.3.0", python = "^3.10"}
blacken-docs = {version = "^1.18.0", python = "^3.10"}
ipython = {version = "^8.10.1", python = "^3.10"}
isort = {version = "^5.13.2", python = "^3.10"}
mdformat = {version = "^0.7", python = "^3.10"}
mdformat-gfm = {version = "^0.3", python = "^3.10"}
mypy = {version = "^1.11.1", python = "^3.10"}
pre-commit = {version = "^3.8.0", python = "^3.10"}
pre-commit-hooks = {version = "^4.6.0", python = "^3.10"}
pylint = {version = "^3.2.6", python = "^3.10"}
pytest = {version = "^8.3.2", python = "^3.10"}
pytest-cov = {version = "^5.0.0", python = "^3.10"}
toml = {version = "^0.10.1", python = "^3.10"}
tox = "^4.1"
types-toml = {version = "^0.10.1", python = "^3.10"}

[tool.isort]
profile = "black"
force_single_line = "true"
lines_after_imports = 2

[build-system]
requires = ["poetry-core>=1.1.0"]
Expand Down
20 changes: 13 additions & 7 deletions tests/fixtures.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# pylint: disable=missing-module-docstring, missing-function-docstring, unused-argument, too-few-public-methods
# pylint: disable=missing-module-docstring,missing-function-docstring,unused-argument,too-few-public-methods,protected-access
import time
from pathlib import Path
from typing import List

import poetry.factory
import poetry.installation.executor
import poetry.installation.operations.operation
import poetry.utils.env
import pytest
import tox.tox_env.python.virtual_env.runner
from poetry.installation.operations.operation import Operation

from tox_poetry_installer import utilities
import tox_poetry_installer.hooks._tox_on_install_helpers


TEST_PROJECT_PATH = Path(__file__).parent.resolve() / "test-project"
Expand Down Expand Up @@ -40,14 +40,20 @@ class MockExecutor:
def __init__(self, env: MockVirtualEnv, **kwargs):
self.env = env

def execute(self, operations: List[Operation]):
def execute(
self, operations: List[poetry.installation.operations.operation.Operation]
):
self.env.installed.extend([operation.package for operation in operations])
time.sleep(1)


@pytest.fixture
def mock_venv(monkeypatch):
monkeypatch.setattr(utilities, "convert_virtualenv", lambda venv: venv)
monkeypatch.setattr(
tox_poetry_installer.hooks._tox_on_install_helpers,
"convert_virtualenv",
lambda venv: venv,
)
monkeypatch.setattr(poetry.installation.executor, "Executor", MockExecutor)
monkeypatch.setattr(
tox.tox_env.python.virtual_env.runner, "VirtualEnvRunner", MockVirtualEnv
Expand All @@ -57,9 +63,9 @@ def mock_venv(monkeypatch):

@pytest.fixture(scope="function")
def mock_poetry_factory(monkeypatch):
pypoetry = poetry.factory.Factory().create_poetry(cwd=TEST_PROJECT_PATH)
project = poetry.factory.Factory().create_poetry(cwd=TEST_PROJECT_PATH)

def mock_factory(*args, **kwargs):
return pypoetry
return project

monkeypatch.setattr(poetry.factory.Factory, "create_poetry", mock_factory)
47 changes: 27 additions & 20 deletions tests/test_installer.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,40 @@
# pylint: disable=missing-module-docstring, redefined-outer-name, unused-argument, wrong-import-order, unused-import
# pylint: disable=missing-module-docstring,redefined-outer-name,unused-argument,unused-import,protected-access
import time
from unittest import mock

import poetry.factory
import poetry.installation.executor
import pytest
import tox.tox_env.python.virtual_env.runner
from poetry.factory import Factory

import tox_poetry_installer.hooks._tox_on_install_helpers

from .fixtures import mock_poetry_factory
from .fixtures import mock_venv
from tox_poetry_installer import installer
from tox_poetry_installer import utilities


def test_deduplication(mock_venv, mock_poetry_factory):
"""Test that the installer does not install duplicate dependencies"""
poetry = Factory().create_poetry(None)
packages: utilities.PackageMap = {
item.name: item for item in poetry.locker.locked_repository().packages
project = poetry.factory.Factory().create_poetry(None)
packages: tox_poetry_installer.hooks._tox_on_install_helpers.PackageMap = {
item.name: item for item in project.locker.locked_repository().packages
}

venv = tox.tox_env.python.virtual_env.runner.VirtualEnvRunner()
to_install = [packages["toml"], packages["toml"]]

installer.install(poetry, venv, to_install)
tox_poetry_installer.hooks._tox_on_install_helpers.install_package(
project, venv, to_install
)

assert len(set(to_install)) == len(venv.installed) # pylint: disable=no-member


def test_parallelization(mock_venv, mock_poetry_factory):
"""Test that behavior is consistent between parallel and non-parallel usage"""
poetry = Factory().create_poetry(None)
packages: utilities.PackageMap = {
item.name: item for item in poetry.locker.locked_repository().packages
project = poetry.factory.Factory().create_poetry(None)
packages: tox_poetry_installer.hooks._tox_on_install_helpers.PackageMap = {
item.name: item for item in project.locker.locked_repository().packages
}

to_install = [
Expand All @@ -45,12 +48,16 @@ def test_parallelization(mock_venv, mock_poetry_factory):

venv_sequential = tox.tox_env.python.virtual_env.runner.VirtualEnvRunner()
start_sequential = time.time()
installer.install(poetry, venv_sequential, to_install, 0)
tox_poetry_installer.hooks._tox_on_install_helpers.install_package(
project, venv_sequential, to_install, 0
)
sequential = time.time() - start_sequential

venv_parallel = tox.tox_env.python.virtual_env.runner.VirtualEnvRunner()
start_parallel = time.time()
installer.install(poetry, venv_parallel, to_install, 5)
tox_poetry_installer.hooks._tox_on_install_helpers.install_package(
project, venv_parallel, to_install, 5
)
parallel = time.time() - start_parallel

# The mock delay during package install is static (one second) so these values should all
Expand All @@ -69,22 +76,22 @@ def test_propagates_exceptions_during_installation(
Regression test for https://github.com/enpaul/tox-poetry-installer/issues/86
"""
from tox_poetry_installer import _poetry # pylint: disable=import-outside-toplevel

poetry = Factory().create_poetry(None)
packages: utilities.PackageMap = {
item.name: item for item in poetry.locker.locked_repository().packages
project = poetry.factory.Factory().create_poetry(None)
packages: tox_poetry_installer.hooks._tox_on_install_helpers.PackageMap = {
item.name: item for item in project.locker.locked_repository().packages
}
to_install = [packages["toml"]]
venv = tox.tox_env.python.virtual_env.runner.VirtualEnvRunner()
fake_exception = ValueError("my testing exception")

with mock.patch.object(
_poetry,
poetry.installation.executor,
"Executor",
**{"return_value.execute.side_effect": fake_exception},
):
with pytest.raises(ValueError) as exc_info:
installer.install(poetry, venv, to_install, num_threads)
tox_poetry_installer.hooks._tox_on_install_helpers.install_package(
project, venv, to_install, num_threads
)

assert exc_info.value is fake_exception
1 change: 1 addition & 0 deletions tests/test_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
The next best thing to having one source of truth is having a way to ensure all of your
sources of truth agree with each other.
"""

from pathlib import Path

import toml
Expand Down
46 changes: 23 additions & 23 deletions tests/test_transients.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,23 @@
# pylint: disable=missing-module-docstring, redefined-outer-name, unused-argument, wrong-import-order, unused-import
# pylint: disable=missing-module-docstring,redefined-outer-name,unused-argument,unused-import,protected-access
import poetry.factory
import poetry.utils.env
import pytest
from poetry.puzzle.provider import Provider

from .fixtures import mock_poetry_factory
from .fixtures import mock_venv
from tox_poetry_installer import constants
import tox_poetry_installer.hooks._tox_on_install_helpers
from tox_poetry_installer import exceptions
from tox_poetry_installer import utilities


def test_exclude_unsafe():
"""Test that the unsafe packages are properly excluded
Also ensure that the internal constant matches the value from Poetry
"""
assert Provider.UNSAFE_PACKAGES == constants.UNSAFE_PACKAGES

for dep in constants.UNSAFE_PACKAGES:
assert not utilities.identify_transients(dep, {}, None)
from .fixtures import mock_poetry_factory
from .fixtures import mock_venv


def test_allow_missing():
"""Test that the ``allow_missing`` parameter works as expected"""
with pytest.raises(exceptions.LockedDepNotFoundError):
utilities.identify_transients("luke-skywalker", {}, None)
tox_poetry_installer.hooks._tox_on_install_helpers.identify_transients(
"luke-skywalker", {}, None
)

assert not utilities.identify_transients(
assert not tox_poetry_installer.hooks._tox_on_install_helpers.identify_transients(
"darth-vader", {}, None, allow_missing=["darth-vader"]
)

Expand All @@ -47,7 +37,9 @@ def test_exclude_pep508():
"=>foo",
]:
with pytest.raises(exceptions.LockedDepVersionConflictError):
utilities.identify_transients(version, {}, None)
tox_poetry_installer.hooks._tox_on_install_helpers.identify_transients(
version, {}, None
)


def test_functional(mock_poetry_factory, mock_venv):
Expand All @@ -56,8 +48,10 @@ def test_functional(mock_poetry_factory, mock_venv):
Trivially test that it resolves dependencies properly and that the parent package
is always the last in the returned list.
"""
pypoetry = poetry.factory.Factory().create_poetry(None)
packages = utilities.build_package_map(pypoetry)
project = poetry.factory.Factory().create_poetry(None)
packages = tox_poetry_installer.hooks._tox_on_install_helpers.build_package_map(
project
)
venv = poetry.utils.env.VirtualEnv() # pylint: disable=no-value-for-parameter

requests_requires = [
Expand All @@ -68,12 +62,18 @@ def test_functional(mock_poetry_factory, mock_venv):
packages["requests"][0],
]

transients = utilities.identify_transients("requests", packages, venv)
transients = tox_poetry_installer.hooks._tox_on_install_helpers.identify_transients(
"requests", packages, venv
)

assert all((item in requests_requires) for item in transients)
assert all((item in transients) for item in requests_requires)

for package in [packages["requests"][0], packages["tox"][0], packages["flask"][0]]:
transients = utilities.identify_transients(package.name, packages, venv)
transients = (
tox_poetry_installer.hooks._tox_on_install_helpers.identify_transients(
package.name, packages, venv
)
)
assert transients[-1] == package
assert len(transients) == len(set(transients))
Loading

0 comments on commit 536fd65

Please sign in to comment.