PY-48011 Pattern Matching: Type inference

Merge-request: IJ-MR-154823
Merged-by: Aleksandr Govenko <aleksandr.govenko@jetbrains.com>

GitOrigin-RevId: 42cb07bee63f34127c85574fc9c09e6043bc7591
This commit is contained in:
Aleksandr.Govenko
2025-03-07 22:56:00 +00:00
committed by intellij-monorepo-bot
parent 6860d4accc
commit 0073c7a8bb
51 changed files with 1301 additions and 377 deletions

View File

@@ -1,16 +1,18 @@
0(1) element: null
1(2) element: PyWhileStatement
2(3,4) READ ACCESS: x
3(13) element: null. Condition: x:false
3(15) element: null. Condition: x:false
4(5) element: null. Condition: x:true
5(6) element: PyStatementList
6(7) element: PyMatchStatement
7(8) READ ACCESS: x
8(9,11) refutable pattern: 42
8(9,12) refutable pattern: 42
9(10) matched pattern: 42
10(13) element: PyBreakStatement
11(12) element: PyExpressionStatement
12(1) READ ACCESS: y
10(11) ASSERTTYPE ACCESS: x
11(15) element: PyBreakStatement
12(13) ASSERTTYPE ACCESS: x
13(14) element: PyExpressionStatement
14(15) READ ACCESS: z
15() element: null
14(1) READ ACCESS: y
15(16) element: PyExpressionStatement
16(17) READ ACCESS: z
17() element: null

View File

@@ -1,16 +1,18 @@
0(1) element: null
1(2) element: PyWhileStatement
2(3,4) READ ACCESS: x
3(13) element: null. Condition: x:false
3(15) element: null. Condition: x:false
4(5) element: null. Condition: x:true
5(6) element: PyStatementList
6(7) element: PyMatchStatement
7(8) READ ACCESS: x
8(9,11) refutable pattern: 42
8(9,12) refutable pattern: 42
9(10) matched pattern: 42
10(1) element: PyContinueStatement
11(12) element: PyExpressionStatement
12(1) READ ACCESS: y
10(11) ASSERTTYPE ACCESS: x
11(1) element: PyContinueStatement
12(13) ASSERTTYPE ACCESS: x
13(14) element: PyExpressionStatement
14(15) READ ACCESS: z
15() element: null
14(1) READ ACCESS: y
15(16) element: PyExpressionStatement
16(17) READ ACCESS: z
17() element: null

View File

@@ -2,9 +2,11 @@
1(2) WRITE ACCESS: x
2(3) element: PyMatchStatement
3(4) READ ACCESS: x
4(5,7) refutable pattern: 42
4(5,8) refutable pattern: 42
5(6) matched pattern: 42
6(9) element: PyReturnStatement
7(8) element: PyExpressionStatement
8(9) READ ACCESS: y
9() element: null
6(7) ASSERTTYPE ACCESS: x
7(11) element: PyReturnStatement
8(9) ASSERTTYPE ACCESS: x
9(10) element: PyExpressionStatement
10(11) READ ACCESS: y
11() element: null

View File

@@ -1,19 +1,18 @@
0(1) element: null
1(2) element: PyMatchStatement
2(3,16) refutable pattern: [42] | foo.bar as x
3(4,16) refutable pattern: [42] | foo.bar
2(3) element: PyAsPattern
3(4) refutable pattern: [42] | foo.bar
4(5,8) refutable pattern: [42]
5(6,8) refutable pattern: 42
6(7) matched pattern: 42
7(12) matched pattern: [42]
8(9,16) refutable pattern: foo.bar
9(10) READ ACCESS: foo
7(11) matched pattern: [42]
8(9) refutable pattern: foo.bar
9(10,15) READ ACCESS: foo
10(11) matched pattern: foo.bar
11(12) matched pattern: [42] | foo.bar
12(13) WRITE ACCESS: x
13(14) matched pattern: [42] | foo.bar as x
14(15) element: PyExpressionStatement
15(16) READ ACCESS: y
16(17) element: PyExpressionStatement
17(18) READ ACCESS: z
18() element: null
13(14) element: PyExpressionStatement
14(15) READ ACCESS: y
15(16) element: PyExpressionStatement
16(17) READ ACCESS: z
17() element: null

View File

@@ -1,12 +1,12 @@
0(1) element: null
1(2) element: PyMatchStatement
2(3,14) refutable pattern: Class(1, attr=foo.bar)
3(4) READ ACCESS: Class
2(3) refutable pattern: Class(1, attr=foo.bar)
3(4,14) READ ACCESS: Class
4(5,14) refutable pattern: 1
5(6) matched pattern: 1
6(7,14) refutable pattern: attr=foo.bar
7(8,14) refutable pattern: foo.bar
8(9) READ ACCESS: foo
7(8) refutable pattern: foo.bar
8(9,14) READ ACCESS: foo
9(10) matched pattern: foo.bar
10(11) matched pattern: attr=foo.bar
11(12) matched pattern: Class(1, attr=foo.bar)

View File

@@ -3,14 +3,13 @@
2(3) WRITE ACCESS: x
3(4) element: PyBinaryExpression
4(5,6) READ ACCESS: x
5(10) element: null. Condition: x > 0:false
5(12) element: null. Condition: x > 0:false
6(7) element: null. Condition: x > 0:true
7(8,9) READ ACCESS: x
8(10) element: null. Condition: x < 10:false
8(12) element: null. Condition: x < 10:false
9(10) element: null. Condition: x < 10:true
10(11) element: PyStatementList. Condition: x > 0 and x < 10:true
11(12) element: PyExpressionStatement
12(13) READ ACCESS: y
13(14) element: PyExpressionStatement
14(15) READ ACCESS: z
15() element: null
10(11) element: PyExpressionStatement
11(12) READ ACCESS: y
12(13) element: PyExpressionStatement
13(14) READ ACCESS: z
14() element: null

View File

@@ -3,18 +3,17 @@
2(3) WRITE ACCESS: x
3(4) element: PyBinaryExpression
4(5,6) READ ACCESS: x
5(14) element: null. Condition: x % 4 == 0:false
5(16) element: null. Condition: x % 4 == 0:false
6(7) element: null. Condition: x % 4 == 0:true
7(8) element: PyBinaryExpression
8(9,10) READ ACCESS: x
9(11) element: null. Condition: x % 400 == 0:false
10(14) element: null. Condition: x % 400 == 0:true
11(12,13) READ ACCESS: x
12(14) element: null. Condition: x % 100 != 0:false
12(16) element: null. Condition: x % 100 != 0:false
13(14) element: null. Condition: x % 100 != 0:true
14(15) element: PyStatementList. Condition: x % 4 == 0 and (x % 400 == 0 or x % 100 != 0):true
15(16) element: PyExpressionStatement
16(17) READ ACCESS: y
17(18) element: PyExpressionStatement
18(19) READ ACCESS: z
19() element: null
14(15) element: PyExpressionStatement
15(16) READ ACCESS: y
16(17) element: PyExpressionStatement
17(18) READ ACCESS: z
18() element: null

View File

@@ -6,11 +6,10 @@
5(7) element: null. Condition: x > 0:false
6(10) element: null. Condition: x > 0:true
7(8,9) READ ACCESS: x
8(10) element: null. Condition: x < 0:false
8(12) element: null. Condition: x < 0:false
9(10) element: null. Condition: x < 0:true
10(11) element: PyStatementList. Condition: x > 0 or x < 0:true
11(12) element: PyExpressionStatement
12(13) READ ACCESS: y
13(14) element: PyExpressionStatement
14(15) READ ACCESS: z
15() element: null
10(11) element: PyExpressionStatement
11(12) READ ACCESS: y
12(13) element: PyExpressionStatement
13(14) READ ACCESS: z
14() element: null

View File

@@ -1,6 +1,6 @@
0(1) element: null
1(2) element: PyMatchStatement
2(3,18) refutable pattern: [x1, x2, x3]
2(3,19) refutable pattern: [x1, x2, x3]
3(4) WRITE ACCESS: x1
4(5) WRITE ACCESS: x2
5(6) WRITE ACCESS: x3
@@ -8,14 +8,15 @@
7(8) element: PyBinaryExpression
8(9,10) READ ACCESS: x1
9(11) element: null. Condition: x1:false
10(14) element: null. Condition: x1:true
11(12,13) READ ACCESS: x2
12(14) element: null. Condition: x2:false
13(14) element: null. Condition: x2:true
14(15,18) READ ACCESS: x3
15(16) element: PyStatementList. Condition: (x1 or x2) > x3:true
16(17) element: PyExpressionStatement
17(18) READ ACCESS: y
18(19) element: PyExpressionStatement
19(20) READ ACCESS: z
20() element: null
10(17) element: null. Condition: x1:true
11(12,13,14) READ ACCESS: x2
12(19) element: null. Condition: x2:false
13(17) element: null. Condition: x2:true
14(15,16) READ ACCESS: x3
15(19) element: null. Condition: (x1 or x2) > x3:false
16(17) element: null. Condition: (x1 or x2) > x3:true
17(18) element: PyExpressionStatement
18(19) READ ACCESS: y
19(20) element: PyExpressionStatement
20(21) READ ACCESS: z
21() element: null

View File

@@ -1,11 +1,13 @@
0(1) element: null
1(2) element: PyMatchStatement
2(6) WRITE ACCESS: x
3(4,8) refutable pattern: [x]
4(5) WRITE ACCESS: x
5(6) matched pattern: [x]
6(7) element: PyExpressionStatement
7(8) READ ACCESS: y
2(3) refutable pattern: x | [x]
3(7) WRITE ACCESS: x
4(5,10) refutable pattern: [x]
5(6) WRITE ACCESS: x
6(7) matched pattern: [x]
7(8) matched pattern: x | [x]
8(9) element: PyExpressionStatement
9(10) READ ACCESS: z
10() element: null
9(10) READ ACCESS: y
10(11) element: PyExpressionStatement
11(12) READ ACCESS: z
12() element: null

View File

@@ -1,11 +1,13 @@
0(1) element: null
1(2) element: PyMatchStatement
2(3,5) refutable pattern: [x]
3(4) WRITE ACCESS: x
4(6) matched pattern: [x]
5(6) WRITE ACCESS: x
6(7) element: PyExpressionStatement
7(8) READ ACCESS: y
2(3) refutable pattern: [x] | x
3(4,6) refutable pattern: [x]
4(5) WRITE ACCESS: x
5(7) matched pattern: [x]
6(7) WRITE ACCESS: x
7(8) matched pattern: [x] | x
8(9) element: PyExpressionStatement
9(10) READ ACCESS: z
10() element: null
9(10) READ ACCESS: y
10(11) element: PyExpressionStatement
11(12) READ ACCESS: z
12() element: null

View File

@@ -10,8 +10,8 @@
9(10,19) refutable pattern: 'bar': foo.bar
10(11,19) refutable pattern: 'bar'
11(12) matched pattern: 'bar'
12(13,19) refutable pattern: foo.bar
13(14) READ ACCESS: foo
12(13) refutable pattern: foo.bar
13(14,19) READ ACCESS: foo
14(15) matched pattern: foo.bar
15(16) matched pattern: 'bar': foo.bar
16(17) matched pattern: {'foo': 1, 'bar': foo.bar}

View File

@@ -1,19 +1,17 @@
0(1) element: null
1(2) element: PyMatchStatement
2(3,16) refutable pattern: 1 | (2 | 3)
2(3) refutable pattern: 1 | (2 | 3)
3(4,5) refutable pattern: 1
4(14) matched pattern: 1
5(6,16) refutable pattern: (2 | 3)
6(7,16) refutable pattern: 2 | 3
7(8,9) refutable pattern: 2
8(14) matched pattern: 2
9(10,16) refutable pattern: 3
10(11) matched pattern: 3
11(12) matched pattern: 2 | 3
12(13) matched pattern: (2 | 3)
13(14) matched pattern: 1 | (2 | 3)
4(11) matched pattern: 1
5(6) refutable pattern: 2 | 3
6(7,8) refutable pattern: 2
7(10) matched pattern: 2
8(9,14) refutable pattern: 3
9(10) matched pattern: 3
10(11) matched pattern: 2 | 3
11(12) matched pattern: 1 | (2 | 3)
12(13) element: PyExpressionStatement
13(14) READ ACCESS: x
14(15) element: PyExpressionStatement
15(16) READ ACCESS: x
16(17) element: PyExpressionStatement
17(18) READ ACCESS: y
18() element: null
15(16) READ ACCESS: y
16() element: null

View File

@@ -1,20 +1,17 @@
0(1) element: null
1(2) element: PyMatchStatement
2(3,17) refutable pattern: [x] | (foo.bar as x)
2(3) refutable pattern: [x] | (foo.bar as x)
3(4,6) refutable pattern: [x]
4(5) WRITE ACCESS: x
5(15) matched pattern: [x]
6(7,17) refutable pattern: (foo.bar as x)
7(8,17) refutable pattern: foo.bar as x
8(9,17) refutable pattern: foo.bar
9(10) READ ACCESS: foo
10(11) matched pattern: foo.bar
11(12) WRITE ACCESS: x
12(13) matched pattern: foo.bar as x
13(14) matched pattern: (foo.bar as x)
14(15) matched pattern: [x] | (foo.bar as x)
15(16) element: PyExpressionStatement
16(17) READ ACCESS: y
17(18) element: PyExpressionStatement
18(19) READ ACCESS: z
19() element: null
5(11) matched pattern: [x]
6(7) element: PyAsPattern
7(8) refutable pattern: foo.bar
8(9,14) READ ACCESS: foo
9(10) matched pattern: foo.bar
10(11) WRITE ACCESS: x
11(12) matched pattern: [x] | (foo.bar as x)
12(13) element: PyExpressionStatement
13(14) READ ACCESS: y
14(15) element: PyExpressionStatement
15(16) READ ACCESS: z
16() element: null

View File

@@ -1,8 +1,8 @@
0(1) element: null
1(2) element: PyMatchStatement
2(3,10) refutable pattern: [] | 42
2(3) refutable pattern: [] | 42
3(4,5) refutable pattern: []
4(8) matched pattern: []
4(7) matched pattern: []
5(6,10) refutable pattern: 42
6(7) matched pattern: 42
7(8) matched pattern: [] | 42

View File

@@ -1,10 +1,12 @@
0(1) element: null
1(2) element: PyMatchStatement
2(5) element: PyWildcardPattern
3(4,7) refutable pattern: 42
4(5) matched pattern: 42
5(6) element: PyExpressionStatement
6(7) READ ACCESS: y
2(3) refutable pattern: _ | 42
3(6) element: PyWildcardPattern
4(5,9) refutable pattern: 42
5(6) matched pattern: 42
6(7) matched pattern: _ | 42
7(8) element: PyExpressionStatement
8(9) READ ACCESS: z
9() element: null
8(9) READ ACCESS: y
9(10) element: PyExpressionStatement
10(11) READ ACCESS: z
11() element: null

View File

@@ -1,18 +1,17 @@
0(1) element: null
1(2) element: PyMatchStatement
2(3,15) refutable pattern: [x]
2(3,14) refutable pattern: [x]
3(4) WRITE ACCESS: x
4(5) matched pattern: [x]
5(6) element: PyBinaryExpression
6(7,8) READ ACCESS: x
7(12) element: null. Condition: x > 0:false
7(14) element: null. Condition: x > 0:false
8(9) element: null. Condition: x > 0:true
9(10,11) READ ACCESS: x
10(12) element: null. Condition: x % 2 == 0:false
10(14) element: null. Condition: x % 2 == 0:false
11(12) element: null. Condition: x % 2 == 0:true
12(13) element: PyStatementList. Condition: x > 0 and x % 2 == 0:true
13(14) element: PyExpressionStatement
14(15) READ ACCESS: y
15(16) element: PyExpressionStatement
16(17) READ ACCESS: z
17() element: null
12(13) element: PyExpressionStatement
13(14) READ ACCESS: y
14(15) element: PyExpressionStatement
15(16) READ ACCESS: z
16() element: null

View File

@@ -3,8 +3,8 @@
2(3,11) refutable pattern: [1, foo.bar]
3(4,11) refutable pattern: 1
4(5) matched pattern: 1
5(6,11) refutable pattern: foo.bar
6(7) READ ACCESS: foo
5(6) refutable pattern: foo.bar
6(7,11) READ ACCESS: foo
7(8) matched pattern: foo.bar
8(9) matched pattern: [1, foo.bar]
9(10) element: PyExpressionStatement

View File

@@ -1,12 +1,14 @@
0(1) element: null
1(2) element: PyMatchStatement
2(3,9) refutable pattern: [1 | x]
3(4,5) refutable pattern: 1
4(7) matched pattern: 1
5(6) WRITE ACCESS: x
6(7) matched pattern: [1 | x]
7(8) element: PyExpressionStatement
8(9) READ ACCESS: y
2(3,11) refutable pattern: [1 | x]
3(4) refutable pattern: 1 | x
4(5,6) refutable pattern: 1
5(7) matched pattern: 1
6(7) WRITE ACCESS: x
7(8) matched pattern: 1 | x
8(9) matched pattern: [1 | x]
9(10) element: PyExpressionStatement
10(11) READ ACCESS: z
11() element: null
10(11) READ ACCESS: y
11(12) element: PyExpressionStatement
12(13) READ ACCESS: z
13() element: null

View File

@@ -1,10 +1,11 @@
0(1) element: null
1(2) element: PyMatchStatement
2(3) WRITE ACCESS: x
3(4,7) READ ACCESS: x
4(5) element: PyStatementList. Condition: x > 0:true
5(6) element: PyExpressionStatement
6(7) READ ACCESS: y
7(8) element: PyExpressionStatement
8(9) READ ACCESS: z
9() element: null
3(4,5) READ ACCESS: x
4(8) element: null. Condition: x > 0:false
5(6) element: null. Condition: x > 0:true
6(7) element: PyExpressionStatement
7(8) READ ACCESS: y
8(9) element: PyExpressionStatement
9(10) READ ACCESS: z
10() element: null