diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2764602..d459390 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ on: jobs: build: name: Build - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - uses: hynek/build-and-inspect-python-package@v2 @@ -18,17 +18,53 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] - name: Python ${{ matrix.python-version }} - runs-on: ubuntu-latest + include: + - name: "pytest (3.9)" + python: "3.9" + tox: "3.9" + - name: "pytest (3.10)" + python: "3.10" + tox: "3.10" + - name: "pytest (3.11)" + python: "3.11" + tox: "3.11" + - name: "pytest (3.12)" + python: "3.12" + tox: "3.12" + - name: "pytest (3.13)" + python: "3.13" + tox: "3.13" + coverage: true + - name: "mypy" + python: "3.13" + tox: mypy + - name: "pyright" + python: "3.13" + tox: pyright + - name: "ruff format" + python: "3.13" + tox: ruff-format + - name: "ruff lint" + python: "3.13" + tox: ruff-lint + - name: "Docs" + python: "3.13" + tox: docs + + name: ${{ matrix.name }} + runs-on: ubuntu-24.04 + steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: astral-sh/setup-uv@v5 with: - python-version: ${{ matrix.python-version }} - allow-prereleases: true - - run: python -Im pip install nox==2024.10.9 poetry==1.8.4 - - run: python -Im nox --python ${{ matrix.python-version }} + python-version: ${{ matrix.python }} + - run: uv pip install tox tox-uv + - run: tox -e ${{ matrix.tox }} + if: ${{ ! matrix.coverage }} + - run: tox -e ${{ matrix.tox }} -- --cov-report=xml + if: ${{ matrix.coverage }} - uses: codecov/codecov-action@v5 + if: ${{ matrix.coverage }} with: token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.gitignore b/.gitignore index 62adc2d..6b9d2c3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.egg-info/ +/*.lock /.*_cache/ /.coverage /.dmypy.json @@ -8,5 +9,4 @@ /coverage.xml /dist/ /docs/_build/ -/poetry.lock __pycache__/ diff --git a/.readthedocs.yml b/.readthedocs.yml index 4de3131..d3385ff 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -3,12 +3,12 @@ version: 2 build: os: "ubuntu-24.04" tools: - python: "3.12" + python: "3.13" jobs: post_create_environment: - - pip install poetry + - pip install uv post_install: - - VIRTUAL_ENV=$READTHEDOCS_VIRTUALENV_PATH poetry install --all-extras --only=main,docs + - UV_PROJECT_ENVIRONMENT=$READTHEDOCS_VIRTUALENV_PATH uv sync --all-extras --group docs --link-mode copys sphinx: configuration: docs/conf.py diff --git a/.tool-versions b/.tool-versions deleted file mode 100644 index 9a60ea6..0000000 --- a/.tool-versions +++ /dev/null @@ -1,3 +0,0 @@ -nodejs 22.11 -poetry 1.8.4 -python 3.13 3.12 3.11 3.10 3.9 diff --git a/README.md b/README.md index d9bb401..bd7c396 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ the parts of the API that there is an actual demand for. Copyright 2019 [Otovo ASA](https://www.otovo.com/), -2023-2024 [Cardboard AS](https://cardboard.inc/). +2023-2025 [Cardboard AS](https://cardboard.inc/). Licensed under the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/docs/conf.py b/docs/conf.py index e9c89ab..3175113 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -2,7 +2,7 @@ project = "python-brreg" author = "Cardboard AS" -copyright = f"2019 Otovo ASA, 2023-2024 {author}" # noqa: A001 +copyright = f"2019 Otovo ASA, 2023-2025 {author}" # noqa: A001 extensions = [ "sphinx.ext.autodoc", diff --git a/docs/index.rst b/docs/index.rst index 955b173..47d3503 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -46,7 +46,7 @@ License Copyright 2019 `Otovo ASA `_, -2023-2024 `Cardboard AS `_. +2023-2025 `Cardboard AS `_. Licensed under the `Apache License, Version 2.0 `_. diff --git a/noxfile.py b/noxfile.py deleted file mode 100644 index 72fd1c0..0000000 --- a/noxfile.py +++ /dev/null @@ -1,97 +0,0 @@ -"""Nox sessions.""" - -import nox - -locations = ["docs/conf.py", "noxfile.py", "src", "tests"] - -supported_pythons = ["3.9", "3.10", "3.11", "3.12", "3.13"] -docs_python = "3.13" - - -@nox.session(python=supported_pythons) -def tests(session: nox.Session) -> None: - """Run the test suite.""" - args = session.posargs or ["--cov", "--cov-report=xml"] - session.run( - "poetry", - "install", - "--quiet", - "--all-extras", - "--only=main,tests", - external=True, - ) - session.run("pytest", *args) - - -@nox.session(python=supported_pythons) -def ruff_format(session: nox.Session) -> None: - """Check formatting using Ruff.""" - args = session.posargs or locations - session.run( - "poetry", - "install", - "--quiet", - "--no-root", - "--only=ruff", - external=True, - ) - session.run("ruff", "format", "--check", *args) - - -@nox.session(python=supported_pythons) -def ruff_check(session: nox.Session) -> None: - """Lint using Ruff.""" - args = session.posargs or locations - session.run( - "poetry", - "install", - "--quiet", - "--no-root", - "--only=ruff", - external=True, - ) - session.run("ruff", "check", *args) - - -@nox.session(python=supported_pythons) -def mypy(session: nox.Session) -> None: - """Type-check using mypy.""" - args = session.posargs or locations - session.run( - "poetry", - "install", - "--quiet", - "--all-extras", - "--only=main,dev,docs,tests,mypy", - external=True, - ) - session.run("mypy", *args) - - -@nox.session(python=supported_pythons) -def pyright(session: nox.Session) -> None: - """Type-check using pyright.""" - args = session.posargs or locations - session.run( - "poetry", - "install", - "--quiet", - "--all-extras", - "--only=main,dev,docs,tests,pyright", - external=True, - ) - session.run("pyright", *args) - - -@nox.session(python=docs_python) -def docs(session: nox.Session) -> None: - """Build the documentation.""" - session.run( - "poetry", - "install", - "--quiet", - "--all-extras", - "--only=main,docs", - external=True, - ) - session.run("sphinx-build", "docs", "docs/_build") diff --git a/pyproject.toml b/pyproject.toml index fec9e18..2294ba9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,48 +1,50 @@ -[tool.poetry] +[project] name = "brreg" version = "1.2.0" description = "API client for Brønnøysundregistrene." -authors = ["Stein Magnus Jodal "] -license = "Apache-2.0" +authors = [{ name = "Stein Magnus Jodal", email = "stein.magnus@jodal.no" }] +requires-python = ">=3.9" readme = "README.md" -homepage = "https://github.com/crdbrd/python-brreg" -repository = "https://github.com/crdbrd/python-brreg" -documentation = "https://brreg.readthedocs.io" +license = "Apache-2.0" keywords = ["brreg", "enhetsregisteret"] classifiers = [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Topic :: Software Development :: Libraries", + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Topic :: Software Development :: Libraries", +] +dependencies = ["httpx>=0.24", "pydantic>=2"] + +[project.urls] +Homepage = "https://github.com/crdbrd/python-brreg" +Repository = "https://github.com/crdbrd/python-brreg" +Documentation = "https://brreg.readthedocs.io" + +[dependency-groups] +dev = [ + "tox>=4.21.2", + "tox-uv>=1.23.2", + { include-group = "docs" }, + { include-group = "mypy" }, + { include-group = "pyright" }, + { include-group = "ruff" }, + { include-group = "tests" }, +] +docs = [ + "sphinx>=5.3", + "sphinx-rtd-theme>=1.2", + "sphinx-autodoc-typehints>=1.12", +] +mypy = ["mypy==1.11.1"] +pyright = ["pyright==1.1.394"] +ruff = ["ruff==0.9.6"] +tests = [ + "coverage[toml]>=7.4.1", + "pytest>=7.4.4", + "pytest-cov>=4.1", + "pytest-httpx==0.35.0", + "pytest-watcher>=0.4.1", ] -[tool.poetry.dependencies] -python = "^3.9.0" -httpx = ">= 0.24" -pydantic = ">= 2" - -[tool.poetry.group.dev.dependencies] -nox = ">=2024.10.9,<2026.0.0" - -[tool.poetry.group.docs.dependencies] -sphinx = ">= 5.3" -sphinx-rtd-theme = ">= 1.2" -sphinx-autodoc-typehints = ">= 1.12" - -[tool.poetry.group.mypy.dependencies] -mypy = "^1.11.1" - -[tool.poetry.group.pyright.dependencies] -pyright = "1.1.394" - -[tool.poetry.group.ruff.dependencies] -ruff = "0.9.6" - -[tool.poetry.group.tests.dependencies] -coverage = { extras = ["toml"], version = "^7.4.1" } -pytest = ">=7.4.4,<9.0.0" -pytest-cov = ">=4.1,<7.0" -pytest-httpx = "0.35.0" -pytest-watcher = "^0.4.1" [tool.coverage.paths] source = ["src"] @@ -55,10 +57,12 @@ source = ["brreg"] fail_under = 100 show_missing = true + [tool.pytest.ini_options] minversion = "6.0" filterwarnings = ["error::RuntimeWarning"] + [tool.mypy] no_implicit_optional = true warn_return_any = true @@ -70,23 +74,33 @@ strict_equality = true module = "brreg.*" disallow_untyped_defs = true + +[tool.pyright] +pythonVersion = "3.9" +typeCheckingMode = "strict" +# Already covered by tests and careful import ordering: +reportImportCycles = false +# Already covered by flake8-self: +reportPrivateUsage = false + + [tool.ruff] target-version = "py39" [tool.ruff.lint] select = ["ALL"] ignore = [ - # These rules interfere with `ruff format` - "COM812", - "ISC001", + # These rules interfere with `ruff format` + "COM812", + "ISC001", ] [tool.ruff.lint.per-file-ignores] "docs/*" = ["INP001"] "tests/*" = [ - "D", # pydocstyle - "PLR2004", # magic-value-comparison - "S101", # assert + "D", # pydocstyle + "PLR2004", # magic-value-comparison + "S101", # assert ] [tool.ruff.lint.isort] @@ -98,16 +112,83 @@ convention = "google" [tool.ruff.lint.pyupgrade] keep-runtime-typing = true -[tool.pyright] -pythonVersion = "3.9" -venvPath = "." -venv = ".venv" -typeCheckingMode = "strict" -# Already covered by tests and careful import ordering: -reportImportCycles = false -# Already covered by flake8-self: -reportPrivateUsage = false + +[tool.tox] +requires = ["tox >= 4.21"] +env_list = [ + "3.9", + "3.10", + "3.11", + "3.12", + "3.13", + "docs", + "mypy", + "pyright", + "ruff-format", + "ruff-lint", +] + +[tool.tox.env_run_base] +dependency_groups = ["tests"] +commands = [ + [ + "pytest", + "--basetemp={envtmpdir}", + "--cov=brreg", + "--cov-report=term-missing", + "{posargs}", + ], +] + +[tool.tox.env.docs] +dependency_groups = ["docs"] +commands = [ + [ + "sphinx-build", + "--builder", + "html", + "--doctree-dir", + "{envtmpdir}{/}doctrees", + "docs", + "{envtmpdir}{/}html", + ], +] + +[tool.tox.env.mypy] +dependency_groups = ["tests", "mypy"] +commands = [ + [ + "mypy", + { replace = "posargs", default = [ + "src", + "tests", + ], extend = true }, + ], +] + +[tool.tox.env.pyright] +dependency_groups = ["tests", "pyright"] +commands = [ + [ + "pyright", + { replace = "posargs", default = [ + "src", + "tests", + ], extend = true }, + ], +] + +[tool.tox.env.ruff-format] +skip_install = true +dependency_groups = ["ruff"] +commands = [["ruff", "format", "--check", "{posargs:.}"]] + +[tool.tox.env.ruff-lint] +skip_install = true +dependency_groups = ["ruff"] +commands = [["ruff", "check", "{posargs:.}"]] + [build-system] -requires = ["poetry-core>=1.0"] -build-backend = "poetry.core.masonry.api" +requires = ["hatchling"] +build-backend = "hatchling.build"