The Bug That Hid Behind Its Own Comment: Fixing Inconsistent Inference in astroid
This is a submission for DEV's Summer Bug Smash: Clear the Lineup powered by Sentry . Project Overview astroid is the static-analysis engine that powers pylint — one of the most widely used linters in the Python ecosystem. Instead of running your code, astroid builds a model of what your code would do (a process called "inference") so pylint can catch real bugs before you ever hit run. That means astroid's inference logic has to be extremely consistent: if it gets confused about what a piece of code returns, pylint either misses real bugs, or — as in this case — flags perfectly correct code as broken. Bug Fix or Performance Improvement I picked up astroid issue #3077 : identical typing.cast(T, self) expressions were being inferred differently depending only on how the surrounding call was written — even when the code was structurally symmetric. In a class like this: class Base : def __call__ ( self ) -> str : return cast ( str , self ) def run ( self ) -> str : return cast ( str , self ) class IrJoin : separator : Base def __call__ ( self , items ): sep : str = self . separator () # implicit __call__ sugar return sep . join ( items ) def run ( self , items ): sep : str = self . separator . run () # explicit method call return sep . join ( items ) Both self.separator() and self.separator.run() do the exact same thing at runtime — I verified this by actually running the file. But pylint only flagged one of them: $ python -m pylint t5.py t5.py:35:15: E1101: Instance of 'Base' has no 'join' member (no-member) The explicit .run() path got a false positive; the equivalent implicit __call__ path did not, even though sep is a plain str in both cases at runtime. Code PR: https://github.com/pylint-dev/astroid/pull/3242 My Improvements Ruling out the obvious suspect My first hypothesis was infer_typing_cast , the function that handles typing.cast() itself — it seemed like the natural place for a cast-related inconsistency to live. Tested in isolation, though, it behaves identi