Background
Today I want to share a tricky bug that might have slipped in to production for my python script. When I was writing test for one of the classes inside project, I found an interesting behavior. If I run the test independently, they all passes. But when I run all the test in all suites together, it keep failing.
Reason
The reason is that I set a
set()
as the default value for fields inside a class definition. (As shown in the code below.)And because it wasn’t instantiated inside the
__init__()
method, all the instances of this class shared the same set
object. This causes the bug.class BadClass: mutable_val: set = set() immutable_val: int = 1 def add_to_mutable(self, i): self.mutable_val.add(i) obj_1 = BadClass() obj_2 = BadClass() obj_1.add_to_mutable(1) obj_2.add_to_mutable(2) print(obj1.mutable_val) # This will give 1 and 2
Conclusion
As a result, we should never use mutable values as default for class parameters. And it’s always a good idea to initialize required values inside
__init__()
method.