Code Monkey home page Code Monkey logo

Comments (6)

Feuermurmel avatar Feuermurmel commented on July 20, 2024 1

Would this work for your case?

I don't think addresses by use case. The type returned by run_until_truthy(foo) is still str | None, even though it will never return None: Playground

from typing.

Daverball avatar Daverball commented on July 20, 2024 1
from typing import Literal, Protocol

class Truthy(Protocol):
    def __bool__(self) -> Literal[True]: ...

class Falsy(Protocol):
    def __bool__(self) -> Literal[False]: ...

This doesn't really appear to work in pyright or mypy however, since None is special cased and doesn't actually follow the NoneType annotation for __bool__ on typeshed, for the others it doesn't work, since Literal[0, "", b"", False] aren't special cased to fulfil this Protocol.

But I would seriously question the value of making something like this work, since excluding a single literal from a type is usually not that helpful (Literal[True, False] are kind of the exception). I think excluding None is usually sufficient and will give you the result you want in most cases.

Of course you could write a couple of simple TypeGuards to convert any value into Truthy/Falsy, but that wouldn't be particularly ergonomic to use and doesn't help with the given example (but it may help with the and/or usecase)

from typing.

JelleZijlstra avatar JelleZijlstra commented on July 20, 2024

In typed code I would prefer checking explicitly for None instead of all falsy values:

def run_until_not_none[T](fn: Callable[[], T | None], num_tries: int = 5) -> T:
    for _ in range(num_tries):
        if (res := fn()) is not None:
            return res

    Exception('Giving up.')

This can already be typed and is less likely to lead to surprises.

from typing.

elenakrittik avatar elenakrittik commented on July 20, 2024

Would this work for your case?

from typing.

Feuermurmel avatar Feuermurmel commented on July 20, 2024

In typed code I would prefer checking explicitly for None instead of all falsy values:

def run_until_not_none[T](fn: Callable[[], T | None], num_tries: int = 5) -> T:
    for _ in range(num_tries):
        if (res := fn()) is not None:
            return res

    Exception('Giving up.')

This can already be typed and is less likely to lead to surprises.

If I wrote that part of the application now, I would definitely use this approach. But I have found existing usages that make use of the fact that the function will be re-run on return values [] and "".

Another case where these types could be useful is when typing functions that have behavior similar to the and and or operators: Playground

from typing.

Feuermurmel avatar Feuermurmel commented on July 20, 2024

But I would seriously question the value of making something like this work, since excluding a single literal from a type is usually not that helpful (Literal[True, False] are kind of the exception). I think excluding None is usually sufficient and will give you the result you want in most cases.

Of course you could write a couple of simple TypeGuards to convert any value into Truthy/Falsy, but that wouldn't be particularly ergonomic to use and doesn't help with the given example (but it may help with the and/or usecase)

My request stems purely from typing existing code. Partly, that code is a result of how Python employs the concept of truthy/falsy in boolean contexts. Because of typing ergonomics, I usually refrain from relying on that concept (e.g. bar if foo is None else None rather than foo or bar), but the language is still pushing me in the direction of using these concepts and I see a lot of code being written that relies on it and is hard to type.

from typing.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.