|
27 | 27 | import nox |
28 | 28 | import nox.sessions |
29 | 29 |
|
30 | | -BLACK_VERSION = "black==23.7.0" |
31 | | -FLAKE8_VERSION = "flake8==7.1.2" |
32 | | -ISORT_VERSION = "isort==5.12.0" |
| 30 | +RUFF_VERSION = "ruff==0.14.14" |
33 | 31 | MYPY_VERSION = "mypy==1.15.0" |
34 | 32 |
|
35 | 33 | # Notebook tests should match colab and BQ Studio. |
|
56 | 54 |
|
57 | 55 | DEFAULT_PYTHON_VERSION = "3.14" |
58 | 56 |
|
59 | | -UNIT_TEST_PYTHON_VERSIONS = ["3.10", "3.11", "3.12", "3.13", "3.14"] |
| 57 | +ALL_PYTHON = ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] |
60 | 58 | UNIT_TEST_STANDARD_DEPENDENCIES = [ |
61 | 59 | "mock", |
62 | 60 | PYTEST_VERSION, |
|
78 | 76 | # 3.10 is needed for Windows tests as it is the only version installed in the |
79 | 77 | # bigframes-windows container image. For more information, search |
80 | 78 | # bigframes/windows-docker, internally. |
81 | | -SYSTEM_TEST_PYTHON_VERSIONS = ["3.10", "3.11", "3.12", "3.13", "3.14"] |
| 79 | +SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ALL_PYTHON |
82 | 80 | SYSTEM_TEST_STANDARD_DEPENDENCIES = [ |
83 | 81 | "jinja2", |
84 | 82 | "mock", |
@@ -135,45 +133,56 @@ def lint(session): |
135 | 133 | Returns a failure if the linters find linting errors or sufficiently |
136 | 134 | serious code quality issues. |
137 | 135 | """ |
138 | | - session.install(FLAKE8_VERSION, BLACK_VERSION, ISORT_VERSION) |
139 | | - session.run( |
140 | | - "isort", |
141 | | - "--check", |
142 | | - *LINT_PATHS, |
143 | | - ) |
| 136 | + session.install("flake8", RUFF_VERSION) |
| 137 | + |
| 138 | + # 2. Check formatting |
144 | 139 | session.run( |
145 | | - "black", |
| 140 | + "ruff", |
| 141 | + "format", |
146 | 142 | "--check", |
| 143 | + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", |
| 144 | + "--line-length=88", |
147 | 145 | *LINT_PATHS, |
148 | 146 | ) |
149 | | - session.run("flake8", *LINT_PATHS) |
150 | | - |
151 | 147 |
|
| 148 | +# Use a python runtime which is available in the owlbot post processor here |
| 149 | +# https://github.com/googleapis/synthtool/blob/master/docker/owlbot/python/Dockerfile |
152 | 150 | @nox.session(python=DEFAULT_PYTHON_VERSION) |
153 | 151 | def blacken(session): |
154 | | - """Run black. Format code to uniform standard.""" |
155 | | - session.install(BLACK_VERSION) |
| 152 | + """(Deprecated) Legacy session. Please use 'nox -s format'.""" |
| 153 | + session.log( |
| 154 | + "WARNING: The 'blacken' session is deprecated and will be removed in a future release. Please use 'nox -s format' in the future." |
| 155 | + ) |
| 156 | + |
| 157 | + # Just run the ruff formatter (keeping legacy behavior of only formatting, not sorting imports) |
| 158 | + session.install(RUFF_VERSION) |
156 | 159 | session.run( |
157 | | - "black", |
| 160 | + "ruff", |
| 161 | + "format", |
| 162 | + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", |
| 163 | + "--line-length=88", |
158 | 164 | *LINT_PATHS, |
159 | 165 | ) |
160 | 166 |
|
161 | | - |
162 | 167 | @nox.session(python=DEFAULT_PYTHON_VERSION) |
163 | 168 | def format(session): |
164 | 169 | """ |
165 | | - Run isort to sort imports. Then run black |
166 | | - to format code to uniform standard. |
| 170 | + Run ruff to sort imports and format code. |
167 | 171 | """ |
168 | | - session.install(BLACK_VERSION, ISORT_VERSION) |
169 | | - # Use the --fss option to sort imports using strict alphabetical order. |
170 | | - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections |
171 | | - session.run( |
172 | | - "isort", |
173 | | - *LINT_PATHS, |
174 | | - ) |
| 172 | + # 1. Install ruff (skipped automatically if you run with --no-venv) |
| 173 | + session.install(RUFF_VERSION) |
| 174 | + |
| 175 | + # 2. Run Ruff to fix imports |
| 176 | + # check --select I: Enables strict import sorting |
| 177 | + # --fix: Applies the changes automatically |
175 | 178 | session.run( |
176 | | - "black", |
| 179 | + "ruff", |
| 180 | + "check", |
| 181 | + "--select", |
| 182 | + "I", |
| 183 | + "--fix", |
| 184 | + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", |
| 185 | + "--line-length=88", # Standard Black line length |
177 | 186 | *LINT_PATHS, |
178 | 187 | ) |
179 | 188 |
|
@@ -242,14 +251,14 @@ def run_unit(session, install_test_extra): |
242 | 251 | ) |
243 | 252 |
|
244 | 253 |
|
245 | | -@nox.session(python=UNIT_TEST_PYTHON_VERSIONS) |
| 254 | +@nox.session(python=ALL_PYTHON) |
246 | 255 | def unit(session): |
247 | 256 | if session.python in ("3.7",): |
248 | 257 | session.skip("Python 3.7 is no longer supported") |
249 | 258 | run_unit(session, install_test_extra=True) |
250 | 259 |
|
251 | 260 |
|
252 | | -@nox.session(python=UNIT_TEST_PYTHON_VERSIONS[-1]) |
| 261 | +@nox.session(python=ALL_PYTHON[-1]) |
253 | 262 | def unit_noextras(session): |
254 | 263 | run_unit(session, install_test_extra=False) |
255 | 264 |
|
@@ -337,6 +346,9 @@ def run_system( |
337 | 346 | CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" |
338 | 347 | ) |
339 | 348 |
|
| 349 | + if "GOOGLE_APPLICATION_CREDENTIALS" not in os.environ: |
| 350 | + session.skip("Credentials must be set via environment variable") |
| 351 | + |
340 | 352 | # Check the value of `RUN_SYSTEM_TESTS` env var. It defaults to true. |
341 | 353 | if os.environ.get("RUN_SYSTEM_TESTS", "true") == "false": |
342 | 354 | session.skip("RUN_SYSTEM_TESTS is set to false, skipping") |
@@ -581,6 +593,9 @@ def docfx(session): |
581 | 593 |
|
582 | 594 |
|
583 | 595 | def prerelease(session: nox.sessions.Session, tests_path, extra_pytest_options=()): |
| 596 | + if "GOOGLE_APPLICATION_CREDENTIALS" not in os.environ: |
| 597 | + session.skip("Credentials must be set via environment variable") |
| 598 | + |
584 | 599 | constraints_path = str( |
585 | 600 | CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" |
586 | 601 | ) |
@@ -638,7 +653,7 @@ def prerelease(session: nox.sessions.Session, tests_path, extra_pytest_options=( |
638 | 653 | ) |
639 | 654 |
|
640 | 655 |
|
641 | | -@nox.session(python=UNIT_TEST_PYTHON_VERSIONS[-1]) |
| 656 | +@nox.session(python=ALL_PYTHON[-1]) |
642 | 657 | def unit_prerelease(session: nox.sessions.Session): |
643 | 658 | """Run the unit test suite with prerelease dependencies.""" |
644 | 659 | prerelease(session, os.path.join("tests", "unit")) |
@@ -942,3 +957,22 @@ def cleanup(session): |
942 | 957 | session.install("-e", ".") |
943 | 958 |
|
944 | 959 | session.run("python", "scripts/manage_cloud_functions.py", *cleanup_options) |
| 960 | + |
| 961 | + |
| 962 | +@nox.session(python=DEFAULT_PYTHON_VERSION) |
| 963 | +def core_deps_from_source(session): |
| 964 | + """Run all tests with core dependencies installed from source |
| 965 | + rather than pulling the dependencies from PyPI. |
| 966 | + """ |
| 967 | + # TODO(https://github.com/googleapis/google-cloud-python/issues/16014): |
| 968 | + # Add core deps from source tests |
| 969 | + session.skip("Core deps from source tests are not yet supported") |
| 970 | + |
| 971 | + |
| 972 | +@nox.session(python=DEFAULT_PYTHON_VERSION) |
| 973 | +def prerelease_deps(session): |
| 974 | + """Run all tests with prerelease versions of dependencies installed. |
| 975 | + """ |
| 976 | + # TODO(https://github.com/googleapis/google-cloud-python/issues/16014): |
| 977 | + # Add prerelease deps tests |
| 978 | + session.skip("prerelease deps tests are not yet supported") |
0 commit comments