Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dealing with lack of non-null assertion operator in Python

I would like to allow Mypy' strict_optional flag. However, consider this:

emails = [get_user(uuid).email for uuid in user_uuids]

where get_user could return None in theory, but in this use case, I know it can't (and am fine with getting an exception if it did). This would have to become:

emails = []
for uuid in user_uuids:
    user = get_user(uuid)
    assert user is not None
    emails.append(user.email)

In TypeScript, there's a non-null assertion operator which would allows you to just add a ! (as in getUser(uuid)!.email).

Is there any better or more elegant way to handle this problem?

like image 295
Garrett Avatar asked Dec 30 '25 23:12

Garrett


1 Answers

I found two ways that I think get close to a non-null assertion operator and therefore cast type Optional[User] to User:

1) Use typing.cast

from typing import cast

emails = [cast(User, get_user(uuid)).email for uuid in user_uuids]

2) Imitate non-null assertion with function

For Python 3.12+:

def not_none[T](obj: T | None) -> T:
    assert obj is not None
    return obj

emails = [not_none(get_user(uuid)).email for uuid in user_uuids]

or older Python versions:

from typing import Optional, TypeVar

T = TypeVar('T')

def not_none(obj: Optional[T]) -> T:
    assert obj is not None
    return obj

emails = [not_none(get_user(uuid)).email for uuid in user_uuids]
like image 58
Garrett Avatar answered Jan 02 '26 12:01

Garrett



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!