Reputation: 12334
I have the following code:
def extract_table_date(bucket_path: str) -> str:
event_date = re.search(r"date=([^/]+)", bucket_path)
return event_date.group(1)[0:10].replace("-", "")
mypy throws error on the last line:
Item "None" of "Optional[Match[str]]" has no attribute "group"
I think I can solve that by assigning a type to event_date
, and I can:
from typing import Match
def extract_table_date(bucket_path: str) -> str:
event_date: Match = re.search(r"date=([^/]+)", bucket_path)
return event_date.group(1)[0:10].replace("-", "")
but mypy now throws another error on the first line of the function:
Incompatible types in assignment (expression has type "Optional[Match[Any]]", variable has type "Match[Any]")
I don't really know how to inform mypy that the result won't be optional but nonetheless I followed the advice at Optional types and the None type by adding an assert:
from typing import Match
def extract_table_date(bucket_path: str) -> str:
assert bucket_path is not None
event_date: Match = re.search(r"date=([^/]+)", bucket_path)
return event_date.group(1)[0:10].replace("-", "")
but mypy still raises the same error.
I try to fix by changing the type defined for event_date
:
from typing import Match, optional, Any
def extract_table_date(bucket_path: str) -> str:
assert bucket_path is not None
event_date: Optional[Match[Any]] = re.search(r"date=([^/]+)", bucket_path)
return event_date.group(1)[0:10].replace("-", "")
but (as expected) I'm now back to almost the same original error:
Item "None" of "Optional[Match[Any]]" has no attribute "group"
Any advice on how to fix this?
Upvotes: 12
Views: 10937
Reputation: 2179
Another possibility would be to use isinstance
.
def extract_table_date(bucket_path: str) -> str:
event_date = re.search(r"date=([^/]+)", bucket_path)
if isinstance(event_date, str):
return event_date.group(1)[0:10].replace("-", "")
return ""
Here you would return "" instead of None.
Upvotes: -2
Reputation: 71512
The thing that's Optional
is event_date
, because re.search
is not guaranteed to return a match. mypy is warning you that this will raise an AttributeError
if that's the case. You can tell it "no, I'm very confident that will not be the case" by doing an assert
to that effect:
def extract_table_date(bucket_path: str) -> str:
event_date = re.search(r"date=([^/]+)", bucket_path)
assert event_date is not None
return event_date.group(1)[0:10].replace("-", "")
If you're wrong, this code will still raise an exception (AssertionError
, because your assert
will fail), but mypy will no longer error because there is now no way for event_date
to be None
when you access its group
attribute.
Note that there is no need to assert on bucket_path
because it's already explicitly typed as str
.
Upvotes: 20