From 3e90887a3632585b048f607668e20927321a39a0 Mon Sep 17 00:00:00 2001 From: Katie Byers Date: Fri, 3 May 2024 15:44:27 -0700 Subject: [PATCH] feat(types): Add `NonNone` non-null assertion operator stand-in (#70236) This introduces a `NonNone` type utility meant to mimic the non-null assertion operator (`!`) in TypeScript. For example, given a function with the signature `make_stuff() -> Stuff | None`, used in a place where you know it's going to return a `Stuff` instance, you can change your call from `stuff = make_stuff()` to `stuff = NonNone(make_stuff())`, and mypy will stop complaining that `stuff` might be `None`. I know you can do this with `cast`, but this seemed more expressive and like it would add a little less( or possibly a lot less) clutter to the code. (Consider a value typed as `dict[str, tuple[list[Stuff]]] | None`. Would you rather `cast(dict[str, tuple[list[Stuff]]], stuff)` or `NonNone(stuff)`?) Disclaimer: This may or may not be the most elegant way to do this, and I'm very open to suggestions for future improvements (or for a different approach entirely), but for now this clears a blocker (and was the best option with which fairly extensive googling provided me), so I went with it. --- src/sentry/utils/types.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sentry/utils/types.py b/src/sentry/utils/types.py index 20eb1220d3236f..987d4003bd1968 100644 --- a/src/sentry/utils/types.py +++ b/src/sentry/utils/types.py @@ -221,3 +221,9 @@ def type_from_value(value): AnyCallable = typing.Callable[..., AnyType] + + +def NonNone(value: T | None) -> T: + """A hacked version of TS's non-null assertion operator""" + assert value is not None + return value