summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Pentchev <roam@debian.org>2023-06-27 18:45:54 +0300
committerPeter Pentchev <roam@debian.org>2023-06-27 18:45:54 +0300
commitcfadc92199045365ff6befeb92e95866c5ec6648 (patch)
treef89702425e29205d868d410471dda50ae2da3eac
parentacece5c2f20a0807d04f6605f272476211053f0d (diff)
parentfa5ab5085ad5446177838024af4607bc0aed7aaf (diff)
Update upstream source from tag 'upstream/0.1.5'
Update to upstream version '0.1.5' with Debian dir a0443b56c28969b25abd9d5b833863ade7bae4ac
-rw-r--r--PKG-INFO22
-rw-r--r--config/ruff-base/pyproject.toml7
-rw-r--r--config/ruff-most/pyproject.toml10
-rw-r--r--docs/changes.md52
-rw-r--r--docs/index.md2
-rwxr-xr-xnix/cleanpy.sh17
-rw-r--r--nix/python-tox.nix19
-rwxr-xr-xnix/run-pytest.sh20
-rwxr-xr-xnix/run-tox.sh17
-rw-r--r--pyproject.toml60
-rw-r--r--requirements/docs.txt2
-rw-r--r--setup.cfg10
-rw-r--r--src/parse_stages/defs.py6
-rw-r--r--src/parse_stages/p_pyp.py85
-rw-r--r--tox.ini69
-rw-r--r--unit_tests/test_eval.py4
-rw-r--r--unit_tests/test_parse.py3
17 files changed, 242 insertions, 163 deletions
diff --git a/PKG-INFO b/PKG-INFO
index 069a277..8a1470f 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,12 +1,32 @@
Metadata-Version: 2.1
Name: parse_stages
-Version: 0.1.4
+Version: 0.1.5
Summary: Parse an expression for selecting stages and tags
Project-URL: Homepage, https://devel.ringlet.net/devel/parse-stages/
Project-URL: Changes, https://devel.ringlet.net/devel/parse-stages/changes/
Project-URL: Issue Tracker, https://gitlab.com/ppentchev/parse-stages/-/issues
Project-URL: Source Code, https://gitlab.com/ppentchev/parse-stages
Author-email: Peter Pentchev <roam@ringlet.net>
+License: BSD-2-Clause
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: DFSG approved
+Classifier: License :: Freely Distributable
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3 :: Only
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
+Classifier: Topic :: Software Development :: Libraries
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Topic :: Software Development :: Testing
+Classifier: Topic :: Software Development :: Testing :: Unit
+Classifier: Typing :: Typed
Requires-Python: >=3.8
Requires-Dist: pyparsing<4,>=3
Description-Content-Type: text/markdown
diff --git a/config/ruff-base/pyproject.toml b/config/ruff-base/pyproject.toml
index 29b450b..2e41989 100644
--- a/config/ruff-base/pyproject.toml
+++ b/config/ruff-base/pyproject.toml
@@ -9,6 +9,9 @@ ignore = [
# We know what "self" is... I hope
"ANN101",
+ # We leave most of the formatting to the `black` tool
+ "COM812",
+
# No blank lines before the class docstring, TYVM
"D203",
@@ -24,3 +27,7 @@ force-single-line = true
known-first-party = ["parse_stages"]
lines-after-imports = 2
single-line-exclusions = ["typing"]
+
+[tool.ruff.per-file-ignores]
+# This is a test suite
+"unit_tests/**.py" = ["S101"]
diff --git a/config/ruff-most/pyproject.toml b/config/ruff-most/pyproject.toml
index 6e6fbaa..07265af 100644
--- a/config/ruff-most/pyproject.toml
+++ b/config/ruff-most/pyproject.toml
@@ -3,16 +3,19 @@
[tool.ruff]
extend = "../ruff-base/pyproject.toml"
-# These are all the Ruff 0.0.265 linters.
+# These are all the Ruff 0.0.275 linters.
select = [
"A",
+ "AIR",
"ANN",
"ARG",
+ "ASYNC",
"B",
"BLE",
"C4",
"C90",
"COM",
+ "CPY",
"D",
"DJ",
"DTZ",
@@ -21,7 +24,9 @@ select = [
"ERA",
"EXE",
"F",
+ "FA",
"FBT",
+ "FIX",
"FLY",
"G",
"I",
@@ -32,6 +37,7 @@ select = [
"N",
"NPY",
"PD",
+ "PERF",
"PGH",
"PIE",
"PL",
@@ -45,9 +51,11 @@ select = [
"S",
"SIM",
"SLF",
+ "SLOT",
"T10",
"T20",
"TCH",
+ "TD",
"TID",
"TRY",
"UP",
diff --git a/docs/changes.md b/docs/changes.md
index 4eb6a81..fa81927 100644
--- a/docs/changes.md
+++ b/docs/changes.md
@@ -7,11 +7,58 @@ SPDX-License-Identifier: BSD-2-Clause
All notable changes to the parse-stages project will be documented in this file.
-The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
+## [0.1.5] - 2023-06-27
+
+### Fixes
+
+- Build infrastructure:
+ - relax the `hatch-requirements-txt` to >= 0.3, which is the version in
+ Debian testing/unstable
+ - specify a lower requirement for `hatchling` as >= 1.8, which is
+ the version in Ubuntu 22.10 (kinetic)
+ - specify an upper requirement for `hatchling`
+- Main source:
+ - do not disable all Flake8 / Ruff checks for three files!
+ - fix some formatting nits in the newly-checked source files
+- Test suite:
+ - drop the `pyupgrade` environment from Tox's default envlist;
+ there is (by design) no way to run it in a no-op, report-only mode
+ - do not pass the `python_version` option to `mypy`, let it check
+ the code with regard to the currently-running Python interpreter
+
+### Additions
+
+- Build infrastructure:
+ - specify the project license
+ - add some more PyPI trove classifiers
+- Test suite:
+ - introduce the `PY_MINVER_MIN` and `PY_MINVER_MAX` environment variables for
+ the `nix/run-pytest.sh` helper tool so that e.g. the current flakiness of
+ Python 3.12 in nixpkgs-unstable can be skipped
+ - add a Nix expression and the `nix/run-tox.sh` helper tool to run
+ all the Tox tests using a different Python version
+ - also include the `reuse` Tox environment in the ones run at the `@check`
+ stage using the `tox-stages` tool
+
+### Other changes
+
+- Main source:
+ - replace assertions in the parsing code with `if` statements that
+ raise our own exceptions
+- Documentation:
+ - refer to version 1.1.0 of the "Keep a Changelog" format specification
+ - use `mkdocstrings` 0.22, no changes
+- Test suite:
+ - drop the `flake8` / `pep8`, `pylint`, and `pydocstyle`
+ Tox test environments, Ruff handles most of these checks now
+ - use Ruff 0.0.275, activate all the new check areas, just in case
+ - use mypy 1.x, no changes
+
## [0.1.4] - 2023-05-13
### Additions
@@ -140,7 +187,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- First public release.
-[Unreleased]: https://gitlab.com/ppentchev/parse-stages/-/compare/release%2F0.1.4...main
+[Unreleased]: https://gitlab.com/ppentchev/parse-stages/-/compare/release%2F0.1.5...main
+[0.1.5]: https://gitlab.com/ppentchev/parse-stages/-/compare/release%2F0.1.4...release%2F0.1.5
[0.1.4]: https://gitlab.com/ppentchev/parse-stages/-/compare/release%2F0.1.3...release%2F0.1.4
[0.1.3]: https://gitlab.com/ppentchev/parse-stages/-/compare/release%2F0.1.2...release%2F0.1.3
[0.1.2]: https://gitlab.com/ppentchev/parse-stages/-/compare/release%2F0.1.1...release%2F0.1.2
diff --git a/docs/index.md b/docs/index.md
index b5776ce..01a59e1 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -26,7 +26,7 @@ section.
A program that uses the `parse-stages` library should specify it in
its list of requirements, e.g. using [PEP508][pep508] syntax:
- parse-stages >= 0.1.4, < 0.2
+ parse-stages >= 0.1.5, < 0.2
[pep508]: https://peps.python.org/pep-0508/ "PEP 508 – Dependency specification for Python Software Packages"
diff --git a/nix/cleanpy.sh b/nix/cleanpy.sh
new file mode 100755
index 0000000..7a5490b
--- /dev/null
+++ b/nix/cleanpy.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+#
+# SPDX-FileCopyrightText: Peter Pentchev <roam@ringlet.net>
+# SPDX-License-Identifier: BSD-2-Clause
+
+set -e
+
+find . -mindepth 1 -maxdepth 1 -type d \( \
+ -name '.tox' \
+ -or -name '.mypy_cache' \
+ -or -name '.pytest_cache' \
+ -or -name '.nox' \
+ -or -name '.ruff_cache' \
+\) -exec rm -rf -- '{}' +
+find . -type d -name '__pycache__' -exec rm -rfv -- '{}' +
+find . -type f -name '*.pyc' -delete -print
+find . -mindepth 1 -maxdepth 2 -type d -name '*.egg-info' -exec rm -rfv -- '{}' +
diff --git a/nix/python-tox.nix b/nix/python-tox.nix
new file mode 100644
index 0000000..f8e0cff
--- /dev/null
+++ b/nix/python-tox.nix
@@ -0,0 +1,19 @@
+# SPDX-FileCopyrightText: Peter Pentchev <roam@ringlet.net>
+# SPDX-License-Identifier: BSD-2-Clause
+
+{ pkgs ? import <nixpkgs> { }
+, py-ver ? 311
+}:
+let
+ python-name = "python${toString py-ver}";
+ python = builtins.getAttr python-name pkgs;
+ python-pkgs = python.withPackages (p: with p; [ tox ]);
+in
+pkgs.mkShell {
+ buildInputs = [ python-pkgs ];
+ shellHook = ''
+ set -e
+ tox run-parallel
+ exit
+ '';
+}
diff --git a/nix/run-pytest.sh b/nix/run-pytest.sh
index 5a83ded..423a420 100755
--- a/nix/run-pytest.sh
+++ b/nix/run-pytest.sh
@@ -5,22 +5,12 @@
set -e
-cleanpy()
-{
- find . -mindepth 1 -maxdepth 1 -type d \( \
- -name '.tox' \
- -or -name '.mypy_cache' \
- -or -name '.pytest_cache' \
- -or -name '.nox' \
- -or -name '.ruff_cache' \
- \) -exec rm -rf -- '{}' +
- find . -type d -name '__pycache__' -exec rm -rfv -- '{}' +
- find . -type f -name '*.pyc' -delete -print
- find . -mindepth 1 -maxdepth 2 -type d -name '*.egg-info' -exec rm -rfv -- '{}' +
-}
+: "${PY_MINVER_MIN:=8}"
+: "${PY_MINVER_MAX:=12}"
-for pyver in 38 39 310 311 312; do
- cleanpy
+for minor in $(seq -- "$PY_MINVER_MIN" "$PY_MINVER_MAX"); do
+ pyver="3$minor"
+ nix/cleanpy.sh
printf -- '\n===== Running tests for %s\n\n\n' "$pyver"
nix-shell --pure --arg py-ver "$pyver" nix/python-pytest.nix
printf -- '\n===== Done with %s\n\n' "$pyver"
diff --git a/nix/run-tox.sh b/nix/run-tox.sh
new file mode 100755
index 0000000..63ebba9
--- /dev/null
+++ b/nix/run-tox.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+#
+# SPDX-FileCopyrightText: Peter Pentchev <roam@ringlet.net>
+# SPDX-License-Identifier: BSD-2-Clause
+
+set -e
+
+: "${PY_MINVER_MIN:=8}"
+: "${PY_MINVER_MAX:=12}"
+
+for minor in $(seq -- "$PY_MINVER_MIN" "$PY_MINVER_MAX"); do
+ pyver="3$minor"
+ nix/cleanpy.sh
+ printf -- '\n===== Running tests for %s\n\n\n' "$pyver"
+ nix-shell --pure --arg py-ver "$pyver" nix/python-tox.nix
+ printf -- '\n===== Done with %s\n\n' "$pyver"
+done
diff --git a/pyproject.toml b/pyproject.toml
index 55b1bf6..9c9c34a 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -3,8 +3,8 @@
[build-system]
requires = [
- "hatchling",
- "hatch-requirements-txt >= 0.4, < 0.5",
+ "hatchling >= 1.8, < 2",
+ "hatch-requirements-txt >= 0.3, < 0.5",
]
build-backend = "hatchling.build"
@@ -12,8 +12,30 @@ build-backend = "hatchling.build"
name = "parse_stages"
description = "Parse an expression for selecting stages and tags"
readme = "README.md"
+license = {text = "BSD-2-Clause"}
requires-python = ">= 3.8"
dynamic = ["dependencies", "version"]
+classifiers = [
+ "Development Status :: 5 - Production/Stable",
+ "Intended Audience :: Developers",
+ "License :: DFSG approved",
+ "License :: Freely Distributable",
+ "License :: OSI Approved :: BSD License",
+ "Operating System :: OS Independent",
+ "Programming Language :: Python",
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3 :: Only",
+ "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",
+ "Topic :: Software Development :: Libraries",
+ "Topic :: Software Development :: Libraries :: Python Modules",
+ "Topic :: Software Development :: Testing",
+ "Topic :: Software Development :: Testing :: Unit",
+ "Typing :: Typed",
+]
[[project.authors]]
name = "Peter Pentchev"
@@ -40,40 +62,6 @@ line-length = 100
[tool.mypy]
strict = true
-python_version = "3.8"
-
-# This is the list of the Pylint 2.16.1 default plugins.
-[tool.pylint]
-py-version = "3.8"
-load-plugins = [
- "pylint.extensions.bad_builtin",
- "pylint.extensions.broad_try_clause",
- "pylint.extensions.check_elif",
- "pylint.extensions.code_style",
- "pylint.extensions.comparetozero",
- "pylint.extensions.comparison_placement",
- "pylint.extensions.confusing_elif",
- "pylint.extensions.consider_refactoring_into_while_condition",
- "pylint.extensions.consider_ternary_expression",
- "pylint.extensions.dict_init_mutate",
- "pylint.extensions.docparams",
- "pylint.extensions.docstyle",
- "pylint.extensions.dunder",
- "pylint.extensions.empty_comment",
- "pylint.extensions.emptystring",
- "pylint.extensions.eq_without_hash",
- "pylint.extensions.for_any_all",
- "pylint.extensions.magic_value",
- "pylint.extensions.mccabe",
- "pylint.extensions.no_self_use",
- "pylint.extensions.overlapping_exceptions",
- "pylint.extensions.private_import",
- "pylint.extensions.redefined_loop_name",
- "pylint.extensions.redefined_variable_type",
- "pylint.extensions.set_membership",
- "pylint.extensions.typing",
- "pylint.extensions.while_used",
-]
[tool.test-stages]
stages = ["ruff and not @manual", "@check and not @manual", "@tests and not @manual"]
diff --git a/requirements/docs.txt b/requirements/docs.txt
index 3792a2d..784a0e0 100644
--- a/requirements/docs.txt
+++ b/requirements/docs.txt
@@ -3,5 +3,5 @@
mkdocs >= 1.4.2, < 2
mkdocs-material >= 9.1.2, < 10
-mkdocstrings >= 0.21.2, < 0.22
+mkdocstrings >= 0.22, < 0.23
mkdocstrings-python >= 1, < 2
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index dca381f..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-FileCopyrightText: Peter Pentchev <roam@ringlet.net>
-# SPDX-License-Identifier: BSD-2-Clause
-
-[flake8]
-max_line_length = 100
-extend_ignore = ANN101
-inline_quotes = double
-
-[pycodestyle]
-max-line-length = 100
diff --git a/src/parse_stages/defs.py b/src/parse_stages/defs.py
index 757e229..7134f4e 100644
--- a/src/parse_stages/defs.py
+++ b/src/parse_stages/defs.py
@@ -2,10 +2,6 @@
# SPDX-License-Identifier: BSD-2-Clause
"""Common definitions for the parse-stages library."""
-# Some of this library's consumers need to be able to use typedload on
-# Python versions < 3.9, so we cannot use the generic types.
-# pylint: disable=deprecated-typing-alias
-
import dataclasses
from typing import List
@@ -46,4 +42,4 @@ class Tagged:
return [self.name]
-VERSION = "0.1.4"
+VERSION = "0.1.5"
diff --git a/src/parse_stages/p_pyp.py b/src/parse_stages/p_pyp.py
index 7f41759..b581bfc 100644
--- a/src/parse_stages/p_pyp.py
+++ b/src/parse_stages/p_pyp.py
@@ -2,16 +2,49 @@
# SPDX-License-Identifier: BSD-2-Clause
"""Parse an expression using the `pyparsing` library."""
-# Let's make sure that the parsed tokens are exactly as we expect them to be
-# flake8: noqa: S101
-
from __future__ import annotations
+import dataclasses
+import typing
+
import pyparsing as pyp
from . import expr
+if typing.TYPE_CHECKING:
+ from typing import Any
+
+
+@dataclasses.dataclass
+class Error(Exception):
+ """A base class for parse-related errors."""
+
+
+@dataclasses.dataclass
+class ParseResultError(Error):
+ """The pyparsing module returned an unexpected series of tokens."""
+
+ tokens: pyp.ParseResults
+ """The unexpected sequence of tokens."""
+
+ def __str__(self) -> str:
+ """Provide a human-readable representation of the error."""
+ return f"Unexpected sequence of parse tokens: {self.tokens!r}"
+
+
+@dataclasses.dataclass
+class ParseError(Error):
+ """Our pyparsing handlers returned an unexpected object."""
+
+ res: Any
+ """The unexpected object returned."""
+
+ def __str__(self) -> str:
+ """Provide a human-readable representation of the error."""
+ return f"Unexpected parsed object: {self.res!r}"
+
+
EMPTY_SET_SPECS = ["", "0", "none"]
"""The list of exact strings that `parse_stage_ids()` will return an empty list for."""
@@ -41,28 +74,32 @@ _p_spec = _p_ws.suppress() + _p_or_expr
@_p_tag.set_parse_action
def _parse_tag(tokens: pyp.ParseResults) -> expr.TagExpr:
"""Parse a tag name."""
- assert len(tokens) == 1 and isinstance(tokens[0], str), repr(tokens)
+ if len(tokens) != 1 or not isinstance(tokens[0], str):
+ raise ParseResultError(tokens)
return expr.TagExpr(tag=tokens[0])
@_p_keyword.set_parse_action
def _parse_keyword(tokens: pyp.ParseResults) -> expr.KeywordExpr:
"""Parse a keyword."""
- assert len(tokens) == 1 and isinstance(tokens[0], str), repr(tokens)
+ if len(tokens) != 1 or not isinstance(tokens[0], str):
+ raise ParseResultError(tokens)
return expr.KeywordExpr(keyword=tokens[0])
@_p_atom.set_parse_action
def _parse_atom(tokens: pyp.ParseResults) -> expr.BoolExpr:
"""Parse an atom (a tag or a keyword)."""
- assert len(tokens) == 1 and isinstance(tokens[0], (expr.TagExpr, expr.KeywordExpr))
+ if len(tokens) != 1 or not isinstance(tokens[0], (expr.TagExpr, expr.KeywordExpr)):
+ raise ParseResultError(tokens)
return tokens[0]
@_p_not_atom.set_parse_action # type: ignore[misc]
def _parse_not_atom(tokens: pyp.ParseResults) -> expr.NotExpr:
"""Parse a "not @tag" or "not keyword" element."""
- assert len(tokens) == 1 and isinstance(tokens[0], expr.BoolExpr)
+ if len(tokens) != 1 or not isinstance(tokens[0], expr.BoolExpr):
+ raise ParseResultError(tokens)
return expr.NotExpr(child=tokens[0])
@@ -70,7 +107,8 @@ def _parse_not_atom(tokens: pyp.ParseResults) -> expr.NotExpr:
def _parse_and_expr(tokens: pyp.ParseResults) -> expr.BoolExpr:
"""Parse a "atom [and atom...]" subexpression."""
children: list[expr.BoolExpr] = tokens.as_list()
- assert children and all(isinstance(item, expr.BoolExpr) for item in children)
+ if not children or any(not isinstance(item, expr.BoolExpr) for item in children):
+ raise ParseResultError(tokens)
if len(children) == 1:
return children[0]
@@ -81,7 +119,8 @@ def _parse_and_expr(tokens: pyp.ParseResults) -> expr.BoolExpr:
def _parse_or_expr(tokens: pyp.ParseResults) -> expr.BoolExpr:
"""Parse a "subexpr [or subexpr...]" subexpression."""
children: list[expr.BoolExpr] = tokens.as_list()
- assert children and all(isinstance(item, expr.BoolExpr) for item in children)
+ if not children or any(not isinstance(item, expr.BoolExpr) for item in children):
+ raise ParseResultError(tokens)
if len(children) == 1:
return children[0]
@@ -94,7 +133,8 @@ _p_complete = _p_spec.leave_whitespace()
def parse_spec(spec: str) -> expr.BoolExpr:
"""Parse an expression using the `pyparsing` library."""
res = _p_complete.parse_string(spec, parse_all=True).as_list()
- assert len(res) == 1 and isinstance(res[0], expr.BoolExpr), repr(res)
+ if len(res) != 1 or not isinstance(res[0], expr.BoolExpr):
+ raise ParseError(res)
return res[0]
@@ -108,9 +148,11 @@ _p_stage_ids = _p_stage_range + (pyp.Literal(",").suppress() + _p_stage_range)[.
@_p_stage_id.set_parse_action
def _parse_stage_id(tokens: pyp.ParseResults) -> int:
"""Parse a single stage ID, return it as a zero-based index."""
- assert len(tokens) == 1 and isinstance(tokens[0], str), repr(tokens)
+ if len(tokens) != 1 or not isinstance(tokens[0], str):
+ raise ParseResultError(tokens)
res = int(tokens[0]) - 1
- assert res >= 0, repr((tokens, res))
+ if res < 0:
+ raise ParseResultError(tokens)
return res
@@ -118,16 +160,18 @@ def _parse_stage_id(tokens: pyp.ParseResults) -> int:
def _parse_stage_range(tokens: pyp.ParseResults) -> list[int]:
"""Parse a range of stage IDs (possibly only containing a single one)."""
if len(tokens) == 1:
- assert isinstance(tokens[0], int), repr(tokens)
+ if not isinstance(tokens[0], int):
+ raise ParseResultError(tokens)
return [tokens[0]]
# The magic value will go away once we can use Python 3.10 structural matching
- assert (
- len(tokens) == 2 # pylint: disable=magic-value-comparison
- and isinstance(tokens[0], int)
- and isinstance(tokens[1], int)
- and tokens[0] < tokens[1]
- ), repr(tokens)
+ if (
+ len(tokens) != 2 # noqa: PLR2004
+ or not isinstance(tokens[0], int)
+ or not isinstance(tokens[1], int)
+ or tokens[0] >= tokens[1]
+ ):
+ raise ParseResultError(tokens)
return list(range(tokens[0], tokens[1] + 1))
@@ -150,5 +194,6 @@ def parse_stage_ids(spec: str, *, empty_set_specs: list[str] | None = None) -> l
return []
res: list[int] = _p_stage_ids_complete.parse_string(spec, parse_all=True).as_list()
- assert all(isinstance(item, int) and item >= 0 for item in res), repr(res)
+ if any(not isinstance(item, int) and item >= 0 for item in res):
+ raise ParseError(res)
return res
diff --git a/tox.ini b/tox.ini
index d676ba2..d817fed 100644
--- a/tox.ini
+++ b/tox.ini
@@ -7,11 +7,7 @@ envlist =
ruff
ruff-all
format
- pep8
mypy
- pylint
- pydocstyle
- pyupgrade
unit-tests
isolated_build = True
@@ -25,7 +21,7 @@ skip_install = True
tags =
check
deps =
- ruff >= 0.0.267, < 0.1
+ ruff >= 0.0.275, < 0.1
commands =
ruff check --config config/ruff-most/pyproject.toml -- {[defs]pyfiles}
@@ -34,7 +30,7 @@ skip_install = True
tags =
check
deps =
- ruff == 0.0.267
+ ruff == 0.0.275
commands =
ruff check --config config/ruff-all/pyproject.toml -- {[defs]pyfiles}
@@ -44,7 +40,7 @@ tags =
check
deps =
black >= 23, < 24
- ruff >= 0.0.267, < 0.1
+ ruff >= 0.0.275, < 0.1
commands =
ruff check --config config/ruff-base/pyproject.toml --select=I --diff -- {[defs]pyfiles}
black --check {[defs]pyfiles}
@@ -56,45 +52,11 @@ tags =
manual
deps =
black >= 23, < 24
- ruff >= 0.0.267, < 0.1
+ ruff >= 0.0.275, < 0.1
commands =
ruff check --config config/ruff-base/pyproject.toml --select=I --fix -- {[defs]pyfiles}
black {[defs]pyfiles}
-# Add flake8-import-conventions if it ever hits PyPI
-[testenv:pep8]
-skip_install = True
-tags =
- check
-deps =
- flake8 >= 5, < 7
- flake8-2020 >= 1, < 2
- flake8-annotations >= 3, < 4
- flake8-blind-except >= 0.2, < 0.3
- flake8-bugbear >= 23, < 24
- flake8-builtins >= 2, < 3
- flake8-commas >= 2, < 3
- flake8-comprehensions >= 3, < 4
- flake8-datetimez >= 20, < 21
- flake8-debugger >= 4, < 5
- flake8-executable >= 2, < 3
- flake8-implicit-str-concat >= 0.4, < 0.5
- flake8-no-pep420 >= 2, < 3
- flake8-pie >= 0.16, < 0.17
- flake8-print >= 5, < 6
- flake8-pytest-style >= 1, < 2
- flake8-quotes >= 3, < 4
- flake8-return >= 1, < 2
- flake8-simplify >= 0.20, < 0.21
- flake8-use-pathlib >= 0.3, < 0.4
- mccabe >= 0.7, < 0.8
- pep8-naming >= 0.13, < 0.14
- pycodestyle >= 2.10, < 3
- tryceratops >= 2, < 3
-commands =
- flake8 {[defs]pyfiles}
- pycodestyle {[defs]pyfiles}
-
[testenv:mypy]
skip_install = True
tags =
@@ -102,32 +64,12 @@ tags =
deps =
-r requirements/install.txt
-r requirements/test.txt
- mypy >= 0.981
+ mypy >= 1, < 2
setenv =
MYPYPATH = {toxinidir}/stubs
commands =
mypy {[defs]pyfiles}
-[testenv:pylint]
-skip_install = True
-tags =
- check
-deps =
- -r requirements/install.txt
- -r requirements/test.txt
- pylint >= 2.17, < 2.18
-commands =
- pylint {[defs]pyfiles}
-
-[testenv:pydocstyle]
-skip_install = True
-tags =
- check
-deps =
- pydocstyle >= 6, < 7
-commands =
- pydocstyle {[defs]pyfiles}
-
[testenv:pyupgrade]
skip_install = True
tags =
@@ -163,7 +105,6 @@ commands =
skip_install = True
tags =
check
- manual
deps =
reuse >= 1, < 2
commands =
diff --git a/unit_tests/test_eval.py b/unit_tests/test_eval.py
index 255c6d1..dea4485 100644
--- a/unit_tests/test_eval.py
+++ b/unit_tests/test_eval.py
@@ -2,13 +2,9 @@
# SPDX-License-Identifier: BSD-2-Clause
"""Test the evaluation of some simple expressions."""
-# This is a test suite, right?
-# flake8: noqa: S101
-
from __future__ import annotations
import dataclasses
-
from typing import NamedTuple
import pytest
diff --git a/unit_tests/test_parse.py b/unit_tests/test_parse.py
index 347a5af..be19fa5 100644
--- a/unit_tests/test_parse.py
+++ b/unit_tests/test_parse.py
@@ -2,9 +2,6 @@
# SPDX-License-Identifier: BSD-2-Clause
"""Test some basic parsing functionality."""
-# This is a test suite, right?
-# flake8: noqa: S101
-
from __future__ import annotations
from typing import NamedTuple