File: noxfile.py

package info (click to toggle)
universal-pathlib 0.3.10-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,656 kB
  • sloc: python: 20,552; makefile: 5
file content (177 lines) | stat: -rw-r--r-- 5,230 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
"""Automation using nox."""

import glob
import os
import sys

import nox

nox.options.reuse_existing_virtualenvs = True
nox.options.error_on_external_run = True

nox.needs_version = ">=2024.04.15"
nox.options.default_venv_backend = "uv"

nox.options.sessions = "lint", "tests", "type-checking", "type-safety"
locations = ("upath",)
running_in_ci = os.environ.get("CI", "") != ""

SUPPORTED_PYTHONS = ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
BASE_PYTHON = SUPPORTED_PYTHONS[-3]
MIN_PYTHON = SUPPORTED_PYTHONS[0]


@(lambda f: f())
def FSSPEC_MIN_VERSION() -> str:
    """Get the minimum fsspec version boundary from pyproject.toml."""
    try:
        from packaging.requirements import Requirement

        if sys.version_info >= (3, 11):
            from tomllib import load as toml_load
        else:
            from tomli import load as toml_load
    except ImportError:
        raise RuntimeError(
            "We rely on nox>=2024.04.15 depending on `packaging` and `tomli/tomllib`."
            " Please report if you see this error."
        )

    with open("pyproject.toml", "rb") as f:
        pyproject_data = toml_load(f)

    for requirement in pyproject_data["project"]["dependencies"]:
        req = Requirement(requirement)
        if req.name == "fsspec":
            for specifier in req.specifier:
                if specifier.operator == ">=":
                    return str(specifier.version)
    raise RuntimeError("Could not find fsspec minimum version in pyproject.toml")


@nox.session(python=SUPPORTED_PYTHONS)
def tests(session: nox.Session) -> None:
    """Run the test suite."""
    # workaround in case no aiohttp binary wheels are available
    if session.python == "3.14":
        session.env["AIOHTTP_NO_EXTENSIONS"] = "1"
        session.install(".[tests,dev]", "pydantic>=2.12.0a1")
    else:
        session.install(".[tests,dev,dev-third-party]")
    session.run("uv", "pip", "freeze", silent=not running_in_ci)
    session.run(
        "pytest",
        "-m",
        "not hdfs",
        "--cov",
        "--cov-config=pyproject.toml",
        *session.posargs,
        env={"COVERAGE_FILE": f".coverage.{session.python}"},
    )


@nox.session(python=MIN_PYTHON, name="tests-minversion")
def tests_minversion(session: nox.Session) -> None:
    session.install(f"fsspec=={FSSPEC_MIN_VERSION}", ".[tests,dev]")
    session.run("uv", "pip", "freeze", silent=not running_in_ci)
    session.run(
        "pytest",
        "-m",
        "not hdfs",
        "--cov",
        "--cov-config=pyproject.toml",
        *session.posargs,
        env={"COVERAGE_FILE": f".coverage.{session.python}"},
    )


tests_minversion.__doc__ = f"Run the test suite with fsspec=={FSSPEC_MIN_VERSION}."


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

    args = *(session.posargs or ("--show-diff-on-failure",)), "--all-files"
    session.run("pre-commit", "run", *args)


@nox.session
def safety(session: nox.Session) -> None:
    """Scan dependencies for insecure packages."""
    session.install(".")
    session.install("safety")
    session.run("safety", "check", "--full-report")


@nox.session
def build(session: nox.Session) -> None:
    """Build sdists and wheels."""
    session.install("build", "setuptools", "twine")
    session.run("python", "-m", "build")
    dists = glob.glob("dist/*")
    session.run("twine", "check", *dists, silent=True)


@nox.session
def develop(session: nox.Session) -> None:
    """Sets up a python development environment for the project."""
    session.run("uv", "venv", external=True)


@nox.session(name="type-checking", python=BASE_PYTHON)
def type_checking(session):
    """Run mypy checks."""
    session.install("-e", ".[typechecking]")
    session.run("python", "-m", "mypy")


@nox.session(name="type-safety", python=SUPPORTED_PYTHONS)
def type_safety(session):
    """Run typesafety tests."""
    session.install("-e", ".[typechecking]")
    session.run(
        "python",
        "-m",
        "pytest",
        "-v",
        "-p",
        "pytest-mypy-plugins",
        "--mypy-pyproject-toml-file",
        "pyproject.toml",
        "typesafety",
        *session.posargs,
    )


@nox.session(name="flavours-upgrade-deps", python=BASE_PYTHON)
def upgrade_flavours(session):
    session.run("uvx", "pur", "-r", "dev/requirements.txt")


@nox.session(name="flavours-codegen", python=BASE_PYTHON)
def generate_flavours(session):
    session.install("-r", "dev/requirements.txt")
    with open("upath/_flavour_sources.py", "w") as target:
        session.run(
            "python",
            "dev/fsspec_inspector/generate_flavours.py",
            stdout=target,
            stderr=None,
        )


@nox.session(name="docs-build", python=BASE_PYTHON)
def docs_build(session):
    """Build the documentation in strict mode."""
    session.install("--group=docs", "-e", ".")
    session.run("mkdocs", "build")


@nox.session(name="docs-serve", python=BASE_PYTHON)
def docs_serve(session):
    """Serve the documentation with live reloading."""
    session.install("--group=docs", "-e", ".")
    session.run("mkdocs", "serve", "--no-strict")