Skip to content

Commit b94494b

Browse files
authored
Support for RF 7.2 GROUP syntax (#733)
1 parent 3bf2f4d commit b94494b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+645
-73
lines changed

robotidy/api.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""
22
Methods for transforming Robot Framework ast model programmatically.
33
"""
4+
45
from __future__ import annotations
56

67
from pathlib import Path
@@ -37,7 +38,8 @@ def transform_model(model, root_dir: str, output: str | None = None, **kwargs) -
3738
"""
3839
robotidy_class = get_robotidy(root_dir, output, **kwargs)
3940
disabler_finder = disablers.RegisterDisablers(
40-
robotidy_class.config.formatting.start_line, robotidy_class.config.formatting.end_line
41+
robotidy_class.config.formatting.start_line,
42+
robotidy_class.config.formatting.end_line,
4143
)
4244
disabler_finder.visit(model)
4345
if disabler_finder.is_disabled_in_file(disablers.ALL_TRANSFORMERS):

robotidy/app.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ def transform_files(self):
6161
self.output_diff(model_path, old_model, new_model)
6262
changed_files += 1
6363
except DataError as err:
64-
click.echo(f"Failed to decode {source} with an error: {err}\nSkipping file", err=True)
64+
click.echo(
65+
f"Failed to decode {source} with an error: {err}\nSkipping file",
66+
err=True,
67+
)
6568
changed_files = previous_changed_files
6669
skipped_files += 1
6770
return self.formatting_result(all_files, changed_files, skipped_files, stdin)
@@ -141,7 +144,12 @@ def get_line_ending(self, path: str):
141144
return f.newlines[0]
142145
return self.config.formatting.line_sep
143146

144-
def output_diff(self, path: str, old_model: misc.StatementLinesCollector, new_model: misc.StatementLinesCollector):
147+
def output_diff(
148+
self,
149+
path: str,
150+
old_model: misc.StatementLinesCollector,
151+
new_model: misc.StatementLinesCollector,
152+
):
145153
if not self.config.show_diff:
146154
return
147155
old = [l + "\n" for l in old_model.text.splitlines()]

robotidy/cli.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@
5555
"--endline",
5656
],
5757
},
58-
{"name": "File exclusion", "options": ["--exclude", "--extend-exclude", "--skip-gitignore"]},
58+
{
59+
"name": "File exclusion",
60+
"options": ["--exclude", "--extend-exclude", "--skip-gitignore"],
61+
},
5962
skip.option_group,
6063
{
6164
"name": "Other",
@@ -124,7 +127,11 @@ def print_transformer_docs(transformer):
124127
@decorators.optional_rich
125128
def print_description(name: str, target_version: int):
126129
# TODO: --desc works only for default transformers, it should also print custom transformer desc
127-
transformers = load_transformers(TransformConfigMap([], [], []), allow_disabled=True, target_version=target_version)
130+
transformers = load_transformers(
131+
TransformConfigMap([], [], []),
132+
allow_disabled=True,
133+
target_version=target_version,
134+
)
128135
transformer_by_names = {transformer.name: transformer for transformer in transformers}
129136
if name == "all":
130137
for transformer in transformers:
@@ -159,7 +166,11 @@ def print_transformers_list(global_config: config_module.MainConfig):
159166
table = Table(title="Transformers", header_style="bold red")
160167
table.add_column("Name", justify="left", no_wrap=True)
161168
table.add_column("Enabled")
162-
transformers = load_transformers(TransformConfigMap([], [], []), allow_disabled=True, target_version=target_version)
169+
transformers = load_transformers(
170+
TransformConfigMap([], [], []),
171+
allow_disabled=True,
172+
target_version=target_version,
173+
)
163174
transformers.extend(_load_external_transformers(transformers, config.transformers_config, target_version))
164175

165176
for transformer in transformers:
@@ -194,7 +205,11 @@ def generate_config(global_config: config_module.MainConfig):
194205
raise exceptions.MissingOptionalTomliWDependencyError()
195206
target_version = global_config.default.target_version
196207
config = global_config.default_loaded
197-
transformers = load_transformers(TransformConfigMap([], [], []), allow_disabled=True, target_version=target_version)
208+
transformers = load_transformers(
209+
TransformConfigMap([], [], []),
210+
allow_disabled=True,
211+
target_version=target_version,
212+
)
198213
transformers.extend(_load_external_transformers(transformers, config.transformers_config, target_version))
199214

200215
toml_config = {

robotidy/config.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,12 @@ def convert_transformers_config(
9898
is_config: bool = False,
9999
) -> list[TransformConfig]:
100100
return [
101-
TransformConfig(tr, force_include=force_included, custom_transformer=custom_transformer, is_config=is_config)
101+
TransformConfig(
102+
tr,
103+
force_include=force_included,
104+
custom_transformer=custom_transformer,
105+
is_config=is_config,
106+
)
102107
for tr in config.get(param_name, ())
103108
]
104109

@@ -186,7 +191,10 @@ def from_config_file(self, config: dict, config_path: Path) -> "RawConfig":
186191
Dictionary key:values needs to be normalized and parsed to correct types.
187192
"""
188193
options_map = map_class_fields_with_their_types(self)
189-
parsed_config = {"defined_in_config": {"defined_in_config", "config_path"}, "config_path": config_path}
194+
parsed_config = {
195+
"defined_in_config": {"defined_in_config", "config_path"},
196+
"config_path": config_path,
197+
}
190198
for key, value in config.items():
191199
# workaround to be able to use two option names for same action - backward compatibility change
192200
if key == "load_transformers":
@@ -206,7 +214,10 @@ def from_config_file(self, config: dict, config_path: Path) -> "RawConfig":
206214
parsed_config[key] = [convert_transform_config(val, key) for val in value]
207215
elif key == "src":
208216
parsed_config[key] = tuple(value)
209-
elif value_type in ("Pattern", Pattern): # future typing for 3.8 provides type as str
217+
elif value_type in (
218+
"Pattern",
219+
Pattern,
220+
): # future typing for 3.8 provides type as str
210221
parsed_config[key] = misc.validate_regex(value)
211222
else:
212223
parsed_config[key] = value
@@ -273,7 +284,10 @@ def get_sources(self, sources: tuple[str, ...]) -> tuple[str, ...] | None:
273284

274285
def get_sources_with_configs(self):
275286
sources = files.get_paths(
276-
self.sources, self.default.exclude, self.default.extend_exclude, self.default.skip_gitignore
287+
self.sources,
288+
self.default.exclude,
289+
self.default.extend_exclude,
290+
self.default.skip_gitignore,
277291
)
278292
for source in sources:
279293
if self.default.config:

robotidy/disablers.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,12 @@ def is_line_start(node):
6666

6767

6868
class DisablersInFile:
69-
def __init__(self, start_line: Optional[int], end_line: Optional[int], file_end: Optional[int] = None):
69+
def __init__(
70+
self,
71+
start_line: Optional[int],
72+
end_line: Optional[int],
73+
file_end: Optional[int] = None,
74+
):
7075
self.start_line = start_line
7176
self.end_line = end_line
7277
self.file_end = file_end

robotidy/files.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,12 @@ def get_path_relative_to_project_root(path: Path, root_parent: Path) -> Path:
128128
return path
129129

130130

131-
def get_paths(src: tuple[str, ...], exclude: Pattern | None, extend_exclude: Pattern | None, skip_gitignore: bool):
131+
def get_paths(
132+
src: tuple[str, ...],
133+
exclude: Pattern | None,
134+
extend_exclude: Pattern | None,
135+
skip_gitignore: bool,
136+
):
132137
root = find_project_root(src)
133138
if skip_gitignore:
134139
gitignore = None

robotidy/skip.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,16 @@ def __init__(self, skip_config: SkipConfig):
114114

115115
@staticmethod
116116
def parse_skip_settings(skip_config):
117-
settings = {"settings", "arguments", "setup", "teardown", "timeout", "template", "return_statement", "tags"}
117+
settings = {
118+
"settings",
119+
"arguments",
120+
"setup",
121+
"teardown",
122+
"timeout",
123+
"template",
124+
"return_statement",
125+
"tags",
126+
}
118127
skip_settings = set()
119128
for setting in settings:
120129
if getattr(skip_config, setting):
@@ -156,7 +165,10 @@ def section(self, name):
156165
documentation_option = click.option("--skip-documentation", is_flag=True, help="Skip formatting of documentation")
157166
return_values_option = click.option("--skip-return-values", is_flag=True, help="Skip formatting of return values")
158167
keyword_call_option = click.option(
159-
"--skip-keyword-call", type=str, multiple=True, help="Keyword call name that should not be formatted"
168+
"--skip-keyword-call",
169+
type=str,
170+
multiple=True,
171+
help="Keyword call name that should not be formatted",
160172
)
161173
keyword_call_pattern_option = click.option(
162174
"--skip-keyword-call-pattern",

robotidy/transformers/AlignSettingsSection.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,13 @@ def align_rows(self, statements, look_up):
147147
def calc_separator(self, index, up_to, indent_arg, token, look_up):
148148
if index < up_to:
149149
if self.fixed_width:
150-
return max(self.fixed_width - len(token.value), self.formatting_config.space_count) * " "
150+
return (
151+
max(
152+
self.fixed_width - len(token.value),
153+
self.formatting_config.space_count,
154+
)
155+
* " "
156+
)
151157
arg_indent = self.argument_indent if indent_arg else 0
152158
if indent_arg and index != 0:
153159
return (

robotidy/transformers/AlignTemplatedTestCases.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,13 @@ def align_header(self, statement):
110110
for index, token in enumerate(statement.data_tokens[:-1]):
111111
tokens.append(token)
112112
if self.min_width:
113-
separator = max(self.formatting_config.space_count, self.min_width - len(token.value)) * " "
113+
separator = (
114+
max(
115+
self.formatting_config.space_count,
116+
self.min_width - len(token.value),
117+
)
118+
* " "
119+
)
114120
else:
115121
separator = (self.widths[index] - len(token.value) + self.formatting_config.space_count) * " "
116122
tokens.append(Token(Token.SEPARATOR, separator))

robotidy/transformers/AlignVariablesSection.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,13 @@ class AlignVariablesSection(Transformer):
4646
To align all columns set ``up_to_column`` to 0.
4747
"""
4848

49-
def __init__(self, up_to_column: int = 2, skip_types: str = "", min_width: int = None, fixed_width: int = None):
49+
def __init__(
50+
self,
51+
up_to_column: int = 2,
52+
skip_types: str = "",
53+
min_width: int = None,
54+
fixed_width: int = None,
55+
):
5056
super().__init__()
5157
self.up_to_column = up_to_column - 1
5258
self.min_width = min_width
@@ -121,7 +127,13 @@ def align_rows(self, statements, look_up):
121127
def get_separator(self, index: int, up_to: int, token, look_up: dict[int, int]) -> str:
122128
if index < up_to:
123129
if self.fixed_width:
124-
return max(self.fixed_width - len(token.value), self.formatting_config.space_count) * " "
130+
return (
131+
max(
132+
self.fixed_width - len(token.value),
133+
self.formatting_config.space_count,
134+
)
135+
* " "
136+
)
125137
return (look_up[index] - len(token.value)) * " "
126138
else:
127139
return self.formatting_config.separator

robotidy/transformers/GenerateDocumentation.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,12 @@ class GenerateDocumentation(Transformer):
130130

131131
WHITESPACE_PATTERN = re.compile(r"(\s{2,}|\t)", re.UNICODE)
132132

133-
def __init__(self, overwrite: bool = False, doc_template: str = "google", template_directory: str | None = None):
133+
def __init__(
134+
self,
135+
overwrite: bool = False,
136+
doc_template: str = "google",
137+
template_directory: str | None = None,
138+
):
134139
self.overwrite = overwrite
135140
self.doc_template = self.load_template(doc_template, template_directory)
136141
self.args_returns_finder = ArgumentsAndReturnsVisitor()
@@ -174,7 +179,11 @@ def visit_Keyword(self, node): # noqa
174179
if not self.overwrite and self.args_returns_finder.doc_exists:
175180
return node
176181
formatting = FormattingData(self.formatting_config.continuation_indent, self.formatting_config.separator)
177-
kw_data = KeywordData(node.name, self.args_returns_finder.arguments, self.args_returns_finder.returns)
182+
kw_data = KeywordData(
183+
node.name,
184+
self.args_returns_finder.arguments,
185+
self.args_returns_finder.returns,
186+
)
178187
generated = self.doc_template.render(keyword=kw_data, formatting=formatting)
179188
doc_node = self.create_documentation_from_string(generated)
180189
if self.overwrite:
@@ -186,7 +195,11 @@ def visit_Documentation(self, node): # noqa
186195
return None
187196

188197
def create_documentation_from_string(self, doc_string):
189-
new_line = [Token(Token.EOL), Token(Token.SEPARATOR, self.formatting_config.indent), Token(Token.CONTINUATION)]
198+
new_line = [
199+
Token(Token.EOL),
200+
Token(Token.SEPARATOR, self.formatting_config.indent),
201+
Token(Token.CONTINUATION),
202+
]
190203
tokens = [
191204
Token(Token.SEPARATOR, self.formatting_config.indent),
192205
Token(Token.DOCUMENTATION, "[Documentation]"),

robotidy/transformers/IndentNestedKeywords.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,11 @@ def visit_SuiteSetup(self, node): # noqa
126126
comments = misc.collect_comments_from_tokens(node.tokens, indent=None)
127127
separator = self.get_separator()
128128
new_line = misc.get_new_line()
129-
tokens = [node.data_tokens[0], separator, *misc.join_tokens_with_token(lines[0][1], separator)]
129+
tokens = [
130+
node.data_tokens[0],
131+
separator,
132+
*misc.join_tokens_with_token(lines[0][1], separator),
133+
]
130134
formatted_tokens = self.parse_keyword_lines(lines, tokens, new_line, eol=node.tokens[-1])
131135
if self.node_was_transformed(node.tokens, formatted_tokens):
132136
node.tokens = formatted_tokens
@@ -144,7 +148,12 @@ def visit_Setup(self, node): # noqa
144148
indent = node.tokens[0]
145149
separator = self.get_separator()
146150
new_line = misc.get_new_line(indent)
147-
tokens = [indent, node.data_tokens[0], separator, *misc.join_tokens_with_token(lines[0][1], separator)]
151+
tokens = [
152+
indent,
153+
node.data_tokens[0],
154+
separator,
155+
*misc.join_tokens_with_token(lines[0][1], separator),
156+
]
148157
comment = misc.merge_comments_into_one(node.tokens)
149158
if comment:
150159
# need to add comments on first line for [Setup] / [Teardown] settings

robotidy/transformers/InlineIf.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,11 @@ def inline_if_from_branch(self, node, indent):
179179
# check for ElseIfHeader first since it's child of IfHeader class
180180
if isinstance(node.header, ElseIfHeader):
181181
header = ElseIfHeader(
182-
[Token(Token.ELSE_IF), Token(Token.SEPARATOR, separator), Token(Token.ARGUMENT, node.header.condition)]
182+
[
183+
Token(Token.ELSE_IF),
184+
Token(Token.SEPARATOR, separator),
185+
Token(Token.ARGUMENT, node.header.condition),
186+
]
183187
)
184188
elif isinstance(node.header, IfHeader):
185189
tokens = [Token(Token.SEPARATOR, indent)]
@@ -202,7 +206,10 @@ def inline_if_from_branch(self, node, indent):
202206

203207
@staticmethod
204208
def to_inline_keyword(keyword, separator, last_token):
205-
tokens = [Token(Token.SEPARATOR, separator), Token(Token.KEYWORD, keyword.keyword)]
209+
tokens = [
210+
Token(Token.SEPARATOR, separator),
211+
Token(Token.KEYWORD, keyword.keyword),
212+
]
206213
for arg in keyword.get_tokens(Token.ARGUMENT):
207214
tokens.extend([Token(Token.SEPARATOR, separator), arg])
208215
tokens.append(last_token)
@@ -321,11 +328,15 @@ def handle_inline_if_create(self, node, indent, assign):
321328
else_found = False
322329
if isinstance(node.header, InlineIfHeader):
323330
header = IfHeader.from_params(
324-
condition=node.condition, indent=indent, separator=self.formatting_config.separator
331+
condition=node.condition,
332+
indent=indent,
333+
separator=self.formatting_config.separator,
325334
)
326335
elif isinstance(node.header, ElseIfHeader):
327336
header = ElseIfHeader.from_params(
328-
condition=node.condition, indent=indent, separator=self.formatting_config.separator
337+
condition=node.condition,
338+
indent=indent,
339+
separator=self.formatting_config.separator,
329340
)
330341
else:
331342
header = ElseHeader.from_params(indent=indent)

robotidy/transformers/NormalizeAssignments.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,10 @@ class NormalizeAssignments(Transformer):
6464
HANDLES_SKIP = frozenset({"skip_sections"})
6565

6666
def __init__(
67-
self, equal_sign_type: str = "autodetect", equal_sign_type_variables: str = "remove", skip: Skip = None
67+
self,
68+
equal_sign_type: str = "autodetect",
69+
equal_sign_type_variables: str = "remove",
70+
skip: Skip = None,
6871
):
6972
super().__init__(skip)
7073
self.remove_equal_sign = re.compile(r"\s?=$")

robotidy/transformers/NormalizeNewLines.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def visit_If(self, node): # noqa
118118
self.trim_empty_lines(node)
119119
return self.generic_visit(node)
120120

121-
visit_For = visit_While = visit_Try = visit_If
121+
visit_For = visit_While = visit_Group = visit_Try = visit_If
122122

123123
def visit_Statement(self, node): # noqa
124124
tokens = []

0 commit comments

Comments
 (0)