question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

PEP647 typing.TypeGuard based is_ok() and is_err() helpers

See original GitHub issue

PEP 647 (https://www.python.org/dev/peps/pep-0647/) makes it possible to write custom type guard functions.

this makes it possible to write shorthand is_ok(...) and is_err(...) functions that effectively work as shorthands for the longer isinstance(..., ...) forms, resulting in denser and more readable code, while still keeping all the benefits of strict type checking:

def is_ok(result: Result[T, E]) -> TypeGuard[Ok[T]]:
    return isinstance(result, Ok)


def is_err(result: Result[T, E]) -> TypeGuard[Err[E]]:
    return isinstance(result, Err)

not all supported python versions support TypeGuard, but the widely used typing_extensions package (https://github.com/python/typing/blob/master/typing_extensions/README.rst) has a functional backport that works with (at least) mypy. i personally do not see a problem adding a dependency on typing_extensions, since it’s maintained ‘upstream’, close to python itself, and it will already be pulled in by many other libraries in many real-world applications.

thoughts? opinions? (cc @francium @dbrgn)

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:4
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
jack-michaudcommented, Jun 10, 2022

It seems like mypy generic typeguards are fixed, but there’s still no negation.

from result import Ok, Result
from typing import TypeVar
from typing_extensions import TypeGuard


E = TypeVar("E")
T = TypeVar("T")


def is_ok(result: Result[T, E]) -> TypeGuard[Ok[T]]:
    return isinstance(result, Ok)

def main(result: Result[str, int]):
    if is_ok(result):
        reveal_type(result)
    else:
        reveal_type(result)
test.py:20: note: Revealed type is "result.result.Ok[builtins.str]"
test.py:22: note: Revealed type is "Union[result.result.Ok[builtins.str], result.result.Err[builtins.int]]"

Doing something like this would work:

def main(result: Result[str, int]):
    if is_ok(result):
        reveal_type(result)
    elif is_err(result):
        reveal_type(result)
test.py:20: note: Revealed type is "result.result.Ok[builtins.str]"
test.py:22: note: Revealed type is "result.result.Err[builtins.int]"

…but ideally we wouldn’t need to do this.

Related discussion for typeguard negations: https://github.com/python/typing/discussions/1013

1reaction
dbrgncommented, Nov 1, 2021

If only older Python versions need it, I don’t think adding a dependency is a problem. By upgrading your Python, you can get rid of the dependency.

We did the same thing with typing when we still supported Python versions that didn’t have this built-in yet.

From my experience with TS, type guards are pretty nice to have.

Read more comments on GitHub >

github_iconTop Results From Across the Web

PEP 647 – User-Defined Type Guards
Python type checkers typically support various forms of type guards expressions. def func(val: Optional[str]): # "is None" type guard if val ...
Read more >
TypeGuard functions not properly recognizing generic types
The is_left() and is_right() helpers use typing.TypeGuard , but Mypy does not recognize the types like it did with the isinstance() check.
Read more >
python TypeGuard (PEP 647) (intermediate) anthony explains ...
today we go over narrowings and ` TypeGuard ` -- which enables you to write your own user-defined narrowings!playlist: ...
Read more >
Type narrowing - mypy 0.991 documentation
Mypy supports User-Defined Type Guards (PEP 647). A type guard is a way for programs to influence conditional type narrowing employed by a...
Read more >
Python Type Hints - How to Narrow Types with TypeGuard
I previously covered type narrowing using isinstance() , assert , and ... TypeGuard was defined in PEP 647, and is available on Python...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found