Skip to content

Commit 8f3fb7d

Browse files
committed
[ty] Add hint that PEP 604 union syntax is only available in 3.10+
1 parent b86960f commit 8f3fb7d

File tree

3 files changed

+69
-3
lines changed

3 files changed

+69
-3
lines changed

crates/ty_python_semantic/resources/mdtest/assignment/annotations.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,33 @@ def foo(v: str | int | None, w: str | str | None, x: str | str):
8888
reveal_type(x) # revealed: str
8989
```
9090

91+
## PEP-604 in non-type-expression context
92+
93+
### In Python 3.10 and later
94+
95+
```toml
96+
[environment]
97+
python-version = "3.10"
98+
```
99+
100+
```py
101+
IntOrStr = int | str
102+
```
103+
104+
### Earlier versions
105+
106+
<!-- snapshot-diagnostics -->
107+
108+
```toml
109+
[environment]
110+
python-version = "3.9"
111+
```
112+
113+
```py
114+
# error: [unsupported-operator]
115+
IntOrStr = int | str
116+
```
117+
91118
## Attribute expressions in type annotations are understood
92119

93120
```py
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
source: crates/ty_test/src/lib.rs
3+
expression: snapshot
4+
---
5+
---
6+
mdtest name: annotations.md - Assignment with annotations - PEP-604 in non-type-expression context - Earlier versions
7+
mdtest path: crates/ty_python_semantic/resources/mdtest/assignment/annotations.md
8+
---
9+
10+
# Python source files
11+
12+
## mdtest_snippet.py
13+
14+
```
15+
1 | # error: [unsupported-operator]
16+
2 | IntOrStr = int | str
17+
```
18+
19+
# Diagnostics
20+
21+
```
22+
error[unsupported-operator]: Operator `|` is unsupported between objects of type `<class 'int'>` and `<class 'str'>`
23+
--> src/mdtest_snippet.py:2:12
24+
|
25+
1 | # error: [unsupported-operator]
26+
2 | IntOrStr = int | str
27+
| ^^^^^^^^^
28+
|
29+
info: Note that `X | Y` PEP 604 union syntax is only available in Python 3.10 and later
30+
info: rule `unsupported-operator` is enabled by default
31+
32+
```

crates/ty_python_semantic/src/types/infer.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use ruff_db::diagnostic::{Annotation, DiagnosticId, Severity};
3838
use ruff_db::files::File;
3939
use ruff_db::parsed::parsed_module;
4040
use ruff_python_ast::visitor::{Visitor, walk_expr};
41-
use ruff_python_ast::{self as ast, AnyNodeRef, ExprContext};
41+
use ruff_python_ast::{self as ast, AnyNodeRef, ExprContext, PythonVersion};
4242
use ruff_text_size::{Ranged, TextRange};
4343
use rustc_hash::{FxHashMap, FxHashSet};
4444
use salsa;
@@ -94,7 +94,7 @@ use crate::types::{
9494
};
9595
use crate::unpack::{Unpack, UnpackPosition};
9696
use crate::util::subscript::{PyIndex, PySlice};
97-
use crate::{Db, FxOrderSet};
97+
use crate::{Db, FxOrderSet, Program};
9898

9999
use super::context::{InNoTypeCheck, InferContext};
100100
use super::diagnostic::{
@@ -5889,11 +5889,18 @@ impl<'db> TypeInferenceBuilder<'db> {
58895889
self.infer_binary_expression_type(binary.into(), false, left_ty, right_ty, *op)
58905890
.unwrap_or_else(|| {
58915891
if let Some(builder) = self.context.report_lint(&UNSUPPORTED_OPERATOR, binary) {
5892-
builder.into_diagnostic(format_args!(
5892+
let mut diag=builder.into_diagnostic(format_args!(
58935893
"Operator `{op}` is unsupported between objects of type `{}` and `{}`",
58945894
left_ty.display(self.db()),
58955895
right_ty.display(self.db())
58965896
));
5897+
5898+
if op == &ast::Operator::BitOr && left_ty.into_class_literal().is_some()
5899+
&& right_ty.into_class_literal().is_some() && Program::get(self.db()).python_version(self.db())
5900+
< PythonVersion::PY310
5901+
{
5902+
diag.info("Note that `X | Y` PEP 604 union syntax is only available in Python 3.10 and later");
5903+
}
58975904
}
58985905
Type::unknown()
58995906
})

0 commit comments

Comments
 (0)