I want to be able to call a function and have the caller be aware that the type of parameter has been checked. My type checker is Pyright through the Pylance extension in vscode with "basic"
level of type checking enabled.
@dataclass()
class Personnel:
person: Person
employee: Optional[Employee]
@dataclass()
class Employee:
department: str
jobs: list[Job]
The current pattern I'm using to get all of the jobs for every employee looks like this:
all_jobs = [
job
for personnel in all_personnel_list if personnel.employee is not None
job for job in personnel.employee.jobs
]
My type checker doesn't complain about accessing personnel.employee.jobs
even though personnel.employee
is an Optional
because the type is checked in the if
statement.
What I would like to be able to do is something like this:
def is_employee(x: Personnel):
return x.employee is not None
all_jobs = [
job
for personnel in all_personnel_list if is_employee(personnel)
job for job in personnel.employee.jobs
]
The problem I'm facing is that my type checker, is giving me an error when I try this because it sees personnel.employee.jobs
as still being Optional
and warning me that I'm not handling the case where personnel.employee
is None
. I realize that having this helper method for such a simple example seems a little silly, but my actual use case would be using more complex helper methods and I'd like them to have descriptive names instead of being a chain of and
statements.
I'm also not exactly sure of how to formally describe this problem, so I apologize if this is a duplicate.
Use typing.TypeIs
for this:
from typing import TypeIs
def is_employee(x: object) -> TypeIs[Employee]:
return isinstance(x, Employee)
For your use-case typing.TypeGuard
should also work:
from typing import TypeGuard
def is_employee(x: object) -> TypeGuard[Employee]:
return isinstance(x, Employee)
You can read the difference between the two in PEP 742