Skip to content

B004 false positives for invalid or obfuscated hasattr and getattr calls #20440

@dscorbett

Description

@dscorbett

Summary

unreliable-callable-check (B004) doesn’t validate the arguments of hasattr or getattr.

It should be suppressed when hasattr is called with anything another than two positional non-starred arguments, lest it suppress or introduce an exception. Example:

$ cat >b004.py <<'# EOF'
try: print(hasattr(0, "__call__", 0, x=0))
except TypeError as e: print(e)

try: print(hasattr(*(), "__call__", "split"))
except TypeError as e: print(e)
# EOF

$ python b004.py
hasattr() takes no keyword arguments
True

$ ruff --isolated check b004.py --select B004 --fix
Found 2 errors (2 fixed, 0 remaining).

$ cat b004.py
try: print(callable(0))
except TypeError as e: print(e)

try: print(callable(*()))
except TypeError as e: print(e)

$ python b004.py
False
callable() takes exactly one argument (0 given)

Similarly, B004 should only apply when getattr is called with two or three positional non-starred arguments.

Version

ruff 0.13.0 (a1fdd66 2025-09-10)

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingfixesRelated to suggested fixes for violations

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions