mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:38:25 +00:00
Format PatternMatchOr
(#6905)
This commit is contained in:
parent
30ebf7fc86
commit
99f4c6886e
7 changed files with 142 additions and 913 deletions
|
@ -467,3 +467,37 @@ match pattern_match_class:
|
|||
# e
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
match pattern_match_or:
|
||||
case ( # leading 1
|
||||
a # trailing 1
|
||||
# own line 1
|
||||
| # trailing 2
|
||||
# own line 2
|
||||
b # trailing 3
|
||||
# own line 3
|
||||
| # trailing 4
|
||||
# own line 4
|
||||
c # trailing 5
|
||||
):
|
||||
...
|
||||
|
||||
case (
|
||||
(a)
|
||||
| # trailing
|
||||
( b )
|
||||
):
|
||||
...
|
||||
|
||||
case (a|b|c):
|
||||
...
|
||||
|
||||
case foo | bar | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh:
|
||||
...
|
||||
|
||||
case ( # end of line
|
||||
a | b
|
||||
# own line
|
||||
):
|
||||
...
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
use thiserror::Error;
|
||||
|
||||
use ruff_formatter::format_element::tag;
|
||||
use ruff_formatter::prelude::*;
|
||||
use ruff_formatter::{format, FormatError, Formatted, PrintError, Printed, SourceCode};
|
||||
use ruff_python_ast::node::{AnyNodeRef, AstNode};
|
||||
use ruff_python_ast::node::AstNode;
|
||||
use ruff_python_ast::Mod;
|
||||
use ruff_python_index::{CommentRanges, CommentRangesBuilder};
|
||||
use ruff_python_parser::lexer::{lex, LexicalError};
|
||||
use ruff_python_parser::{parse_tokens, Mode, ParseError};
|
||||
use ruff_source_file::Locator;
|
||||
use ruff_text_size::TextLen;
|
||||
|
||||
use crate::comments::{
|
||||
dangling_comments, leading_comments, trailing_comments, Comments, SourceComment,
|
||||
|
@ -178,45 +176,6 @@ pub fn pretty_comments(formatted: &Formatted<PyFormatContext>, source: &str) ->
|
|||
)
|
||||
}
|
||||
|
||||
pub(crate) struct NotYetImplementedCustomText<'a> {
|
||||
text: &'static str,
|
||||
node: AnyNodeRef<'a>,
|
||||
}
|
||||
|
||||
/// Formats a placeholder for nodes that have not yet been implemented
|
||||
pub(crate) fn not_yet_implemented_custom_text<'a, T>(
|
||||
text: &'static str,
|
||||
node: T,
|
||||
) -> NotYetImplementedCustomText<'a>
|
||||
where
|
||||
T: Into<AnyNodeRef<'a>>,
|
||||
{
|
||||
NotYetImplementedCustomText {
|
||||
text,
|
||||
node: node.into(),
|
||||
}
|
||||
}
|
||||
|
||||
impl Format<PyFormatContext<'_>> for NotYetImplementedCustomText<'_> {
|
||||
fn fmt(&self, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
f.write_element(FormatElement::Tag(Tag::StartVerbatim(
|
||||
tag::VerbatimKind::Verbatim {
|
||||
length: self.text.text_len(),
|
||||
},
|
||||
)));
|
||||
|
||||
text(self.text).fmt(f)?;
|
||||
|
||||
f.write_element(FormatElement::Tag(Tag::EndVerbatim));
|
||||
|
||||
f.context()
|
||||
.comments()
|
||||
.mark_verbatim_node_comments_formatted(self.node);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::Path;
|
||||
|
|
|
@ -2,8 +2,10 @@ use ruff_formatter::write;
|
|||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use ruff_python_ast::PatternMatchOr;
|
||||
|
||||
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
|
||||
use crate::not_yet_implemented_custom_text;
|
||||
use crate::comments::leading_comments;
|
||||
use crate::expression::parentheses::{
|
||||
in_parentheses_only_soft_line_break_or_space, NeedsParentheses, OptionalParentheses,
|
||||
};
|
||||
use crate::prelude::*;
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -11,13 +13,35 @@ pub struct FormatPatternMatchOr;
|
|||
|
||||
impl FormatNodeRule<PatternMatchOr> for FormatPatternMatchOr {
|
||||
fn fmt_fields(&self, item: &PatternMatchOr, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
write!(
|
||||
f,
|
||||
[not_yet_implemented_custom_text(
|
||||
"NOT_YET_IMPLEMENTED_PatternMatchOf | (y)",
|
||||
item
|
||||
)]
|
||||
)
|
||||
let PatternMatchOr { range: _, patterns } = item;
|
||||
let inner = format_with(|f: &mut PyFormatter| {
|
||||
let mut patterns = patterns.iter();
|
||||
let comments = f.context().comments().clone();
|
||||
|
||||
let Some(first) = patterns.next() else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
first.format().fmt(f)?;
|
||||
|
||||
for pattern in patterns {
|
||||
let leading_value_comments = comments.leading(pattern);
|
||||
// Format the expressions leading comments **before** the operator
|
||||
if leading_value_comments.is_empty() {
|
||||
write!(f, [in_parentheses_only_soft_line_break_or_space()])?;
|
||||
} else {
|
||||
write!(
|
||||
f,
|
||||
[hard_line_break(), leading_comments(leading_value_comments)]
|
||||
)?;
|
||||
}
|
||||
write!(f, [text("|"), space(), pattern.format()])?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
});
|
||||
|
||||
inner.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,507 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_python_formatter/tests/fixtures.rs
|
||||
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_complex.py
|
||||
---
|
||||
## Input
|
||||
|
||||
```py
|
||||
# Cases sampled from Lib/test/test_patma.py
|
||||
|
||||
# case black_test_patma_098
|
||||
match x:
|
||||
case -0j:
|
||||
y = 0
|
||||
# case black_test_patma_142
|
||||
match x:
|
||||
case bytes(z):
|
||||
y = 0
|
||||
# case black_test_patma_073
|
||||
match x:
|
||||
case 0 if 0:
|
||||
y = 0
|
||||
case 0 if 1:
|
||||
y = 1
|
||||
# case black_test_patma_006
|
||||
match 3:
|
||||
case 0 | 1 | 2 | 3:
|
||||
x = True
|
||||
# case black_test_patma_049
|
||||
match x:
|
||||
case [0, 1] | [1, 0]:
|
||||
y = 0
|
||||
# case black_check_sequence_then_mapping
|
||||
match x:
|
||||
case [*_]:
|
||||
return "seq"
|
||||
case {}:
|
||||
return "map"
|
||||
# case black_test_patma_035
|
||||
match x:
|
||||
case {0: [1, 2, {}]}:
|
||||
y = 0
|
||||
case {0: [1, 2, {}] | True} | {1: [[]]} | {0: [1, 2, {}]} | [] | "X" | {}:
|
||||
y = 1
|
||||
case []:
|
||||
y = 2
|
||||
# case black_test_patma_107
|
||||
match x:
|
||||
case 0.25 + 1.75j:
|
||||
y = 0
|
||||
# case black_test_patma_097
|
||||
match x:
|
||||
case -0j:
|
||||
y = 0
|
||||
# case black_test_patma_007
|
||||
match 4:
|
||||
case 0 | 1 | 2 | 3:
|
||||
x = True
|
||||
# case black_test_patma_154
|
||||
match x:
|
||||
case 0 if x:
|
||||
y = 0
|
||||
# case black_test_patma_134
|
||||
match x:
|
||||
case {1: 0}:
|
||||
y = 0
|
||||
case {0: 0}:
|
||||
y = 1
|
||||
case {**z}:
|
||||
y = 2
|
||||
# case black_test_patma_185
|
||||
match Seq():
|
||||
case [*_]:
|
||||
y = 0
|
||||
# case black_test_patma_063
|
||||
match x:
|
||||
case 1:
|
||||
y = 0
|
||||
case 1:
|
||||
y = 1
|
||||
# case black_test_patma_248
|
||||
match x:
|
||||
case {"foo": bar}:
|
||||
y = bar
|
||||
# case black_test_patma_019
|
||||
match (0, 1, 2):
|
||||
case [0, 1, *x, 2]:
|
||||
y = 0
|
||||
# case black_test_patma_052
|
||||
match x:
|
||||
case [0]:
|
||||
y = 0
|
||||
case [1, 0] if (x := x[:0]):
|
||||
y = 1
|
||||
case [1, 0]:
|
||||
y = 2
|
||||
# case black_test_patma_191
|
||||
match w:
|
||||
case [x, y, *_]:
|
||||
z = 0
|
||||
# case black_test_patma_110
|
||||
match x:
|
||||
case -0.25 - 1.75j:
|
||||
y = 0
|
||||
# case black_test_patma_151
|
||||
match (x,):
|
||||
case [y]:
|
||||
z = 0
|
||||
# case black_test_patma_114
|
||||
match x:
|
||||
case A.B.C.D:
|
||||
y = 0
|
||||
# case black_test_patma_232
|
||||
match x:
|
||||
case None:
|
||||
y = 0
|
||||
# case black_test_patma_058
|
||||
match x:
|
||||
case 0:
|
||||
y = 0
|
||||
# case black_test_patma_233
|
||||
match x:
|
||||
case False:
|
||||
y = 0
|
||||
# case black_test_patma_078
|
||||
match x:
|
||||
case []:
|
||||
y = 0
|
||||
case [""]:
|
||||
y = 1
|
||||
case "":
|
||||
y = 2
|
||||
# case black_test_patma_156
|
||||
match x:
|
||||
case z:
|
||||
y = 0
|
||||
# case black_test_patma_189
|
||||
match w:
|
||||
case [x, y, *rest]:
|
||||
z = 0
|
||||
# case black_test_patma_042
|
||||
match x:
|
||||
case (0 as z) | (1 as z) | (2 as z) if z == x % 2:
|
||||
y = 0
|
||||
# case black_test_patma_034
|
||||
match x:
|
||||
case {0: [1, 2, {}]}:
|
||||
y = 0
|
||||
case {0: [1, 2, {}] | False} | {1: [[]]} | {0: [1, 2, {}]} | [] | "X" | {}:
|
||||
y = 1
|
||||
case []:
|
||||
y = 2
|
||||
```
|
||||
|
||||
## Black Differences
|
||||
|
||||
```diff
|
||||
--- Black
|
||||
+++ Ruff
|
||||
@@ -16,11 +16,11 @@
|
||||
y = 1
|
||||
# case black_test_patma_006
|
||||
match 3:
|
||||
- case 0 | 1 | 2 | 3:
|
||||
+ case NOT_YET_IMPLEMENTED_PatternMatchOf | (y):
|
||||
x = True
|
||||
# case black_test_patma_049
|
||||
match x:
|
||||
- case [0, 1] | [1, 0]:
|
||||
+ case NOT_YET_IMPLEMENTED_PatternMatchOf | (y):
|
||||
y = 0
|
||||
# case black_check_sequence_then_mapping
|
||||
match x:
|
||||
@@ -32,7 +32,7 @@
|
||||
match x:
|
||||
case {0: [1, 2, {}]}:
|
||||
y = 0
|
||||
- case {0: [1, 2, {}] | True} | {1: [[]]} | {0: [1, 2, {}]} | [] | "X" | {}:
|
||||
+ case NOT_YET_IMPLEMENTED_PatternMatchOf | (y):
|
||||
y = 1
|
||||
case []:
|
||||
y = 2
|
||||
@@ -46,7 +46,7 @@
|
||||
y = 0
|
||||
# case black_test_patma_007
|
||||
match 4:
|
||||
- case 0 | 1 | 2 | 3:
|
||||
+ case NOT_YET_IMPLEMENTED_PatternMatchOf | (y):
|
||||
x = True
|
||||
# case black_test_patma_154
|
||||
match x:
|
||||
@@ -132,13 +132,13 @@
|
||||
z = 0
|
||||
# case black_test_patma_042
|
||||
match x:
|
||||
- case (0 as z) | (1 as z) | (2 as z) if z == x % 2:
|
||||
+ case NOT_YET_IMPLEMENTED_PatternMatchOf | (y) if z == x % 2:
|
||||
y = 0
|
||||
# case black_test_patma_034
|
||||
match x:
|
||||
case {0: [1, 2, {}]}:
|
||||
y = 0
|
||||
- case {0: [1, 2, {}] | False} | {1: [[]]} | {0: [1, 2, {}]} | [] | "X" | {}:
|
||||
+ case NOT_YET_IMPLEMENTED_PatternMatchOf | (y):
|
||||
y = 1
|
||||
case []:
|
||||
y = 2
|
||||
```
|
||||
|
||||
## Ruff Output
|
||||
|
||||
```py
|
||||
# Cases sampled from Lib/test/test_patma.py
|
||||
|
||||
# case black_test_patma_098
|
||||
match x:
|
||||
case -0j:
|
||||
y = 0
|
||||
# case black_test_patma_142
|
||||
match x:
|
||||
case bytes(z):
|
||||
y = 0
|
||||
# case black_test_patma_073
|
||||
match x:
|
||||
case 0 if 0:
|
||||
y = 0
|
||||
case 0 if 1:
|
||||
y = 1
|
||||
# case black_test_patma_006
|
||||
match 3:
|
||||
case NOT_YET_IMPLEMENTED_PatternMatchOf | (y):
|
||||
x = True
|
||||
# case black_test_patma_049
|
||||
match x:
|
||||
case NOT_YET_IMPLEMENTED_PatternMatchOf | (y):
|
||||
y = 0
|
||||
# case black_check_sequence_then_mapping
|
||||
match x:
|
||||
case [*_]:
|
||||
return "seq"
|
||||
case {}:
|
||||
return "map"
|
||||
# case black_test_patma_035
|
||||
match x:
|
||||
case {0: [1, 2, {}]}:
|
||||
y = 0
|
||||
case NOT_YET_IMPLEMENTED_PatternMatchOf | (y):
|
||||
y = 1
|
||||
case []:
|
||||
y = 2
|
||||
# case black_test_patma_107
|
||||
match x:
|
||||
case 0.25 + 1.75j:
|
||||
y = 0
|
||||
# case black_test_patma_097
|
||||
match x:
|
||||
case -0j:
|
||||
y = 0
|
||||
# case black_test_patma_007
|
||||
match 4:
|
||||
case NOT_YET_IMPLEMENTED_PatternMatchOf | (y):
|
||||
x = True
|
||||
# case black_test_patma_154
|
||||
match x:
|
||||
case 0 if x:
|
||||
y = 0
|
||||
# case black_test_patma_134
|
||||
match x:
|
||||
case {1: 0}:
|
||||
y = 0
|
||||
case {0: 0}:
|
||||
y = 1
|
||||
case {**z}:
|
||||
y = 2
|
||||
# case black_test_patma_185
|
||||
match Seq():
|
||||
case [*_]:
|
||||
y = 0
|
||||
# case black_test_patma_063
|
||||
match x:
|
||||
case 1:
|
||||
y = 0
|
||||
case 1:
|
||||
y = 1
|
||||
# case black_test_patma_248
|
||||
match x:
|
||||
case {"foo": bar}:
|
||||
y = bar
|
||||
# case black_test_patma_019
|
||||
match (0, 1, 2):
|
||||
case [0, 1, *x, 2]:
|
||||
y = 0
|
||||
# case black_test_patma_052
|
||||
match x:
|
||||
case [0]:
|
||||
y = 0
|
||||
case [1, 0] if (x := x[:0]):
|
||||
y = 1
|
||||
case [1, 0]:
|
||||
y = 2
|
||||
# case black_test_patma_191
|
||||
match w:
|
||||
case [x, y, *_]:
|
||||
z = 0
|
||||
# case black_test_patma_110
|
||||
match x:
|
||||
case -0.25 - 1.75j:
|
||||
y = 0
|
||||
# case black_test_patma_151
|
||||
match (x,):
|
||||
case [y]:
|
||||
z = 0
|
||||
# case black_test_patma_114
|
||||
match x:
|
||||
case A.B.C.D:
|
||||
y = 0
|
||||
# case black_test_patma_232
|
||||
match x:
|
||||
case None:
|
||||
y = 0
|
||||
# case black_test_patma_058
|
||||
match x:
|
||||
case 0:
|
||||
y = 0
|
||||
# case black_test_patma_233
|
||||
match x:
|
||||
case False:
|
||||
y = 0
|
||||
# case black_test_patma_078
|
||||
match x:
|
||||
case []:
|
||||
y = 0
|
||||
case [""]:
|
||||
y = 1
|
||||
case "":
|
||||
y = 2
|
||||
# case black_test_patma_156
|
||||
match x:
|
||||
case z:
|
||||
y = 0
|
||||
# case black_test_patma_189
|
||||
match w:
|
||||
case [x, y, *rest]:
|
||||
z = 0
|
||||
# case black_test_patma_042
|
||||
match x:
|
||||
case NOT_YET_IMPLEMENTED_PatternMatchOf | (y) if z == x % 2:
|
||||
y = 0
|
||||
# case black_test_patma_034
|
||||
match x:
|
||||
case {0: [1, 2, {}]}:
|
||||
y = 0
|
||||
case NOT_YET_IMPLEMENTED_PatternMatchOf | (y):
|
||||
y = 1
|
||||
case []:
|
||||
y = 2
|
||||
```
|
||||
|
||||
## Black Output
|
||||
|
||||
```py
|
||||
# Cases sampled from Lib/test/test_patma.py
|
||||
|
||||
# case black_test_patma_098
|
||||
match x:
|
||||
case -0j:
|
||||
y = 0
|
||||
# case black_test_patma_142
|
||||
match x:
|
||||
case bytes(z):
|
||||
y = 0
|
||||
# case black_test_patma_073
|
||||
match x:
|
||||
case 0 if 0:
|
||||
y = 0
|
||||
case 0 if 1:
|
||||
y = 1
|
||||
# case black_test_patma_006
|
||||
match 3:
|
||||
case 0 | 1 | 2 | 3:
|
||||
x = True
|
||||
# case black_test_patma_049
|
||||
match x:
|
||||
case [0, 1] | [1, 0]:
|
||||
y = 0
|
||||
# case black_check_sequence_then_mapping
|
||||
match x:
|
||||
case [*_]:
|
||||
return "seq"
|
||||
case {}:
|
||||
return "map"
|
||||
# case black_test_patma_035
|
||||
match x:
|
||||
case {0: [1, 2, {}]}:
|
||||
y = 0
|
||||
case {0: [1, 2, {}] | True} | {1: [[]]} | {0: [1, 2, {}]} | [] | "X" | {}:
|
||||
y = 1
|
||||
case []:
|
||||
y = 2
|
||||
# case black_test_patma_107
|
||||
match x:
|
||||
case 0.25 + 1.75j:
|
||||
y = 0
|
||||
# case black_test_patma_097
|
||||
match x:
|
||||
case -0j:
|
||||
y = 0
|
||||
# case black_test_patma_007
|
||||
match 4:
|
||||
case 0 | 1 | 2 | 3:
|
||||
x = True
|
||||
# case black_test_patma_154
|
||||
match x:
|
||||
case 0 if x:
|
||||
y = 0
|
||||
# case black_test_patma_134
|
||||
match x:
|
||||
case {1: 0}:
|
||||
y = 0
|
||||
case {0: 0}:
|
||||
y = 1
|
||||
case {**z}:
|
||||
y = 2
|
||||
# case black_test_patma_185
|
||||
match Seq():
|
||||
case [*_]:
|
||||
y = 0
|
||||
# case black_test_patma_063
|
||||
match x:
|
||||
case 1:
|
||||
y = 0
|
||||
case 1:
|
||||
y = 1
|
||||
# case black_test_patma_248
|
||||
match x:
|
||||
case {"foo": bar}:
|
||||
y = bar
|
||||
# case black_test_patma_019
|
||||
match (0, 1, 2):
|
||||
case [0, 1, *x, 2]:
|
||||
y = 0
|
||||
# case black_test_patma_052
|
||||
match x:
|
||||
case [0]:
|
||||
y = 0
|
||||
case [1, 0] if (x := x[:0]):
|
||||
y = 1
|
||||
case [1, 0]:
|
||||
y = 2
|
||||
# case black_test_patma_191
|
||||
match w:
|
||||
case [x, y, *_]:
|
||||
z = 0
|
||||
# case black_test_patma_110
|
||||
match x:
|
||||
case -0.25 - 1.75j:
|
||||
y = 0
|
||||
# case black_test_patma_151
|
||||
match (x,):
|
||||
case [y]:
|
||||
z = 0
|
||||
# case black_test_patma_114
|
||||
match x:
|
||||
case A.B.C.D:
|
||||
y = 0
|
||||
# case black_test_patma_232
|
||||
match x:
|
||||
case None:
|
||||
y = 0
|
||||
# case black_test_patma_058
|
||||
match x:
|
||||
case 0:
|
||||
y = 0
|
||||
# case black_test_patma_233
|
||||
match x:
|
||||
case False:
|
||||
y = 0
|
||||
# case black_test_patma_078
|
||||
match x:
|
||||
case []:
|
||||
y = 0
|
||||
case [""]:
|
||||
y = 1
|
||||
case "":
|
||||
y = 2
|
||||
# case black_test_patma_156
|
||||
match x:
|
||||
case z:
|
||||
y = 0
|
||||
# case black_test_patma_189
|
||||
match w:
|
||||
case [x, y, *rest]:
|
||||
z = 0
|
||||
# case black_test_patma_042
|
||||
match x:
|
||||
case (0 as z) | (1 as z) | (2 as z) if z == x % 2:
|
||||
y = 0
|
||||
# case black_test_patma_034
|
||||
match x:
|
||||
case {0: [1, 2, {}]}:
|
||||
y = 0
|
||||
case {0: [1, 2, {}] | False} | {1: [[]]} | {0: [1, 2, {}]} | [] | "X" | {}:
|
||||
y = 1
|
||||
case []:
|
||||
y = 2
|
||||
```
|
||||
|
||||
|
|
@ -158,24 +158,6 @@ match bar1:
|
|||
pass
|
||||
case _:
|
||||
pass
|
||||
@@ -87,7 +96,7 @@
|
||||
match something:
|
||||
case {
|
||||
"key": key as key_1,
|
||||
- "password": PASS.ONE | PASS.TWO | PASS.THREE as password,
|
||||
+ "password": NOT_YET_IMPLEMENTED_PatternMatchOf | (y) as password,
|
||||
}:
|
||||
pass
|
||||
case {"maybe": something(complicated as this) as that}:
|
||||
@@ -101,7 +110,7 @@
|
||||
case 2 as b, 3 as c:
|
||||
pass
|
||||
|
||||
- case 4 as d, (5 as e), (6 | 7 as g), *h:
|
||||
+ case 4 as d, (5 as e), (NOT_YET_IMPLEMENTED_PatternMatchOf | (y) as g), *h:
|
||||
pass
|
||||
|
||||
|
||||
```
|
||||
|
||||
## Ruff Output
|
||||
|
@ -279,7 +261,7 @@ match a, *b(), c:
|
|||
match something:
|
||||
case {
|
||||
"key": key as key_1,
|
||||
"password": NOT_YET_IMPLEMENTED_PatternMatchOf | (y) as password,
|
||||
"password": PASS.ONE | PASS.TWO | PASS.THREE as password,
|
||||
}:
|
||||
pass
|
||||
case {"maybe": something(complicated as this) as that}:
|
||||
|
@ -293,7 +275,7 @@ match something:
|
|||
case 2 as b, 3 as c:
|
||||
pass
|
||||
|
||||
case 4 as d, (5 as e), (NOT_YET_IMPLEMENTED_PatternMatchOf | (y) as g), *h:
|
||||
case 4 as d, (5 as e), (6 | 7 as g), *h:
|
||||
pass
|
||||
|
||||
|
||||
|
|
|
@ -1,335 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_python_formatter/tests/fixtures.rs
|
||||
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_310/pattern_matching_simple.py
|
||||
---
|
||||
## Input
|
||||
|
||||
```py
|
||||
# Cases sampled from PEP 636 examples
|
||||
|
||||
match command.split():
|
||||
case [action, obj]:
|
||||
... # interpret action, obj
|
||||
|
||||
match command.split():
|
||||
case [action]:
|
||||
... # interpret single-verb action
|
||||
case [action, obj]:
|
||||
... # interpret action, obj
|
||||
|
||||
match command.split():
|
||||
case ["quit"]:
|
||||
print("Goodbye!")
|
||||
quit_game()
|
||||
case ["look"]:
|
||||
current_room.describe()
|
||||
case ["get", obj]:
|
||||
character.get(obj, current_room)
|
||||
case ["go", direction]:
|
||||
current_room = current_room.neighbor(direction)
|
||||
# The rest of your commands go here
|
||||
|
||||
match command.split():
|
||||
case ["drop", *objects]:
|
||||
for obj in objects:
|
||||
character.drop(obj, current_room)
|
||||
# The rest of your commands go here
|
||||
|
||||
match command.split():
|
||||
case ["quit"]:
|
||||
pass
|
||||
case ["go", direction]:
|
||||
print("Going:", direction)
|
||||
case ["drop", *objects]:
|
||||
print("Dropping: ", *objects)
|
||||
case _:
|
||||
print(f"Sorry, I couldn't understand {command!r}")
|
||||
|
||||
match command.split():
|
||||
case ["north"] | ["go", "north"]:
|
||||
current_room = current_room.neighbor("north")
|
||||
case ["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"]:
|
||||
... # Code for picking up the given object
|
||||
|
||||
match command.split():
|
||||
case ["go", ("north" | "south" | "east" | "west")]:
|
||||
current_room = current_room.neighbor(...)
|
||||
# how do I know which direction to go?
|
||||
|
||||
match command.split():
|
||||
case ["go", ("north" | "south" | "east" | "west") as direction]:
|
||||
current_room = current_room.neighbor(direction)
|
||||
|
||||
match command.split():
|
||||
case ["go", direction] if direction in current_room.exits:
|
||||
current_room = current_room.neighbor(direction)
|
||||
case ["go", _]:
|
||||
print("Sorry, you can't go that way")
|
||||
|
||||
match event.get():
|
||||
case Click(position=(x, y)):
|
||||
handle_click_at(x, y)
|
||||
case KeyPress(key_name="Q") | Quit():
|
||||
game.quit()
|
||||
case KeyPress(key_name="up arrow"):
|
||||
game.go_north()
|
||||
case KeyPress():
|
||||
pass # Ignore other keystrokes
|
||||
case other_event:
|
||||
raise ValueError(f"Unrecognized event: {other_event}")
|
||||
|
||||
match event.get():
|
||||
case Click((x, y), button=Button.LEFT): # This is a left click
|
||||
handle_click_at(x, y)
|
||||
case Click():
|
||||
pass # ignore other clicks
|
||||
|
||||
|
||||
def where_is(point):
|
||||
match point:
|
||||
case Point(x=0, y=0):
|
||||
print("Origin")
|
||||
case Point(x=0, y=y):
|
||||
print(f"Y={y}")
|
||||
case Point(x=x, y=0):
|
||||
print(f"X={x}")
|
||||
case Point():
|
||||
print("Somewhere else")
|
||||
case _:
|
||||
print("Not a point")
|
||||
```
|
||||
|
||||
## Black Differences
|
||||
|
||||
```diff
|
||||
--- Black
|
||||
+++ Ruff
|
||||
@@ -39,18 +39,18 @@
|
||||
print(f"Sorry, I couldn't understand {command!r}")
|
||||
|
||||
match command.split():
|
||||
- case ["north"] | ["go", "north"]:
|
||||
+ case NOT_YET_IMPLEMENTED_PatternMatchOf | (y):
|
||||
current_room = current_room.neighbor("north")
|
||||
- case ["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"]:
|
||||
+ case NOT_YET_IMPLEMENTED_PatternMatchOf | (y):
|
||||
... # Code for picking up the given object
|
||||
|
||||
match command.split():
|
||||
- case ["go", ("north" | "south" | "east" | "west")]:
|
||||
+ case ["go", (NOT_YET_IMPLEMENTED_PatternMatchOf | (y))]:
|
||||
current_room = current_room.neighbor(...)
|
||||
# how do I know which direction to go?
|
||||
|
||||
match command.split():
|
||||
- case ["go", ("north" | "south" | "east" | "west") as direction]:
|
||||
+ case ["go", (NOT_YET_IMPLEMENTED_PatternMatchOf | (y)) as direction]:
|
||||
current_room = current_room.neighbor(direction)
|
||||
|
||||
match command.split():
|
||||
@@ -62,7 +62,7 @@
|
||||
match event.get():
|
||||
case Click(position=(x, y)):
|
||||
handle_click_at(x, y)
|
||||
- case KeyPress(key_name="Q") | Quit():
|
||||
+ case NOT_YET_IMPLEMENTED_PatternMatchOf | (y):
|
||||
game.quit()
|
||||
case KeyPress(key_name="up arrow"):
|
||||
game.go_north()
|
||||
```
|
||||
|
||||
## Ruff Output
|
||||
|
||||
```py
|
||||
# Cases sampled from PEP 636 examples
|
||||
|
||||
match command.split():
|
||||
case [action, obj]:
|
||||
... # interpret action, obj
|
||||
|
||||
match command.split():
|
||||
case [action]:
|
||||
... # interpret single-verb action
|
||||
case [action, obj]:
|
||||
... # interpret action, obj
|
||||
|
||||
match command.split():
|
||||
case ["quit"]:
|
||||
print("Goodbye!")
|
||||
quit_game()
|
||||
case ["look"]:
|
||||
current_room.describe()
|
||||
case ["get", obj]:
|
||||
character.get(obj, current_room)
|
||||
case ["go", direction]:
|
||||
current_room = current_room.neighbor(direction)
|
||||
# The rest of your commands go here
|
||||
|
||||
match command.split():
|
||||
case ["drop", *objects]:
|
||||
for obj in objects:
|
||||
character.drop(obj, current_room)
|
||||
# The rest of your commands go here
|
||||
|
||||
match command.split():
|
||||
case ["quit"]:
|
||||
pass
|
||||
case ["go", direction]:
|
||||
print("Going:", direction)
|
||||
case ["drop", *objects]:
|
||||
print("Dropping: ", *objects)
|
||||
case _:
|
||||
print(f"Sorry, I couldn't understand {command!r}")
|
||||
|
||||
match command.split():
|
||||
case NOT_YET_IMPLEMENTED_PatternMatchOf | (y):
|
||||
current_room = current_room.neighbor("north")
|
||||
case NOT_YET_IMPLEMENTED_PatternMatchOf | (y):
|
||||
... # Code for picking up the given object
|
||||
|
||||
match command.split():
|
||||
case ["go", (NOT_YET_IMPLEMENTED_PatternMatchOf | (y))]:
|
||||
current_room = current_room.neighbor(...)
|
||||
# how do I know which direction to go?
|
||||
|
||||
match command.split():
|
||||
case ["go", (NOT_YET_IMPLEMENTED_PatternMatchOf | (y)) as direction]:
|
||||
current_room = current_room.neighbor(direction)
|
||||
|
||||
match command.split():
|
||||
case ["go", direction] if direction in current_room.exits:
|
||||
current_room = current_room.neighbor(direction)
|
||||
case ["go", _]:
|
||||
print("Sorry, you can't go that way")
|
||||
|
||||
match event.get():
|
||||
case Click(position=(x, y)):
|
||||
handle_click_at(x, y)
|
||||
case NOT_YET_IMPLEMENTED_PatternMatchOf | (y):
|
||||
game.quit()
|
||||
case KeyPress(key_name="up arrow"):
|
||||
game.go_north()
|
||||
case KeyPress():
|
||||
pass # Ignore other keystrokes
|
||||
case other_event:
|
||||
raise ValueError(f"Unrecognized event: {other_event}")
|
||||
|
||||
match event.get():
|
||||
case Click((x, y), button=Button.LEFT): # This is a left click
|
||||
handle_click_at(x, y)
|
||||
case Click():
|
||||
pass # ignore other clicks
|
||||
|
||||
|
||||
def where_is(point):
|
||||
match point:
|
||||
case Point(x=0, y=0):
|
||||
print("Origin")
|
||||
case Point(x=0, y=y):
|
||||
print(f"Y={y}")
|
||||
case Point(x=x, y=0):
|
||||
print(f"X={x}")
|
||||
case Point():
|
||||
print("Somewhere else")
|
||||
case _:
|
||||
print("Not a point")
|
||||
```
|
||||
|
||||
## Black Output
|
||||
|
||||
```py
|
||||
# Cases sampled from PEP 636 examples
|
||||
|
||||
match command.split():
|
||||
case [action, obj]:
|
||||
... # interpret action, obj
|
||||
|
||||
match command.split():
|
||||
case [action]:
|
||||
... # interpret single-verb action
|
||||
case [action, obj]:
|
||||
... # interpret action, obj
|
||||
|
||||
match command.split():
|
||||
case ["quit"]:
|
||||
print("Goodbye!")
|
||||
quit_game()
|
||||
case ["look"]:
|
||||
current_room.describe()
|
||||
case ["get", obj]:
|
||||
character.get(obj, current_room)
|
||||
case ["go", direction]:
|
||||
current_room = current_room.neighbor(direction)
|
||||
# The rest of your commands go here
|
||||
|
||||
match command.split():
|
||||
case ["drop", *objects]:
|
||||
for obj in objects:
|
||||
character.drop(obj, current_room)
|
||||
# The rest of your commands go here
|
||||
|
||||
match command.split():
|
||||
case ["quit"]:
|
||||
pass
|
||||
case ["go", direction]:
|
||||
print("Going:", direction)
|
||||
case ["drop", *objects]:
|
||||
print("Dropping: ", *objects)
|
||||
case _:
|
||||
print(f"Sorry, I couldn't understand {command!r}")
|
||||
|
||||
match command.split():
|
||||
case ["north"] | ["go", "north"]:
|
||||
current_room = current_room.neighbor("north")
|
||||
case ["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"]:
|
||||
... # Code for picking up the given object
|
||||
|
||||
match command.split():
|
||||
case ["go", ("north" | "south" | "east" | "west")]:
|
||||
current_room = current_room.neighbor(...)
|
||||
# how do I know which direction to go?
|
||||
|
||||
match command.split():
|
||||
case ["go", ("north" | "south" | "east" | "west") as direction]:
|
||||
current_room = current_room.neighbor(direction)
|
||||
|
||||
match command.split():
|
||||
case ["go", direction] if direction in current_room.exits:
|
||||
current_room = current_room.neighbor(direction)
|
||||
case ["go", _]:
|
||||
print("Sorry, you can't go that way")
|
||||
|
||||
match event.get():
|
||||
case Click(position=(x, y)):
|
||||
handle_click_at(x, y)
|
||||
case KeyPress(key_name="Q") | Quit():
|
||||
game.quit()
|
||||
case KeyPress(key_name="up arrow"):
|
||||
game.go_north()
|
||||
case KeyPress():
|
||||
pass # Ignore other keystrokes
|
||||
case other_event:
|
||||
raise ValueError(f"Unrecognized event: {other_event}")
|
||||
|
||||
match event.get():
|
||||
case Click((x, y), button=Button.LEFT): # This is a left click
|
||||
handle_click_at(x, y)
|
||||
case Click():
|
||||
pass # ignore other clicks
|
||||
|
||||
|
||||
def where_is(point):
|
||||
match point:
|
||||
case Point(x=0, y=0):
|
||||
print("Origin")
|
||||
case Point(x=0, y=y):
|
||||
print(f"Y={y}")
|
||||
case Point(x=x, y=0):
|
||||
print(f"X={x}")
|
||||
case Point():
|
||||
print("Somewhere else")
|
||||
case _:
|
||||
print("Not a point")
|
||||
```
|
||||
|
||||
|
|
@ -473,6 +473,40 @@ match pattern_match_class:
|
|||
# e
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
match pattern_match_or:
|
||||
case ( # leading 1
|
||||
a # trailing 1
|
||||
# own line 1
|
||||
| # trailing 2
|
||||
# own line 2
|
||||
b # trailing 3
|
||||
# own line 3
|
||||
| # trailing 4
|
||||
# own line 4
|
||||
c # trailing 5
|
||||
):
|
||||
...
|
||||
|
||||
case (
|
||||
(a)
|
||||
| # trailing
|
||||
( b )
|
||||
):
|
||||
...
|
||||
|
||||
case (a|b|c):
|
||||
...
|
||||
|
||||
case foo | bar | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh:
|
||||
...
|
||||
|
||||
case ( # end of line
|
||||
a | b
|
||||
# own line
|
||||
):
|
||||
...
|
||||
```
|
||||
|
||||
## Output
|
||||
|
@ -966,6 +1000,44 @@ match pattern_match_class:
|
|||
# e
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
match pattern_match_or:
|
||||
case ( # leading 1
|
||||
a # trailing 1 # trailing 2
|
||||
# own line 1
|
||||
# own line 2
|
||||
| b # trailing 3 # trailing 4
|
||||
# own line 3
|
||||
# own line 4
|
||||
| c # trailing 5
|
||||
):
|
||||
...
|
||||
|
||||
case (
|
||||
(
|
||||
a # trailing
|
||||
)
|
||||
| (b)
|
||||
):
|
||||
...
|
||||
|
||||
case a | b | c:
|
||||
...
|
||||
|
||||
case (
|
||||
foo
|
||||
| bar
|
||||
| aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
|
||||
):
|
||||
...
|
||||
|
||||
case ( # end of line
|
||||
a
|
||||
| b
|
||||
# own line
|
||||
):
|
||||
...
|
||||
```
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue