Update hatch use to "hatch check", and ruff to >= 0.16.0
Marco Ricci

Marco Ricci commited on 2026-08-29 18:35:09
Zeige 1 geänderte Dateien mit 57 Einfügungen und 25 Löschungen.


As part of the ruff upgrade, the hatch configuration uses rule names now
instead of rule codes.  The code still uses the rule codes, because
these are currently the only non-tool-specific notation available.
... ...
@@ -57,7 +57,7 @@ dev = [
57 57
     # available in the main virtual environment as well, so that your
58 58
     # editor/IDE setup can access them as well.
59 59
     "mypy >= 1.0",
60
-    "ruff >= 0.9.0",
60
+    "ruff >= 0.16.0",
61 61
     # Test dependencies should be installed as well, to have static
62 62
     # analysis in the test suite working too.
63 63
     #
... ...
@@ -370,7 +370,7 @@ extra-dependencies = [
370 370
 ]
371 371
 detached = false
372 372
 
373
-[tool.hatch.envs.hatch-static-analysis]
373
+[tool.hatch.envs.hatch-check-code]
374 374
 config-path = "/dev/null"
375 375
 dependencies = [
376 376
     # Override the default dependencies, lest the ruff requirements
... ...
@@ -379,6 +379,25 @@ dependencies = [
379 379
 features = [
380 380
     "dev",
381 381
 ]
382
+[tool.hatch.envs.hatch-check-fmt]
383
+config-path = "/dev/null"
384
+dependencies = [
385
+    # Override the default dependencies, lest the ruff requirements
386
+    # conflict.
387
+]
388
+features = [
389
+    "dev",
390
+]
391
+[tool.hatch.envs.hatch-check-types]
392
+config-path = "/dev/null"
393
+dependencies = [
394
+    # Override the default dependencies, lest the ruff requirements
395
+    # conflict.
396
+    "pyrefly >= 1.0.0",
397
+]
398
+features = [
399
+    "dev",
400
+]
382 401
 
383 402
 [tool.hatch.envs.hatch-test]
384 403
 default-args = ['src', 'tests']
... ...
@@ -487,36 +506,47 @@ ignore = [
487 506
     # that the linting and formatting can proceed, and then *afterwards*
488 507
     # the files are re-linted.  We hope that any *true* E501 errors left
489 508
     # over from this *are* text strings that should be manually broken.
490
-    'W191', 'E111', 'E114', 'E117', 'D206', 'D300', 'Q000', 'Q001',
491
-    'Q002', 'Q003', 'COM812', 'COM819', 'ISC001', 'ISC002',
509
+    'tab-indentation', 'indentation-with-invalid-multiple',
510
+    'indentation-with-invalid-multiple-comment', 'over-indented',
511
+    'docstring-tab-indentation', 'triple-single-quotes',
512
+    'bad-quotes-inline-string', 'bad-quotes-multiline-string',
513
+    'bad-quotes-docstring', 'avoidable-escaped-quote',
514
+    'missing-trailing-comma', 'prohibited-trailing-comma',
515
+    'single-line-implicit-string-concatenation',
516
+    'multi-line-implicit-string-concatenation',
492 517
     # We use `assert` regularly to appease the type checker, and because
493 518
     # it is the right language tool for this job.
494
-    'S101',
519
+    'assert',
495 520
     # The formatter takes care of trailing commas and docstring code
496 521
     # automatically.
497
-    'COM812', 'W505',
522
+    'missing-trailing-comma', 'doc-line-too-long',
498 523
     # We document transitive exceptions as well (if we feel they would
499 524
     # be surprising to the user otherwise).
500
-    'DOC502',
525
+    'docstring-extraneous-exception',
501 526
     # We currently don't have issues for every TODO.  Forcing an issue
502 527
     # also goes against the philosophy of TODOs as low-overhead markers
503 528
     # for future work; see
504 529
     # https://gist.github.com/dmnd/ed5d8ef8de2e4cfea174bd5dafcda382 .
505
-    'TD003',
530
+    'missing-todo-link',
506 531
     # We somewhat regularly use loops where each iteration needs
507 532
     # a separate try-except block.
508
-    'PERF203',
533
+    'try-except-in-loop',
509 534
     # We do not currently use pathlib.  The PTH rules are unselected,
510 535
     # but FURB includes several pathlib-related rules.
511
-    'FURB101', 'FURB103',
536
+    'read-whole-file', 'write-whole-file',
512 537
     # We catch type-ignore comments without specific code via the mypy
513 538
     # configuration, not via ruff.
514
-    'PGH003',
539
+    'blanket-type-ignore',
515 540
     # Provisionally ignore the `__init__.py` rule, until we can adapt our
516 541
     # codebase.
517
-    'RUF067',
542
+    'non-empty-init-module',
543
+    # We prefer noqa comments over ruff-specific ignores, for tool
544
+    # compatibility reasons, even if the comments themselves become harder
545
+    # to read. Using them in the ruff config section is fine thought,
546
+    # because that *is* ruff-specific.
547
+    'noqa-comments',
518 548
     # Still undecided about this one.
519
-    'PLW0717',
549
+    'too-many-statements-in-try-clause',
520 550
 ]
521 551
 preview = true
522 552
 # We select here in the order of presentation on the ruff documentation
... ...
@@ -550,25 +580,25 @@ select = [
550 580
     # Suggested by hatch, assumingly because it may be important to
551 581
     # verify that the value is exactly the empty string, and not just
552 582
     # any falsy value.
553
-    'PLC1901',
583
+    'compare-to-empty-string',
554 584
     # Suggested by hatch, assumingly because tests may use "magic
555 585
     # values".
556
-    'PLR2004',
586
+    'magic-value-comparison',
557 587
     # Suggested by hatch, because tests are typically organized as
558 588
     # classes and instance methods but may not really be using the
559 589
     # `self` argument.
560
-    'PLR6301',
590
+    'no-self-use',
561 591
     # Suggested by hatch, because these warnings may be precisely what
562 592
     # the tests are supposed to test.
563 593
     'S',
564 594
     # Suggested by hatch, because pytest-style tests conventionally
565 595
     # import code from each other via relative imports.
566
-    'TID252',
596
+    'relative-imports',
567 597
     # Our tests regularly use arguments named `input` to store an input
568 598
     # (text-/byte-)string.
569
-    'A002',
599
+    'builtin-argument-shadowing',
570 600
     # We regularly annotate pytest fixtures like monkeypatch as `Any`.
571
-    'ANN401',
601
+    'any-type',
572 602
     # Our tests generally don't contain docstrings.
573 603
     'D', 'DOC',
574 604
     # Our tests are regularly parametrized with booleans, for benign
... ...
@@ -577,24 +607,26 @@ select = [
577 607
     # One of our standard modules is called `derivepassphrase._types`.
578 608
     # Importing this from the tests directory would then automatically
579 609
     # trigger `PLC2701`.
580
-    'PLC2701',
610
+    'import-private-name',
581 611
     # Too many public methods/arguments/returns/branches/locals doesn't
582 612
     # really apply here.
583
-    'PLR0904', 'PLR0911', 'PLR0912', 'PLR0913', 'PLR0914', 'PLR0915',
584
-    'PLR0916', 'PLR0917',
613
+    'too-many-public-methods', 'too-many-return-statements',
614
+    'too-many-branches', 'too-many-arguments', 'too-many-locals',
615
+    'too-many-statements', 'too-many-boolean-expressions',
616
+    'too-many-positional-arguments',
585 617
     # To fully test the `derivepassphrase.cli` module (and a couple
586 618
     # other things), we need to call and to mock several internal
587 619
     # functions, which would automatically trigger `SLF001`.
588
-    'SLF001',
620
+    'private-member-access',
589 621
     # pytest does not support sensible introspection of
590 622
     # `assert all(...)` expressions in tests the same way it supports
591 623
     # introspection in `asssert all([...])`.  So the extra list
592 624
     # comprehension actually improves debuggability in this case.
593
-    'C419',
625
+    'unnecessary-comprehension-in-call',
594 626
     # The tests sometimes include long strings (in non-Python formats)
595 627
     # that should be included verbatim, without artificial line
596 628
     # breaking, so they can be grepped for.
597
-    'E501',
629
+    'line-too-long',
598 630
 ]
599 631
 
600 632
 [tool.ruff.lint.flake8-copyright]
601 633