We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Interfaces with Protocols and ABCs step 18 of 26
Validate Records with TypeIs Instead of cast
The type hints track showed how TypeIs narrows a value in both branches of
an if. It also showed why the check must return True for every value of
its type. Here you use it to check data that comes from outside your
program, such as decoded JSON, instead of casting it.
The starter reads each record like this:
payload = cast(UserRecord, record)
typing.cast(T, value) tells mypy to treat the value as T. It checks
nothing and does nothing at runtime. So mypy accepts the starter, and the
starter crashes on the first record that has no roles key.
What to write
Keep the UserRecord TypedDict as it is, with name: str and
roles: list[str]. Add this function:
def is_user_record(value: object) -> TypeIs[UserRecord]: ...
It returns True when all of these hold, and False otherwise:
- The value is a
dict. - Every key is a string, including any extra keys.
nameis present and is astr.rolesis present and is alistwhose items are all strings. A tuple does not count.
Extra keys are fine, whatever their values. An empty name, an empty roles
list and repeated roles are all valid. A False result from a TypeIs
check tells mypy the value is not a UserRecord, so rejecting any of these
would make mypy wrong about the value in the else branch. Leave the input unchanged, and do not convert
numbers to strings or fill in missing keys.
Then change solve(records) to return one string per record, in order:
- For a valid record, its name in uppercase, a colon, and the number of roles.
- For anything else,
"invalid".
Use if is_user_record(record):, so mypy narrows record to UserRecord
inside the if, and remove every cast.
Example
solve([{"name": "ada", "roles": ["dev", "dev"]}, None])
# ["ADA:2", "invalid"]
Repeated roles count separately. An empty list of records gives an empty list.
The typing documentation's
type narrowing guide
compares TypeIs with TypeGuard.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
Python reference solution
Sign in to track your attempts toward unlocking the reference solution.