I don't think this has anything to do with typing or providing type hints. The type hint is the `: set` part, not the `= set()` part. You can declare the type without assigning to the variable. Indeed, as you already said, `x` is a class property here, and is shared amongst instances of the class. It might be a good idea to move the attribute assignment to the `__init__` method.
In the following way, you can safely provide the type hint: ```python class Foo: x: set def __init__(self, s): self.x = set() if s: self.x.add(s) ``` Or, even shorter: ```python class Foo: def __init__(self, s: str): self.x: set[str] = {s} if s else set() print(reveal_type(Foo.x)) # mypy only ``` On Fri, Sep 24, 2021 at 7:58 AM Robert Latest via Python-list < python-list@python.org> wrote: > Hi all, > > this just caused me several hours of my life until I could whittle it down > to > this minimal example. Simple question: Why is the x member of object "foo" > modified by initializing "bar"? > > Obviously, initializing foo with None doesn't set foo.x at all. So I guess > x > stays a class property, not an instance property. And instantiating bar > just > added an item to the class property but didn't instantiate a new set. So > basically, neither foo nor bar ever had their "own" x, right? > > Oooohh, dangerous! Never use mutable types in type hint, unless it's in > explicit dataclasses (which automatically add an appropriate __init__()?) > > Now I must fine-comb all my code for more of these. > > class Foo(): > x : set = set() > > def __init__(self, s): > if s: > self.x.add(s) > > foo = Foo(None) > print(foo.x) # prints 'set()' > bar = Foo('abc') > print(foo.x) # prints '{'abc'} > > -- > https://mail.python.org/mailman/listinfo/python-list > -- https://mail.python.org/mailman/listinfo/python-list