Skip to content

Commit 0f47810

Browse files
committed
red_knot_python_semantic: improve diagnostics for unsupported boolean conversions
This mostly only improves things for incorrect arguments and for an incorrect return type. It doesn't do much to improve the case where `__bool__` isn't callable and leaves the union/other cases untouched completely. I picked this one because, at first glance, this _looked_ like a lower hanging fruit. The conceptual improvement here is pretty straight-forward: add annotations for relevant data. But it took me a bit to figure out how to connect all of the pieces.
1 parent eb1d251 commit 0f47810

19 files changed

+107
-35
lines changed

crates/red_knot_python_semantic/resources/mdtest/conditional/if_expression.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,6 @@ def _(flag: bool):
4242
class NotBoolable:
4343
__bool__: int = 3
4444

45-
# error: [unsupported-bool-conversion] "Boolean conversion is unsupported for type `NotBoolable`; its `__bool__` method isn't callable"
45+
# error: [unsupported-bool-conversion] "Boolean conversion is unsupported for type `NotBoolable`"
4646
3 if NotBoolable() else 4
4747
```

crates/red_knot_python_semantic/resources/mdtest/conditional/if_statement.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,10 @@ def _(flag: bool):
154154
class NotBoolable:
155155
__bool__: int = 3
156156

157-
# error: [unsupported-bool-conversion] "Boolean conversion is unsupported for type `NotBoolable`; its `__bool__` method isn't callable"
157+
# error: [unsupported-bool-conversion] "Boolean conversion is unsupported for type `NotBoolable`"
158158
if NotBoolable():
159159
...
160-
# error: [unsupported-bool-conversion] "Boolean conversion is unsupported for type `NotBoolable`; its `__bool__` method isn't callable"
160+
# error: [unsupported-bool-conversion] "Boolean conversion is unsupported for type `NotBoolable`"
161161
elif NotBoolable():
162162
...
163163
```

crates/red_knot_python_semantic/resources/mdtest/conditional/match.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ class NotBoolable:
292292
def _(target: int, flag: NotBoolable):
293293
y = 1
294294
match target:
295-
# error: [unsupported-bool-conversion] "Boolean conversion is unsupported for type `NotBoolable`; its `__bool__` method isn't callable"
295+
# error: [unsupported-bool-conversion] "Boolean conversion is unsupported for type `NotBoolable`"
296296
case 1 if flag:
297297
y = 2
298298
case 2:

crates/red_knot_python_semantic/resources/mdtest/expression/assert.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
class NotBoolable:
55
__bool__: int = 3
66

7-
# error: [unsupported-bool-conversion] "Boolean conversion is unsupported for type `NotBoolable`; its `__bool__` method isn't callable"
7+
# error: [unsupported-bool-conversion] "Boolean conversion is unsupported for type `NotBoolable`"
88
assert NotBoolable()
99
```

crates/red_knot_python_semantic/resources/mdtest/expression/boolean.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ if NotBoolable():
123123
class NotBoolable:
124124
__bool__: None = None
125125

126-
# error: [unsupported-bool-conversion] "Boolean conversion is unsupported for type `NotBoolable`; its `__bool__` method isn't callable"
126+
# error: [unsupported-bool-conversion] "Boolean conversion is unsupported for type `NotBoolable`"
127127
if NotBoolable():
128128
...
129129
```
@@ -135,7 +135,7 @@ def test(cond: bool):
135135
class NotBoolable:
136136
__bool__: int | None = None if cond else 3
137137

138-
# error: [unsupported-bool-conversion] "Boolean conversion is unsupported for type `NotBoolable`; its `__bool__` method isn't callable"
138+
# error: [unsupported-bool-conversion] "Boolean conversion is unsupported for type `NotBoolable`"
139139
if NotBoolable():
140140
...
141141
```
@@ -149,7 +149,7 @@ def test(cond: bool):
149149

150150
a = 10 if cond else NotBoolable()
151151

152-
# error: [unsupported-bool-conversion] "Boolean conversion is unsupported for type `Literal[10] | NotBoolable`; its `__bool__` method isn't callable"
152+
# error: [unsupported-bool-conversion] "Boolean conversion is unsupported for type `Literal[10] | NotBoolable`"
153153
if a:
154154
...
155155
```

crates/red_knot_python_semantic/resources/mdtest/loops/while_loop.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ def _(flag: bool, flag2: bool):
123123
class NotBoolable:
124124
__bool__: int = 3
125125

126-
# error: [unsupported-bool-conversion] "Boolean conversion is unsupported for type `NotBoolable`; its `__bool__` method isn't callable"
126+
# error: [unsupported-bool-conversion] "Boolean conversion is unsupported for type `NotBoolable`"
127127
while NotBoolable():
128128
...
129129
```

crates/red_knot_python_semantic/resources/mdtest/narrow/truthiness.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ def _(
270270
if af:
271271
reveal_type(af) # revealed: type[AmbiguousClass] & ~AlwaysFalsy
272272

273-
# error: [unsupported-bool-conversion] "Boolean conversion is unsupported for type `MetaDeferred`; the return type of its bool method (`MetaAmbiguous`) isn't assignable to `bool"
273+
# error: [unsupported-bool-conversion] "Boolean conversion is unsupported for type `MetaDeferred`"
274274
if d:
275275
# TODO: Should be `Unknown`
276276
reveal_type(d) # revealed: type[DeferredClass] & ~AlwaysFalsy

crates/red_knot_python_semantic/resources/mdtest/snapshots/instances.md_-_Binary_operations_on_instances_-_Operations_involving_types_with_invalid_`__bool__`_methods.snap

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,13 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/binary/instances.m
2424
# Diagnostics
2525

2626
```
27-
error: lint:unsupported-bool-conversion: Boolean conversion is unsupported for type `NotBoolable`; its `__bool__` method isn't callable
27+
error: lint:unsupported-bool-conversion: Boolean conversion is unsupported for type `NotBoolable`
2828
--> /src/mdtest_snippet.py:7:8
2929
|
3030
6 | # error: [unsupported-bool-conversion]
3131
7 | 10 and a and True
3232
| ^
3333
|
34+
info: `__bool__` on `NotBoolable` must be callable
3435
3536
```

crates/red_knot_python_semantic/resources/mdtest/snapshots/membership_test.md_-_Comparison___Membership_Test_-_Return_type_that_doesn't_implement_`__bool__`_correctly.snap

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/comparison/instanc
2828
# Diagnostics
2929

3030
```
31-
error: lint:unsupported-bool-conversion: Boolean conversion is unsupported for type `NotBoolable`; its `__bool__` method isn't callable
31+
error: lint:unsupported-bool-conversion: Boolean conversion is unsupported for type `NotBoolable`
3232
--> /src/mdtest_snippet.py:9:1
3333
|
3434
8 | # error: [unsupported-bool-conversion]
@@ -37,17 +37,19 @@ error: lint:unsupported-bool-conversion: Boolean conversion is unsupported for t
3737
10 | # error: [unsupported-bool-conversion]
3838
11 | 10 not in WithContains()
3939
|
40+
info: `__bool__` on `NotBoolable` must be callable
4041

4142
```
4243

4344
```
44-
error: lint:unsupported-bool-conversion: Boolean conversion is unsupported for type `NotBoolable`; its `__bool__` method isn't callable
45+
error: lint:unsupported-bool-conversion: Boolean conversion is unsupported for type `NotBoolable`
4546
--> /src/mdtest_snippet.py:11:1
4647
|
4748
9 | 10 in WithContains()
4849
10 | # error: [unsupported-bool-conversion]
4950
11 | 10 not in WithContains()
5051
| ^^^^^^^^^^^^^^^^^^^^^^^^
5152
|
53+
info: `__bool__` on `NotBoolable` must be callable
5254

5355
```

crates/red_knot_python_semantic/resources/mdtest/snapshots/not.md_-_Unary_not_-_Object_that_implements_`__bool__`_incorrectly.snap

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@ mdtest path: crates/red_knot_python_semantic/resources/mdtest/unary/not.md
2222
# Diagnostics
2323

2424
```
25-
error: lint:unsupported-bool-conversion: Boolean conversion is unsupported for type `NotBoolable`; its `__bool__` method isn't callable
25+
error: lint:unsupported-bool-conversion: Boolean conversion is unsupported for type `NotBoolable`
2626
--> /src/mdtest_snippet.py:5:1
2727
|
2828
4 | # error: [unsupported-bool-conversion]
2929
5 | not NotBoolable()
3030
| ^^^^^^^^^^^^^^^^^
3131
|
32+
info: `__bool__` on `NotBoolable` must be callable
3233
3334
```

0 commit comments

Comments
 (0)