Skip to content

Commit

Permalink
Fix backward incompatible changes from RF 7
Browse files Browse the repository at this point in the history
  • Loading branch information
bhirsz committed Nov 19, 2023
1 parent ac0a6d5 commit 4d88826
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 30 deletions.
5 changes: 5 additions & 0 deletions docs/releasenotes/unreleased/fixes.1.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Robot Framework 7.0 backward incompatible changes: VariableIterator refactor
----------------------------------------------------------------------------

Robotidy variables handling relied upon ``VariableIterator`` class imported from Robot Framework package.
It caused ImportError which should be now fixed.
5 changes: 5 additions & 0 deletions docs/releasenotes/unreleased/fixes.2.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Robot Framework 7.0 backward incompatible changes: ForceTags deprecation (#584)
--------------------------------------------------------------------------------

Our tag transformers imports ``Force Tags`` class from ``robot`` module. It was deprecated in Robot Framework 7
and caused ImportError when using Robotidy. It should be now fixed.
21 changes: 10 additions & 11 deletions robotidy/transformers/RenameKeywords.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import re
import string
from typing import Optional

from robot.api.parsing import Token
from robot.variables.search import VariableIterator

from robotidy.disablers import skip_if_disabled, skip_section_if_disabled
from robotidy.exceptions import InvalidParameterValueError
from robotidy.transformers import Transformer
from robotidy.transformers.run_keywords import get_run_keywords
from robotidy.utils import misc
from robotidy.utils import misc, variable_matcher


class RenameKeywords(Transformer):
Expand Down Expand Up @@ -101,16 +99,17 @@ def rename_node(self, token, is_keyword_call):
def normalize_name(self, value, is_keyword_call):
var_found = False
parts = []
remaining = ""
for prefix, match, remaining in VariableIterator(value, ignore_errors=True):
after = ""
for match in variable_matcher.VariableMatches(value, ignore_errors=True):
var_found = True
# rename strips whitespace, so we need to preserve it if needed
if not prefix.strip() and parts:
parts.extend([" ", match])
if not match.before.strip() and parts:
parts.extend([" ", match.match])
else:
parts.extend([self.rename_part(prefix, is_keyword_call), match])
parts.extend([self.rename_part(match.before, is_keyword_call), match.match])
after = match.after
if var_found:
parts.append(self.rename_part(remaining, is_keyword_call))
parts.append(self.rename_part(after, is_keyword_call))
return "".join(parts).strip()
return self.rename_part(value, is_keyword_call)

Expand Down Expand Up @@ -142,8 +141,8 @@ def rename_with_pattern(self, value: str, is_keyword_call: bool):
if is_keyword_call and "." in value:
# rename only non lib part
found_lib = -1
for prefix, _, _ in VariableIterator(value):
found_lib = prefix.find(".")
for match in variable_matcher.VariableMatches(value):
found_lib = match.before.find(".")
break
if found_lib != -1:
lib_name = value[: found_lib + 1]
Expand Down
27 changes: 12 additions & 15 deletions robotidy/transformers/RenameVariables.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@

from robot.api.parsing import Arguments, Token
from robot.errors import VariableError
from robot.variables import VariableIterator
from robot.variables.search import search_variable

from robotidy.disablers import skip_if_disabled, skip_section_if_disabled
from robotidy.exceptions import InvalidParameterValueError
from robotidy.skip import Skip
from robotidy.transformers import Transformer
from robotidy.utils import misc
from robotidy.utils import misc, variable_matcher

SET_GLOBAL_VARIABLES = {"settestvariable", "settaskvariable", "setsuitevariable", "setglobalvariable"}

Expand All @@ -32,7 +31,7 @@ def is_nested_variable(variable: str) -> bool:
if not match.base:
return False
match = search_variable(match.base, ignore_errors=True)
return match.base
return bool(match.base)


def resolve_var_name(name: str) -> str:
Expand Down Expand Up @@ -383,23 +382,20 @@ def visit_While(self, node): # noqa

def rename_value(self, value: str, variable_case: str, is_var: bool = False):
try:
variables = list(VariableIterator(value))
variables = list(variable_matcher.VariableMatches(value))
except VariableError: # for example ${variable which wasn't closed properly
variables = []
if not variables:
if is_var:
return self.rename(value, case=variable_case, strip_fn="strip")
return value
name = ""
remaining = ""
for before, variable, remaining in variables:
if before:
name, after = "", ""
for match in variables:
if match.before:
if is_var:
name += self.rename(before, case=variable_case, strip_fn="lstrip")
name += self.rename(match.before, case=variable_case, strip_fn="lstrip")
else:
name += before
# handle ${variable}[item][${syntax}]
match = search_variable(variable, ignore_errors=True)
name += match.before
# inline eval will start and end with {}
if not (match.base.startswith("{") and match.base.endswith("}")):
base = self.rename_value(match.base, variable_case=variable_case, is_var=True)
Expand All @@ -410,11 +406,12 @@ def rename_value(self, value: str, variable_case: str, is_var: bool = False):
renamed_item = self.rename_value(item, variable_case=variable_case, is_var=False)
base += f"[{renamed_item}]"
name += base
if remaining:
after = match.after
if after:
if is_var:
name += self.rename(remaining, case=variable_case, strip_fn="rstrip")
name += self.rename(after, case=variable_case, strip_fn="rstrip")
else:
name += remaining
name += after
return name

def set_name_case(self, name: str, case: str):
Expand Down
6 changes: 3 additions & 3 deletions tests/utest/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ def test_help(self, flag):
@pytest.mark.parametrize("source, return_status", [("golden.robot", 0), ("not_golden.robot", 1)])
def test_check(self, source, return_status):
source = TEST_DATA_DIR / "check" / source
with patch("robotidy.misc.ModelWriter") as mock_writer:
with patch("robotidy.utils.misc.ModelWriter") as mock_writer:
run_tidy(
["--check", "--transform", "NormalizeSectionHeaderName", str(source)],
exit_code=return_status,
Expand All @@ -333,7 +333,7 @@ def test_check(self, source, return_status):
@pytest.mark.parametrize("source, return_status", [("golden.robot", 0), ("not_golden.robot", 1)])
def test_check_overwrite(self, source, return_status):
source = TEST_DATA_DIR / "check" / source
with patch("robotidy.misc.ModelWriter") as mock_writer:
with patch("robotidy.utils.misc.ModelWriter") as mock_writer:
run_tidy(
["--check", "--overwrite", "--transform", "NormalizeSectionHeaderName", str(source)],
exit_code=return_status,
Expand All @@ -353,7 +353,7 @@ def test_disable_coloring(self, color_flag, color_env):
if color_flag:
command.append(color_flag)
command.extend(["--transform", "NormalizeSectionHeaderName", str(source)])
with patch.dict("os.environ", mocked_env), patch("robotidy.misc.decorate_diff_with_color") as mock_color:
with patch.dict("os.environ", mocked_env), patch("robotidy.utils.misc.decorate_diff_with_color") as mock_color:
run_tidy(command)
if should_be_colored:
mock_color.assert_called()
Expand Down
2 changes: 1 addition & 1 deletion tests/utest/test_load_transformers.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ def test_overwriting_disabled_in_version(self, target_version, version, transfor
TransformConfig(config, force_include=False, custom_transformer=False, is_config=True)
for config in configure
]
with patch("robotidy.transformers.ROBOT_VERSION", mocked_version):
with patch("robotidy.utils.misc.ROBOT_VERSION", mocked_version):
transformers = load_transformers(
TransformConfigMap(transform_transformers, [], configure_transformers),
skip=skip_config,
Expand Down

0 comments on commit 4d88826

Please sign in to comment.