Type alias stub for formatter (#5880)

**Summary** This replaces the `todo!()` with a type alias stub in the
formatter. I added the tests from
704eb40108/parser/src/parser.rs (L901-L936)
as ruff python formatter tests.

**Test Plan** None, testing is part of the actual implementation
This commit is contained in:
konsti 2023-07-19 17:28:07 +02:00 committed by GitHub
parent a51606a10a
commit a227775f62
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 748 additions and 1 deletions

View file

@ -0,0 +1,5 @@
type A=int
type Gen[T]=list[T]
type = aliased
print(type(42))

View file

@ -0,0 +1,5 @@
type A = int
type Gen[T] = list[T]
type = aliased
print(type(42))

View file

@ -0,0 +1,13 @@
def func [T ](): pass
async def func [ T ] (): pass
class C[ T ] : pass
def all_in[T : int,U : (bytes, str),* Ts,**P](): pass
def really_long[WhatIsTheLongestTypeVarNameYouCanThinkOfEnoughToMakeBlackSplitThisLine](): pass
def even_longer[WhatIsTheLongestTypeVarNameYouCanThinkOfEnoughToMakeBlackSplitThisLine: WhatIfItHadABound](): pass
def it_gets_worse[WhatIsTheLongestTypeVarNameYouCanThinkOfEnoughToMakeBlackSplitThisLine, ItCouldBeGenericOverMultipleTypeVars](): pass
def magic[Trailing, Comma,](): pass

View file

@ -0,0 +1,40 @@
def func[T]():
pass
async def func[T]():
pass
class C[T]:
pass
def all_in[T: int, U: (bytes, str), *Ts, **P]():
pass
def really_long[
WhatIsTheLongestTypeVarNameYouCanThinkOfEnoughToMakeBlackSplitThisLine
]():
pass
def even_longer[
WhatIsTheLongestTypeVarNameYouCanThinkOfEnoughToMakeBlackSplitThisLine: WhatIfItHadABound
]():
pass
def it_gets_worse[
WhatIsTheLongestTypeVarNameYouCanThinkOfEnoughToMakeBlackSplitThisLine,
ItCouldBeGenericOverMultipleTypeVars,
]():
pass
def magic[
Trailing,
Comma,
]():
pass

View file

@ -154,6 +154,9 @@ class Test:
not parsed.hostname.strip()):
pass
a = "type comment with trailing space" # type: str
#######################
### SECTION COMMENT ###
#######################

View file

@ -162,6 +162,8 @@ class Test:
pass
a = "type comment with trailing space" # type: str
#######################
### SECTION COMMENT ###
#######################

View file

@ -0,0 +1,20 @@
def f(): # type: ignore
...
class x: # some comment
...
class y:
... # comment
# whitespace doesn't matter (note the next line has a trailing space and tab)
class z:
...
def g():
# hi
...
def h():
...
# bye

View file

@ -0,0 +1,18 @@
def f(): # type: ignore
...
class x: # some comment
...
class y: ... # comment
# whitespace doesn't matter (note the next line has a trailing space and tab)
class z: ...
def g():
# hi
...
def h():
...
# bye

View file

@ -0,0 +1,21 @@
# This is a regression test. Issue #3737
a = ( # type: ignore
int( # type: ignore
int( # type: ignore
int( # type: ignore
6
)
)
)
)
b = (
int(
6
)
)
print( "111") # type: ignore
print( "111" ) # type: ignore
print( "111" ) # type: ignore

View file

@ -0,0 +1,15 @@
# This is a regression test. Issue #3737
a = ( # type: ignore
int( # type: ignore
int( # type: ignore
int(6) # type: ignore
)
)
)
b = int(6)
print("111") # type: ignore
print("111") # type: ignore
print("111") # type: ignore

View file

@ -49,6 +49,7 @@ FIXTURE_SETS = [
"py_39",
"py_310",
"py_311",
"py_312",
"simple_cases",
"miscellaneous",
".",

View file

@ -0,0 +1,38 @@
# Copied from https://github.com/RustPython/Parser/blob/704eb40108239a8faf9bd1d4217e8dad0ac7edb3/parser/src/parser.rs#L901-L936
type X = int
type X = int | str
type X = int | "ForwardRefY"
type X[T] = T | list[X[T]] # recursive
type X[T] = int
type X[T] = list[T] | set[T]
type X[T, *Ts, **P] = (T, Ts, P)
type X[T: int, *Ts, **P] = (T, Ts, P)
type X[T: (int, str), *Ts, **P] = (T, Ts, P)
# soft keyword as alias name
type type = int
type match = int
type case = int
# soft keyword as value
type foo = type
type foo = match
type foo = case
# multine definitions
type \
X = int
type X \
= int
type X = \
int
type X = (
int
)
type \
X[T] = T
type X \
[T] = T
type X[T] \
= T

View file

@ -361,6 +361,46 @@ impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::StmtDelete {
}
}
impl FormatRule<ast::StmtTypeAlias, PyFormatContext<'_>>
for crate::statement::stmt_type_alias::FormatStmtTypeAlias
{
#[inline]
fn fmt(
&self,
node: &ast::StmtTypeAlias,
f: &mut Formatter<PyFormatContext<'_>>,
) -> FormatResult<()> {
FormatNodeRule::<ast::StmtTypeAlias>::fmt(self, node, f)
}
}
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::StmtTypeAlias {
type Format<'a> = FormatRefWithRule<
'a,
ast::StmtTypeAlias,
crate::statement::stmt_type_alias::FormatStmtTypeAlias,
PyFormatContext<'ast>,
>;
fn format(&self) -> Self::Format<'_> {
FormatRefWithRule::new(
self,
crate::statement::stmt_type_alias::FormatStmtTypeAlias::default(),
)
}
}
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::StmtTypeAlias {
type Format = FormatOwnedWithRule<
ast::StmtTypeAlias,
crate::statement::stmt_type_alias::FormatStmtTypeAlias,
PyFormatContext<'ast>,
>;
fn into_format(self) -> Self::Format {
FormatOwnedWithRule::new(
self,
crate::statement::stmt_type_alias::FormatStmtTypeAlias::default(),
)
}
}
impl FormatRule<ast::StmtAssign, PyFormatContext<'_>>
for crate::statement::stmt_assign::FormatStmtAssign
{

View file

@ -27,6 +27,7 @@ pub(crate) mod stmt_raise;
pub(crate) mod stmt_return;
pub(crate) mod stmt_try;
pub(crate) mod stmt_try_star;
pub(crate) mod stmt_type_alias;
pub(crate) mod stmt_while;
pub(crate) mod stmt_with;
pub(crate) mod suite;
@ -64,7 +65,7 @@ impl FormatRule<Stmt, PyFormatContext<'_>> for FormatStmt {
Stmt::Pass(x) => x.format().fmt(f),
Stmt::Break(x) => x.format().fmt(f),
Stmt::Continue(x) => x.format().fmt(f),
Stmt::TypeAlias(_) => todo!(),
Stmt::TypeAlias(x) => x.format().fmt(f),
}
}
}

View file

@ -0,0 +1,17 @@
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter};
use ruff_formatter::{write, Buffer, FormatResult};
use rustpython_parser::ast::StmtTypeAlias;
#[derive(Default)]
pub struct FormatStmtTypeAlias;
impl FormatNodeRule<StmtTypeAlias> for FormatStmtTypeAlias {
fn fmt_fields(&self, _item: &StmtTypeAlias, f: &mut PyFormatter) -> FormatResult<()> {
write!(
f,
[not_yet_implemented_custom_text(
"type NOT_YET_IMPLEMENTED_type_alias = int"
)]
)
}
}

View file

@ -0,0 +1,50 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_312/type_aliases.py
---
## Input
```py
type A=int
type Gen[T]=list[T]
type = aliased
print(type(42))
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,5 +1,5 @@
-type A = int
-type Gen[T] = list[T]
+type NOT_YET_IMPLEMENTED_type_alias = int
+type NOT_YET_IMPLEMENTED_type_alias = int
type = aliased
print(type(42))
```
## Ruff Output
```py
type NOT_YET_IMPLEMENTED_type_alias = int
type NOT_YET_IMPLEMENTED_type_alias = int
type = aliased
print(type(42))
```
## Black Output
```py
type A = int
type Gen[T] = list[T]
type = aliased
print(type(42))
```

View file

@ -0,0 +1,159 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/py_312/type_params.py
---
## Input
```py
def func [T ](): pass
async def func [ T ] (): pass
class C[ T ] : pass
def all_in[T : int,U : (bytes, str),* Ts,**P](): pass
def really_long[WhatIsTheLongestTypeVarNameYouCanThinkOfEnoughToMakeBlackSplitThisLine](): pass
def even_longer[WhatIsTheLongestTypeVarNameYouCanThinkOfEnoughToMakeBlackSplitThisLine: WhatIfItHadABound](): pass
def it_gets_worse[WhatIsTheLongestTypeVarNameYouCanThinkOfEnoughToMakeBlackSplitThisLine, ItCouldBeGenericOverMultipleTypeVars](): pass
def magic[Trailing, Comma,](): pass
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,40 +1,30 @@
-def func[T]():
+def func():
pass
-async def func[T]():
+async def func():
pass
-class C[T]:
+class C:
pass
-def all_in[T: int, U: (bytes, str), *Ts, **P]():
+def all_in():
pass
-def really_long[
- WhatIsTheLongestTypeVarNameYouCanThinkOfEnoughToMakeBlackSplitThisLine
-]():
+def really_long():
pass
-def even_longer[
- WhatIsTheLongestTypeVarNameYouCanThinkOfEnoughToMakeBlackSplitThisLine: WhatIfItHadABound
-]():
+def even_longer():
pass
-def it_gets_worse[
- WhatIsTheLongestTypeVarNameYouCanThinkOfEnoughToMakeBlackSplitThisLine,
- ItCouldBeGenericOverMultipleTypeVars,
-]():
+def it_gets_worse():
pass
-def magic[
- Trailing,
- Comma,
-]():
+def magic():
pass
```
## Ruff Output
```py
def func():
pass
async def func():
pass
class C:
pass
def all_in():
pass
def really_long():
pass
def even_longer():
pass
def it_gets_worse():
pass
def magic():
pass
```
## Black Output
```py
def func[T]():
pass
async def func[T]():
pass
class C[T]:
pass
def all_in[T: int, U: (bytes, str), *Ts, **P]():
pass
def really_long[
WhatIsTheLongestTypeVarNameYouCanThinkOfEnoughToMakeBlackSplitThisLine
]():
pass
def even_longer[
WhatIsTheLongestTypeVarNameYouCanThinkOfEnoughToMakeBlackSplitThisLine: WhatIfItHadABound
]():
pass
def it_gets_worse[
WhatIsTheLongestTypeVarNameYouCanThinkOfEnoughToMakeBlackSplitThisLine,
ItCouldBeGenericOverMultipleTypeVars,
]():
pass
def magic[
Trailing,
Comma,
]():
pass
```

View file

@ -161,6 +161,9 @@ class Test:
not parsed.hostname.strip()):
pass
a = "type comment with trailing space" # type: str
#######################
### SECTION COMMENT ###
#######################
@ -444,6 +447,8 @@ class Test:
pass
a = "type comment with trailing space" # type: str
#######################
### SECTION COMMENT ###
#######################
@ -622,6 +627,8 @@ class Test:
pass
a = "type comment with trailing space" # type: str
#######################
### SECTION COMMENT ###
#######################

View file

@ -0,0 +1,121 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/ignore_pyi.py
---
## Input
```py
def f(): # type: ignore
...
class x: # some comment
...
class y:
... # comment
# whitespace doesn't matter (note the next line has a trailing space and tab)
class z:
...
def g():
# hi
...
def h():
...
# bye
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,18 +1,26 @@
def f(): # type: ignore
...
-class x: # some comment
+
+class x:
+ # some comment
...
-class y: ... # comment
+class y:
+ ... # comment
+
+
# whitespace doesn't matter (note the next line has a trailing space and tab)
-class z: ...
+class z:
+ ...
+
def g():
# hi
...
+
def h():
...
# bye
```
## Ruff Output
```py
def f(): # type: ignore
...
class x:
# some comment
...
class y:
... # comment
# whitespace doesn't matter (note the next line has a trailing space and tab)
class z:
...
def g():
# hi
...
def h():
...
# bye
```
## Black Output
```py
def f(): # type: ignore
...
class x: # some comment
...
class y: ... # comment
# whitespace doesn't matter (note the next line has a trailing space and tab)
class z: ...
def g():
# hi
...
def h():
...
# bye
```

View file

@ -0,0 +1,89 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/black/simple_cases/multiline_consecutive_open_parentheses_ignore.py
---
## Input
```py
# This is a regression test. Issue #3737
a = ( # type: ignore
int( # type: ignore
int( # type: ignore
int( # type: ignore
6
)
)
)
)
b = (
int(
6
)
)
print( "111") # type: ignore
print( "111" ) # type: ignore
print( "111" ) # type: ignore
```
## Black Differences
```diff
--- Black
+++ Ruff
@@ -1,10 +1,8 @@
# This is a regression test. Issue #3737
-a = ( # type: ignore
+a = int( # type: ignore # type: ignore
int( # type: ignore
- int( # type: ignore
- int(6) # type: ignore
- )
+ int(6) # type: ignore
)
)
```
## Ruff Output
```py
# This is a regression test. Issue #3737
a = int( # type: ignore # type: ignore
int( # type: ignore
int(6) # type: ignore
)
)
b = int(6)
print("111") # type: ignore
print("111") # type: ignore
print("111") # type: ignore
```
## Black Output
```py
# This is a regression test. Issue #3737
a = ( # type: ignore
int( # type: ignore
int( # type: ignore
int(6) # type: ignore
)
)
)
b = int(6)
print("111") # type: ignore
print("111") # type: ignore
print("111") # type: ignore
```

View file

@ -0,0 +1,82 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/type_alias.py
---
## Input
```py
# Copied from https://github.com/RustPython/Parser/blob/704eb40108239a8faf9bd1d4217e8dad0ac7edb3/parser/src/parser.rs#L901-L936
type X = int
type X = int | str
type X = int | "ForwardRefY"
type X[T] = T | list[X[T]] # recursive
type X[T] = int
type X[T] = list[T] | set[T]
type X[T, *Ts, **P] = (T, Ts, P)
type X[T: int, *Ts, **P] = (T, Ts, P)
type X[T: (int, str), *Ts, **P] = (T, Ts, P)
# soft keyword as alias name
type type = int
type match = int
type case = int
# soft keyword as value
type foo = type
type foo = match
type foo = case
# multine definitions
type \
X = int
type X \
= int
type X = \
int
type X = (
int
)
type \
X[T] = T
type X \
[T] = T
type X[T] \
= T
```
## Output
```py
# Copied from https://github.com/RustPython/Parser/blob/704eb40108239a8faf9bd1d4217e8dad0ac7edb3/parser/src/parser.rs#L901-L936
type NOT_YET_IMPLEMENTED_type_alias = int
type NOT_YET_IMPLEMENTED_type_alias = int
type NOT_YET_IMPLEMENTED_type_alias = int
type NOT_YET_IMPLEMENTED_type_alias = int # recursive
type NOT_YET_IMPLEMENTED_type_alias = int
type NOT_YET_IMPLEMENTED_type_alias = int
type NOT_YET_IMPLEMENTED_type_alias = int
type NOT_YET_IMPLEMENTED_type_alias = int
type NOT_YET_IMPLEMENTED_type_alias = int
# soft keyword as alias name
type NOT_YET_IMPLEMENTED_type_alias = int
type NOT_YET_IMPLEMENTED_type_alias = int
type NOT_YET_IMPLEMENTED_type_alias = int
# soft keyword as value
type NOT_YET_IMPLEMENTED_type_alias = int
type NOT_YET_IMPLEMENTED_type_alias = int
type NOT_YET_IMPLEMENTED_type_alias = int
# multine definitions
type NOT_YET_IMPLEMENTED_type_alias = int
type NOT_YET_IMPLEMENTED_type_alias = int
type NOT_YET_IMPLEMENTED_type_alias = int
type NOT_YET_IMPLEMENTED_type_alias = int
type NOT_YET_IMPLEMENTED_type_alias = int
type NOT_YET_IMPLEMENTED_type_alias = int
type NOT_YET_IMPLEMENTED_type_alias = int
```