mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 02:12:22 +00:00
Add formatting of type parameters in class and function definitions (#6161)
Part of #5062 Closes https://github.com/astral-sh/ruff/issues/5931 Implements formatting of a sequence of type parameters in a dedicated struct for reuse by classes, functions, and type aliases (preparing for #5929). Adds formatting of type parameters in class and function definitions — previously, they were just elided.
This commit is contained in:
parent
9425ed72a0
commit
1a60d1e3c6
22 changed files with 825 additions and 172 deletions
|
@ -1,6 +1,7 @@
|
||||||
use crate::node::AnyNodeRef;
|
use crate::node::AnyNodeRef;
|
||||||
use crate::{
|
use crate::{
|
||||||
Decorator, Expr, Identifier, Parameters, Ranged, StmtAsyncFunctionDef, StmtFunctionDef, Suite,
|
Decorator, Expr, Identifier, Parameters, Ranged, StmtAsyncFunctionDef, StmtFunctionDef, Suite,
|
||||||
|
TypeParams,
|
||||||
};
|
};
|
||||||
use ruff_text_size::TextRange;
|
use ruff_text_size::TextRange;
|
||||||
|
|
||||||
|
@ -79,6 +80,13 @@ impl<'a> AnyFunctionDefinition<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn type_params(self) -> Option<&'a TypeParams> {
|
||||||
|
match self {
|
||||||
|
Self::FunctionDefinition(definition) => definition.type_params.as_ref(),
|
||||||
|
Self::AsyncFunctionDefinition(definition) => definition.type_params.as_ref(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` if this is [`Self::AsyncFunctionDefinition`]
|
/// Returns `true` if this is [`Self::AsyncFunctionDefinition`]
|
||||||
pub const fn is_async(self) -> bool {
|
pub const fn is_async(self) -> bool {
|
||||||
matches!(self, Self::AsyncFunctionDefinition(_))
|
matches!(self, Self::AsyncFunctionDefinition(_))
|
||||||
|
|
|
@ -2880,6 +2880,34 @@ impl AstNode for Decorator {
|
||||||
AnyNode::from(self)
|
AnyNode::from(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl AstNode for ast::TypeParams {
|
||||||
|
fn cast(kind: AnyNode) -> Option<Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
if let AnyNode::TypeParams(node) = kind {
|
||||||
|
Some(node)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cast_ref(kind: AnyNodeRef) -> Option<&Self> {
|
||||||
|
if let AnyNodeRef::TypeParams(node) = kind {
|
||||||
|
Some(node)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any_node_ref(&self) -> AnyNodeRef {
|
||||||
|
AnyNodeRef::from(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_any_node(self) -> AnyNode {
|
||||||
|
AnyNode::from(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
impl AstNode for ast::TypeParamTypeVar {
|
impl AstNode for ast::TypeParamTypeVar {
|
||||||
fn cast(kind: AnyNode) -> Option<Self>
|
fn cast(kind: AnyNode) -> Option<Self>
|
||||||
where
|
where
|
||||||
|
@ -3531,6 +3559,11 @@ impl From<Decorator> for AnyNode {
|
||||||
AnyNode::Decorator(node)
|
AnyNode::Decorator(node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl From<TypeParams> for AnyNode {
|
||||||
|
fn from(node: TypeParams) -> Self {
|
||||||
|
AnyNode::TypeParams(node)
|
||||||
|
}
|
||||||
|
}
|
||||||
impl From<TypeParamTypeVar> for AnyNode {
|
impl From<TypeParamTypeVar> for AnyNode {
|
||||||
fn from(node: TypeParamTypeVar) -> Self {
|
fn from(node: TypeParamTypeVar) -> Self {
|
||||||
AnyNode::TypeParamTypeVar(node)
|
AnyNode::TypeParamTypeVar(node)
|
||||||
|
@ -4804,6 +4837,11 @@ impl<'a> From<&'a Decorator> for AnyNodeRef<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a ast::TypeParams> for AnyNodeRef<'a> {
|
||||||
|
fn from(node: &'a ast::TypeParams) -> Self {
|
||||||
|
AnyNodeRef::TypeParams(node)
|
||||||
|
}
|
||||||
|
}
|
||||||
impl<'a> From<&'a TypeParamTypeVar> for AnyNodeRef<'a> {
|
impl<'a> From<&'a TypeParamTypeVar> for AnyNodeRef<'a> {
|
||||||
fn from(node: &'a TypeParamTypeVar) -> Self {
|
fn from(node: &'a TypeParamTypeVar) -> Self {
|
||||||
AnyNodeRef::TypeParamTypeVar(node)
|
AnyNodeRef::TypeParamTypeVar(node)
|
||||||
|
|
|
@ -54,6 +54,7 @@ groups = {
|
||||||
"expr": "expression",
|
"expr": "expression",
|
||||||
"stmt": "statement",
|
"stmt": "statement",
|
||||||
"pattern": "pattern",
|
"pattern": "pattern",
|
||||||
|
"type_param": "type_param",
|
||||||
"other": "other",
|
"other": "other",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,3 +21,14 @@ b3 = [
|
||||||
aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa,
|
aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa,
|
||||||
aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa
|
aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Comment placement in non-empty lists
|
||||||
|
c1 = [ # trailing open bracket
|
||||||
|
# leading item
|
||||||
|
1,
|
||||||
|
|
||||||
|
# between
|
||||||
|
|
||||||
|
2, # trailing item
|
||||||
|
# leading close bracket
|
||||||
|
] # trailing close bracket
|
||||||
|
|
|
@ -43,6 +43,14 @@ class TestTrailingComment2: # trailing comment
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTrailingComment3[T]: # trailing comment
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTrailingComment4[T](A): # trailing comment
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Test:
|
class Test:
|
||||||
"""Docstring"""
|
"""Docstring"""
|
||||||
|
|
||||||
|
@ -144,3 +152,57 @@ class AltCLIPOutput(
|
||||||
# Copied from transformers.models.clip.modeling_clip.CLIPOutput with CLIP->AltCLIP
|
# Copied from transformers.models.clip.modeling_clip.CLIPOutput with CLIP->AltCLIP
|
||||||
):
|
):
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, Cccccccccccccccccccccc]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, *Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, **Cccccccccccccccccccccc]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[*Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[**Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[**P, *Ts, T]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[ # trailing bracket comment
|
||||||
|
# leading comment
|
||||||
|
A,
|
||||||
|
|
||||||
|
# in between comment
|
||||||
|
|
||||||
|
B,
|
||||||
|
# another leading comment
|
||||||
|
C,
|
||||||
|
D, # trailing comment
|
||||||
|
# leading bracket comment
|
||||||
|
]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa](B, C, D):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa](Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, Cccccccccccccccccccccccc, Ddddddddddddddddddddddddd):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[A, B, C](meta=Aaaaaaaaaaaaaaaaaaaaaa):
|
||||||
|
pass
|
||||||
|
|
|
@ -66,6 +66,52 @@ def argument_with_long_type_annotation(
|
||||||
|
|
||||||
def test(): ...
|
def test(): ...
|
||||||
|
|
||||||
|
# Type parameter empty line spacing
|
||||||
|
def test[
|
||||||
|
# comment
|
||||||
|
A,
|
||||||
|
|
||||||
|
# another
|
||||||
|
|
||||||
|
B,
|
||||||
|
](): ...
|
||||||
|
|
||||||
|
|
||||||
|
# Type parameter comments
|
||||||
|
def type_param_comments[ # trailing bracket comment
|
||||||
|
# leading comment
|
||||||
|
A,
|
||||||
|
|
||||||
|
# in between comment
|
||||||
|
|
||||||
|
B,
|
||||||
|
# another leading comment
|
||||||
|
C,
|
||||||
|
D, # trailing comment
|
||||||
|
# leading bracket comment
|
||||||
|
]():
|
||||||
|
# body comment
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Note empty type parameters is not valid syntax, e.g.
|
||||||
|
# def test[](): ...
|
||||||
|
|
||||||
|
|
||||||
|
# Different type parameter wrappings
|
||||||
|
|
||||||
|
def single_line[Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa, Bbbbbbbbbbbbbbb, Ccccccccccccccccc]():
|
||||||
|
pass
|
||||||
|
|
||||||
|
def params_on_their_own_line[Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa, Bbbbbbbbbbbbbbb, Ccccccccccc, Ddddddddddddd, Eeeeeeee]():
|
||||||
|
pass
|
||||||
|
|
||||||
|
def param_per_line[Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa, Bbbbbbbbbbbbbbb, Ccccccccccccccccc, Ddddddddddddd, Eeeeeeeeeeeeeeeee, ffffffffffff]():
|
||||||
|
pass
|
||||||
|
|
||||||
|
def single_line_trailing_comma[A, B, C,]():
|
||||||
|
pass
|
||||||
|
|
||||||
# Comment
|
# Comment
|
||||||
def with_leading_comment(): ...
|
def with_leading_comment(): ...
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ use ruff_python_ast::node::AnyNodeRef;
|
||||||
use ruff_python_ast::whitespace::indentation;
|
use ruff_python_ast::whitespace::indentation;
|
||||||
use ruff_python_ast::{
|
use ruff_python_ast::{
|
||||||
self as ast, Arguments, Comprehension, Expr, ExprAttribute, ExprBinOp, ExprIfExp, ExprSlice,
|
self as ast, Arguments, Comprehension, Expr, ExprAttribute, ExprBinOp, ExprIfExp, ExprSlice,
|
||||||
ExprStarred, MatchCase, Parameters, Ranged,
|
ExprStarred, MatchCase, Parameters, Ranged, TypeParams,
|
||||||
};
|
};
|
||||||
use ruff_python_trivia::{
|
use ruff_python_trivia::{
|
||||||
indentation_at_offset, PythonWhitespace, SimpleToken, SimpleTokenKind, SimpleTokenizer,
|
indentation_at_offset, PythonWhitespace, SimpleToken, SimpleTokenKind, SimpleTokenizer,
|
||||||
|
@ -85,6 +85,7 @@ pub(super) fn place_comment<'a>(
|
||||||
handle_leading_class_with_decorators_comment(comment, class_def)
|
handle_leading_class_with_decorators_comment(comment, class_def)
|
||||||
}
|
}
|
||||||
AnyNodeRef::StmtImportFrom(import_from) => handle_import_from_comment(comment, import_from),
|
AnyNodeRef::StmtImportFrom(import_from) => handle_import_from_comment(comment, import_from),
|
||||||
|
AnyNodeRef::TypeParams(type_params) => handle_type_params_comment(comment, type_params),
|
||||||
_ => CommentPlacement::Default(comment),
|
_ => CommentPlacement::Default(comment),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -563,6 +564,51 @@ fn handle_own_line_comment_after_branch<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attach an enclosed end-of-line comment to a set of [`TypeParams`].
|
||||||
|
///
|
||||||
|
/// For example, given:
|
||||||
|
/// ```python
|
||||||
|
/// type foo[ # comment
|
||||||
|
/// bar,
|
||||||
|
/// ] = ...
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// The comment will be attached to the [`TypeParams`] node as a dangling comment, to ensure
|
||||||
|
/// that it remains on the same line as open bracket.
|
||||||
|
fn handle_type_params_comment<'a>(
|
||||||
|
comment: DecoratedComment<'a>,
|
||||||
|
type_params: &'a TypeParams,
|
||||||
|
) -> CommentPlacement<'a> {
|
||||||
|
// The comment needs to be on the same line, but before the first type param. For example, we want
|
||||||
|
// to treat this as a dangling comment:
|
||||||
|
// ```python
|
||||||
|
// type foo[ # comment
|
||||||
|
// bar,
|
||||||
|
// baz,
|
||||||
|
// qux,
|
||||||
|
// ]
|
||||||
|
// ```
|
||||||
|
// However, this should _not_ be treated as a dangling comment:
|
||||||
|
// ```python
|
||||||
|
// type foo[bar, # comment
|
||||||
|
// baz,
|
||||||
|
// qux,
|
||||||
|
// ] = ...
|
||||||
|
// ```
|
||||||
|
// Thus, we check whether the comment is an end-of-line comment _between_ the start of the
|
||||||
|
// statement and the first type param. If so, the only possible position is immediately following
|
||||||
|
// the open parenthesis.
|
||||||
|
if comment.line_position().is_end_of_line() {
|
||||||
|
if let Some(first_type_param) = type_params.type_params.first() {
|
||||||
|
if type_params.start() < comment.start() && comment.end() < first_type_param.start() {
|
||||||
|
return CommentPlacement::dangling(comment.enclosing_node(), comment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CommentPlacement::Default(comment)
|
||||||
|
}
|
||||||
|
|
||||||
/// Attaches comments for the positional-only parameters separator `/` or the keywords-only
|
/// Attaches comments for the positional-only parameters separator `/` or the keywords-only
|
||||||
/// parameters separator `*` as dangling comments to the enclosing [`Parameters`] node.
|
/// parameters separator `*` as dangling comments to the enclosing [`Parameters`] node.
|
||||||
///
|
///
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::iter::Peekable;
|
||||||
use ruff_python_ast::{
|
use ruff_python_ast::{
|
||||||
Alias, Arguments, Comprehension, Decorator, ElifElseClause, ExceptHandler, Expr, Keyword,
|
Alias, Arguments, Comprehension, Decorator, ElifElseClause, ExceptHandler, Expr, Keyword,
|
||||||
MatchCase, Mod, Parameter, ParameterWithDefault, Parameters, Pattern, Ranged, Stmt, TypeParam,
|
MatchCase, Mod, Parameter, ParameterWithDefault, Parameters, Pattern, Ranged, Stmt, TypeParam,
|
||||||
WithItem,
|
TypeParams, WithItem,
|
||||||
};
|
};
|
||||||
use ruff_text_size::{TextRange, TextSize};
|
use ruff_text_size::{TextRange, TextSize};
|
||||||
|
|
||||||
|
@ -301,6 +301,13 @@ impl<'ast> PreorderVisitor<'ast> for CommentsVisitor<'ast> {
|
||||||
self.finish_node(elif_else_clause);
|
self.finish_node(elif_else_clause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_type_params(&mut self, type_params: &'ast TypeParams) {
|
||||||
|
if self.start_node(type_params).is_traverse() {
|
||||||
|
walk_type_params(self, type_params);
|
||||||
|
}
|
||||||
|
self.finish_node(type_params);
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_type_param(&mut self, type_param: &'ast TypeParam) {
|
fn visit_type_param(&mut self, type_param: &'ast TypeParam) {
|
||||||
if self.start_node(type_param).is_traverse() {
|
if self.start_node(type_param).is_traverse() {
|
||||||
walk_type_param(self, type_param);
|
walk_type_param(self, type_param);
|
||||||
|
|
|
@ -2939,3 +2939,163 @@ impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::ElifElseClause {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FormatRule<ast::TypeParams, PyFormatContext<'_>>
|
||||||
|
for crate::type_param::type_params::FormatTypeParams
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn fmt(
|
||||||
|
&self,
|
||||||
|
node: &ast::TypeParams,
|
||||||
|
f: &mut Formatter<PyFormatContext<'_>>,
|
||||||
|
) -> FormatResult<()> {
|
||||||
|
FormatNodeRule::<ast::TypeParams>::fmt(self, node, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::TypeParams {
|
||||||
|
type Format<'a> = FormatRefWithRule<
|
||||||
|
'a,
|
||||||
|
ast::TypeParams,
|
||||||
|
crate::type_param::type_params::FormatTypeParams,
|
||||||
|
PyFormatContext<'ast>,
|
||||||
|
>;
|
||||||
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
FormatRefWithRule::new(
|
||||||
|
self,
|
||||||
|
crate::type_param::type_params::FormatTypeParams::default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::TypeParams {
|
||||||
|
type Format = FormatOwnedWithRule<
|
||||||
|
ast::TypeParams,
|
||||||
|
crate::type_param::type_params::FormatTypeParams,
|
||||||
|
PyFormatContext<'ast>,
|
||||||
|
>;
|
||||||
|
fn into_format(self) -> Self::Format {
|
||||||
|
FormatOwnedWithRule::new(
|
||||||
|
self,
|
||||||
|
crate::type_param::type_params::FormatTypeParams::default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FormatRule<ast::TypeParamTypeVar, PyFormatContext<'_>>
|
||||||
|
for crate::type_param::type_param_type_var::FormatTypeParamTypeVar
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn fmt(
|
||||||
|
&self,
|
||||||
|
node: &ast::TypeParamTypeVar,
|
||||||
|
f: &mut Formatter<PyFormatContext<'_>>,
|
||||||
|
) -> FormatResult<()> {
|
||||||
|
FormatNodeRule::<ast::TypeParamTypeVar>::fmt(self, node, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::TypeParamTypeVar {
|
||||||
|
type Format<'a> = FormatRefWithRule<
|
||||||
|
'a,
|
||||||
|
ast::TypeParamTypeVar,
|
||||||
|
crate::type_param::type_param_type_var::FormatTypeParamTypeVar,
|
||||||
|
PyFormatContext<'ast>,
|
||||||
|
>;
|
||||||
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
FormatRefWithRule::new(
|
||||||
|
self,
|
||||||
|
crate::type_param::type_param_type_var::FormatTypeParamTypeVar::default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::TypeParamTypeVar {
|
||||||
|
type Format = FormatOwnedWithRule<
|
||||||
|
ast::TypeParamTypeVar,
|
||||||
|
crate::type_param::type_param_type_var::FormatTypeParamTypeVar,
|
||||||
|
PyFormatContext<'ast>,
|
||||||
|
>;
|
||||||
|
fn into_format(self) -> Self::Format {
|
||||||
|
FormatOwnedWithRule::new(
|
||||||
|
self,
|
||||||
|
crate::type_param::type_param_type_var::FormatTypeParamTypeVar::default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FormatRule<ast::TypeParamTypeVarTuple, PyFormatContext<'_>>
|
||||||
|
for crate::type_param::type_param_type_var_tuple::FormatTypeParamTypeVarTuple
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn fmt(
|
||||||
|
&self,
|
||||||
|
node: &ast::TypeParamTypeVarTuple,
|
||||||
|
f: &mut Formatter<PyFormatContext<'_>>,
|
||||||
|
) -> FormatResult<()> {
|
||||||
|
FormatNodeRule::<ast::TypeParamTypeVarTuple>::fmt(self, node, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::TypeParamTypeVarTuple {
|
||||||
|
type Format<'a> = FormatRefWithRule<
|
||||||
|
'a,
|
||||||
|
ast::TypeParamTypeVarTuple,
|
||||||
|
crate::type_param::type_param_type_var_tuple::FormatTypeParamTypeVarTuple,
|
||||||
|
PyFormatContext<'ast>,
|
||||||
|
>;
|
||||||
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
FormatRefWithRule::new(
|
||||||
|
self,
|
||||||
|
crate::type_param::type_param_type_var_tuple::FormatTypeParamTypeVarTuple::default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::TypeParamTypeVarTuple {
|
||||||
|
type Format = FormatOwnedWithRule<
|
||||||
|
ast::TypeParamTypeVarTuple,
|
||||||
|
crate::type_param::type_param_type_var_tuple::FormatTypeParamTypeVarTuple,
|
||||||
|
PyFormatContext<'ast>,
|
||||||
|
>;
|
||||||
|
fn into_format(self) -> Self::Format {
|
||||||
|
FormatOwnedWithRule::new(
|
||||||
|
self,
|
||||||
|
crate::type_param::type_param_type_var_tuple::FormatTypeParamTypeVarTuple::default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FormatRule<ast::TypeParamParamSpec, PyFormatContext<'_>>
|
||||||
|
for crate::type_param::type_param_param_spec::FormatTypeParamParamSpec
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn fmt(
|
||||||
|
&self,
|
||||||
|
node: &ast::TypeParamParamSpec,
|
||||||
|
f: &mut Formatter<PyFormatContext<'_>>,
|
||||||
|
) -> FormatResult<()> {
|
||||||
|
FormatNodeRule::<ast::TypeParamParamSpec>::fmt(self, node, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'ast> AsFormat<PyFormatContext<'ast>> for ast::TypeParamParamSpec {
|
||||||
|
type Format<'a> = FormatRefWithRule<
|
||||||
|
'a,
|
||||||
|
ast::TypeParamParamSpec,
|
||||||
|
crate::type_param::type_param_param_spec::FormatTypeParamParamSpec,
|
||||||
|
PyFormatContext<'ast>,
|
||||||
|
>;
|
||||||
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
FormatRefWithRule::new(
|
||||||
|
self,
|
||||||
|
crate::type_param::type_param_param_spec::FormatTypeParamParamSpec::default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'ast> IntoFormat<PyFormatContext<'ast>> for ast::TypeParamParamSpec {
|
||||||
|
type Format = FormatOwnedWithRule<
|
||||||
|
ast::TypeParamParamSpec,
|
||||||
|
crate::type_param::type_param_param_spec::FormatTypeParamParamSpec,
|
||||||
|
PyFormatContext<'ast>,
|
||||||
|
>;
|
||||||
|
fn into_format(self) -> Self::Format {
|
||||||
|
FormatOwnedWithRule::new(
|
||||||
|
self,
|
||||||
|
crate::type_param::type_param_param_spec::FormatTypeParamParamSpec::default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ pub(crate) mod other;
|
||||||
pub(crate) mod pattern;
|
pub(crate) mod pattern;
|
||||||
mod prelude;
|
mod prelude;
|
||||||
pub(crate) mod statement;
|
pub(crate) mod statement;
|
||||||
|
pub(crate) mod type_param;
|
||||||
|
|
||||||
include!("../../ruff_formatter/shared_traits.rs");
|
include!("../../ruff_formatter/shared_traits.rs");
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
use ruff_formatter::write;
|
use ruff_formatter::{write, Buffer};
|
||||||
use ruff_python_ast::{Ranged, StmtClassDef};
|
use ruff_python_ast::{Ranged, StmtClassDef};
|
||||||
use ruff_python_trivia::{lines_after, skip_trailing_trivia};
|
use ruff_python_trivia::{lines_after, skip_trailing_trivia};
|
||||||
|
|
||||||
use crate::comments::{leading_comments, trailing_comments};
|
use crate::comments::{leading_comments, trailing_comments};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::statement::suite::SuiteKind;
|
use crate::statement::suite::SuiteKind;
|
||||||
|
use crate::FormatNodeRule;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct FormatStmtClassDef;
|
pub struct FormatStmtClassDef;
|
||||||
|
@ -16,7 +17,7 @@ impl FormatNodeRule<StmtClassDef> for FormatStmtClassDef {
|
||||||
name,
|
name,
|
||||||
arguments,
|
arguments,
|
||||||
body,
|
body,
|
||||||
type_params: _,
|
type_params,
|
||||||
decorator_list,
|
decorator_list,
|
||||||
} = item;
|
} = item;
|
||||||
|
|
||||||
|
@ -58,6 +59,10 @@ impl FormatNodeRule<StmtClassDef> for FormatStmtClassDef {
|
||||||
|
|
||||||
write!(f, [text("class"), space(), name.format()])?;
|
write!(f, [text("class"), space(), name.format()])?;
|
||||||
|
|
||||||
|
if let Some(type_params) = type_params.as_deref() {
|
||||||
|
write!(f, [type_params.format()])?;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(arguments) = arguments.as_deref() {
|
if let Some(arguments) = arguments.as_deref() {
|
||||||
// Drop empty parentheses, e.g., in:
|
// Drop empty parentheses, e.g., in:
|
||||||
// ```python
|
// ```python
|
||||||
|
|
|
@ -80,15 +80,13 @@ impl FormatRule<AnyFunctionDefinition<'_>, PyFormatContext<'_>> for FormatAnyFun
|
||||||
|
|
||||||
let name = item.name();
|
let name = item.name();
|
||||||
|
|
||||||
write!(
|
write!(f, [text("def"), space(), name.format()])?;
|
||||||
f,
|
|
||||||
[
|
if let Some(type_params) = item.type_params() {
|
||||||
text("def"),
|
write!(f, [type_params.format()])?;
|
||||||
space(),
|
}
|
||||||
name.format(),
|
|
||||||
item.arguments().format(),
|
write!(f, [item.arguments().format()])?;
|
||||||
]
|
|
||||||
)?;
|
|
||||||
|
|
||||||
if let Some(return_annotation) = item.returns() {
|
if let Some(return_annotation) = item.returns() {
|
||||||
write!(
|
write!(
|
||||||
|
|
37
crates/ruff_python_formatter/src/type_param/mod.rs
Normal file
37
crates/ruff_python_formatter/src/type_param/mod.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
use crate::prelude::*;
|
||||||
|
use ruff_formatter::{FormatOwnedWithRule, FormatRefWithRule};
|
||||||
|
use ruff_python_ast::TypeParam;
|
||||||
|
|
||||||
|
pub(crate) mod type_param_param_spec;
|
||||||
|
pub(crate) mod type_param_type_var;
|
||||||
|
pub(crate) mod type_param_type_var_tuple;
|
||||||
|
pub(crate) mod type_params;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct FormatTypeParam;
|
||||||
|
|
||||||
|
impl FormatRule<TypeParam, PyFormatContext<'_>> for FormatTypeParam {
|
||||||
|
fn fmt(&self, item: &TypeParam, f: &mut PyFormatter) -> FormatResult<()> {
|
||||||
|
match item {
|
||||||
|
TypeParam::TypeVar(x) => x.format().fmt(f),
|
||||||
|
TypeParam::TypeVarTuple(x) => x.format().fmt(f),
|
||||||
|
TypeParam::ParamSpec(x) => x.format().fmt(f),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ast> AsFormat<PyFormatContext<'ast>> for TypeParam {
|
||||||
|
type Format<'a> = FormatRefWithRule<'a, TypeParam, FormatTypeParam, PyFormatContext<'ast>>;
|
||||||
|
|
||||||
|
fn format(&self) -> Self::Format<'_> {
|
||||||
|
FormatRefWithRule::new(self, FormatTypeParam)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ast> IntoFormat<PyFormatContext<'ast>> for TypeParam {
|
||||||
|
type Format = FormatOwnedWithRule<TypeParam, FormatTypeParam, PyFormatContext<'ast>>;
|
||||||
|
|
||||||
|
fn into_format(self) -> Self::Format {
|
||||||
|
FormatOwnedWithRule::new(self, FormatTypeParam)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
use crate::builders::PyFormatterExtensions;
|
||||||
|
use crate::context::PyFormatContext;
|
||||||
|
use crate::expression::parentheses::parenthesized;
|
||||||
|
use crate::prelude::*;
|
||||||
|
use ruff_formatter::{Format, FormatResult};
|
||||||
|
use ruff_python_ast::TypeParam;
|
||||||
|
use ruff_text_size::TextSize;
|
||||||
|
|
||||||
|
pub(crate) struct FormatTypeParamsClause<'a> {
|
||||||
|
pub(crate) sequence_end: TextSize,
|
||||||
|
pub(crate) type_params: &'a Vec<TypeParam>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Formats a sequence of [`TypeParam`] nodes.
|
||||||
|
impl Format<PyFormatContext<'_>> for FormatTypeParamsClause<'_> {
|
||||||
|
fn fmt(&self, f: &mut Formatter<PyFormatContext<'_>>) -> FormatResult<()> {
|
||||||
|
if self.type_params.is_empty() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let items = format_with(|f| {
|
||||||
|
f.join_comma_separated(self.sequence_end)
|
||||||
|
.nodes(self.type_params.iter())
|
||||||
|
.finish()
|
||||||
|
});
|
||||||
|
|
||||||
|
parenthesized("[", &items, "]").fmt(f)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
use crate::{AsFormat, FormatNodeRule, PyFormatter};
|
||||||
|
use ruff_formatter::prelude::text;
|
||||||
|
use ruff_formatter::{write, Buffer, FormatResult};
|
||||||
|
use ruff_python_ast::TypeParamParamSpec;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct FormatTypeParamParamSpec;
|
||||||
|
|
||||||
|
impl FormatNodeRule<TypeParamParamSpec> for FormatTypeParamParamSpec {
|
||||||
|
fn fmt_fields(&self, item: &TypeParamParamSpec, f: &mut PyFormatter) -> FormatResult<()> {
|
||||||
|
let TypeParamParamSpec { range: _, name } = item;
|
||||||
|
write!(f, [text("**"), name.format()])
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
use crate::{AsFormat, FormatNodeRule, PyFormatter};
|
||||||
|
use ruff_formatter::prelude::{space, text};
|
||||||
|
use ruff_formatter::{write, Buffer, Format, FormatResult};
|
||||||
|
use ruff_python_ast::TypeParamTypeVar;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct FormatTypeParamTypeVar;
|
||||||
|
|
||||||
|
impl FormatNodeRule<TypeParamTypeVar> for FormatTypeParamTypeVar {
|
||||||
|
fn fmt_fields(&self, item: &TypeParamTypeVar, f: &mut PyFormatter) -> FormatResult<()> {
|
||||||
|
let TypeParamTypeVar {
|
||||||
|
range: _,
|
||||||
|
name,
|
||||||
|
bound,
|
||||||
|
} = item;
|
||||||
|
name.format().fmt(f)?;
|
||||||
|
if let Some(bound) = bound {
|
||||||
|
write!(f, [text(":"), space(), bound.format()])?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
use crate::{AsFormat, FormatNodeRule, PyFormatter};
|
||||||
|
use ruff_formatter::prelude::text;
|
||||||
|
use ruff_formatter::{write, Buffer, FormatResult};
|
||||||
|
use ruff_python_ast::TypeParamTypeVarTuple;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct FormatTypeParamTypeVarTuple;
|
||||||
|
|
||||||
|
impl FormatNodeRule<TypeParamTypeVarTuple> for FormatTypeParamTypeVarTuple {
|
||||||
|
fn fmt_fields(&self, item: &TypeParamTypeVarTuple, f: &mut PyFormatter) -> FormatResult<()> {
|
||||||
|
let TypeParamTypeVarTuple { range: _, name } = item;
|
||||||
|
write!(f, [text("*"), name.format()])
|
||||||
|
}
|
||||||
|
}
|
41
crates/ruff_python_formatter/src/type_param/type_params.rs
Normal file
41
crates/ruff_python_formatter/src/type_param/type_params.rs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
use crate::builders::PyFormatterExtensions;
|
||||||
|
use crate::comments::trailing_comments;
|
||||||
|
use crate::expression::parentheses::parenthesized;
|
||||||
|
use crate::prelude::*;
|
||||||
|
use ruff_formatter::write;
|
||||||
|
use ruff_formatter::FormatResult;
|
||||||
|
use ruff_python_ast::node::AstNode;
|
||||||
|
|
||||||
|
use ruff_python_ast::TypeParams;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct FormatTypeParams;
|
||||||
|
|
||||||
|
/// Formats a sequence of [`TypeParam`] nodes.
|
||||||
|
impl FormatNodeRule<TypeParams> for FormatTypeParams {
|
||||||
|
fn fmt_fields(&self, item: &TypeParams, f: &mut PyFormatter) -> FormatResult<()> {
|
||||||
|
// A dangling comment indicates a comment on the same line as the opening bracket, e.g.:
|
||||||
|
// ```python
|
||||||
|
// type foo[ # This type parameter clause has a dangling comment.
|
||||||
|
// a,
|
||||||
|
// b,
|
||||||
|
// c,
|
||||||
|
// ] = ...
|
||||||
|
let comments = f.context().comments().clone();
|
||||||
|
let dangling_comments = comments.dangling_comments(item.as_any_node_ref());
|
||||||
|
write!(f, [trailing_comments(dangling_comments)])?;
|
||||||
|
|
||||||
|
let items = format_with(|f| {
|
||||||
|
f.join_comma_separated(item.range.end())
|
||||||
|
.nodes(item.type_params.iter())
|
||||||
|
.finish()
|
||||||
|
});
|
||||||
|
|
||||||
|
parenthesized("[", &items, "]").fmt(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fmt_dangling_comments(&self, _node: &TypeParams, _f: &mut PyFormatter) -> FormatResult<()> {
|
||||||
|
// Handled in `fmt_fields`
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,159 +0,0 @@
|
||||||
---
|
|
||||||
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
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,17 @@ b3 = [
|
||||||
aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa,
|
aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa,
|
||||||
aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa
|
aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Comment placement in non-empty lists
|
||||||
|
c1 = [ # trailing open bracket
|
||||||
|
# leading item
|
||||||
|
1,
|
||||||
|
|
||||||
|
# between
|
||||||
|
|
||||||
|
2, # trailing item
|
||||||
|
# leading close bracket
|
||||||
|
] # trailing close bracket
|
||||||
```
|
```
|
||||||
|
|
||||||
## Output
|
## Output
|
||||||
|
@ -53,6 +64,16 @@ b3 = [
|
||||||
aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa,
|
aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa,
|
||||||
aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa,
|
aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Comment placement in non-empty lists
|
||||||
|
c1 = [
|
||||||
|
# trailing open bracket
|
||||||
|
# leading item
|
||||||
|
1,
|
||||||
|
# between
|
||||||
|
2, # trailing item
|
||||||
|
# leading close bracket
|
||||||
|
] # trailing close bracket
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,14 @@ class TestTrailingComment2: # trailing comment
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTrailingComment3[T]: # trailing comment
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTrailingComment4[T](A): # trailing comment
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Test:
|
class Test:
|
||||||
"""Docstring"""
|
"""Docstring"""
|
||||||
|
|
||||||
|
@ -150,6 +158,60 @@ class AltCLIPOutput(
|
||||||
# Copied from transformers.models.clip.modeling_clip.CLIPOutput with CLIP->AltCLIP
|
# Copied from transformers.models.clip.modeling_clip.CLIPOutput with CLIP->AltCLIP
|
||||||
):
|
):
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, Cccccccccccccccccccccc]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, *Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, **Cccccccccccccccccccccc]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[*Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[**Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[**P, *Ts, T]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[ # trailing bracket comment
|
||||||
|
# leading comment
|
||||||
|
A,
|
||||||
|
|
||||||
|
# in between comment
|
||||||
|
|
||||||
|
B,
|
||||||
|
# another leading comment
|
||||||
|
C,
|
||||||
|
D, # trailing comment
|
||||||
|
# leading bracket comment
|
||||||
|
]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa](B, C, D):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa](Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, Cccccccccccccccccccccccc, Ddddddddddddddddddddddddd):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[A, B, C](meta=Aaaaaaaaaaaaaaaaaaaaaa):
|
||||||
|
pass
|
||||||
```
|
```
|
||||||
|
|
||||||
## Output
|
## Output
|
||||||
|
@ -216,6 +278,14 @@ class TestTrailingComment2: # trailing comment
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTrailingComment3[T]: # trailing comment
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTrailingComment4[T](A): # trailing comment
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Test:
|
class Test:
|
||||||
"""Docstring"""
|
"""Docstring"""
|
||||||
|
|
||||||
|
@ -318,6 +388,77 @@ class AltCLIPOutput(
|
||||||
# Copied from transformers.models.clip.modeling_clip.CLIPOutput with CLIP->AltCLIP
|
# Copied from transformers.models.clip.modeling_clip.CLIPOutput with CLIP->AltCLIP
|
||||||
):
|
):
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[
|
||||||
|
Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
|
||||||
|
Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,
|
||||||
|
Cccccccccccccccccccccc,
|
||||||
|
]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[
|
||||||
|
Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
|
||||||
|
*Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,
|
||||||
|
**Cccccccccccccccccccccc,
|
||||||
|
]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[
|
||||||
|
Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[
|
||||||
|
*Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[
|
||||||
|
**Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[**P, *Ts, T]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[ # trailing bracket comment
|
||||||
|
# leading comment
|
||||||
|
A,
|
||||||
|
# in between comment
|
||||||
|
B,
|
||||||
|
# another leading comment
|
||||||
|
C,
|
||||||
|
D, # trailing comment
|
||||||
|
# leading bracket comment
|
||||||
|
]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[
|
||||||
|
Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
](B, C, D):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[
|
||||||
|
Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
](
|
||||||
|
Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,
|
||||||
|
Cccccccccccccccccccccccc,
|
||||||
|
Ddddddddddddddddddddddddd,
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestTypeParams[A, B, C](meta=Aaaaaaaaaaaaaaaaaaaaaa):
|
||||||
|
pass
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,52 @@ def argument_with_long_type_annotation(
|
||||||
|
|
||||||
def test(): ...
|
def test(): ...
|
||||||
|
|
||||||
|
# Type parameter empty line spacing
|
||||||
|
def test[
|
||||||
|
# comment
|
||||||
|
A,
|
||||||
|
|
||||||
|
# another
|
||||||
|
|
||||||
|
B,
|
||||||
|
](): ...
|
||||||
|
|
||||||
|
|
||||||
|
# Type parameter comments
|
||||||
|
def type_param_comments[ # trailing bracket comment
|
||||||
|
# leading comment
|
||||||
|
A,
|
||||||
|
|
||||||
|
# in between comment
|
||||||
|
|
||||||
|
B,
|
||||||
|
# another leading comment
|
||||||
|
C,
|
||||||
|
D, # trailing comment
|
||||||
|
# leading bracket comment
|
||||||
|
]():
|
||||||
|
# body comment
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Note empty type parameters is not valid syntax, e.g.
|
||||||
|
# def test[](): ...
|
||||||
|
|
||||||
|
|
||||||
|
# Different type parameter wrappings
|
||||||
|
|
||||||
|
def single_line[Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa, Bbbbbbbbbbbbbbb, Ccccccccccccccccc]():
|
||||||
|
pass
|
||||||
|
|
||||||
|
def params_on_their_own_line[Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa, Bbbbbbbbbbbbbbb, Ccccccccccc, Ddddddddddddd, Eeeeeeee]():
|
||||||
|
pass
|
||||||
|
|
||||||
|
def param_per_line[Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa, Bbbbbbbbbbbbbbb, Ccccccccccccccccc, Ddddddddddddd, Eeeeeeeeeeeeeeeee, ffffffffffff]():
|
||||||
|
pass
|
||||||
|
|
||||||
|
def single_line_trailing_comma[A, B, C,]():
|
||||||
|
pass
|
||||||
|
|
||||||
# Comment
|
# Comment
|
||||||
def with_leading_comment(): ...
|
def with_leading_comment(): ...
|
||||||
|
|
||||||
|
@ -353,6 +399,70 @@ def test():
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
|
# Type parameter empty line spacing
|
||||||
|
def test[
|
||||||
|
# comment
|
||||||
|
A,
|
||||||
|
# another
|
||||||
|
B,
|
||||||
|
]():
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
# Type parameter comments
|
||||||
|
def type_param_comments[ # trailing bracket comment
|
||||||
|
# leading comment
|
||||||
|
A,
|
||||||
|
# in between comment
|
||||||
|
B,
|
||||||
|
# another leading comment
|
||||||
|
C,
|
||||||
|
D, # trailing comment
|
||||||
|
# leading bracket comment
|
||||||
|
]():
|
||||||
|
# body comment
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Note empty type parameters is not valid syntax, e.g.
|
||||||
|
# def test[](): ...
|
||||||
|
|
||||||
|
|
||||||
|
# Different type parameter wrappings
|
||||||
|
|
||||||
|
def single_line[Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa, Bbbbbbbbbbbbbbb, Ccccccccccccccccc]():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def params_on_their_own_line[
|
||||||
|
Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
|
||||||
|
Bbbbbbbbbbbbbbb,
|
||||||
|
Ccccccccccc,
|
||||||
|
Ddddddddddddd,
|
||||||
|
Eeeeeeee,
|
||||||
|
]():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def param_per_line[
|
||||||
|
Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
|
||||||
|
Bbbbbbbbbbbbbbb,
|
||||||
|
Ccccccccccccccccc,
|
||||||
|
Ddddddddddddd,
|
||||||
|
Eeeeeeeeeeeeeeeee,
|
||||||
|
ffffffffffff,
|
||||||
|
]():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def single_line_trailing_comma[
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
C,
|
||||||
|
]():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
# Comment
|
# Comment
|
||||||
def with_leading_comment():
|
def with_leading_comment():
|
||||||
...
|
...
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue