File tree Expand file tree Collapse file tree 5 files changed +74
-0
lines changed Expand file tree Collapse file tree 5 files changed +74
-0
lines changed Original file line number Diff line number Diff line change @@ -642,6 +642,26 @@ of the above sections.
642
642
643
643
assert text is not None # OK, check against None is allowed as a special case.
644
644
645
+ .. option :: --strict-bool
646
+
647
+ By default ``bool `` values are treated as subtypes of ``int ``,
648
+ just like in runtime:
649
+
650
+ .. code-block :: python
651
+
652
+ >> > bool .__mro__
653
+ (< class ' bool' > , < class ' int' > , < class ' object' > )
654
+
655
+ While it will work in runtime,
656
+ some cases might require a little bit more strictness.
657
+ With this flag enabled, you will get the following error:
658
+
659
+ .. code-block :: python
660
+
661
+ def requires_int (arg : int ) -> None : ...
662
+
663
+ requires_int(5 > 0 ) # Error: Argument 1 has incompatible type "bool"; expected "int"
664
+
645
665
.. option :: --extra-checks
646
666
647
667
This flag enables additional checks that are technically correct but may be
Original file line number Diff line number Diff line change @@ -843,6 +843,14 @@ def add_invertible_flag(
843
843
group = strictness_group ,
844
844
)
845
845
846
+ add_invertible_flag (
847
+ "--strict-bool" ,
848
+ default = False ,
849
+ strict_flag = True ,
850
+ help = "Prohib to treat bool as int" ,
851
+ group = strictness_group ,
852
+ )
853
+
846
854
add_invertible_flag (
847
855
"--extra-checks" ,
848
856
default = False ,
Original file line number Diff line number Diff line change @@ -50,6 +50,7 @@ class BuildType:
50
50
"mypyc" ,
51
51
"strict_concatenate" ,
52
52
"strict_equality" ,
53
+ "strict_bool" ,
53
54
"strict_optional" ,
54
55
"warn_no_return" ,
55
56
"warn_return_any" ,
@@ -208,6 +209,10 @@ def __init__(self) -> None:
208
209
# This makes 1 == '1', 1 in ['1'], and 1 is '1' errors.
209
210
self .strict_equality = False
210
211
212
+ # Prohibit to treat `bool` as `int` in subtyping contexts.
213
+ # This makes `1 + True` an error.
214
+ self .strict_bool = False
215
+
211
216
# Deprecated, use extra_checks instead.
212
217
self .strict_concatenate = False
213
218
Original file line number Diff line number Diff line change @@ -512,6 +512,13 @@ def visit_instance(self, left: Instance) -> bool:
512
512
if left .type .alt_promote and left .type .alt_promote .type is right .type :
513
513
return True
514
514
rname = right .type .fullname
515
+ if (
516
+ self .options
517
+ and self .options .strict_bool
518
+ and left .type .fullname == "builtins.bool"
519
+ and rname == "builtins.int"
520
+ ):
521
+ return False
515
522
# Always try a nominal check if possible,
516
523
# there might be errors that a user wants to silence *once*.
517
524
# NamedTuples are a special case, because `NamedTuple` is not listed
Original file line number Diff line number Diff line change @@ -2284,3 +2284,37 @@ class C(Generic[T]): ...
2284
2284
2285
2285
A = Union[C, List] # OK
2286
2286
[builtins fixtures/list.pyi]
2287
+
2288
+ [case testStrictBool]
2289
+ # flags: --strict-bool --show-error-codes
2290
+ from typing import List, Union
2291
+
2292
+ def a(x: int): ...
2293
+ a(True) # E: Argument 1 to "a" has incompatible type "bool"; expected "int" [arg-type]
2294
+ a(False) # E: Argument 1 to "a" has incompatible type "bool"; expected "int" [arg-type]
2295
+
2296
+ bl: bool
2297
+ a(bl) # E: Argument 1 to "a" has incompatible type "bool"; expected "int" [arg-type]
2298
+
2299
+ def b() -> int:
2300
+ return bl # E: Incompatible return value type (got "bool", expected "int") [return-value]
2301
+
2302
+ c: List[int] = [
2303
+ True, # E: List item 0 has incompatible type "bool"; expected "int" [list-item]
2304
+ False, # E: List item 1 has incompatible type "bool"; expected "int" [list-item]
2305
+ bl, # E: List item 2 has incompatible type "bool"; expected "int" [list-item]
2306
+ ]
2307
+
2308
+ # OK:
2309
+ def d(x: Union[int, bool], y: bool): ...
2310
+ d(1, True)
2311
+ d(True, False)
2312
+ d(bl, bl)
2313
+ [builtins fixtures/list.pyi]
2314
+
2315
+ [case testStrictBoolWithStrictFlag]
2316
+ # flags: --strict
2317
+
2318
+ def a(x: int) -> None: ...
2319
+ b: bool
2320
+ a(b) # E: Argument 1 to "a" has incompatible type "bool"; expected "int"
You can’t perform that action at this time.
0 commit comments