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
8 changes: 3 additions & 5 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ jobs:
id-token: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.10
uses: actions/setup-python@v4
- uses: actions/checkout@v4
- uses: wntrblm/nox@2023.04.22
with:
python-version: '3.10'
- run: pip install -U nox
python-versions: "3.12"
- run: nox -s build
- uses: pypa/gh-action-pypi-publish@release/v1
12 changes: 2 additions & 10 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: wntrblm/nox@2023.04.22
with:
python-version: |
3.8
3.9
3.10
3.11
pypy3.8
pypy3.9
3.7
- run: pip install -U nox
python-versions: "3.7, 3.8, 3.9, 3.10, 3.11, 3.12"
- run: nox
- run: nox -s build
37 changes: 13 additions & 24 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,34 +1,23 @@
repos:
- hooks:
- id: black
language_version: python3
repo: https://github.com/psf/black
rev: 22.6.0
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
hooks:
- id: check-toml
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
- hooks:
- repo: https://github.com/tox-dev/pyproject-fmt
rev: "1.7.0"
hooks:
- id: pyproject-fmt
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.2.0
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
- id: ruff-format
- repo: https://github.com/codespell-project/codespell
rev: v2.2.2
hooks:
- id: codespell
additional_dependencies: ["tomli"]
repo: https://github.com/codespell-project/codespell
rev: v2.2.2
- hooks:
- id: isort
language_version: python3
repo: https://github.com/timothycrosley/isort
rev: 5.10.1
- hooks:
- id: flake8
language_version: python3
additional_dependencies:
- flake8-bugbear
- flake8-comprehensions
- flake8-debugger
- flake8-string-format
- flake8-bandit
repo: https://github.com/PyCQA/flake8
rev: 5.0.4
24 changes: 5 additions & 19 deletions noxfile.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
"""Automation using nox.
"""
"""Automation using nox."""

import glob
import sys

import nox

nox.options.reuse_existing_virtualenvs = True
nox.options.sessions = "lint", "tests", "compat"
nox.options.sessions = "lint", "tests"
locations = "pytest_test_utils", "tests.py"


@nox.session(
python=["3.7", "3.8", "3.9", "3.10", "3.11", "pypy3.8", "pypy3.9"]
)
@nox.session(python=["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"])
def tests(session: nox.Session) -> None:
session.install(".[tests]")
# `pytest --cov` will start coverage after pytest
Expand All @@ -21,29 +18,18 @@ def tests(session: nox.Session) -> None:
session.run("coverage", "report", "--show-missing", "--skip-covered")


@nox.session(python=["3.7", "3.8"])
@nox.parametrize("pytest", ["3.9.1", "4.0", "5.0", "6.0"])
def compat(session: nox.Session, pytest: str) -> None:
session.install(".[tests]")
session.install(f"pytest=={pytest}")
session.run("coverage", "run", "-m", "pytest", "tests.py")


@nox.session
def lint(session: nox.Session) -> None:
session.install("pre-commit")
session.install("-e", ".[dev]")

if session.posargs:
args = session.posargs + ["--all-files"]
args = [*session.posargs, "--all-files"]
else:
args = ["--all-files", "--show-diff-on-failure"]

session.run("pre-commit", "run", *args)
session.run("python", "-m", "mypy")
if sys.version_info >= (3, 11):
return
session.run("python", "-m", "pylint", *locations)


@nox.session
Expand Down
88 changes: 56 additions & 32 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,30 +1,64 @@
[build-system]
requires = ["setuptools>=48", "setuptools_scm[toml]>=6.3.1"]
build-backend = "setuptools.build_meta"
requires = [
"setuptools>=48",
"setuptools_scm[toml]>=6.3.1",
]

[project]
name = "pytest-test-utils"
readme = "README.md"
license = { text = "Apache License 2.0" }
authors = [{ name = "Saugat Pachhai", email = "support@dvc.org" }]
requires-python = ">=3.7"
classifiers = [
"Framework :: Pytest",
"Programming Language :: Python :: 3 :: Only",
"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",
]
dynamic = [
"version",
]
dependencies = [
"pytest>=3.9",
]
[project.optional-dependencies]
dev = [
"mypy",
"pytest-test-utils[tests]",
]
tests = [
"coverage>=6",
]
[project.urls]
Issues = "https://github.com/iterative/pytest-test-utils/issues"
Source = "https://github.com/iterative/pytest-test-utils"
[project.entry-points.pytest11]
pytest_test_utils = "pytest_test_utils.pytest_plugin"

[tool.setuptools.package-data]
pytest_test_utils = ["py.typed"]

[tool.setuptools_scm]

[tool.black]
line-length = 79
include = '\.pyi?$'
exclude = '''
/(
\.eggs
| \.git
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| _build
| buck-out
| build
| dist
)/
'''

[tool.isort]
profile = "black"
line_length = 79
[tool.ruff]
output-format = "full"
show-fixes = true

[tool.ruff.lint]
ignore = ["S101"]
extend-select = ["S", "I", "B", "C4", "T10"]

[tool.codespell]
ignore-words-list = "cachable"

[tool.pytest.ini_options]
testpaths = ["tests.py"]

[tool.mypy]
# Error output
Expand All @@ -43,13 +77,3 @@ files = ["pytest_test_utils", "tests.py"]
[[tool.mypy.overrides]]
module = ["tests"]
strict_equality = false

[tool.pylint.message_control]
enable = ["no-else-return"]
disable = ["missing-function-docstring", "missing-module-docstring", "missing-class-docstring"]

[tool.pytest.ini_options]
testpaths = ["tests.py"]

[tool.codespell]
ignore-words-list = "cachable"
4 changes: 1 addition & 3 deletions pytest_test_utils/_approx.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ def __init__(
"""Initialize the approx_datetime with `abs` as tolerance."""
assert isinstance(expected, datetime)
abs = abs or self.default_tolerance
assert abs >= timedelta(
0
), f"absolute tolerance can't be negative: {abs}"
assert abs >= timedelta(0), f"absolute tolerance can't be negative: {abs}"
super().__init__(expected, abs=abs)

def __repr__(self) -> str: # pragma: no cover
Expand Down
12 changes: 3 additions & 9 deletions pytest_test_utils/matchers.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ def __init__(
pattern: Union[AnyStr, Pattern[AnyStr]],
flags: Union[int, re.RegexFlag] = 0,
) -> None:
self._regex: Pattern[AnyStr] = re.compile(
pattern, flags # type: ignore[arg-type]
)
self._regex: Pattern[AnyStr] = re.compile(pattern, flags) # type: ignore[arg-type]

def __repr__(self) -> str:
flags = self._regex.flags & ~32 # 32 is default
Expand Down Expand Up @@ -63,9 +61,7 @@ class MatcherDict:
# - should not call itself dict or use dict in repr because it creates
# confusing error messages (shadowing python builtins is bad anyway)

def __init__(
self, d: Optional[Mapping[Any, Any]] = None, **keys: Any
) -> None:
def __init__(self, d: Optional[Mapping[Any, Any]] = None, **keys: Any) -> None:
self.d: Dict[Any, Any] = {}
if d:
self.d.update(d)
Expand Down Expand Up @@ -112,9 +108,7 @@ def __repr__(self) -> str:
def __eq__(self, other: Any) -> bool:
# Unforturnately this doesn't work with classes with slots
# self.__class__ = other.__class__
return all(
getattr(other, name) == v for name, v in self.attribs.items()
)
return all(getattr(other, name) == v for name, v in self.attribs.items())


class any_of:
Expand Down
4 changes: 1 addition & 3 deletions pytest_test_utils/tmp_dir_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ def __init__(self, tmp_path_factory: "TempPathFactory") -> None:
self.tmp_path_factory: "TempPathFactory" = tmp_path_factory

def mktemp(self, basename: str, numbered: bool = True) -> TmpDir:
return TmpDir(
self.tmp_path_factory.mktemp(basename, numbered=numbered)
)
return TmpDir(self.tmp_path_factory.mktemp(basename, numbered=numbered))

def getbasetemp(self) -> TmpDir:
return TmpDir(self.tmp_path_factory.getbasetemp())
55 changes: 0 additions & 55 deletions setup.cfg

This file was deleted.

16 changes: 4 additions & 12 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,7 @@ def test_gen_dict_bytes(tmp_dir: TmpDir) -> None:
]
assert (tmp_dir / os.fsdecode("file")).read_bytes() == b"lorem"
assert (tmp_dir / os.fsdecode("dir")).is_dir()
assert (
tmp_dir / os.fsdecode("dir") / os.fsdecode("file")
).read_bytes() == b"ipsum"
assert (tmp_dir / os.fsdecode("dir") / os.fsdecode("file")).read_bytes() == b"ipsum"


def test_chdir(tmp_path: Path, tmp_dir: TmpDir) -> None:
Expand Down Expand Up @@ -113,13 +111,9 @@ def test_matcher_repr(matcher: Type[Matcher]) -> None:
== "M.dict(foo='foo', n=123)"
)
assert repr(matcher.instance_of(str)) == "instance_of(str)"
assert (
repr(matcher.instance_of((str, bytes))) == "instance_of((str, bytes))"
)
assert repr(matcher.instance_of((str, bytes))) == "instance_of((str, bytes))"
assert repr(matcher.unordered("foo", "bar")) == "unordered('foo', 'bar')"
assert (
repr(matcher.re(r"^plots\.csv-\w+$")) == "regex(r'^plots\\.csv-\\w+$')"
)
assert repr(matcher.re(r"^plots\.csv-\w+$")) == "regex(r'^plots\\.csv-\\w+$')"


def test_matcher_dict(matcher: Type[Matcher]) -> None:
Expand Down Expand Up @@ -152,9 +146,7 @@ def test_matcher_attrs(matcher: Type[Matcher]) -> None:


def test_matcher_attrs_nested(matcher: Type[Matcher]) -> None:
obj = SimpleNamespace(
nested=SimpleNamespace(foo="foo", bar="bar"), foobar="bar"
)
obj = SimpleNamespace(nested=SimpleNamespace(foo="foo", bar="bar"), foobar="bar")
assert obj == matcher.attrs(nested=matcher.attrs(foo="foo"))


Expand Down