Type annotation pitfall
Peter Saalbrink
petersaalbrink at gmail.com
Fri Sep 24 07:28:29 EDT 2021
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 at 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
>
More information about the Python-list
mailing list