Skip to content

Commit cb306cb

Browse files
committed
feat: support for new keyword model changes in RFW 7
1 parent 023bfd7 commit cb306cb

File tree

3 files changed

+175
-69
lines changed

3 files changed

+175
-69
lines changed

packages/debugger/src/robotcode/debugger/debugger.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
from robot.errors import VariableError
3737
from robot.output import LOGGER
3838
from robot.running import EXECUTION_CONTEXTS, Keyword, TestCase, TestSuite
39-
from robot.running.userkeyword import UserKeywordHandler
4039
from robot.utils import NormalizedDict
4140
from robot.variables import evaluate_expression
4241
from robotcode.core.event import event
@@ -72,6 +71,11 @@
7271
VariablePresentationHint,
7372
)
7473

74+
if get_robot_version() >= (7, 0):
75+
from robot.running.invalidkeyword import InvalidKeywordRunner as UserKeywordHandler
76+
else:
77+
from robot.running.userkeyword import UserKeywordHandler
78+
7579
if get_robot_version() >= (6, 1):
7680

7781
def internal_evaluate_expression(expression: str, variable_store: Any) -> Any:

packages/language_server/src/robotcode/language_server/robotframework/diagnostics/library_doc.py

Lines changed: 169 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -500,18 +500,26 @@ def resolve(
500500
self.var_positional,
501501
self.named_only,
502502
self.var_named,
503-
self.embedded,
504503
self.defaults,
504+
self.embedded,
505505
None,
506506
)
507507
self.__robot_arguments.name = self.name
508508
if validate:
509-
resolver = ArgumentResolver(
510-
self.__robot_arguments,
511-
resolve_named=resolve_named,
512-
resolve_variables_until=resolve_variables_until,
513-
dict_to_kwargs=dict_to_kwargs,
514-
)
509+
if get_robot_version() < (7, 0):
510+
resolver = ArgumentResolver(
511+
self.__robot_arguments,
512+
resolve_named=resolve_named,
513+
resolve_variables_until=resolve_variables_until,
514+
dict_to_kwargs=dict_to_kwargs,
515+
)
516+
else:
517+
resolver = ArgumentResolver(
518+
self.__robot_arguments,
519+
resolve_named=resolve_named,
520+
resolve_args_until=resolve_variables_until,
521+
dict_to_kwargs=dict_to_kwargs,
522+
)
515523
return cast(Tuple[List[Any], List[Tuple[str, Any]]], resolver.resolve(arguments, variables))
516524

517525
class MyNamedArgumentResolver(NamedArgumentResolver):
@@ -1300,18 +1308,35 @@ def longname(self) -> Any:
13001308

13011309
@property
13021310
def is_error_handler(self) -> bool:
1303-
from robot.running.usererrorhandler import UserErrorHandler
1311+
if get_robot_version() < (7, 0):
1312+
from robot.running.usererrorhandler import UserErrorHandler
1313+
1314+
return isinstance(self.kw, UserErrorHandler)
13041315

1305-
return isinstance(self.kw, UserErrorHandler)
1316+
from robot.running.invalidkeyword import InvalidKeyword
1317+
1318+
return isinstance(self.kw, InvalidKeyword)
13061319

13071320
@property
13081321
def error_handler_message(self) -> Optional[str]:
1309-
from robot.running.usererrorhandler import UserErrorHandler
1310-
13111322
if self.is_error_handler:
1312-
return str(cast(UserErrorHandler, self.kw).error)
1323+
return str(self.kw.error)
1324+
13131325
return None
13141326

1327+
@property
1328+
def error(self) -> Any:
1329+
return self.kw.error
1330+
1331+
@property
1332+
def args(self) -> Any:
1333+
try:
1334+
return self.kw.args
1335+
except (SystemExit, KeyboardInterrupt):
1336+
raise
1337+
except BaseException:
1338+
return None
1339+
13151340

13161341
class MessageAndTraceback(NamedTuple):
13171342
message: str
@@ -1580,7 +1605,6 @@ def get_library_doc(
15801605
from robot.output.loggerhelper import AbstractLogger
15811606
from robot.running.outputcapture import OutputCapturer
15821607
from robot.running.runkwregister import RUN_KW_REGISTER
1583-
from robot.running.testlibraries import _get_lib_class
15841608
from robot.utils import Importer
15851609

15861610
class Logger(AbstractLogger):
@@ -1607,10 +1631,21 @@ def get_test_library(
16071631
create_handlers: bool = True,
16081632
logger: Any = LOGGER,
16091633
) -> Any:
1610-
libclass = _get_lib_class(libcode)
1611-
lib = libclass(libcode, name, args or [], source, logger, variables)
1612-
if create_handlers:
1613-
lib.create_handlers()
1634+
if get_robot_version() < (7, 0):
1635+
libclass = robot.running.testlibraries._get_lib_class(libcode)
1636+
lib = libclass(libcode, name, args or [], source, logger, variables)
1637+
if create_handlers:
1638+
lib.create_handlers()
1639+
else:
1640+
lib = robot.running.testlibraries.TestLibrary.from_code(
1641+
libcode,
1642+
name,
1643+
source=Path(source),
1644+
args=args or [],
1645+
variables=variables,
1646+
create_keywords=create_handlers,
1647+
logger=logger,
1648+
)
16141649

16151650
return lib
16161651

@@ -1684,7 +1719,10 @@ def get_test_library(
16841719
create_handlers=False,
16851720
variables=robot_variables,
16861721
)
1687-
lib.get_instance()
1722+
if get_robot_version() < (7, 0):
1723+
_ = lib.get_instance()
1724+
else:
1725+
_ = lib.instance
16881726
except (SystemExit, KeyboardInterrupt):
16891727
raise
16901728
except BaseException as e:
@@ -1700,13 +1738,16 @@ def get_test_library(
17001738
if args:
17011739
try:
17021740
lib = get_test_library(libcode, source, library_name, (), create_handlers=False)
1703-
lib.get_instance()
1741+
if get_robot_version() < (7, 0):
1742+
_ = lib.get_instance()
1743+
else:
1744+
_ = lib.instance
17041745
except (SystemExit, KeyboardInterrupt):
17051746
raise
17061747
except BaseException:
17071748
lib = None
17081749

1709-
real_source = lib.source if lib is not None else source
1750+
real_source = str(lib.source) if lib is not None else source
17101751

17111752
libdoc = LibraryDoc(
17121753
name=library_name,
@@ -1727,16 +1768,28 @@ def get_test_library(
17271768

17281769
if lib is not None:
17291770
try:
1730-
libdoc.has_listener = lib.has_listener
1771+
if get_robot_version() < (7, 0):
1772+
libdoc.has_listener = lib.has_listener
1773+
1774+
if isinstance(lib, robot.running.testlibraries._ModuleLibrary):
1775+
libdoc.library_type = LibraryType.MODULE
1776+
elif isinstance(lib, robot.running.testlibraries._ClassLibrary):
1777+
libdoc.library_type = LibraryType.CLASS
1778+
elif isinstance(lib, robot.running.testlibraries._DynamicLibrary):
1779+
libdoc.library_type = LibraryType.DYNAMIC
1780+
elif isinstance(lib, robot.running.testlibraries._HybridLibrary):
1781+
libdoc.library_type = LibraryType.HYBRID
1782+
else:
1783+
libdoc.has_listener = bool(lib.listeners)
17311784

1732-
if isinstance(lib, robot.running.testlibraries._ModuleLibrary):
1733-
libdoc.library_type = LibraryType.MODULE
1734-
elif isinstance(lib, robot.running.testlibraries._ClassLibrary):
1735-
libdoc.library_type = LibraryType.CLASS
1736-
elif isinstance(lib, robot.running.testlibraries._DynamicLibrary):
1737-
libdoc.library_type = LibraryType.DYNAMIC
1738-
elif isinstance(lib, robot.running.testlibraries._HybridLibrary):
1739-
libdoc.library_type = LibraryType.HYBRID
1785+
if isinstance(lib, robot.running.testlibraries.ModuleLibrary):
1786+
libdoc.library_type = LibraryType.MODULE
1787+
elif isinstance(lib, robot.running.testlibraries.ClassLibrary):
1788+
libdoc.library_type = LibraryType.CLASS
1789+
elif isinstance(lib, robot.running.testlibraries.DynamicLibrary):
1790+
libdoc.library_type = LibraryType.DYNAMIC
1791+
elif isinstance(lib, robot.running.testlibraries.HybridLibrary):
1792+
libdoc.library_type = LibraryType.HYBRID
17401793

17411794
init_wrappers = [KeywordWrapper(lib.init, source)]
17421795
init_keywords = [(KeywordDocBuilder().build_keyword(k), k) for k in init_wrappers]
@@ -1758,15 +1811,22 @@ def get_test_library(
17581811
longname=f"{libdoc.name}.{kw[0].name}",
17591812
doc_format=str(lib.doc_format) or ROBOT_DOC_FORMAT,
17601813
is_initializer=True,
1761-
arguments_spec=ArgumentSpec.from_robot_argument_spec(kw[1].arguments),
1814+
arguments_spec=ArgumentSpec.from_robot_argument_spec(
1815+
kw[1].arguments if get_robot_version() < (7, 0) else kw[1].args
1816+
),
17621817
)
17631818
for kw in init_keywords
17641819
]
17651820
)
17661821

17671822
logger = Logger()
17681823
lib.logger = logger
1769-
lib.create_handlers()
1824+
1825+
if get_robot_version() < (7, 0):
1826+
lib.create_handlers()
1827+
else:
1828+
lib.create_keywords()
1829+
17701830
for m in logger.messages:
17711831
if m[1] == "ERROR":
17721832
errors.append(
@@ -1778,7 +1838,18 @@ def get_test_library(
17781838
)
17791839
)
17801840

1781-
keyword_wrappers = [KeywordWrapper(k, source) for k in lib.handlers]
1841+
if get_robot_version() < (7, 0):
1842+
keyword_wrappers = [KeywordWrapper(k, source) for k in lib.handlers]
1843+
else:
1844+
keyword_wrappers = [KeywordWrapper(k, source) for k in lib.keywords]
1845+
1846+
def get_args_to_process(libdoc_name: str, kw_name: str) -> Any:
1847+
result = RUN_KW_REGISTER.get_args_to_process(libdoc_name, kw_name)
1848+
if result == -1:
1849+
return None
1850+
1851+
return result
1852+
17821853
keyword_docs = [(KeywordDocBuilder().build_keyword(k), k) for k in keyword_wrappers]
17831854
libdoc.keywords = KeywordStore(
17841855
source=libdoc.name,
@@ -1802,12 +1873,14 @@ def get_test_library(
18021873
is_error_handler=kw[1].is_error_handler,
18031874
error_handler_message=kw[1].error_handler_message,
18041875
is_registered_run_keyword=RUN_KW_REGISTER.is_run_keyword(libdoc.name, kw[0].name),
1805-
args_to_process=RUN_KW_REGISTER.get_args_to_process(libdoc.name, kw[0].name),
1876+
args_to_process=get_args_to_process(libdoc.name, kw[0].name),
18061877
deprecated=kw[0].deprecated,
1807-
arguments_spec=ArgumentSpec.from_robot_argument_spec(kw[1].arguments)
1878+
arguments_spec=ArgumentSpec.from_robot_argument_spec(
1879+
kw[1].arguments if get_robot_version() < (7, 0) else kw[1].args
1880+
)
18081881
if not kw[1].is_error_handler
18091882
else None,
1810-
return_type=str(kw[1].arguments.return_type) if get_robot_version() >= (7, 0) else None,
1883+
return_type=str(kw[1].args.return_type) if get_robot_version() >= (7, 0) else None,
18111884
)
18121885
for kw in keyword_docs
18131886
],
@@ -2436,9 +2509,14 @@ def get_model_doc(
24362509
from robot.parsing.model.blocks import Keyword
24372510
from robot.parsing.model.statements import Arguments, KeywordName
24382511
from robot.running.builder.transformers import ResourceBuilder
2439-
from robot.running.model import ResourceFile
2440-
from robot.running.usererrorhandler import UserErrorHandler
2441-
from robot.running.userkeyword import UserLibrary
2512+
2513+
if get_robot_version() < (7, 0):
2514+
from robot.running.model import ResourceFile
2515+
from robot.running.usererrorhandler import UserErrorHandler
2516+
from robot.running.userkeyword import UserLibrary
2517+
else:
2518+
from robot.running.invalidkeyword import InvalidKeyword as UserErrorHandler
2519+
from robot.running.resourcemodel import ResourceFile
24422520

24432521
errors: List[Error] = []
24442522
keyword_name_nodes: List[KeywordName] = []
@@ -2506,41 +2584,45 @@ def get_argument_definitions_from_line(line: int) -> List[ArgumentDefinition]:
25062584
with LOGGER.cache_only:
25072585
ResourceBuilder(res).visit(model)
25082586

2509-
class MyUserLibrary(UserLibrary):
2510-
current_kw: Any = None
2587+
if get_robot_version() < (7, 0):
25112588

2512-
def _log_creating_failed(self, handler: UserErrorHandler, error: BaseException) -> None:
2513-
err = Error(
2514-
message=f"Creating keyword '{handler.name}' failed: {error!s}",
2515-
type_name=type(error).__qualname__,
2516-
source=self.current_kw.source if self.current_kw is not None else None,
2517-
line_no=self.current_kw.lineno if self.current_kw is not None else None,
2518-
)
2519-
errors.append(err)
2589+
class MyUserLibrary(UserLibrary):
2590+
current_kw: Any = None
25202591

2521-
def _create_handler(self, kw: Any) -> Any:
2522-
self.current_kw = kw
2523-
try:
2524-
handler = super()._create_handler(kw)
2525-
setattr(handler, "errors", None)
2526-
except DataError as e:
2592+
def _log_creating_failed(self, handler: UserErrorHandler, error: BaseException) -> None:
25272593
err = Error(
2528-
message=str(e),
2529-
type_name=type(e).__qualname__,
2530-
source=kw.source,
2531-
line_no=kw.lineno,
2594+
message=f"Creating keyword '{handler.name}' failed: {error!s}",
2595+
type_name=type(error).__qualname__,
2596+
source=self.current_kw.source if self.current_kw is not None else None,
2597+
line_no=self.current_kw.lineno if self.current_kw is not None else None,
25322598
)
25332599
errors.append(err)
25342600

2535-
handler = UserErrorHandler(e, kw.name, self.name)
2536-
handler.source = kw.source
2537-
handler.lineno = kw.lineno
2601+
def _create_handler(self, kw: Any) -> Any:
2602+
self.current_kw = kw
2603+
try:
2604+
handler = super()._create_handler(kw)
2605+
setattr(handler, "errors", None)
2606+
except DataError as e:
2607+
err = Error(
2608+
message=str(e),
2609+
type_name=type(e).__qualname__,
2610+
source=kw.source,
2611+
line_no=kw.lineno,
2612+
)
2613+
errors.append(err)
2614+
2615+
handler = UserErrorHandler(e, kw.name, self.name)
2616+
handler.source = kw.source
2617+
handler.lineno = kw.lineno
25382618

2539-
setattr(handler, "errors", [err])
2619+
setattr(handler, "errors", [err])
25402620

2541-
return handler
2621+
return handler
25422622

2543-
lib = MyUserLibrary(res)
2623+
lib = MyUserLibrary(res)
2624+
else:
2625+
lib = res
25442626

25452627
libdoc = LibraryDoc(
25462628
name=lib.name or "",
@@ -2552,6 +2634,21 @@ def _create_handler(self, kw: Any) -> Any:
25522634
errors=errors,
25532635
)
25542636

2637+
def get_kw_errors(kw: Any) -> Any:
2638+
r = getattr(kw, "errors") if hasattr(kw, "errors") else None
2639+
if get_robot_version() >= (7, 0) and kw.error:
2640+
if not r:
2641+
r = []
2642+
r.append(
2643+
Error(
2644+
message=str(kw.error),
2645+
type_name="KeywordError",
2646+
source=kw.source,
2647+
line_no=kw.lineno,
2648+
)
2649+
)
2650+
return r
2651+
25552652
libdoc.keywords = KeywordStore(
25562653
source=libdoc.name,
25572654
source_type=libdoc.type,
@@ -2571,15 +2668,20 @@ def _create_handler(self, kw: Any) -> Any:
25712668
libtype=libdoc.type,
25722669
longname=f"{libdoc.name}.{kw[0].name}",
25732670
is_embedded=is_embedded_keyword(kw[0].name),
2574-
errors=getattr(kw[1], "errors") if hasattr(kw[1], "errors") else None,
2671+
errors=get_kw_errors(kw[1]),
25752672
is_error_handler=isinstance(kw[1], UserErrorHandler),
25762673
error_handler_message=str(cast(UserErrorHandler, kw[1]).error)
25772674
if isinstance(kw[1], UserErrorHandler)
25782675
else None,
2579-
arguments_spec=ArgumentSpec.from_robot_argument_spec(kw[1].arguments),
2676+
arguments_spec=ArgumentSpec.from_robot_argument_spec(
2677+
kw[1].arguments if get_robot_version() < (7, 0) else kw[1].args
2678+
),
25802679
argument_definitions=get_argument_definitions_from_line(kw[0].lineno),
25812680
)
2582-
for kw in [(KeywordDocBuilder(resource=True).build_keyword(lw), lw) for lw in lib.handlers]
2681+
for kw in [
2682+
(KeywordDocBuilder(resource=True).build_keyword(lw), lw)
2683+
for lw in (lib.handlers if get_robot_version() < (7, 0) else lib.keywords)
2684+
]
25832685
],
25842686
)
25852687

0 commit comments

Comments
 (0)