I have a method which works like this, with it normally being used to return a Path
.
from typing import Literal, Union
from pathlib import Path
def get_filename(return_type: Literal["Path", "str"]) -> Union[Path, str]:
filename = "./foo/bar.csv"
if return_type == "str":
return filename
elif return_type == "Path":
return Path(filename)
else:
raise ValueError(
f'Return type must be either "Path" or "str", not {return_type}'
)
file = get_filename(return_type="Path")
print(file.is_file())
On the final line I get the following message from Pylance:
(method) is_file: () -> bool | Unknown Whether this path is a regular file (also True for symlinks pointing to regular files).
Cannot access member "is_file" for type "str" Member "is_file" is unknownPylancereportGeneralTypeIssues
Is there a way to correctly type hint this situation so that Pylance knows file
is a Path
? Or should I just make it always return Path and have another method which calls get_filename
converts the output to string and then return that?
Thanks
Edit 1
I have just realised another, more common scenario:
import pandas as pd
# returns dataframe
df = pd.read_csv(file)
# returns a series, Pylance doesn't know this
series = pd.read_csv(file, squeeze=True)
Here in pandas an input argument can change the output type and Pylance can also not deal with this. For Pylance to know series
is a pd.Series
you must do:
# return series which pylance is happy with
df = pd.read_csv(file)
series = df.squeeze()
I think you can do this using typing.overload
:
from typing import Literal, overload
from pathlib import Path
@overload
def get_filename(return_type: Literal["Path"]) -> Path:...
@overload
def get_filename(return_type: Literal["str"]) -> str:...
def get_filename(return_type):
# your code goes here