Repository navigation
Enable ruff's correctness, complexity and performance rules - #81
Merged
Merged
Conversation
Output of `ruff check --fix` followed by `ruff format`, unedited, for the rules the next commits enable: W605 (invalid escape sequence), PLR1730 (if-stmt-min-max), FURB122 (for-loop-writes) and FURB105 (print-empty-string). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DfsDLLUtil.dfsGetItemValueType ignores the native return code, so an invalid item pointer yields value type 0 instead of an error. Fails until the next commit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every other DfsDLLUtil wrapper passes the native return code to DfsDLL.CheckReturnCode; dfsGetItemValueType stored it in an unused variable (ruff F841), so a failed read returned value type 0 silently. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ReadingDfs2File and ReadingDfsuFile read header values into variables they never used (ruff F841), with the expected value only in a comment. Assert those values so the example tests check them, and drop the unused timeSpan and ok results in the dfsu examples. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ruff F841 leftovers: static items DfsuBuilder creates for their side effect, the result of eumSetupLoadLinux, a calendar flag DfsShowInfo never reads, and files the builder tests fetch only to trigger GetFile. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Output of `ruff check --fix --unsafe-fixes` for TRY201 (verbose-raise),
C408 (unnecessary dict() call) and the one SIM102 (collapsible-if) ruff
could rewrite, plus its F841 fix for the exception names a bare `raise` no
longer needs. Each was read: `raise` re-raises the same exception and
traceback as `raise e`, `{}` equals `dict()`, and the merged condition in
MapProjection.__del__ short-circuits the same way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SIM102 (collapsible-if), by hand where ruff offers no fix: each `if A:` holding only `if B:` becomes `if A and B:`. In ReadDfs0DataDouble the equidistant time and calendar branches did the same thing, so they become one condition. Evaluation order is unchanged, so __FpDynamicIncrement still runs on every write. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PLR0133 (comparison-of-constant): `assert "message" == ""` was a C#-style Assert.Fail; self.fail says so and keeps the message. SIM117: one `with` for the subtest and the expected error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Select every rule ruff 0.16.10 marks stable and tags correctness, complexity or performance in its rule metadata (`ruff rule --all --output-format json`, field "category"). F, UP, B and E9 already carried theirs; the other 165 are listed by code, grouped by linter, because ruff has no category selector. F841 leaves the ignore list now that the earlier commits removed every unused variable. TID255 is preview in 0.16.10, so it waits for a ruff bump. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
FAST001 (FastAPI) and PD012 (pandas-vet) can never fire here, as nothing imports either library. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # CHANGELOG.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs: no issue; requested directly.
What and why
Ruff tags every rule with a category. This PR selects every stable rule in the correctness, complexity and performance categories and fixes all 56 hits they found on master; none are left as ignores. Ruff has no category selector, so
pyproject.tomllists the 163 codes thatF,UP,BandE9did not already select, grouped by linter. Rules for frameworks mikecore does not use are left out:FAST001(FastAPI) andPD012(pandas-vet) found nothing and never could, since nothing imports either library.F841(unused variable) is a correctness rule, so it comes off the ignore list.The two autofix commits are exact ruff output: rerunning ruff on each parent commit rebuilds them byte for byte (see "Verify it yourself"). Only the other commits need reading.
DfsDLLUtil.dfsGetItemValueTypestored the native return code in an unused variable (F841), so a failed read returnedDataValueType.Instantaneoussilently. Every otherDfsDLLUtilcall checks it withDfsDLL.CheckReturnCode; this one now does too.Commits
Hand-written commits are bold.
996deb2Apply ruff's safe autofixes:ruff check --fix+ruff formatoutput for W605, PLR1730, FURB122, FURB105. No need to read it; it reproduces exactly.f9e877bTest that reading an item's value type reports a DFS error. Fails on its own.475c620Check the return code when reading an item's value type. The bug fix, two lines.b687464Assert the values the reading examples only read.ReadingDfs2File/ReadingDfsuFileread header values and gave the expected value only in a comment. They now assert it, which makes the example tests check something.b7b8de4Remove unused variables. The remaining F841 hits, removed with the call kept wherever it has a side effect.79a4b46Apply ruff's unsafe autofixes:ruff check --fix --unsafe-fixesoutput for TRY201, C408, one SIM102, and the F841 that the bareraisecreates. It reproduces exactly; each fix was also read.684bd2fCollapse nested ifs that ruff could not rewrite. SIM102, 9 sites. Look at the merged equidistant branches inReadDfs0DataDouble.c0a899dFail tests with self.fail and combine nested with statements. PLR0133, SIM117.5581cb5Note the item value type fix in the changelog.594dc32Enable ruff's correctness, complexity and performance rules. The config. It comes last, so lint passes on every commit.3fd9940Leave out rules for frameworks mikecore does not use. DropsFAST001andPD012.Code Review Guide
Glossary
ruff rule --all --output-format json(correctness, suspicious, complexity, performance, pedantic, style, …). The ruff docs filter by it. Config can't select by it.--fix. Unsafe fixes need--unsafe-fixesbecause they may change behaviour in edge cases, so the one unsafe-fix commit was also read by hand.rok): the integer each native DFS function returns. Non-zero means an error, whichDfsDLL.CheckReturnCoderaises.Where the change sits
Opening any dfs file reads each item's value type through the changed helper, which now hands the return code to
CheckReturnCode. The lint changes touch no other call path.Conventions followed
DfsDLL.CheckReturnCodemikecore/DfsFile.py:2065-2072
mikecore/DfsFile.py:2116-2119
test_dfs_basic.pycall the DFS wrapper layer directlytests/test_dfs_basic.py:54-60
tests/test_dfs_basic.py:63-65
CHANGELOG.md:66-67
CHANGELOG.md:68-69
Deviations
dfsGetItemValueTypefail. A null pointer is the one input the real library rejects (it returns rc 1000, with no mocks). Alternative: leave the fix untested.tests/test_dfs_basic.py:16-19
tests/test_dfs_basic.py:63-65
selectlists rule codes instead of linter prefixes. Why: ruff can't select by category, and most linters only partly fall in these three (e.g. Pylint 43 of 95 rules). Alternative: select whole linters, which brings in pedantic and style rules nobody asked for.pyproject.toml (master):72
pyproject.toml:72-134
tests/examples_dfs2.py (master):17-18
tests/examples_dfs2.py:17-19
Evidence
Before (master with this PR's
pyproject.toml, ruff 0.16.10):After (this branch):
Autofix commits are pure ruff output. Rerunning ruff on each commit's parent and diffing the trees (
diff -r) gives no differences: exit 0 for996deb2and exit 0 for79a4b46.The side bug. At
f9e877b(test only):At
475c620it passes, and the rest oftest_dfs_basic.pypasses too (12 passed, 1 xfailed).The merged
ReadDfs0DataDoublebranch keeps its output. First three times read from each temporal-axis test file, identical before and after684bd2f:Verify it yourself
Review
MapProjection.__del__assigns_mzMapProjPointer = ctypes.c_void_p()to a local, notself. F841 skips it because the name starts with_. Declined: it was already there, runs only in the finaliser, and no user can observe it, so no public-API test could show it failing. Recorded under "Not in this PR".preview = true, which also changes how stable rules behave across the whole config. The 21 preview rules in these categories (excluding Airflow's) are listed under "Not in this PR". Only TID255 becomes stable in ruff 0.17, so the config comment names it alone.One round; verdict CLEAN, no must-fix findings.
Risk
dfsGetItemValueType, which now raises where it used to return value type 0. This is safe because every item read from a valid file returns rc 0 there; the full suite opens dfs0/1/2/3/dfsu files and passes (171 passed).__FpDynamicIncrement()still runs first on every write, becauseandevaluates its left side first. The mergedReadDfs0DataDoublebranch gives identical output on all four temporal-axis types (Evidence).Reading*example is called only with the file its comments describe (tests/test_dfs2.py:21,tests/test_dfsu2D.py:18).Not in this PR
preview = truefor the whole config, which is a separate decision. TID255 also needs CI's ruff bumped to 0.17, which is a workflow change.MapProjection.__del__local assignment (mikecore/Projections.py:1141): dead but harmless. A fix can't be shown failing by any test a user would see (see Review).🤖 Generated with Claude Code