8000 Check expr that are implicitly true for lack dunder bool/len by ikonst · Pull Request #10666 · python/mypy · GitHub
[go: up one dir, main page]

Skip to content

Check expr that are implicitly true for lack dunder bool/len #10666

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

Merged
merged 33 commits into from
Sep 3, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
1bc2b9d
wip
ikonst May 29, 2021
b3b301f
fix fixtures and tests
ikonst Jun 18, 2021
76bd3e2
Undo unneeded test change
ikonst Jun 25, 2021
801f274
Let’s try to just warn in boolean context (no tests yet)
ikonst Jun 25, 2021
cbcd9d9
disable for non-strict optional + message
ikonst Jun 25, 2021
c58bb6a
futile attempt to improve _format_expr_name
ikonst Jun 25, 2021
6e497bb
kick CI
ikonst Jun 25, 2021
f0a5081
even more futile attempts on _format_expr_name
ikonst Jun 25, 2021
12278df
add error code
ikonst Jun 25, 2021
bcf8706
docs
ikonst Jun 25, 2021
050bd67
fix type_guard support
ikonst Jun 25, 2021
d2851a3
fix _format_expr_name sig
ikonst Jun 25, 2021
6f0951d
revert change to testConditionalBoolLiteralUnionNarrowing
ikonst Jun 25, 2021
dc70b7c
handle FunctionLikes + re-add test
ikonst Jun 25, 2021
c68df2f
fix list fixture
ikonst Jun 25, 2021
f346448
fix typing
ikonst Jun 26, 2021
903d72b
Merge remote-tracking branch 'origin/master' into check-always-true
ikonst Jun 30, 2021
d36a54c
fix type errors
ikonst Jun 30, 2021
b9dd548
fix TypeFixture
ikonst Jun 30, 2021
212af09
fix sphinx syntax
ikonst Jun 30, 2021
246d065
restructure _check_for_truthy_type
ikonst Jun 30, 2021
9e19e85
Rewrite implicit_bool short description
ikonst Jun 30, 2021
1753f2c
Remove unused _is_truthy_instance
ikonst Jul 1, 2021
e60082d
why did I ever change this code?
ikonst Jul 1, 2021
250c19b
testImplicitBool: clean up newlines
ikonst Aug 5, 2021
7166b54
Revert most of the changes to test fixtures
ikonst Aug 5, 2021
9349eef
Merge remote-tracking branch 'origin/master' into check-always-true
ikonst Aug 5, 2021
d432220
confused but removing timedelta.__bool__
ikonst Aug 5, 2021
6267456
Apply suggestions from code review
hauntsaninja Aug 5, 2021
31977ab
Update test-data/unit/check-errorcodes.test
hauntsaninja Aug 5, 2021
5c6d763
more copy changes
Aug 8, 2021
13af1eb
add a test
Aug 8, 2021
338e35b
Try to provide more color in the docs
ikonst Sep 3, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
handle FunctionLikes + re-add test
  • Loading branch information
ikonst committed Jun 25, 2021
commit dc70b7cac6385ccf210fd2518bf5c868569e3578
11 changes: 8 additions & 3 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -3998,13 +3998,18 @@ def _check_for_truthy_type(self, t: Type, expr: Expression) -> None:
if not state.strict_optional:
return # if everything can be None, all bets are off
if self._is_truthy_instance(t):
self.msg.note(
self.msg.fail(
'{} which does not implement __bool__ or __len__ '
'so it will always be true in boolean context'.format(self._format_expr_name(expr, t)), expr,
code=codes.IMPLICIT_BOOL,
)
elif isinstance(t, UnionType) and all(self._is_truthy_instance(t) for t in t.items):
self.msg.note(
elif isinstance(t, FunctionLike):
self.msg.fail(
f'function "{t}" will always be true in boolean context', expr,
code=codes.IMPLICIT_BOOL,
)
elif isinstance(t, UnionType) and all(self._is_truthy_instance(t) or isinstance(t, FunctionLike) for t in t.items):
self.msg.fail(
"{} none of which implement __bool__ or __len__ "
"so it will always be true in boolean context".format(self._format_expr_name(expr, t)), expr,
code=codes.IMPLICIT_BOOL,
Expand Down
58 changes: 58 additions & 0 deletions test-data/unit/check-errorcodes.test
Original file line number Diff line number Diff line change
Expand Up @@ -807,3 +807,61 @@ from typing_extensions import TypedDict

Foo = TypedDict("Bar", {}) # E: First argument "Bar" to TypedDict() does not match variable name "Foo" [name-match]
[builtins fixtures/dict.pyi]
[case testImplicitBool]
# flags: --enable-error-code implicit-bool
from typing import List, Union
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could be good to reduce the whitespace in this test


class Foo:
pass


foo = Foo()
if foo: # E: "__main__.foo" has type "__main__.Foo" which does not implement __bool__ or __len__ so it will always be true in boolean context [implicit-bool]
pass

zero = 0
if zero:
pass


false = False
if false:
pass


null = None
if null:
pass


s = ''
if s:
pass


good_union: Union[str, int] = 5
if good_union:
pass


bad_union: Union[Foo, object] = Foo()
if bad_union: # E: "__main__.bad_union" has type "Union[__main__.Foo, builtins.object]" none of which implement __bool__ or __len__ so it will always be true in boolean context [implicit-bool]
pass


def f():
pass


if f: # E: function "def () -> Any" will always be true in boolean context [implicit-bool]
pass


lst: List[int] = []
if lst:
pass


conditional_result = 'foo' if f else 'bar' # E: function "def () -> Any" will always be true in boolean context [implicit-bool]

[builtins fixtures/list.pyi]
2 changes: 1 addition & 1 deletion test-data/unit/fixtures/list.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class function: pass
class int:
def __bool__(self) -> bool: pass
class float: pass
class str: pass
class str(Sequence[str]): pass
class bool(int): pass

property = object() # Dummy definition.
0