Skip to content

v1.14.0

Choose a tag to compare

@kratos0718 kratos0718 released this 20 Sep 10:02
· 22 commits to main since this release

What's new

10 new checks (CH061-CH070), bringing the total to 70:

  • CH061 regex-backspace-escape - a regex pattern with a literal backspace byte, almost always an un-raw \b
  • CH062 total-ordering-missing-eq - @functools.total_ordering missing the __eq__ it needs to derive correct comparisons
  • CH063 unbounded-cycle-consumption - itertools.cycle(...) piped into something that tries to consume it in full
  • CH064 asyncio-wait-bare-coroutine - a bare coroutine inside asyncio.wait([...]), a hard TypeError on Python 3.11+
  • CH065 dict-fromkeys-mutable-default - dict.fromkeys(keys, value) aliasing one value across every key
  • CH066 os-path-join-absolute-literal - os.path.join's absolute-literal reset (the os.path sibling of CH056's pathlib version)
  • CH067 namedtuple-mutable-default - a NamedTuple field with a mutable default, shared across instances unlike a pydantic field default
  • CH068 logging-extra-reserved-key - a logging extra={} key colliding with a LogRecord attribute
  • CH069 contextvar-mutable-default - a ContextVar mutated in place on .get() instead of copied-then-set
  • CH070 threading-local-mutable-class-attr - a threading.local subclass leaking a class-level mutable attribute across every thread

This batch's first corpus scan came back much cleaner than the last one - only 3 checks had any hits, and only CH069 needed real narrowing (all 7 first-pass hits turned out to already use the correct copy-then-set pattern, independently, in 4 unrelated projects). CH067 and CH068 each found one real, unfiled bug on the first pass with no narrowing needed - see docs/FINDINGS.md for the full story.

35 new tests (419 total), self-scan clean, fresh clean-venv wheel install verified.