mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 02:12:22 +00:00
magic trailing comma for ExprList (#5365)
This commit is contained in:
parent
190bed124f
commit
50a7769d69
11 changed files with 163 additions and 186 deletions
|
@ -52,23 +52,7 @@ impl FormatNodeRule<ExprList> for FormatExprList {
|
|||
"A non-empty expression list has dangling comments"
|
||||
);
|
||||
|
||||
let items = format_with(|f| {
|
||||
let mut iter = elts.iter();
|
||||
|
||||
if let Some(first) = iter.next() {
|
||||
write!(f, [first.format()])?;
|
||||
}
|
||||
|
||||
for item in iter {
|
||||
write!(f, [text(","), soft_line_break_or_space(), item.format()])?;
|
||||
}
|
||||
|
||||
if !elts.is_empty() {
|
||||
write!(f, [if_group_breaks(&text(","))])?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
});
|
||||
let items = format_with(|f| f.join_comma_separated().nodes(elts.iter()).finish());
|
||||
|
||||
write!(
|
||||
f,
|
||||
|
|
|
@ -145,16 +145,8 @@ if True:
|
|||
|
||||
# looping over a 1-tuple should also not get wrapped
|
||||
for x in (1,):
|
||||
@@ -63,14 +42,10 @@
|
||||
for (x,) in (1,), (2,), (3,):
|
||||
pass
|
||||
|
||||
-[
|
||||
- 1,
|
||||
- 2,
|
||||
- 3,
|
||||
-]
|
||||
+[1, 2, 3]
|
||||
@@ -70,7 +49,7 @@
|
||||
]
|
||||
|
||||
division_result_tuple = (6 / 2,)
|
||||
-print("foo %r", (foo.bar,))
|
||||
|
@ -162,7 +154,7 @@ if True:
|
|||
|
||||
if True:
|
||||
IGNORED_TYPES_FOR_ATTRIBUTE_CHECKING = (
|
||||
@@ -79,21 +54,6 @@
|
||||
@@ -79,21 +58,6 @@
|
||||
)
|
||||
|
||||
if True:
|
||||
|
@ -236,7 +228,11 @@ for x in (1,):
|
|||
for (x,) in (1,), (2,), (3,):
|
||||
pass
|
||||
|
||||
[1, 2, 3]
|
||||
[
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
]
|
||||
|
||||
division_result_tuple = (6 / 2,)
|
||||
NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
|
||||
|
|
|
@ -307,7 +307,7 @@ instruction()#comment with bad spacing
|
|||
while True:
|
||||
if False:
|
||||
continue
|
||||
@@ -141,24 +111,19 @@
|
||||
@@ -141,10 +111,7 @@
|
||||
# and round and round we go
|
||||
|
||||
# let's return
|
||||
|
@ -318,15 +318,8 @@ instruction()#comment with bad spacing
|
|||
+ return NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
|
||||
|
||||
|
||||
-CONFIG_FILES = (
|
||||
- [
|
||||
- CONFIG_FILE,
|
||||
- ]
|
||||
- + SHARED_CONFIG_FILES
|
||||
- + USER_CONFIG_FILES
|
||||
-) # type: Final
|
||||
+CONFIG_FILES = [CONFIG_FILE] + SHARED_CONFIG_FILES + USER_CONFIG_FILES # type: Final
|
||||
|
||||
CONFIG_FILES = (
|
||||
@@ -158,7 +125,11 @@
|
||||
|
||||
class Test:
|
||||
def _init_host(self, parsed) -> None:
|
||||
|
@ -339,7 +332,7 @@ instruction()#comment with bad spacing
|
|||
pass
|
||||
|
||||
|
||||
@@ -167,7 +132,7 @@
|
||||
@@ -167,7 +138,7 @@
|
||||
#######################
|
||||
|
||||
|
||||
|
@ -469,7 +462,13 @@ def inline_comments_in_brackets_ruin_everything():
|
|||
return NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
|
||||
|
||||
|
||||
CONFIG_FILES = [CONFIG_FILE] + SHARED_CONFIG_FILES + USER_CONFIG_FILES # type: Final
|
||||
CONFIG_FILES = (
|
||||
[
|
||||
CONFIG_FILE,
|
||||
]
|
||||
+ SHARED_CONFIG_FILES
|
||||
+ USER_CONFIG_FILES
|
||||
) # type: Final
|
||||
|
||||
|
||||
class Test:
|
||||
|
|
|
@ -274,7 +274,7 @@ last_call()
|
|||
Name
|
||||
None
|
||||
True
|
||||
@@ -30,98 +31,83 @@
|
||||
@@ -30,33 +31,39 @@
|
||||
-1
|
||||
~int and not v1 ^ 123 + v2 | True
|
||||
(~int) and (not ((v1 ^ (123 + v2)) | True))
|
||||
|
@ -337,32 +337,27 @@ last_call()
|
|||
()
|
||||
(1,)
|
||||
(1, 2)
|
||||
(1, 2, 3)
|
||||
[]
|
||||
[1, 2, 3, 4, 5, 6, 7, 8, 9, (10 or A), (11 or B), (12 or C)]
|
||||
-[
|
||||
- 1,
|
||||
- 2,
|
||||
- 3,
|
||||
-]
|
||||
@@ -68,60 +75,51 @@
|
||||
2,
|
||||
3,
|
||||
]
|
||||
-[*a]
|
||||
-[*range(10)]
|
||||
-[
|
||||
- *a,
|
||||
- 4,
|
||||
- 5,
|
||||
-]
|
||||
+[1, 2, 3]
|
||||
+[*NOT_YET_IMPLEMENTED_ExprStarred]
|
||||
+[*NOT_YET_IMPLEMENTED_ExprStarred]
|
||||
+[*NOT_YET_IMPLEMENTED_ExprStarred, 4, 5]
|
||||
+[4, *NOT_YET_IMPLEMENTED_ExprStarred, 5]
|
||||
[
|
||||
- 4,
|
||||
- *a,
|
||||
- 5,
|
||||
-]
|
||||
-[
|
||||
+ *NOT_YET_IMPLEMENTED_ExprStarred,
|
||||
4,
|
||||
5,
|
||||
]
|
||||
[
|
||||
4,
|
||||
- *a,
|
||||
+ *NOT_YET_IMPLEMENTED_ExprStarred,
|
||||
5,
|
||||
]
|
||||
[
|
||||
this_is_a_very_long_variable_which_will_force_a_delimiter_split,
|
||||
element,
|
||||
another,
|
||||
|
@ -432,7 +427,7 @@ last_call()
|
|||
(1).real
|
||||
(1.0).real
|
||||
....__class__
|
||||
@@ -130,34 +116,28 @@
|
||||
@@ -130,34 +128,28 @@
|
||||
tuple[str, ...]
|
||||
tuple[str, int, float, dict[str, int]]
|
||||
tuple[
|
||||
|
@ -480,7 +475,7 @@ last_call()
|
|||
numpy[0, :]
|
||||
numpy[:, i]
|
||||
numpy[0, :2]
|
||||
@@ -171,25 +151,32 @@
|
||||
@@ -171,25 +163,32 @@
|
||||
numpy[1 : c + 1, c]
|
||||
numpy[-(c + 1) :, d]
|
||||
numpy[:, l[-2]]
|
||||
|
@ -523,7 +518,7 @@ last_call()
|
|||
"priority": 1,
|
||||
"import_session_id": 1,
|
||||
**kwargs,
|
||||
@@ -198,35 +185,21 @@
|
||||
@@ -198,35 +197,21 @@
|
||||
b = (1,)
|
||||
c = 1
|
||||
d = (1,) + a + (2,)
|
||||
|
@ -532,17 +527,6 @@ last_call()
|
|||
-g = 1, *"ten"
|
||||
-what_is_up_with_those_new_coord_names = (coord_names + set(vars_to_create)) + set(
|
||||
- vars_to_remove
|
||||
-)
|
||||
-what_is_up_with_those_new_coord_names = (coord_names | set(vars_to_create)) - set(
|
||||
- vars_to_remove
|
||||
-)
|
||||
-result = (
|
||||
- session.query(models.Customer.id)
|
||||
- .filter(
|
||||
- models.Customer.account_id == account_id, models.Customer.email == email_address
|
||||
- )
|
||||
- .order_by(models.Customer.id.asc())
|
||||
- .all()
|
||||
+e = NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
|
||||
+f = 1, *NOT_YET_IMPLEMENTED_ExprStarred
|
||||
+g = 1, *NOT_YET_IMPLEMENTED_ExprStarred
|
||||
|
@ -550,6 +534,20 @@ last_call()
|
|||
+ (coord_names + NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg))
|
||||
+ + NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
|
||||
)
|
||||
-what_is_up_with_those_new_coord_names = (coord_names | set(vars_to_create)) - set(
|
||||
- vars_to_remove
|
||||
+what_is_up_with_those_new_coord_names = (
|
||||
+ (coord_names | NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg))
|
||||
+ - NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
|
||||
)
|
||||
-result = (
|
||||
- session.query(models.Customer.id)
|
||||
- .filter(
|
||||
- models.Customer.account_id == account_id, models.Customer.email == email_address
|
||||
- )
|
||||
- .order_by(models.Customer.id.asc())
|
||||
- .all()
|
||||
-)
|
||||
-result = (
|
||||
- session.query(models.Customer.id)
|
||||
- .filter(
|
||||
|
@ -559,10 +557,7 @@ last_call()
|
|||
- models.Customer.id.asc(),
|
||||
- )
|
||||
- .all()
|
||||
+what_is_up_with_those_new_coord_names = (
|
||||
+ (coord_names | NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg))
|
||||
+ - NOT_IMPLEMENTED_call(NOT_IMPLEMENTED_arg)
|
||||
)
|
||||
-)
|
||||
-Ø = set()
|
||||
-authors.łukasz.say_thanks()
|
||||
+result = NOT_IMPLEMENTED_call()
|
||||
|
@ -572,7 +567,7 @@ last_call()
|
|||
mapping = {
|
||||
A: 0.25 * (10.0 / 12),
|
||||
B: 0.1 * (10.0 / 12),
|
||||
@@ -236,31 +209,29 @@
|
||||
@@ -236,31 +221,29 @@
|
||||
|
||||
|
||||
def gen():
|
||||
|
@ -617,7 +612,7 @@ last_call()
|
|||
...
|
||||
for j in 1 + (2 + 3):
|
||||
...
|
||||
@@ -272,7 +243,7 @@
|
||||
@@ -272,7 +255,7 @@
|
||||
addr_proto,
|
||||
addr_canonname,
|
||||
addr_sockaddr,
|
||||
|
@ -626,7 +621,7 @@ last_call()
|
|||
pass
|
||||
a = (
|
||||
aaaa.bbbb.cccc.dddd.eeee.ffff.gggg.hhhh.iiii.jjjj.kkkk.llll.mmmm.nnnn.oooo.pppp
|
||||
@@ -291,9 +262,9 @@
|
||||
@@ -291,9 +274,9 @@
|
||||
is not qqqq.rrrr.ssss.tttt.uuuu.vvvv.xxxx.yyyy.zzzz
|
||||
)
|
||||
if (
|
||||
|
@ -639,7 +634,7 @@ last_call()
|
|||
):
|
||||
return True
|
||||
if (
|
||||
@@ -327,13 +298,18 @@
|
||||
@@ -327,13 +310,18 @@
|
||||
):
|
||||
return True
|
||||
if (
|
||||
|
@ -661,7 +656,7 @@ last_call()
|
|||
^ aaaaaaaa.i << aaaaaaaa.k >> aaaaaaaa.l**aaaaaaaa.m // aaaaaaaa.n
|
||||
):
|
||||
return True
|
||||
@@ -341,7 +317,8 @@
|
||||
@@ -341,7 +329,8 @@
|
||||
~aaaaaaaaaaaaaaaa.a
|
||||
+ aaaaaaaaaaaaaaaa.b
|
||||
- aaaaaaaaaaaaaaaa.c * aaaaaaaaaaaaaaaa.d @ aaaaaaaaaaaaaaaa.e
|
||||
|
@ -671,7 +666,7 @@ last_call()
|
|||
^ aaaaaaaaaaaaaaaa.i
|
||||
<< aaaaaaaaaaaaaaaa.k
|
||||
>> aaaaaaaaaaaaaaaa.l**aaaaaaaaaaaaaaaa.m // aaaaaaaaaaaaaaaa.n
|
||||
@@ -366,5 +343,5 @@
|
||||
@@ -366,5 +355,5 @@
|
||||
^ bbbb.a & aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
^ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
)
|
||||
|
@ -755,11 +750,23 @@ NOT_IMPLEMENTED_true if NOT_IMPLEMENTED_cond else NOT_IMPLEMENTED_false
|
|||
(1, 2, 3)
|
||||
[]
|
||||
[1, 2, 3, 4, 5, 6, 7, 8, 9, (10 or A), (11 or B), (12 or C)]
|
||||
[1, 2, 3]
|
||||
[
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
]
|
||||
[*NOT_YET_IMPLEMENTED_ExprStarred]
|
||||
[*NOT_YET_IMPLEMENTED_ExprStarred]
|
||||
[*NOT_YET_IMPLEMENTED_ExprStarred, 4, 5]
|
||||
[4, *NOT_YET_IMPLEMENTED_ExprStarred, 5]
|
||||
[
|
||||
*NOT_YET_IMPLEMENTED_ExprStarred,
|
||||
4,
|
||||
5,
|
||||
]
|
||||
[
|
||||
4,
|
||||
*NOT_YET_IMPLEMENTED_ExprStarred,
|
||||
5,
|
||||
]
|
||||
[
|
||||
this_is_a_very_long_variable_which_will_force_a_delimiter_split,
|
||||
element,
|
||||
|
|
|
@ -29,35 +29,50 @@ x = [
|
|||
```diff
|
||||
--- Black
|
||||
+++ Ruff
|
||||
@@ -1,15 +1,9 @@
|
||||
@@ -1,14 +1,18 @@
|
||||
# fmt: off
|
||||
-x = [
|
||||
x = [
|
||||
- 1, 2,
|
||||
- 3, 4,
|
||||
-]
|
||||
+x = [1, 2, 3, 4]
|
||||
+ 1,
|
||||
+ 2,
|
||||
+ 3,
|
||||
+ 4,
|
||||
]
|
||||
# fmt: on
|
||||
|
||||
# fmt: off
|
||||
-x = [
|
||||
x = [
|
||||
- 1, 2,
|
||||
- 3, 4,
|
||||
-]
|
||||
+x = [1, 2, 3, 4]
|
||||
+ 1,
|
||||
+ 2,
|
||||
+ 3,
|
||||
+ 4,
|
||||
]
|
||||
# fmt: on
|
||||
|
||||
x = [1, 2, 3, 4]
|
||||
```
|
||||
|
||||
## Ruff Output
|
||||
|
||||
```py
|
||||
# fmt: off
|
||||
x = [1, 2, 3, 4]
|
||||
x = [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
]
|
||||
# fmt: on
|
||||
|
||||
# fmt: off
|
||||
x = [1, 2, 3, 4]
|
||||
x = [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
]
|
||||
# fmt: on
|
||||
|
||||
x = [1, 2, 3, 4]
|
||||
|
|
|
@ -15,22 +15,19 @@ l3 = ["I have", "trailing comma", "so I should be braked",]
|
|||
```diff
|
||||
--- Black
|
||||
+++ Ruff
|
||||
@@ -3,9 +3,9 @@
|
||||
@@ -3,7 +3,11 @@
|
||||
"into multiple lines",
|
||||
"because it is way too long",
|
||||
]
|
||||
-l2 = ["But this list shouldn't", "even though it also has", "way too many characters in it"] # fmt: skip
|
||||
-l3 = [
|
||||
- "I have",
|
||||
- "trailing comma",
|
||||
- "so I should be braked",
|
||||
-]
|
||||
+l2 = [
|
||||
+ "But this list shouldn't",
|
||||
+ "even though it also has",
|
||||
+ "way too many characters in it",
|
||||
+] # fmt: skip
|
||||
+l3 = ["I have", "trailing comma", "so I should be braked"]
|
||||
l3 = [
|
||||
"I have",
|
||||
"trailing comma",
|
||||
```
|
||||
|
||||
## Ruff Output
|
||||
|
@ -46,7 +43,11 @@ l2 = [
|
|||
"even though it also has",
|
||||
"way too many characters in it",
|
||||
] # fmt: skip
|
||||
l3 = ["I have", "trailing comma", "so I should be braked"]
|
||||
l3 = [
|
||||
"I have",
|
||||
"trailing comma",
|
||||
"so I should be braked",
|
||||
]
|
||||
```
|
||||
|
||||
## Black Output
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
---
|
||||
source: crates/ruff_python_formatter/tests/fixtures.rs
|
||||
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/fmtskip4.py
|
||||
---
|
||||
## Input
|
||||
|
||||
```py
|
||||
a = 2
|
||||
# fmt: skip
|
||||
l = [1, 2, 3,]
|
||||
```
|
||||
|
||||
## Black Differences
|
||||
|
||||
```diff
|
||||
--- Black
|
||||
+++ Ruff
|
||||
@@ -1,7 +1,3 @@
|
||||
a = 2
|
||||
# fmt: skip
|
||||
-l = [
|
||||
- 1,
|
||||
- 2,
|
||||
- 3,
|
||||
-]
|
||||
+l = [1, 2, 3]
|
||||
```
|
||||
|
||||
## Ruff Output
|
||||
|
||||
```py
|
||||
a = 2
|
||||
# fmt: skip
|
||||
l = [1, 2, 3]
|
||||
```
|
||||
|
||||
## Black Output
|
||||
|
||||
```py
|
||||
a = 2
|
||||
# fmt: skip
|
||||
l = [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
]
|
||||
```
|
||||
|
||||
|
|
@ -97,7 +97,7 @@ some_module.some_function(
|
|||
if (
|
||||
a
|
||||
== {
|
||||
@@ -47,23 +43,17 @@
|
||||
@@ -47,22 +43,24 @@
|
||||
"f": 6,
|
||||
"g": 7,
|
||||
"h": 8,
|
||||
|
@ -112,23 +112,24 @@ some_module.some_function(
|
|||
-def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> (
|
||||
- Set["xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"]
|
||||
-):
|
||||
- json = {
|
||||
- "k": {
|
||||
- "k2": {
|
||||
- "k3": [
|
||||
- 1,
|
||||
- ]
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> Set[
|
||||
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
+]:
|
||||
+ json = {"k": {"k2": {"k3": [1]}}}
|
||||
json = {
|
||||
"k": {
|
||||
"k2": {
|
||||
"k3": [
|
||||
1,
|
||||
- ]
|
||||
- }
|
||||
- }
|
||||
+ ],
|
||||
+ },
|
||||
+ },
|
||||
}
|
||||
|
||||
|
||||
# The type annotation shouldn't get a trailing comma since that would change its type.
|
||||
@@ -80,35 +70,16 @@
|
||||
@@ -80,35 +78,16 @@
|
||||
pass
|
||||
|
||||
|
||||
|
@ -228,7 +229,15 @@ def f(
|
|||
def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> Set[
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
]:
|
||||
json = {"k": {"k2": {"k3": [1]}}}
|
||||
json = {
|
||||
"k": {
|
||||
"k2": {
|
||||
"k3": [
|
||||
1,
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
# The type annotation shouldn't get a trailing comma since that would change its type.
|
||||
|
|
|
@ -24,7 +24,7 @@ list_of_types = [tuple[int,],]
|
|||
```diff
|
||||
--- Black
|
||||
+++ Ruff
|
||||
@@ -1,22 +1,17 @@
|
||||
@@ -1,16 +1,15 @@
|
||||
# We should not treat the trailing comma
|
||||
# in a single-element subscript.
|
||||
-a: tuple[int,]
|
||||
|
@ -48,14 +48,13 @@ list_of_types = [tuple[int,],]
|
|||
]
|
||||
|
||||
# Magic commas still work as expected for non-subscripts.
|
||||
-small_list = [
|
||||
- 1,
|
||||
-]
|
||||
-list_of_types = [
|
||||
@@ -18,5 +17,5 @@
|
||||
1,
|
||||
]
|
||||
list_of_types = [
|
||||
- tuple[int,],
|
||||
-]
|
||||
+small_list = [1]
|
||||
+list_of_types = [tuple[(int,)]]
|
||||
+ tuple[(int,)],
|
||||
]
|
||||
```
|
||||
|
||||
## Ruff Output
|
||||
|
@ -76,8 +75,12 @@ d = tuple[
|
|||
]
|
||||
|
||||
# Magic commas still work as expected for non-subscripts.
|
||||
small_list = [1]
|
||||
list_of_types = [tuple[(int,)]]
|
||||
small_list = [
|
||||
1,
|
||||
]
|
||||
list_of_types = [
|
||||
tuple[(int,)],
|
||||
]
|
||||
```
|
||||
|
||||
## Black Output
|
||||
|
|
|
@ -59,7 +59,7 @@ func(
|
|||
```diff
|
||||
--- Black
|
||||
+++ Ruff
|
||||
@@ -1,25 +1,35 @@
|
||||
@@ -1,25 +1,39 @@
|
||||
# We should not remove the trailing comma in a single-element subscript.
|
||||
-a: tuple[int,]
|
||||
-b = tuple[int,]
|
||||
|
@ -78,9 +78,14 @@ func(
|
|||
+]
|
||||
|
||||
# Remove commas for non-subscripts.
|
||||
small_list = [1]
|
||||
-small_list = [1]
|
||||
-list_of_types = [tuple[int,]]
|
||||
+list_of_types = [tuple[(int,)]]
|
||||
+small_list = [
|
||||
+ 1,
|
||||
+]
|
||||
+list_of_types = [
|
||||
+ tuple[(int,)],
|
||||
+]
|
||||
small_set = {1}
|
||||
-set_of_types = {tuple[int,]}
|
||||
+set_of_types = {tuple[(int,)]}
|
||||
|
@ -124,8 +129,12 @@ d = tuple[
|
|||
]
|
||||
|
||||
# Remove commas for non-subscripts.
|
||||
small_list = [1]
|
||||
list_of_types = [tuple[(int,)]]
|
||||
small_list = [
|
||||
1,
|
||||
]
|
||||
list_of_types = [
|
||||
tuple[(int,)],
|
||||
]
|
||||
small_set = {1}
|
||||
set_of_types = {tuple[(int,)]}
|
||||
|
||||
|
|
|
@ -102,7 +102,10 @@ a < b > c == d
|
|||
|
||||
(
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
< [bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, ff]
|
||||
< [
|
||||
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,
|
||||
ff,
|
||||
]
|
||||
< [ccccccccccccccccccccccccccccc, dddd]
|
||||
< ddddddddddddddddddddddddddddddddddddddddddd
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue