-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
Hey guys, first of all thanks for this wonderful tool !
My report might not be considered a bug if you consider that PEP 724 isn't handled by mypy. If that's the case, let me know and I can open a new ticket dedicated to adding PEP 724. This being said, I assumed that PEP 724 was covered by mypy but it doesn't seem to be the case. Here is a dummy reproducer
from dataclasses import dataclass
from typing import TypeGuard, Union
@dataclass
class ThermalModel:
conductivity: float
@dataclass
class MechanicalModel:
stiffness: float
Model = Union[ThermalModel, MechanicalModel]
def is_valid_thermal_model(obj: Model) -> TypeGuard[ThermalModel]:
return hasattr(obj, "conductivity") and obj.conductivity >= 0
def run_simulation(model: Model):
if is_valid_thermal_model(model):
model.conductivity *= 2.0
else:
model.stiffness *= 1.1Since is_valid_thermal_model is False, I would expect the type to be narrowed to MechanicalModel when working in the else statement. However, I get the following error error: Item "ThermalModel" of "ThermalModel | MechanicalModel" has no attribute "stiffness" [union-attr]. My understanding here is that PEP 647 is covered but not PEP 724.
Note that if I apply another if statement with TypeGuard instead of the else statement, it works fine. Here would be the changes
def is_valid_mechanical_model(obj: Model) -> TypeGuard[MechanicalModel]:
return hasattr(obj, "stiffness") and obj.stiffness >= 0
def run_simulation(model: Model):
if is_valid_thermal_model(model):
model.conductivity *= 2.0
elif is_valid_mechanical_model(model):
model.stiffness *= 1.1Expected Behavior
I wouldn't expect any error with the previous snippet.
Actual Behavior
The error obtained is error: Item "ThermalModel" of "ThermalModel | MechanicalModel" has no attribute "stiffness" [union-attr].
Your Environment
- Mypy version used: mypy 1.18.2 (compiled: yes)
- Mypy command-line flags:
mypy myfile_.py - Mypy configuration options from
mypy.ini(and other config files): None - Python version used: 3.10
Note that the version used is the latest version available on PyPI.