Skip to content

Instantly share code, notes, and snippets.

@DamianZaremba
Last active April 28, 2022 16:34
Show Gist options
  • Save DamianZaremba/ffb0c0cd11586c896a673059ec670dfa to your computer and use it in GitHub Desktop.
Save DamianZaremba/ffb0c0cd11586c896a673059ec670dfa to your computer and use it in GitHub Desktop.
mypy scoping issue?
import dataclasses
from typing import List, Union
@dataclasses.dataclass()
class RecordType1:
pass
@dataclasses.dataclass()
class RecordType2:
pass
def decode(records: List[Union[RecordType1, RecordType2]], x: int) -> None:
if x == 1:
record = RecordType1()
if record:
records.append(record)
elif x == 2:
record = RecordType2()
if record:
records.append(record)
def main() -> None:
records: List[Union[RecordType1, RecordType2]] = []
for x in {1, 2, 3}:
decode(records, x)
print(records)
if __name__ == '__main__':
main()
'''
$ mypy --strict test.py
test.py:21: error: Incompatible types in assignment (expression has type "RecordType2", variable has type "RecordType1")
Found 1 error in 1 file (checked 1 source file)
'''
import dataclasses
from typing import List, Union
@dataclasses.dataclass()
class RecordType1:
pass
@dataclasses.dataclass()
class RecordType2:
pass
def decode(records: List[Union[RecordType1, RecordType2]], x: int) -> None:
if x == 1:
if record := RecordType1():
records.append(record)
elif x == 2:
if record := RecordType2():
records.append(record)
def main() -> None:
records: List[Union[RecordType1, RecordType2]] = []
for x in {1, 2, 3}:
decode(records, x)
print(records)
if __name__ == '__main__':
main()
'''
test2.py:20: error: Incompatible types in assignment (expression has type "RecordType2", variable has type "RecordType1")
Found 1 error in 1 file (checked 1 source file)
'''
import dataclasses
from typing import List, Union
@dataclasses.dataclass()
class RecordType1:
pass
@dataclasses.dataclass()
class RecordType2:
pass
def decode(records: List[Union[RecordType1, RecordType2]], x: int) -> None:
if x == 1:
if record := RecordType1():
records.append(record)
if x == 2:
if record := RecordType2():
records.append(record)
def main() -> None:
records: List[Union[RecordType1, RecordType2]] = []
for x in {1, 2, 3}:
decode(records, x)
print(records)
if __name__ == '__main__':
main()
'''
test3.py:21: error: Incompatible types in assignment (expression has type "RecordType2", variable has type "RecordType1")
Found 1 error in 1 file (checked 1 source file)
'''
import dataclasses
from typing import List, Union
@dataclasses.dataclass()
class RecordType1:
pass
@dataclasses.dataclass()
class RecordType2:
pass
def decode(records: List[Union[RecordType1, RecordType2]], x: int) -> None:
if x == 1:
if record := RecordType1():
records.append(record)
return None
if x == 2:
if record := RecordType2():
records.append(record)
return None
def main() -> None:
records: List[Union[RecordType1, RecordType2]] = []
for x in {1, 2, 3}:
decode(records, x)
print(records)
if __name__ == '__main__':
main()
'''
test4.py:22: error: Incompatible types in assignment (expression has type "RecordType2", variable has type "RecordType1")
Found 1 error in 1 file (checked 1 source file)
'''
import dataclasses
from typing import List, Union
from typing_extensions import reveal_type
@dataclasses.dataclass()
class RecordType1:
pass
@dataclasses.dataclass()
class RecordType2:
pass
def decode(records: List[Union[RecordType1, RecordType2]], x: int) -> None:
if x == 1:
record = RecordType1()
if record:
records.append(record)
elif x == 2:
reveal_type(record)
record = RecordType2()
if record:
records.append(record)
def main() -> None:
records: List[Union[RecordType1, RecordType2]] = []
for x in {1, 2, 3}:
decode(records, x)
print(records)
if __name__ == '__main__':
main()
'''
$ python test5.py
Traceback (most recent call last):
File "/divesoft-parser/test5.py", line 37, in <module>
main()
File "/divesoft-parser/test5.py", line 32, in main
decode(records, x)
File "/divesoft-parser/test5.py", line 23, in decode
reveal_type(record)
UnboundLocalError: local variable 'record' referenced before assignment
$ mypy --strict test5.py
test5.py:23: note: Revealed type is "test.RecordType1"
test5.py:24: error: Incompatible types in assignment (expression has type "RecordType2", variable has type "RecordType1")
Found 1 error in 1 file (checked 1 source file)
'''
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment