Search code examples
pythonmypy

mypy - Item "None" of "Optional[CustomAttrsModel]" has no attribute "country"


When I run mypy checkings I am getting an error. I am no able to ignore it or turn it off the strict optional checking. It there a way to solve this.

Here is the line that is throwing the error:

 if tree.data.attributes.custom != JAPAN:

where attributes is declared as:

class TreeAttributesModel(BaseModel):
    id: Optional[TreeId]
    name: Optional[str] = None
    status: StatusEnum
    custom: Optional[CustomAttrsModel] = None

and CustomAttrsModel is declared as it follows:

class CustomAttrsModel(BaseModel):
    seller: Optional[str]
    buyed_at: Optional[datetime]
    country: Optional[Union[CountryEnum, str]]

Could you please help me with this?


Solution

  • I had to tweak your snippets a bit to get a MWE, but here we go:

    import enum
    import dataclasses
    
    from datetime import datetime
    from typing import Optional, Union
    
    
    class StatusEnum(enum.Enum):
        OK = enum.auto()
        NOK = enum.auto()
    
    class CountryEnum(enum.Enum):
        JAPAN = enum.auto()
        RAPTURE = enum.auto()
    
    @dataclasses.dataclass
    class TreeAttributesModel:
        id: Optional[str]
        name: Optional[str]  # = None had to remove default, attribs w/o default cannot follow attribs w/ one
        status: StatusEnum
        custom: Optional[CustomAttrsModel] = None
        
    @dataclasses.dataclass
    class CustomAttrsModel:
        seller: Optional[str]
        buyed_at: Optional[datetime]
        country: Optional[Union[CountryEnum, str]]
    
    custom = CustomAttrsModel(seller="test", buyed_at=None, country=CountryEnum.JAPAN)
    attribs = TreeAttributesModel(id="test", name="test", status=StatusEnum.OK, custom=custom)
    
    assert attribs.custom is not None  # this is typed as being optional, so make sure it isn't None
    assert attribs.custom.country is not None  # same as above
    result = attribs.custom.country != CountryEnum.JAPAN
    

    The message is: just use assert something is not None whenever something is Optional ;)