Compare commits

...

9 Commits

Author SHA1 Message Date
d816678975
Update dev dependencies to latest versions 2024-08-16 14:47:06 -04:00
552f2080f5
Remove python 3.7 support, add python 3.12 2024-08-16 14:47:06 -04:00
ddbf442a30
Update to isort and black 24 2024-08-16 14:27:46 -04:00
13cfb8616c
Replace reorder-python-imports with isort
See here for indept explanation: https://github.com/psf/black/issues/4175
See here (and related) for the attitude: https://github.com/asottile/reorder-python-imports/issues/366
2024-08-16 14:26:51 -04:00
df343396a4
Remove safety dependency vulnerability scanner
I went back and fourth on this, but ultimately decided that it's more trouble
than it's worth. Between false positives, deeply nested packages raising
vulnerabilities, and the brittleness of the poetry-plugin-export that the
tooling relies on, it causes more headaches than it avoids. A future PR will
enable dependabot tooling that will open PRs to automatically fix this problem
so I don't have to deal with it anymore (hopefully)
2024-08-16 13:26:12 -04:00
f66e59ab85
Pin all development dependencies to python^3.10 2024-08-16 12:50:51 -04:00
f37463d172
Fix linting errors
Remove unused imports
Disable redundant errors
Add notes for why errors are disabled
2024-08-16 11:06:31 -04:00
6837a64121
Add handling of error when poetry.lock does not exist
Fixes #81
2024-08-16 11:06:31 -04:00
506aae0ccd
Replace optional [poetry] extra with explicit poetry dependencies
Fixes #79
2024-08-16 11:06:31 -04:00
18 changed files with 877 additions and 1368 deletions

View File

@ -26,7 +26,6 @@ poetry --version --no-ansi;
poetry run pip --version; poetry run pip --version;
poetry install \ poetry install \
--extras poetry \
--quiet \ --quiet \
--remove-untracked \ --remove-untracked \
--no-ansi; --no-ansi;

View File

@ -12,8 +12,6 @@ jobs:
strategy: strategy:
matrix: matrix:
python: python:
- version: "3.7"
toxenv: py37
- version: "3.8" - version: "3.8"
toxenv: py38 toxenv: py38
- version: "3.9" - version: "3.9"
@ -22,6 +20,8 @@ jobs:
toxenv: py310 toxenv: py310
- version: "3.11" - version: "3.11"
toxenv: py311 toxenv: py311
- version: "3.12"
toxenv: py312
fail-fast: true fail-fast: true
steps: steps:
- name: Checkout - name: Checkout

View File

@ -47,12 +47,13 @@ repos:
- id: reorder-python-imports - id: reorder-python-imports
name: reorder-python-imports name: reorder-python-imports
entry: reorder-python-imports entry: isort
language: system language: system
args: require_serial: true
- "--unclassifiable-application-module=tox_poetry_installer"
types: types:
- python - python
args:
- "--filter-files"
- id: black - id: black
name: black name: black

2106
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -23,45 +23,46 @@ classifiers = [
"Natural Language :: English", "Natural Language :: English",
"Operating System :: OS Independent", "Operating System :: OS Independent",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: CPython",
] ]
[tool.poetry.plugins.tox] [tool.poetry.plugins.tox]
poetry_installer = "tox_poetry_installer" poetry_installer = "tox_poetry_installer"
[tool.poetry.extras]
poetry = ["poetry", "cleo"]
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.7" python = "^3.8"
cleo = {version = ">=1.0,<3.0", optional = true} cleo = ">=1.0,<3.0"
poetry = {version = "^1.5.0", optional = true} poetry = "^1.5.0"
poetry-core = "^1.1.0" poetry-core = "^1.1.0"
tox = "^4" tox = "^4.1"
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
bandit = "^1.6.2" bandit = {version = "^1.7.7", python = "^3.10"}
black = "^22.3.0" black = {version = "^24.3.0", python = "^3.10"}
blacken-docs = "^1.8.0" blacken-docs = {version = "^1.18.0", python = "^3.10"}
ipython = {version = "^8.10.1", python = "^3.8"} ipython = {version = "^8.10.1", python = "^3.10"}
mdformat = "^0.7" isort = {version = "^5.13.2", python = "^3.10"}
mdformat-gfm = "^0.3" mdformat = {version = "^0.7", python = "^3.10"}
mypy = "^0.930" mdformat-gfm = {version = "^0.3", python = "^3.10"}
pre-commit = "^2.7.1" mypy = {version = "^0.930", python = "^3.10"}
pre-commit-hooks = "^3.3.0" pre-commit = {version = "^3.8.0", python = "^3.10"}
pylint = "^2.13.0" pre-commit-hooks = {version = "^4.6.0", python = "^3.10"}
pytest = "^6.0.2" pylint = {version = "^3.2.6", python = "^3.10"}
pytest-cov = "^2.10.1" pytest = {version = "^8.3.2", python = "^3.10"}
reorder-python-imports = "^2.3.5" pytest-cov = {version = "^5.0.0", python = "^3.10"}
safety = "^2.2.0" toml = {version = "^0.10.1", python = "^3.10"}
toml = "^0.10.1" tox = "^4.1"
tox = "^4" types-toml = {version = "^0.10.1", python = "^3.10"}
types-toml = "^0.10.1"
[tool.isort]
profile = "black"
force_single_line = "true"
lines_after_imports = 2
[build-system] [build-system]
requires = ["poetry-core>=1.1.0"] requires = ["poetry-core>=1.1.0"]

View File

@ -1,4 +1,4 @@
# 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 import time
from pathlib import Path from pathlib import Path
from typing import List from typing import List

View File

@ -1,4 +1,4 @@
# 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 import time
from unittest import mock from unittest import mock
@ -7,6 +7,7 @@ import tox.tox_env.python.virtual_env.runner
from poetry.factory import Factory from poetry.factory import Factory
import tox_poetry_installer.hooks._tox_on_install_helpers import tox_poetry_installer.hooks._tox_on_install_helpers
from .fixtures import mock_poetry_factory from .fixtures import mock_poetry_factory
from .fixtures import mock_venv from .fixtures import mock_venv

View File

@ -3,6 +3,7 @@
The next best thing to having one source of truth is having a way to ensure all of your 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. sources of truth agree with each other.
""" """
from pathlib import Path from pathlib import Path
import toml import toml

View File

@ -1,14 +1,13 @@
# 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.factory
import poetry.utils.env import poetry.utils.env
import pytest import pytest
from poetry.puzzle.provider import Provider
import tox_poetry_installer.hooks._tox_on_install_helpers import tox_poetry_installer.hooks._tox_on_install_helpers
from tox_poetry_installer import exceptions
from .fixtures import mock_poetry_factory from .fixtures import mock_poetry_factory
from .fixtures import mock_venv from .fixtures import mock_venv
from tox_poetry_installer import constants
from tox_poetry_installer import exceptions
def test_allow_missing(): def test_allow_missing():

18
tox.ini
View File

@ -1,13 +1,11 @@
[tox] [tox]
envlist = py37, py38, py39, py310, py311, static, static-tests, security envlist = py3{8,9,10,11,12} static, static-tests, security
skip_missing_interpreters = true skip_missing_interpreters = true
[testenv] [testenv]
description = Run the tests description = Run the tests
require_locked_deps = true require_locked_deps = true
require_poetry = true require_poetry = true
extras =
poetry
locked_deps = locked_deps =
pytest pytest
pytest-cov pytest-cov
@ -26,10 +24,10 @@ ignore_errors = true
locked_deps = locked_deps =
black black
blacken-docs blacken-docs
isort
mdformat mdformat
mdformat-gfm mdformat-gfm
mypy mypy
reorder-python-imports
pre-commit pre-commit
pre-commit-hooks pre-commit-hooks
pylint pylint
@ -52,6 +50,7 @@ locked_deps =
pylint pylint
pytest pytest
mypy mypy
toml
types-toml types-toml
commands = commands =
pylint {toxinidir}/tests/ \ pylint {toxinidir}/tests/ \
@ -78,14 +77,3 @@ commands =
--recursive \ --recursive \
--quiet \ --quiet \
--skip B101 --skip B101
poetry export \
--format requirements.txt \
--output {envtmpdir}/requirements.txt \
--without-hashes \
--with dev \
--extras poetry
safety check \
--file {envtmpdir}/requirements.txt \
--output text \
# https://github.com/pytest-dev/py/issues/287
--ignore 51457

View File

@ -21,13 +21,14 @@ at the module scope it is imported into function scope wherever Poetry component
moves import errors from load time to runtime which allows the plugin to be skipped if Poetry isn't moves import errors from load time to runtime which allows the plugin to be skipped if Poetry isn't
installed and/or a more helpful error be raised within the Tox framework. installed and/or a more helpful error be raised within the Tox framework.
""" """
# pylint: disable=unused-import
import sys import sys
from tox_poetry_installer import exceptions from tox_poetry_installer import exceptions
try: try:
# pylint: disable=import-outside-toplevel,unused-import
from cleo.io.null_io import NullIO from cleo.io.null_io import NullIO
from poetry.config.config import Config from poetry.config.config import Config
from poetry.core.packages.dependency import Dependency as PoetryDependency from poetry.core.packages.dependency import Dependency as PoetryDependency

View File

@ -5,7 +5,7 @@ in this module.
All constants should be type hinted. All constants should be type hinted.
""" """
from typing import Set
from typing import Tuple from typing import Tuple
from tox_poetry_installer import __about__ from tox_poetry_installer import __about__

View File

@ -11,6 +11,7 @@ All exceptions should inherit from the common base exception :exc:`ToxPoetryInst
+-- LockedDepNotFoundError +-- LockedDepNotFoundError
+-- ExtraNotFoundError +-- ExtraNotFoundError
+-- LockedDepsRequiredError +-- LockedDepsRequiredError
+-- LockfileParsingError
""" """
@ -41,3 +42,7 @@ class ExtraNotFoundError(ToxPoetryInstallerException):
class LockedDepsRequiredError(ToxPoetryInstallerException): class LockedDepsRequiredError(ToxPoetryInstallerException):
"""Environment cannot specify unlocked dependencies when locked dependencies are required""" """Environment cannot specify unlocked dependencies when locked dependencies are required"""
class LockfileParsingError(ToxPoetryInstallerException):
"""Failed to load or parse the Poetry lockfile"""

View File

@ -1,4 +1,5 @@
"""Helper functions for the :func:`tox_on_install` hook""" """Helper functions for the :func:`tox_on_install` hook"""
import collections import collections
import concurrent.futures import concurrent.futures
import contextlib import contextlib
@ -20,9 +21,14 @@ from tox_poetry_installer import constants
from tox_poetry_installer import exceptions from tox_poetry_installer import exceptions
from tox_poetry_installer import logger from tox_poetry_installer import logger
if typing.TYPE_CHECKING: if typing.TYPE_CHECKING:
from tox_poetry_installer import _poetry from tox_poetry_installer import _poetry
# This is globally disabled to support the usage of the _poetry shadow module
# pylint: disable=import-outside-toplevel
PackageMap = Dict[str, List[PoetryPackage]] PackageMap = Dict[str, List[PoetryPackage]]

View File

@ -1,12 +1,16 @@
"""Add required env configuration options to the tox INI file""" """Add required env configuration options to the tox INI file"""
from typing import List from typing import List
from tox.config.sets import EnvConfigSet from tox.config.sets import EnvConfigSet
from tox.plugin import impl from tox.plugin import impl
# pylint: disable=missing-function-docstring
@impl @impl
def tox_add_env_config(env_conf: EnvConfigSet): def tox_add_env_config(
env_conf: EnvConfigSet,
):
env_conf.add_config( env_conf.add_config(
"poetry_dep_groups", "poetry_dep_groups",
of_type=List[str], of_type=List[str],

View File

@ -1,10 +1,12 @@
"""Add additional command line arguments to tox to configure plugin behavior""" """Add additional command line arguments to tox to configure plugin behavior"""
from tox.config.cli.parser import ToxParser from tox.config.cli.parser import ToxParser
from tox.plugin import impl from tox.plugin import impl
from tox_poetry_installer import constants from tox_poetry_installer import constants
# pylint: disable=missing-function-docstring
@impl @impl
def tox_add_option(parser: ToxParser): def tox_add_option(parser: ToxParser):
parser.add_argument( parser.add_argument(

View File

@ -4,6 +4,7 @@ Loads the local Poetry environment and the corresponding lockfile then pulls the
specified by the Tox environment. Finally these dependencies are installed into the Tox specified by the Tox environment. Finally these dependencies are installed into the Tox
environment using the Poetry ``PipInstaller`` backend. environment using the Poetry ``PipInstaller`` backend.
""" """
from itertools import chain from itertools import chain
from tox.plugin import impl from tox.plugin import impl
@ -21,10 +22,9 @@ from tox_poetry_installer.hooks._tox_on_install_helpers import find_project_deps
from tox_poetry_installer.hooks._tox_on_install_helpers import install_package from tox_poetry_installer.hooks._tox_on_install_helpers import install_package
# pylint: disable=missing-function-docstring,unused-argument
@impl @impl
def tox_on_install( def tox_on_install(tox_env: ToxVirtualEnv, *args) -> None:
tox_env: ToxVirtualEnv, section: str # pylint: disable=unused-argument
) -> None:
try: try:
poetry = check_preconditions(tox_env) poetry = check_preconditions(tox_env)
except exceptions.SkipEnvironment as err: except exceptions.SkipEnvironment as err:
@ -41,10 +41,16 @@ def tox_on_install(
virtualenv = convert_virtualenv(tox_env) virtualenv = convert_virtualenv(tox_env)
if not poetry.locker.is_fresh(): try:
logger.warning( if not poetry.locker.is_fresh():
f"The Poetry lock file is not up to date with the latest changes in {poetry.file}" logger.warning(
) f"The Poetry lock file is not up to date with the latest changes in {poetry.file}"
)
except FileNotFoundError as err:
logger.error(f"Could not parse lockfile: {err}")
raise exceptions.LockfileParsingError(
f"Could not parse lockfile: {err}"
) from err
try: try:
if tox_env.conf["require_locked_deps"] and tox_env.conf["deps"].lines(): if tox_env.conf["require_locked_deps"] and tox_env.conf["deps"].lines():

View File

@ -4,6 +4,7 @@ Calling ``tox.reporter.something()`` and having to format a string with the pref
gets really old fast, but more importantly it also makes the flow of the main code gets really old fast, but more importantly it also makes the flow of the main code
more difficult to follow because of the added complexity. more difficult to follow because of the added complexity.
""" """
import logging import logging
from tox_poetry_installer import constants from tox_poetry_installer import constants