Avoid Calling Magic Methods
ID |
python.avoid_calling_magic_methods |
Severity |
low |
Remediation Complexity |
medium |
Remediation Risk |
low |
Remediation Effort |
medium |
Resource |
Code Smell |
Language |
Python |
Tags |
best-practice, code-style |
Description
Reports direct calls to dunder methods (obj.str(), obj.len(), obj.add(other), …). Dunder methods are the protocol the interpreter dispatches to; user code should call the corresponding builtin or operator (str(obj), len(obj), obj + other). Calling the dunder directly bypasses the resolution rules (descriptor protocol, fallbacks, type coercion) and produces subtle wrong-behaviour bugs.
obj.__str__() # FLAW — use str(obj)
obj.__len__() # FLAW — use len(obj)
obj.__eq__(other) # FLAW — use obj == other
super().__init__() # OK
str(obj) # OK
len(obj) # OK
Rationale
The classic case is obj.eq(other) returning NotImplemented (Python’s protocol for "I don’t know how to compare these — defer to the right operand"). The == operator handles NotImplemented correctly; calling eq directly does not, so the result is NotImplemented instead of True/False. The same shape applies to every comparison and arithmetic dunder.
Calls to super().init(…) are exempt — that is the canonical way to invoke the parent constructor.
Remediation
Use the public Python equivalent:
| Dunder | Use instead |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
the operator ( |
|
the comparison operator ( |