Never use mutable values in Python class default values

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.