Skip to content

Commit

Permalink
Tooling updates: Ruff and Poetry dependency groups (#184)
Browse files Browse the repository at this point in the history
* Use docs deps group when building docs

* Replace flake8-black with a black nox session

* Use tests deps group when running tests

* Use mypy dependency group to run mypy

* Create scripts deps group

* Run darglint independently of flake8

* Replace flake8 and isort with ruff

* Fix ruff lints

* Use dependency group to report coverage

* Add dev dep on nox

This is possible now since nox only installs specific dep groups

* Minimize noqa comments

* Enable Ruff's own linting rules

* Enable flake8-quotes rules

* Enable flake8-simplify rules

* Enable flake8-type-checking rules

* Enable flake8-tidy-imports rules

* Enable flake8-print rules

* Split flake8-comprehensions and mccabe rules

* Enable pep8-naming rules

* Enable pyupgrade rules

* Enable flake8-boolean-trap rules

* Enable flake8-builtins rules

* Enable flake8-datetimez rules

* Enable flake8-implicit-str-concat rules

* Enable flake8-no-pep420 rules

* Enable flake8-pie rules

* Enable flake8-pytest-style rules

* Enable flake8-raise rules

* Enable flake8-return rules

* Enable flake8-self rules

* Enable flake8-unused-arguments rules

* Enable flake8-use-pathlib rules

* Enable eradicate rules

* Enable pygrep-hooks rules

* Enable Pylint rules

* Enable tryceratops rules
  • Loading branch information
jodal authored Mar 11, 2023
1 parent 212cf7e commit 059bc69
Show file tree
Hide file tree
Showing 32 changed files with 287 additions and 248 deletions.
2 changes: 1 addition & 1 deletion .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ build:
post_install:
- pip install poetry
- poetry config virtualenvs.create false
- poetry install --with docs --without dev
- poetry install --all-extras --only=main,docs

sphinx:
configuration: docs/conf.py
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

project = "biip"
author = "Stein Magnus Jodal"
copyright = f"2020-2022, {author}"
copyright = f"2020-2022, {author}" # noqa: A001

extensions = [
"sphinx.ext.autodoc",
Expand Down
68 changes: 31 additions & 37 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,58 +10,52 @@
def tests(session):
"""Run the test suite."""
args = session.posargs or ["--cov"]
session.run("poetry", "install", external=True)
session.run("poetry", "install", "--all-extras", "--only=main,tests", external=True)
session.run("pytest", *args)


@nox.session(python="3.11")
def coverage(session):
"""Upload test coverage data."""
session.run("poetry", "install", "--no-root", "--only=tests", external=True)
session.run("coverage", "xml", "--fail-under=0")
session.run("codecov", *session.posargs)


@nox.session(python=["3.7", "3.8", "3.9", "3.10", "3.11"])
def black(session):
"""Check formatting using Black."""
args = session.posargs or locations
session.run("poetry", "install", "--no-root", "--only=black", external=True)
session.run("black", *args)


@nox.session(python=["3.7", "3.8", "3.9", "3.10", "3.11"])
def flake8(session):
"""Lint using flake8."""
def ruff(session):
"""Lint using ruff."""
args = session.posargs or locations
session.install(
"darglint",
"flake8",
"flake8-annotations",
"flake8-black",
"flake8-bugbear",
"flake8-docstrings",
"flake8-isort",
)
session.run("flake8", *args)
session.run("poetry", "install", "--no-root", "--only=ruff", external=True)
session.run("ruff", *args)


@nox.session(python=["3.7", "3.8", "3.9", "3.10", "3.11"])
def darglint(session):
"""Check docstrings using darglint."""
args = session.posargs or ["src"]
session.run("poetry", "install", "--no-root", "--only=darglint", external=True)
session.run("darglint", *args)


@nox.session(python=["3.7", "3.8", "3.9", "3.10", "3.11"])
def mypy(session):
"""Type-check using mypy."""
args = session.posargs or locations
session.install(
"mypy",
"types-dataclasses",
)
session.run("poetry", "install", "--only=mypy", external=True)
session.run("mypy", *args)


@nox.session(python="3.11")
def docs(session):
"""Build the documentation."""
session.run(
"poetry",
"install",
"--no-dev",
"--extras=money",
external=True,
)
session.install(
"sphinx",
"sphinx-rtd-theme",
"sphinx-autodoc-typehints",
)
session.run("poetry", "install", "--all-extras", "--only=main,docs", external=True)
session.run("sphinx-build", "docs", "docs/_build")


@nox.session(python="3.11")
def coverage(session):
"""Upload test coverage data."""
session.install("coverage[toml]", "codecov")
session.run("coverage", "xml", "--fail-under=0")
session.run("codecov", *session.posargs)
109 changes: 88 additions & 21 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,36 @@ py-moneyed = { version = ">=0.8", optional = true }
[tool.poetry.extras]
money = ["py-moneyed"]

[tool.poetry.group.dev.dependencies]
beautifulsoup4 = "^4.11.2"
[tool.poetry.group.black.dependencies]
black = "^23.1.0"
codecov = "^2.1.12"
coverage = "^7.2.1"

[tool.poetry.group.darglint.dependencies]
darglint = "^1.8.1"
flake8 = "^5.0.4"
flake8-annotations = "^2.9.1"
flake8-black = "^0.3.6"
flake8-bugbear = "^23.2.13"
flake8-docstrings = "^1.7.0"
flake8-isort = "^6.0.0"
httpx = "^0.23.3"
isort = "^5.11.5"
mypy = "^1.1.1"
py-moneyed = "^3.0"
pytest = "^7.2.2"
pytest-cov = "^4.0.0"
xdoctest = "^1.1.1"

[tool.poetry.group.dev.dependencies]
nox = "^2022.11.21"

[tool.poetry.group.docs.dependencies]
sphinx = "^4.0.0"
sphinx-rtd-theme = "^1.1.1"
sphinx-autodoc-typehints = "^1.12.0"
py-moneyed = "^3.0"

[tool.poetry.group.mypy.dependencies]
mypy = "^1.1.1"

[tool.poetry.group.ruff.dependencies]
ruff = "^0.0.254"

[tool.poetry.group.scripts.dependencies]
beautifulsoup4 = "^4.11.2"
httpx = "^0.23.3"

[tool.poetry.group.tests.dependencies]
codecov = "^2.1.12"
coverage = { extras = ["toml"], version = "^7.2.1" }
pytest = "^7.2.2"
pytest-cov = "^4.0.0"
xdoctest = "^1.1.1"

[tool.black]
target-version = ["py37", "py38", "py39", "py310", "py311"]
Expand All @@ -63,9 +68,6 @@ source = ["biip"]
fail_under = 100
show_missing = true

[tool.isort]
profile = "black"

[tool.pytest.ini_options]
minversion = "6.0"
addopts = "--xdoc"
Expand All @@ -85,6 +87,71 @@ disallow_untyped_defs = true
module = ["bs4.*", "moneyed.*", "nox.*", "pytest.*"]
ignore_missing_imports = true

[tool.ruff]
select = [
"A", # flake8-builtins
"ANN", # flake8-annotations
"ARG", # flake8-unused-arguments
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"C90", # mccabe
"D", # pydocstyle
"DTZ", # flake8-datetimez
"E", # pycodestyle
"ERA", # eradicate
"F", # pyflakes
"FBT", # flake8-boolean-trap
"I", # isort
"INP", # flake8-no-pep420
"ISC", # flake8-implicit-str-concat
"N", # pep8-naming
"PGH", # pygrep-hooks
"PIE", # flake8-pie
"PLC", # pylint convention
"PLE", # pylint error
"PLR", # pylint refactor
"PLW", # pylint warning
"PT", # flake8-pytest-style
"PTH", # flake8-use-pathlib
"Q", # flake8-quotes
"RET", # flake8-return
"RSE", # flake8-raise
"RUF", # ruff
"SIM", # flake8-simplify
"SLF", # flake8-self
"T20", # flake8-print
"TCH", # flake8-type-checking
"TID", # flake8-tidy-imports
"TRY", # tryceratops
"UP", # pyupgrade
"W", # pycodestyle
]
ignore = [
"A003", # builtin-attribute-shadowing
"ANN101", # missing-type-self
"ANN102", # missing-type-cls
"PLR2004", # magic-value-comparison
"RET504", # unnecessary-assign
"TRY003", # raise-vanilla-args
#
# Equivalent to `pyupgrade --keep-runtime-typing`:
"UP006", # deprecated-collection-type
"UP007", # typing-union
]
target-version = "py37"

[tool.ruff.per-file-ignores]
"docs/*" = ["INP001"]
"noxfile.py" = ["ANN"]
"scripts/*" = ["INP001", "T20"]
"tests/*" = ["D"]

[tool.ruff.isort]
known-first-party = ["biip"]

[tool.ruff.pydocstyle]
convention = "google"

[build-system]
requires = ["poetry-core>=1.0"]
build-backend = "poetry.core.masonry.api"
8 changes: 4 additions & 4 deletions scripts/download_gs1_prefixes.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ def parse(html_content: bytes) -> List[_GS1PrefixRange]:
note_start = usage.index(", see")
usage = usage[:note_start]

for range in prefixes.split("&"):
if "-" in range:
start, end = map(str.strip, range.split("-"))
for range_ in prefixes.split("&"):
if "-" in range_:
start, end = map(str.strip, range_.split("-"))
else:
start, end = range.strip(), range.strip()
start, end = range_.strip(), range_.strip()

length = len(start)
min_value = int(start)
Expand Down
36 changes: 0 additions & 36 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,3 @@ ignore_raise =
# Exception is used for cases that are bugs and should never happen.
Exception
strictness = short

[flake8]
exclude = .git,.nox,.venv
max-line-length = 88
select =
# Regular flake8 rules
C, E, F, W
# flake8-annotations rules
ANN
# flake8-bugbear rules
B
# B950: line too long (soft speed limit)
B950
# flake8-black rules
BLK
# flake8-docstrings rules
D
# darglint rules
DAR
# flake8-isort rules
I
ignore =
# ANN101: Missing type annotation for self in method
ANN101
# ANN102: Missing type annotation for cls in method
ANN102
# E203: whitespace before ':' (not PEP8 compliant)
E203
# E501: line too long (replaced by B950)
E501
# W503: line break before binary operator (not PEP8 compliant)
W503
per-file-ignores =
noxfile.py:ANN
tests/*:D
docstring-convention = google
10 changes: 8 additions & 2 deletions src/biip/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,15 @@
"""

try:
from importlib.metadata import PackageNotFoundError, version # type: ignore
from importlib.metadata import ( # type: ignore[import]
PackageNotFoundError,
version,
)
except ImportError: # pragma: no cover
from importlib_metadata import version, PackageNotFoundError # type: ignore
from importlib_metadata import ( # type: ignore[import,no-redef]
PackageNotFoundError,
version,
)

from biip._exceptions import BiipException, EncodeError, ParseError
from biip._parser import ParseResult, parse
Expand Down
8 changes: 1 addition & 7 deletions src/biip/_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,13 @@
__all__ = ["BiipException", "EncodeError", "ParseError"]


class BiipException(Exception):
class BiipException(Exception): # noqa: N818
"""Base class for all custom exceptions raised by the library."""

pass


class EncodeError(BiipException):
"""Error raised if encoding of a value fails."""

pass


class ParseError(BiipException):
"""Error raised if parsing of barcode data fails."""

pass
14 changes: 8 additions & 6 deletions src/biip/_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,12 @@ def parse(
(parse_func, val) = queue.pop(0)
parse_func(val, config=config, queue=queue, result=result)

if result._has_result():
if result._has_result(): # noqa: SLF001
return result
else:
raise ParseError(f"Failed to parse {value!r}:\n{result._get_errors_list()}")

raise ParseError(
f"Failed to parse {value!r}:\n{result._get_errors_list()}" # noqa: SLF001
)


@dataclass
Expand Down Expand Up @@ -187,7 +189,7 @@ def _parse_gtin(
def _parse_upc(
value: str,
*,
config: ParseConfig,
config: ParseConfig, # noqa: ARG001
queue: ParseQueue,
result: ParseResult,
) -> None:
Expand All @@ -208,8 +210,8 @@ def _parse_upc(
def _parse_sscc(
value: str,
*,
config: ParseConfig,
queue: ParseQueue,
config: ParseConfig, # noqa: ARG001
queue: ParseQueue, # noqa: ARG001
result: ParseResult,
) -> None:
if result.sscc is not None:
Expand Down
15 changes: 6 additions & 9 deletions src/biip/gs1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,12 @@
DEFAULT_SEPARATOR_CHARS: Tuple[str] = (ASCII_GROUP_SEPARATOR,)

# The following must be imported in this specific order.
from biip.gs1._symbology import GS1Symbology # isort:skip # noqa: E402
from biip.gs1._application_identifiers import ( # isort:skip # noqa: E402
GS1ApplicationIdentifier,
)
from biip.gs1._prefixes import GS1CompanyPrefix, GS1Prefix # isort:skip # noqa: E402
from biip.gs1._element_strings import ( # isort:skip # noqa: E402
GS1ElementString,
)
from biip.gs1._messages import GS1Message # isort:skip # noqa: E402
# ruff: noqa: E402, I001
from biip.gs1._symbology import GS1Symbology
from biip.gs1._application_identifiers import GS1ApplicationIdentifier
from biip.gs1._prefixes import GS1CompanyPrefix, GS1Prefix
from biip.gs1._element_strings import GS1ElementString
from biip.gs1._messages import GS1Message

__all__ = [
"GS1CompanyPrefix",
Expand Down
Loading

0 comments on commit 059bc69

Please sign in to comment.