Repository navigation
12 new checks (CH089-CH100), bringing the total to 100.
Same discipline as every prior batch: each check verified empirically before implementation, corpus-scanned against ~30 real open-source frameworks, and narrowed against real false positives rather than shipped on first pass.
CH091 (hash-eq-field-mismatch) was the deepest precision chase this project has done — seven distinct, legitimate ways for __hash__ and __eq__ to reference "the same field" without looking alike syntactically (a method call or @property standing in for a field, multi-field equality via a tuple or a wrapping call instead of named pairs, blanket equality via __dict__ or dataclasses.fields() reflection, and a property wrapping a differently-named private attribute). One genuine bug survived all seven rounds: semantic-kernel's ChatHistorySummarizationReducer hashes two fields its __eq__ never compares.
CH096 (post-init-on-non-dataclass) went from 615 false positives to 1 after finding the same "something else calls __post_init__" convention independently reinvented twice (vllm's own @config decorator, transformers' PreTrainedConfig.__init__ hook).
New checks also catch:
str/bytesmixed in the same.join()__exit__unconditionally suppressing every exceptionPath.write_text()/write_bytes()given the wrong typeasyncio.to_thread()given an async function (never runs its body)- The same keyword passed both directly and via
**-dict-unpack - A lambda target on a spawn/forkserver multiprocessing context
raise NotImplementedinstead ofNotImplementedError- Two
__slots__-declaring bases colliding str.maketrans()with mismatched-length arguments__iter__returningselfwith no__next__
Zero runtime dependencies, verified via a fresh pip install into a clean venv.