From 8e01ad930015889ea8be1f26556fcc4e4d918e82 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Mon, 11 Oct 2021 23:55:47 +0300 Subject: [PATCH] `None.__bool__` returns `Literal[False]` (#11290) Closes #11287 --- mypy/checkmember.py | 7 ++++--- test-data/unit/check-basic.test | 11 ++++++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/mypy/checkmember.py b/mypy/checkmember.py index 4fc96de039b0..3579fda2e7f4 100644 --- a/mypy/checkmember.py +++ b/mypy/checkmember.py @@ -317,17 +317,18 @@ def analyze_union_member_access(name: str, typ: UnionType, mx: MemberContext) -> def analyze_none_member_access(name: str, typ: NoneType, mx: MemberContext) -> Type: - if mx.chk.should_suppress_optional_error([typ]): - return AnyType(TypeOfAny.from_error) is_python_3 = mx.chk.options.python_version[0] >= 3 # In Python 2 "None" has exactly the same attributes as "object". Python 3 adds a single # extra attribute, "__bool__". if is_python_3 and name == '__bool__': + literal_false = LiteralType(False, fallback=mx.named_type('builtins.bool')) return CallableType(arg_types=[], arg_kinds=[], arg_names=[], - ret_type=mx.named_type('builtins.bool'), + ret_type=literal_false, fallback=mx.named_type('builtins.function')) + elif mx.chk.should_suppress_optional_error([typ]): + return AnyType(TypeOfAny.from_error) else: return _analyze_member_access(name, mx.named_type('builtins.object'), mx) diff --git a/test-data/unit/check-basic.test b/test-data/unit/check-basic.test index 184c9e58ca58..03dee485c848 100644 --- a/test-data/unit/check-basic.test +++ b/test-data/unit/check-basic.test @@ -401,9 +401,18 @@ def foo( [case testNoneHasBool] none = None b = none.__bool__() -reveal_type(b) # N: Revealed type is "builtins.bool" +reveal_type(b) # N: Revealed type is "Literal[False]" [builtins fixtures/bool.pyi] +[case testNoneHasBoolShowNoneErrorsFalse] +none = None +b = none.__bool__() +reveal_type(b) # N: Revealed type is "Literal[False]" +[builtins fixtures/bool.pyi] +[file mypy.ini] +\[mypy] +show_none_errors = False + [case testAssignmentInvariantNoteForList] from typing import List x: List[int]