-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
bool()
return type on with no arguments
#6069
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Sounds worth trying. |
Will create a PR soon 🙂 |
One problem I see: x = bool()
...
x = determine_truth() # error |
Yes, looks like this is the case. My main motivation was the fact that I saw this code today: if bool(): # it should have been `self.bool()` in my case
print('trying to do something, but it is unreachable') It was not even caught by But, here's the problem you've described: from typing import Literal
def lit() -> Literal[False]:
"""Imagine, that this is a new `bool.__new__` constructor."""
x = lit()
...
x = bool() # E: Incompatible types in assignment (expression has type "bool", variable has type "Literal[False]") |
I think it's fine to return We still can't make it so that
This isn't needed, because |
Actually, class defaultdict(Dict[_KT, _VT], Generic[_KT, _VT]):
...
@overload
def __init__(self, default_factory: Callable[[], _VT] | None) -> None: ...
... So if you pass in something that returns |
I fear that this change will have a lot of false positives. And types here would be inconsistent: # 1. will have `bool` type:
a = False
# 2. will have `Literal[False]` type:
a = bool() But, in runtime |
This might cause problems for the mypy test suite, because it frequently does Also, we shouldn't need the self type, since bool cannot be subclassed. |
The mypy test suite's behaviour should be largely determined by the type fixtures, so hopefully not too bad. In any case, if this is a change we want to make, we should make it. |
There are primitive types with the same logic: So, |
I had a moment to think about this problem. And it looks like we won't able to solve this without a slight modification to So, I propose to add "weak literal" types. What are they? How do we create "weak literal" types? It can be only be created when some def some() -> Literal[False]: ...
s = some() # Literal[False, weak=False]
s = True # error
class bool:
@overload
def __init__() -> Literal[False]: ...
@overload
def __init__(arg) -> 'bool': ... # `Literal[False]` has `bool` as a fallback type, so it is considered "weak"
b = bool() # Literal[False, weak=True]
b = True # ok
class other:
@overload
def __init__() -> Literal[False]: ...
@overload
def __init__(arg) -> str: ... # `Literal[False]` is not compatible with `str`, literal is strong
o = other() # Literal[False, weak=False]
o = True # error What do you think? |
I'm not aware of any use cases for non-weak literals, so I mostly see this as an annoying "feature" of mypy. |
Reading through this and searching around.. I wonder if this would be a mypy feature? Enum actually has it already: from enum import Enum
class MyBool(Enum):
TRUE = True
FALSE = False
reveal_type(MyBool.TRUE) # Revealed type is "Literal[test.MyBool.TRUE]?"
x = MyBool.TRUE
reveal_type(x) # Revealed type is "test.MyBool" Based on some searching I think this behavior is related to tracking So mypy would need to know that |
Right now
bool
has this__new__
signature:def __new__(cls: Type[_T], __o: object = ...) -> _T: ...
Should not it be:
?
Current source:
typeshed/stdlib/builtins.pyi
Line 676 in 2217ac8
What do you think?
The text was updated successfully, but these errors were encountered: