Comments (7)
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.
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 TypeGuard
s 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.
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.
Would this work for your case?
from typing.
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.
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 excludingNone
is usually sufficient and will give you the result you want in most cases.Of course you could write a couple of simple
TypeGuard
s to convert any value intoTruthy
/Falsy
, but that wouldn't be particularly ergonomic to use and doesn't help with the given example (but it may help with theand
/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.
It may be helpful to note that object.__bool__()
does not exist, which makes the link between if
/bool()
and __bool__()
tenuous. (It might simplify the world if object.__bool__()
was defined, and bool(x)
was equivalent to x.__bool__()
, subject to type checks.)
from typing.
Related Issues (20)
- Proposal: Add coerced type narrowing similar to 'cast' HOT 1
- Idenity Type HOT 2
- [spec] clarify assert_type behavior as asserting type equivalence
- [spec] better clarify the difference between a runtime type object and a static type HOT 1
- [spec] a protocol type should be assignable to object? HOT 1
- [spec] define or replace the term "concrete type" HOT 1
- [spec] conceptual foundation and glossary entries for variance
- [spec] Overload processing order HOT 2
- Clarify signification of `Annotation` HOT 2
- A generic 'frame' type
- Enable Projects? HOT 5
- (🎁) `get_type_hints` should add the class to the locals HOT 4
- Conformance tests: PEP 702 HOT 1
- [spec] Clarification: Are symbols not listed in `__all__` ever considered public? HOT 1
- [spec] Formalize excluded Protocol members HOT 2
- Introduce an Unknown type HOT 3
- [@overload]: What is the effect of the *implementation* type-signature? HOT 3
- [spec] Can staticmethod calls infer type parameters for the containing class? HOT 1
- `Counter.__init__` can't be typed safely HOT 4
- Web gt
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from typing.