robotcode-robot 0.75.0__py3-none-any.whl → 0.76.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- robotcode/robot/__version__.py +1 -1
- robotcode/robot/diagnostics/document_cache_helper.py +22 -0
- robotcode/robot/diagnostics/imports_manager.py +29 -16
- robotcode/robot/diagnostics/library_doc.py +93 -108
- robotcode/robot/diagnostics/namespace.py +288 -248
- robotcode/robot/diagnostics/namespace_analyzer.py +36 -6
- robotcode/robot/diagnostics/workspace_config.py +1 -0
- {robotcode_robot-0.75.0.dist-info → robotcode_robot-0.76.0.dist-info}/METADATA +2 -2
- {robotcode_robot-0.75.0.dist-info → robotcode_robot-0.76.0.dist-info}/RECORD +11 -11
- {robotcode_robot-0.75.0.dist-info → robotcode_robot-0.76.0.dist-info}/WHEEL +0 -0
- {robotcode_robot-0.75.0.dist-info → robotcode_robot-0.76.0.dist-info}/licenses/LICENSE.txt +0 -0
    
        robotcode/robot/__version__.py
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            __version__ = "0. | 
| 1 | 
            +
            __version__ = "0.76.0"
         | 
| @@ -40,6 +40,10 @@ class UnknownFileTypeError(Exception): | |
| 40 40 | 
             
                pass
         | 
| 41 41 |  | 
| 42 42 |  | 
| 43 | 
            +
            class _CacheEntry:
         | 
| 44 | 
            +
                pass
         | 
| 45 | 
            +
             | 
| 46 | 
            +
             | 
| 43 47 | 
             
            class DocumentsCacheHelper:
         | 
| 44 48 | 
             
                _logger = LoggingDescriptor()
         | 
| 45 49 |  | 
| @@ -50,6 +54,8 @@ class DocumentsCacheHelper: | |
| 50 54 | 
             
                    file_watcher_manager: FileWatcherManagerBase,
         | 
| 51 55 | 
             
                    robot_profile: Optional[RobotBaseProfile],
         | 
| 52 56 | 
             
                ) -> None:
         | 
| 57 | 
            +
                    self.INITIALIZED_NAMESPACE = _CacheEntry()
         | 
| 58 | 
            +
             | 
| 53 59 | 
             
                    self.workspace = workspace
         | 
| 54 60 | 
             
                    self.documents_manager = documents_manager
         | 
| 55 61 | 
             
                    self.file_watcher_manager = file_watcher_manager
         | 
| @@ -425,6 +431,20 @@ class DocumentsCacheHelper: | |
| 425 431 |  | 
| 426 432 | 
             
                        self.namespace_invalidated(self, sender, callback_filter=language_id_filter(document))
         | 
| 427 433 |  | 
| 434 | 
            +
                def __namespace_initialized(self, sender: Namespace) -> None:
         | 
| 435 | 
            +
                    if sender.document is not None:
         | 
| 436 | 
            +
                        self._logger.debug(
         | 
| 437 | 
            +
                            lambda: f"Save initialized Namespace: {sender.document.uri if sender.document else None}"
         | 
| 438 | 
            +
                        )
         | 
| 439 | 
            +
                        sender.document.set_data(self.INITIALIZED_NAMESPACE, sender)
         | 
| 440 | 
            +
             | 
| 441 | 
            +
                def get_initialized_namespace(self, document: TextDocument) -> Namespace:
         | 
| 442 | 
            +
                    result: Optional[Namespace] = document.get_data(self.INITIALIZED_NAMESPACE)
         | 
| 443 | 
            +
                    if result is None:
         | 
| 444 | 
            +
                        self._logger.debug(lambda: f"There is no initialized Namespace: {document.uri if document else None}")
         | 
| 445 | 
            +
                        result = self.get_namespace(document)
         | 
| 446 | 
            +
                    return result
         | 
| 447 | 
            +
             | 
| 428 448 | 
             
                def __get_namespace_for_document_type(
         | 
| 429 449 | 
             
                    self, document: TextDocument, document_type: Optional[DocumentType]
         | 
| 430 450 | 
             
                ) -> Namespace:
         | 
| @@ -451,6 +471,7 @@ class DocumentsCacheHelper: | |
| 451 471 | 
             
                        workspace_languages,
         | 
| 452 472 | 
             
                    )
         | 
| 453 473 | 
             
                    result.has_invalidated.add(self.__invalidate_namespace)
         | 
| 474 | 
            +
                    result.has_initialized.add(self.__namespace_initialized)
         | 
| 454 475 |  | 
| 455 476 | 
             
                    return result
         | 
| 456 477 |  | 
| @@ -484,6 +505,7 @@ class DocumentsCacheHelper: | |
| 484 505 | 
             
                        environment,
         | 
| 485 506 | 
             
                        cache_config.ignored_libraries,
         | 
| 486 507 | 
             
                        cache_config.ignored_variables,
         | 
| 508 | 
            +
                        cache_config.ignore_arguments_for_library,
         | 
| 487 509 | 
             
                        analysis_config.global_library_search_order,
         | 
| 488 510 | 
             
                        cache_base_path,
         | 
| 489 511 | 
             
                    )
         | 
| @@ -496,6 +496,7 @@ class ImportsManager: | |
| 496 496 | 
             
                    environment: Optional[Dict[str, str]],
         | 
| 497 497 | 
             
                    ignored_libraries: List[str],
         | 
| 498 498 | 
             
                    ignored_variables: List[str],
         | 
| 499 | 
            +
                    ignore_arguments_for_library: List[str],
         | 
| 499 500 | 
             
                    global_library_search_order: List[str],
         | 
| 500 501 | 
             
                    cache_base_path: Optional[Path],
         | 
| 501 502 | 
             
                ) -> None:
         | 
| @@ -538,6 +539,7 @@ class ImportsManager: | |
| 538 539 |  | 
| 539 540 | 
             
                    self.ignored_libraries_patters = [Pattern(s) for s in ignored_libraries]
         | 
| 540 541 | 
             
                    self.ignored_variables_patters = [Pattern(s) for s in ignored_variables]
         | 
| 542 | 
            +
                    self.ignore_arguments_for_library_patters = [Pattern(s) for s in ignore_arguments_for_library]
         | 
| 541 543 |  | 
| 542 544 | 
             
                    self.global_library_search_order = global_library_search_order
         | 
| 543 545 |  | 
| @@ -561,9 +563,9 @@ class ImportsManager: | |
| 561 563 | 
             
                    if environment:
         | 
| 562 564 | 
             
                        self._environment.update(environment)
         | 
| 563 565 |  | 
| 564 | 
            -
                    self._library_files_cache = SimpleLRUCache()
         | 
| 565 | 
            -
                    self._resource_files_cache = SimpleLRUCache()
         | 
| 566 | 
            -
                    self._variables_files_cache = SimpleLRUCache()
         | 
| 566 | 
            +
                    self._library_files_cache = SimpleLRUCache(1024)
         | 
| 567 | 
            +
                    self._resource_files_cache = SimpleLRUCache(1024)
         | 
| 568 | 
            +
                    self._variables_files_cache = SimpleLRUCache(1024)
         | 
| 567 569 |  | 
| 568 570 | 
             
                    self._executor_lock = RLock(default_timeout=120, name="ImportsManager._executor_lock")
         | 
| 569 571 | 
             
                    self._executor: Optional[ProcessPoolExecutor] = None
         | 
| @@ -864,7 +866,8 @@ class ImportsManager: | |
| 864 866 | 
             
                    name: str,
         | 
| 865 867 | 
             
                    base_dir: str = ".",
         | 
| 866 868 | 
             
                    variables: Optional[Dict[str, Optional[Any]]] = None,
         | 
| 867 | 
            -
                ) -> Tuple[Optional[LibraryMetaData], str]:
         | 
| 869 | 
            +
                ) -> Tuple[Optional[LibraryMetaData], str, bool]:
         | 
| 870 | 
            +
                    ignore_arguments = False
         | 
| 868 871 | 
             
                    try:
         | 
| 869 872 | 
             
                        import_name = self.find_library(name, base_dir=base_dir, variables=variables)
         | 
| 870 873 |  | 
| @@ -886,6 +889,12 @@ class ImportsManager: | |
| 886 889 | 
             
                                )
         | 
| 887 890 |  | 
| 888 891 | 
             
                        if result is not None:
         | 
| 892 | 
            +
                            ignore_arguments = any(
         | 
| 893 | 
            +
                                (p.matches(result.name) if result.name is not None else False)
         | 
| 894 | 
            +
                                or (p.matches(result.origin) if result.origin is not None else False)
         | 
| 895 | 
            +
                                for p in self.ignore_arguments_for_library_patters
         | 
| 896 | 
            +
                            )
         | 
| 897 | 
            +
             | 
| 889 898 | 
             
                            if any(
         | 
| 890 899 | 
             
                                (p.matches(result.name) if result.name is not None else False)
         | 
| 891 900 | 
             
                                or (p.matches(result.origin) if result.origin is not None else False)
         | 
| @@ -895,7 +904,7 @@ class ImportsManager: | |
| 895 904 | 
             
                                    lambda: f"Ignore library {result.name or '' if result is not None else ''}"
         | 
| 896 905 | 
             
                                    f" {result.origin or '' if result is not None else ''} for caching."
         | 
| 897 906 | 
             
                                )
         | 
| 898 | 
            -
                                return None, import_name
         | 
| 907 | 
            +
                                return None, import_name, ignore_arguments
         | 
| 899 908 |  | 
| 900 909 | 
             
                            if result.origin is not None:
         | 
| 901 910 | 
             
                                result.mtimes = {result.origin: Path(result.origin).stat().st_mtime_ns}
         | 
| @@ -912,13 +921,13 @@ class ImportsManager: | |
| 912 921 | 
             
                                    }
         | 
| 913 922 | 
             
                                )
         | 
| 914 923 |  | 
| 915 | 
            -
                        return result, import_name
         | 
| 924 | 
            +
                        return result, import_name, ignore_arguments
         | 
| 916 925 | 
             
                    except (SystemExit, KeyboardInterrupt):
         | 
| 917 926 | 
             
                        raise
         | 
| 918 927 | 
             
                    except BaseException:
         | 
| 919 928 | 
             
                        pass
         | 
| 920 929 |  | 
| 921 | 
            -
                    return None, import_name
         | 
| 930 | 
            +
                    return None, import_name, ignore_arguments
         | 
| 922 931 |  | 
| 923 932 | 
             
                def get_variables_meta(
         | 
| 924 933 | 
             
                    self,
         | 
| @@ -1131,7 +1140,7 @@ class ImportsManager: | |
| 1131 1140 | 
             
                    base_dir: str,
         | 
| 1132 1141 | 
             
                    variables: Optional[Dict[str, Any]] = None,
         | 
| 1133 1142 | 
             
                ) -> LibraryDoc:
         | 
| 1134 | 
            -
                    meta, source = self.get_library_meta(name, base_dir, variables)
         | 
| 1143 | 
            +
                    meta, source, ignore_arguments = self.get_library_meta(name, base_dir, variables)
         | 
| 1135 1144 |  | 
| 1136 1145 | 
             
                    self._logger.debug(lambda: f"Load Library {source}{args!r}")
         | 
| 1137 1146 |  | 
| @@ -1171,7 +1180,7 @@ class ImportsManager: | |
| 1171 1180 | 
             
                        result = executor.submit(
         | 
| 1172 1181 | 
             
                            get_library_doc,
         | 
| 1173 1182 | 
             
                            name,
         | 
| 1174 | 
            -
                            args,
         | 
| 1183 | 
            +
                            args if not ignore_arguments else (),
         | 
| 1175 1184 | 
             
                            working_dir,
         | 
| 1176 1185 | 
             
                            base_dir,
         | 
| 1177 1186 | 
             
                            self.get_resolvable_command_line_variables(),
         | 
| @@ -1400,13 +1409,17 @@ class ImportsManager: | |
| 1400 1409 | 
             
                ) -> VariablesDoc:
         | 
| 1401 1410 | 
             
                    source = self.find_variables(name, base_dir, variables, resolve_variables, resolve_command_line_vars)
         | 
| 1402 1411 |  | 
| 1403 | 
            -
                     | 
| 1404 | 
            -
                         | 
| 1405 | 
            -
             | 
| 1406 | 
            -
             | 
| 1407 | 
            -
             | 
| 1408 | 
            -
             | 
| 1409 | 
            -
             | 
| 1412 | 
            +
                    if args:
         | 
| 1413 | 
            +
                        resolved_args = resolve_args(
         | 
| 1414 | 
            +
                            args,
         | 
| 1415 | 
            +
                            str(self.root_folder),
         | 
| 1416 | 
            +
                            base_dir,
         | 
| 1417 | 
            +
                            self.get_resolvable_command_line_variables() if resolve_command_line_vars else None,
         | 
| 1418 | 
            +
                            variables,
         | 
| 1419 | 
            +
                        )
         | 
| 1420 | 
            +
                    else:
         | 
| 1421 | 
            +
                        resolved_args = ()
         | 
| 1422 | 
            +
             | 
| 1410 1423 | 
             
                    entry_key = _VariablesEntryKey(source, resolved_args)
         | 
| 1411 1424 |  | 
| 1412 1425 | 
             
                    with self._variables_lock:
         | 
| @@ -33,7 +33,38 @@ from typing import ( | |
| 33 33 | 
             
                cast,
         | 
| 34 34 | 
             
            )
         | 
| 35 35 |  | 
| 36 | 
            +
            import robot.running.testlibraries
         | 
| 37 | 
            +
            from robot.errors import DataError, VariableError
         | 
| 38 | 
            +
            from robot.libdocpkg import LibraryDocumentation
         | 
| 39 | 
            +
            from robot.libdocpkg.htmlwriter import LibdocHtmlWriter
         | 
| 40 | 
            +
            from robot.libdocpkg.robotbuilder import KeywordDocBuilder
         | 
| 41 | 
            +
            from robot.libraries import STDLIBS
         | 
| 42 | 
            +
            from robot.output.logger import LOGGER
         | 
| 43 | 
            +
            from robot.output.loggerhelper import AbstractLogger
         | 
| 36 44 | 
             
            from robot.parsing.lexer.tokens import Token
         | 
| 45 | 
            +
            from robot.parsing.lexer.tokens import Token as RobotToken
         | 
| 46 | 
            +
            from robot.parsing.model.blocks import Keyword
         | 
| 47 | 
            +
            from robot.parsing.model.statements import Arguments, KeywordName
         | 
| 48 | 
            +
            from robot.running.arguments.argumentresolver import (
         | 
| 49 | 
            +
                ArgumentResolver,
         | 
| 50 | 
            +
                DictToKwargs,
         | 
| 51 | 
            +
                NamedArgumentResolver,
         | 
| 52 | 
            +
                VariableReplacer,
         | 
| 53 | 
            +
            )
         | 
| 54 | 
            +
            from robot.running.arguments.argumentspec import ArgInfo
         | 
| 55 | 
            +
            from robot.running.arguments.argumentspec import (
         | 
| 56 | 
            +
                ArgumentSpec as RobotArgumentSpec,
         | 
| 57 | 
            +
            )
         | 
| 58 | 
            +
            from robot.running.arguments.embedded import EmbeddedArguments
         | 
| 59 | 
            +
            from robot.running.builder.transformers import ResourceBuilder
         | 
| 60 | 
            +
            from robot.running.outputcapture import OutputCapturer
         | 
| 61 | 
            +
            from robot.running.runkwregister import RUN_KW_REGISTER
         | 
| 62 | 
            +
            from robot.utils.importer import Importer
         | 
| 63 | 
            +
            from robot.utils.robotpath import find_file as robot_find_file
         | 
| 64 | 
            +
            from robot.variables import Variables
         | 
| 65 | 
            +
            from robot.variables.filesetter import PythonImporter, YamlImporter
         | 
| 66 | 
            +
            from robot.variables.finders import VariableFinder
         | 
| 67 | 
            +
            from robot.variables.search import contains_variable
         | 
| 37 68 | 
             
            from robotcode.core.lsp.types import Position, Range
         | 
| 38 69 | 
             
            from robotcode.robot.diagnostics.entities import (
         | 
| 39 70 | 
             
                ArgumentDefinition,
         | 
| @@ -53,6 +84,30 @@ from robotcode.robot.utils.markdownformatter import MarkDownFormatter | |
| 53 84 | 
             
            from robotcode.robot.utils.match import normalize, normalize_namespace
         | 
| 54 85 | 
             
            from robotcode.robot.utils.stubs import HasError, HasErrors
         | 
| 55 86 |  | 
| 87 | 
            +
            if get_robot_version() < (7, 0):
         | 
| 88 | 
            +
                from robot.running.handlers import _PythonHandler, _PythonInitHandler
         | 
| 89 | 
            +
                from robot.running.model import ResourceFile
         | 
| 90 | 
            +
                from robot.running.usererrorhandler import UserErrorHandler
         | 
| 91 | 
            +
                from robot.running.userkeyword import UserLibrary
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                robot_notset = ArgInfo.NOTSET
         | 
| 94 | 
            +
             | 
| 95 | 
            +
            if get_robot_version() >= (6, 1):
         | 
| 96 | 
            +
                from robot.libdocpkg.datatypes import (
         | 
| 97 | 
            +
                    TypeDoc as RobotTypeDoc,
         | 
| 98 | 
            +
                )
         | 
| 99 | 
            +
                from robot.running.arguments.argumentspec import TypeInfo
         | 
| 100 | 
            +
                from robot.variables.filesetter import JsonImporter
         | 
| 101 | 
            +
             | 
| 102 | 
            +
            if get_robot_version() >= (7, 0):
         | 
| 103 | 
            +
                from robot.running.invalidkeyword import InvalidKeyword
         | 
| 104 | 
            +
                from robot.running.invalidkeyword import (
         | 
| 105 | 
            +
                    InvalidKeyword as UserErrorHandler,
         | 
| 106 | 
            +
                )
         | 
| 107 | 
            +
                from robot.running.resourcemodel import ResourceFile
         | 
| 108 | 
            +
                from robot.utils import NOT_SET as robot_notset  # type: ignore[no-redef] # noqa: N811
         | 
| 109 | 
            +
             | 
| 110 | 
            +
             | 
| 56 111 | 
             
            RUN_KEYWORD_NAMES = [
         | 
| 57 112 | 
             
                "Run Keyword",
         | 
| 58 113 | 
             
                "Run Keyword And Continue On Failure",
         | 
| @@ -144,9 +199,6 @@ def convert_from_rest(text: str) -> str: | |
| 144 199 |  | 
| 145 200 |  | 
| 146 201 | 
             
            def is_embedded_keyword(name: str) -> bool:
         | 
| 147 | 
            -
                from robot.errors import DataError, VariableError
         | 
| 148 | 
            -
                from robot.running.arguments.embedded import EmbeddedArguments
         | 
| 149 | 
            -
             | 
| 150 202 | 
             
                try:
         | 
| 151 203 | 
             
                    if get_robot_version() >= (6, 0):
         | 
| 152 204 | 
             
                        if EmbeddedArguments.from_name(name):
         | 
| @@ -182,9 +234,6 @@ class KeywordMatcher: | |
| 182 234 |  | 
| 183 235 | 
             
                @property
         | 
| 184 236 | 
             
                def embedded_arguments(self) -> Any:
         | 
| 185 | 
            -
                    from robot.errors import DataError, VariableError
         | 
| 186 | 
            -
                    from robot.running.arguments.embedded import EmbeddedArguments
         | 
| 187 | 
            -
             | 
| 188 237 | 
             
                    if self._embedded_arguments is None:
         | 
| 189 238 | 
             
                        if self._can_have_embedded:
         | 
| 190 239 | 
             
                            try:
         | 
| @@ -351,13 +400,6 @@ class KeywordArgumentKind(Enum): | |
| 351 400 |  | 
| 352 401 |  | 
| 353 402 | 
             
            def robot_arg_repr(arg: Any) -> Optional[str]:
         | 
| 354 | 
            -
                from robot.running.arguments.argumentspec import ArgInfo
         | 
| 355 | 
            -
             | 
| 356 | 
            -
                if get_robot_version() >= (7, 0):
         | 
| 357 | 
            -
                    from robot.utils import NOT_SET as robot_notset  # noqa: N811
         | 
| 358 | 
            -
                else:
         | 
| 359 | 
            -
                    robot_notset = ArgInfo.NOTSET
         | 
| 360 | 
            -
             | 
| 361 403 | 
             
                robot_arg = cast(ArgInfo, arg)
         | 
| 362 404 |  | 
| 363 405 | 
             
                if robot_arg.default is robot_notset:
         | 
| @@ -389,8 +431,6 @@ class ArgumentInfo: | |
| 389 431 |  | 
| 390 432 | 
             
                @staticmethod
         | 
| 391 433 | 
             
                def from_robot(arg: Any) -> ArgumentInfo:
         | 
| 392 | 
            -
                    from robot.running.arguments.argumentspec import ArgInfo
         | 
| 393 | 
            -
             | 
| 394 434 | 
             
                    robot_arg = cast(ArgInfo, arg)
         | 
| 395 435 |  | 
| 396 436 | 
             
                    return ArgumentInfo(
         | 
| @@ -484,16 +524,6 @@ class ArgumentSpec: | |
| 484 524 | 
             
                    dict_to_kwargs: bool = False,
         | 
| 485 525 | 
             
                    validate: bool = True,
         | 
| 486 526 | 
             
                ) -> Tuple[List[Any], List[Tuple[str, Any]]]:
         | 
| 487 | 
            -
                    from robot.running.arguments.argumentresolver import (
         | 
| 488 | 
            -
                        ArgumentResolver,
         | 
| 489 | 
            -
                        DictToKwargs,
         | 
| 490 | 
            -
                        NamedArgumentResolver,
         | 
| 491 | 
            -
                        VariableReplacer,
         | 
| 492 | 
            -
                    )
         | 
| 493 | 
            -
                    from robot.running.arguments.argumentspec import (
         | 
| 494 | 
            -
                        ArgumentSpec as RobotArgumentSpec,
         | 
| 495 | 
            -
                    )
         | 
| 496 | 
            -
             | 
| 497 527 | 
             
                    if not hasattr(self, "__robot_arguments"):
         | 
| 498 528 | 
             
                        if get_robot_version() < (7, 0):
         | 
| 499 529 | 
             
                            self.__robot_arguments = RobotArgumentSpec(
         | 
| @@ -1352,16 +1382,17 @@ class KeywordWrapper: | |
| 1352 1382 | 
             
                    except BaseException:
         | 
| 1353 1383 | 
             
                        return ""
         | 
| 1354 1384 |  | 
| 1355 | 
            -
                 | 
| 1356 | 
            -
                def is_error_handler(self) -> bool:
         | 
| 1357 | 
            -
                    if get_robot_version() < (7, 0):
         | 
| 1358 | 
            -
                        from robot.running.usererrorhandler import UserErrorHandler
         | 
| 1385 | 
            +
                if get_robot_version() < (7, 0):
         | 
| 1359 1386 |  | 
| 1387 | 
            +
                    @property
         | 
| 1388 | 
            +
                    def is_error_handler(self) -> bool:
         | 
| 1360 1389 | 
             
                        return isinstance(self.kw, UserErrorHandler)
         | 
| 1361 1390 |  | 
| 1362 | 
            -
             | 
| 1391 | 
            +
                else:
         | 
| 1363 1392 |  | 
| 1364 | 
            -
                     | 
| 1393 | 
            +
                    @property
         | 
| 1394 | 
            +
                    def is_error_handler(self) -> bool:
         | 
| 1395 | 
            +
                        return isinstance(self.kw, InvalidKeyword)
         | 
| 1365 1396 |  | 
| 1366 1397 | 
             
                @property
         | 
| 1367 1398 | 
             
                def error_handler_message(self) -> Optional[str]:
         | 
| @@ -1454,7 +1485,6 @@ __default_variables: Any = None | |
| 1454 1485 |  | 
| 1455 1486 |  | 
| 1456 1487 | 
             
            def _get_default_variables() -> Any:
         | 
| 1457 | 
            -
                from robot.variables import Variables
         | 
| 1458 1488 |  | 
| 1459 1489 | 
             
                global __default_variables
         | 
| 1460 1490 | 
             
                if __default_variables is None:
         | 
| @@ -1464,6 +1494,7 @@ def _get_default_variables() -> Any: | |
| 1464 1494 | 
             
                        "${/}": os.sep,
         | 
| 1465 1495 | 
             
                        "${:}": os.pathsep,
         | 
| 1466 1496 | 
             
                        "${\\n}": os.linesep,
         | 
| 1497 | 
            +
                        "${EMPTY}": "",
         | 
| 1467 1498 | 
             
                        "${SPACE}": " ",
         | 
| 1468 1499 | 
             
                        "${True}": True,
         | 
| 1469 1500 | 
             
                        "${False}": False,
         | 
| @@ -1504,7 +1535,6 @@ def resolve_robot_variables( | |
| 1504 1535 | 
             
                command_line_variables: Optional[Dict[str, Optional[Any]]] = None,
         | 
| 1505 1536 | 
             
                variables: Optional[Dict[str, Optional[Any]]] = None,
         | 
| 1506 1537 | 
             
            ) -> Any:
         | 
| 1507 | 
            -
                from robot.variables import Variables
         | 
| 1508 1538 |  | 
| 1509 1539 | 
             
                result: Variables = _get_default_variables().copy()
         | 
| 1510 1540 |  | 
| @@ -1541,15 +1571,17 @@ def resolve_variable( | |
| 1541 1571 | 
             
                command_line_variables: Optional[Dict[str, Optional[Any]]] = None,
         | 
| 1542 1572 | 
             
                variables: Optional[Dict[str, Optional[Any]]] = None,
         | 
| 1543 1573 | 
             
            ) -> Any:
         | 
| 1544 | 
            -
                from robot.variables.finders import VariableFinder
         | 
| 1545 1574 |  | 
| 1546 1575 | 
             
                _update_env(working_dir)
         | 
| 1547 1576 |  | 
| 1548 | 
            -
                 | 
| 1549 | 
            -
             | 
| 1550 | 
            -
                     | 
| 1577 | 
            +
                if contains_variable(name, "$@&%"):
         | 
| 1578 | 
            +
                    robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
         | 
| 1579 | 
            +
                    if get_robot_version() >= (6, 1):
         | 
| 1580 | 
            +
                        return VariableFinder(robot_variables).find(name.replace("\\", "\\\\"))
         | 
| 1581 | 
            +
             | 
| 1582 | 
            +
                    return VariableFinder(robot_variables.store).find(name.replace("\\", "\\\\"))
         | 
| 1551 1583 |  | 
| 1552 | 
            -
                return  | 
| 1584 | 
            +
                return name.replace("\\", "\\\\")
         | 
| 1553 1585 |  | 
| 1554 1586 |  | 
| 1555 1587 | 
             
            @contextmanager
         | 
| @@ -1581,18 +1613,18 @@ def _find_library_internal( | |
| 1581 1613 | 
             
                command_line_variables: Optional[Dict[str, Optional[Any]]] = None,
         | 
| 1582 1614 | 
             
                variables: Optional[Dict[str, Optional[Any]]] = None,
         | 
| 1583 1615 | 
             
            ) -> Tuple[str, Any]:
         | 
| 1584 | 
            -
                from robot.errors import DataError
         | 
| 1585 | 
            -
                from robot.libraries import STDLIBS
         | 
| 1586 | 
            -
                from robot.utils.robotpath import find_file as robot_find_file
         | 
| 1587 1616 |  | 
| 1588 1617 | 
             
                _update_env(working_dir)
         | 
| 1589 1618 |  | 
| 1590 | 
            -
                robot_variables =  | 
| 1619 | 
            +
                robot_variables = None
         | 
| 1591 1620 |  | 
| 1592 | 
            -
                 | 
| 1593 | 
            -
                     | 
| 1594 | 
            -
             | 
| 1595 | 
            -
                     | 
| 1621 | 
            +
                if contains_variable(name, "$@&%"):
         | 
| 1622 | 
            +
                    robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
         | 
| 1623 | 
            +
             | 
| 1624 | 
            +
                    try:
         | 
| 1625 | 
            +
                        name = robot_variables.replace_string(name, ignore_errors=False)
         | 
| 1626 | 
            +
                    except DataError as error:
         | 
| 1627 | 
            +
                        raise DataError(f"Replacing variables from setting 'Library' failed: {error}")
         | 
| 1596 1628 |  | 
| 1597 1629 | 
             
                if name in STDLIBS:
         | 
| 1598 1630 | 
             
                    result = ROBOT_LIBRARY_PACKAGE + "." + name
         | 
| @@ -1622,9 +1654,6 @@ def get_robot_library_html_doc_str( | |
| 1622 1654 | 
             
                base_dir: str = ".",
         | 
| 1623 1655 | 
             
                theme: Optional[str] = None,
         | 
| 1624 1656 | 
             
            ) -> str:
         | 
| 1625 | 
            -
                from robot.libdocpkg import LibraryDocumentation
         | 
| 1626 | 
            -
                from robot.libdocpkg.htmlwriter import LibdocHtmlWriter
         | 
| 1627 | 
            -
             | 
| 1628 1657 | 
             
                _update_env(working_dir)
         | 
| 1629 1658 |  | 
| 1630 1659 | 
             
                if Path(name).suffix.lower() in ALLOWED_RESOURCE_FILE_EXTENSIONS:
         | 
| @@ -1652,15 +1681,6 @@ def get_library_doc( | |
| 1652 1681 | 
             
                command_line_variables: Optional[Dict[str, Optional[Any]]] = None,
         | 
| 1653 1682 | 
             
                variables: Optional[Dict[str, Optional[Any]]] = None,
         | 
| 1654 1683 | 
             
            ) -> LibraryDoc:
         | 
| 1655 | 
            -
                import robot.running.testlibraries
         | 
| 1656 | 
            -
                from robot.libdocpkg.robotbuilder import KeywordDocBuilder
         | 
| 1657 | 
            -
                from robot.libraries import STDLIBS
         | 
| 1658 | 
            -
                from robot.output import LOGGER
         | 
| 1659 | 
            -
                from robot.output.loggerhelper import AbstractLogger
         | 
| 1660 | 
            -
                from robot.running.outputcapture import OutputCapturer
         | 
| 1661 | 
            -
                from robot.running.runkwregister import RUN_KW_REGISTER
         | 
| 1662 | 
            -
                from robot.utils import Importer
         | 
| 1663 | 
            -
             | 
| 1664 1684 | 
             
                class Logger(AbstractLogger):
         | 
| 1665 1685 | 
             
                    def __init__(self) -> None:
         | 
| 1666 1686 | 
             
                        super().__init__()
         | 
| @@ -1951,10 +1971,6 @@ def get_library_doc( | |
| 1951 1971 | 
             
                            )
         | 
| 1952 1972 |  | 
| 1953 1973 | 
             
                            if get_robot_version() >= (6, 1):
         | 
| 1954 | 
            -
                                from robot.libdocpkg.datatypes import (
         | 
| 1955 | 
            -
                                    TypeDoc as RobotTypeDoc,
         | 
| 1956 | 
            -
                                )
         | 
| 1957 | 
            -
                                from robot.running.arguments.argumentspec import TypeInfo
         | 
| 1958 1974 |  | 
| 1959 1975 | 
             
                                def _yield_type_info(info: TypeInfo) -> Iterable[TypeInfo]:
         | 
| 1960 1976 | 
             
                                    if not info.is_union:
         | 
| @@ -2028,25 +2044,24 @@ def _find_variables_internal( | |
| 2028 2044 | 
             
                base_dir: str = ".",
         | 
| 2029 2045 | 
             
                command_line_variables: Optional[Dict[str, Optional[Any]]] = None,
         | 
| 2030 2046 | 
             
                variables: Optional[Dict[str, Optional[Any]]] = None,
         | 
| 2031 | 
            -
            ) ->  | 
| 2032 | 
            -
                from robot.errors import DataError
         | 
| 2033 | 
            -
                from robot.utils.robotpath import find_file as robot_find_file
         | 
| 2047 | 
            +
            ) -> str:
         | 
| 2034 2048 |  | 
| 2035 2049 | 
             
                _update_env(working_dir)
         | 
| 2036 2050 |  | 
| 2037 | 
            -
                 | 
| 2051 | 
            +
                if contains_variable(name, "$@&%"):
         | 
| 2052 | 
            +
                    robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
         | 
| 2038 2053 |  | 
| 2039 | 
            -
             | 
| 2040 | 
            -
             | 
| 2041 | 
            -
             | 
| 2042 | 
            -
             | 
| 2054 | 
            +
                    try:
         | 
| 2055 | 
            +
                        name = robot_variables.replace_string(name, ignore_errors=False)
         | 
| 2056 | 
            +
                    except DataError as error:
         | 
| 2057 | 
            +
                        raise DataError(f"Replacing variables from setting 'Variables' failed: {error}")
         | 
| 2043 2058 |  | 
| 2044 2059 | 
             
                result = name
         | 
| 2045 2060 |  | 
| 2046 2061 | 
             
                if is_variables_by_path(result):
         | 
| 2047 2062 | 
             
                    result = robot_find_file(result, base_dir or ".", "Variables")
         | 
| 2048 2063 |  | 
| 2049 | 
            -
                return  | 
| 2064 | 
            +
                return result
         | 
| 2050 2065 |  | 
| 2051 2066 |  | 
| 2052 2067 | 
             
            def resolve_args(
         | 
| @@ -2076,7 +2091,7 @@ def find_variables( | |
| 2076 2091 | 
             
                variables: Optional[Dict[str, Optional[Any]]] = None,
         | 
| 2077 2092 | 
             
            ) -> str:
         | 
| 2078 2093 | 
             
                if get_robot_version() >= (5, 0):
         | 
| 2079 | 
            -
                    return _find_variables_internal(name, working_dir, base_dir, command_line_variables, variables) | 
| 2094 | 
            +
                    return _find_variables_internal(name, working_dir, base_dir, command_line_variables, variables)
         | 
| 2080 2095 |  | 
| 2081 2096 | 
             
                return find_file(
         | 
| 2082 2097 | 
             
                    name,
         | 
| @@ -2096,13 +2111,6 @@ def get_variables_doc( | |
| 2096 2111 | 
             
                command_line_variables: Optional[Dict[str, Optional[Any]]] = None,
         | 
| 2097 2112 | 
             
                variables: Optional[Dict[str, Optional[Any]]] = None,
         | 
| 2098 2113 | 
             
            ) -> VariablesDoc:
         | 
| 2099 | 
            -
                from robot.libdocpkg.robotbuilder import KeywordDocBuilder
         | 
| 2100 | 
            -
                from robot.output import LOGGER
         | 
| 2101 | 
            -
                from robot.utils.importer import Importer
         | 
| 2102 | 
            -
                from robot.variables.filesetter import PythonImporter, YamlImporter
         | 
| 2103 | 
            -
             | 
| 2104 | 
            -
                if get_robot_version() >= (6, 1):
         | 
| 2105 | 
            -
                    from robot.variables.filesetter import JsonImporter
         | 
| 2106 2114 |  | 
| 2107 2115 | 
             
                import_name: str = name
         | 
| 2108 2116 | 
             
                stem = Path(name).stem
         | 
| @@ -2183,7 +2191,6 @@ def get_variables_doc( | |
| 2183 2191 | 
             
                                    #         super().__init__(name, library)
         | 
| 2184 2192 | 
             
                                    pass
         | 
| 2185 2193 | 
             
                                else:
         | 
| 2186 | 
            -
                                    from robot.running.handlers import _PythonHandler
         | 
| 2187 2194 |  | 
| 2188 2195 | 
             
                                    class VarHandler(_PythonHandler):
         | 
| 2189 2196 | 
             
                                        def _get_name(self, handler_name: Any, handler_method: Any) -> Any:
         | 
| @@ -2229,8 +2236,6 @@ def get_variables_doc( | |
| 2229 2236 |  | 
| 2230 2237 | 
             
                                    pass
         | 
| 2231 2238 | 
             
                                else:
         | 
| 2232 | 
            -
                                    from robot.running.handlers import _PythonInitHandler
         | 
| 2233 | 
            -
             | 
| 2234 2239 | 
             
                                    get_variables = getattr(libcode, "__init__", None) or getattr(libcode, "__init__", None)
         | 
| 2235 2240 |  | 
| 2236 2241 | 
             
                                    class InitVarHandler(_PythonInitHandler):
         | 
| @@ -2344,16 +2349,14 @@ def find_file( | |
| 2344 2349 | 
             
                variables: Optional[Dict[str, Optional[Any]]] = None,
         | 
| 2345 2350 | 
             
                file_type: str = "Resource",
         | 
| 2346 2351 | 
             
            ) -> str:
         | 
| 2347 | 
            -
                from robot.errors import DataError
         | 
| 2348 | 
            -
                from robot.utils.robotpath import find_file as robot_find_file
         | 
| 2349 | 
            -
             | 
| 2350 2352 | 
             
                _update_env(working_dir)
         | 
| 2351 2353 |  | 
| 2352 | 
            -
                 | 
| 2353 | 
            -
             | 
| 2354 | 
            -
                     | 
| 2355 | 
            -
             | 
| 2356 | 
            -
                     | 
| 2354 | 
            +
                if contains_variable(name, "$@&%"):
         | 
| 2355 | 
            +
                    robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
         | 
| 2356 | 
            +
                    try:
         | 
| 2357 | 
            +
                        name = robot_variables.replace_string(name, ignore_errors=False)
         | 
| 2358 | 
            +
                    except DataError as error:
         | 
| 2359 | 
            +
                        raise DataError(f"Replacing variables from setting '{file_type}' failed: {error}")
         | 
| 2357 2360 |  | 
| 2358 2361 | 
             
                return cast(str, robot_find_file(name, base_dir or ".", file_type))
         | 
| 2359 2362 |  | 
| @@ -2616,24 +2619,6 @@ def get_model_doc( | |
| 2616 2619 | 
             
                scope: str = "GLOBAL",
         | 
| 2617 2620 | 
             
                append_model_errors: bool = True,
         | 
| 2618 2621 | 
             
            ) -> LibraryDoc:
         | 
| 2619 | 
            -
                from robot.errors import DataError, VariableError
         | 
| 2620 | 
            -
                from robot.libdocpkg.robotbuilder import KeywordDocBuilder
         | 
| 2621 | 
            -
                from robot.output.logger import LOGGER
         | 
| 2622 | 
            -
                from robot.parsing.lexer.tokens import Token as RobotToken
         | 
| 2623 | 
            -
                from robot.parsing.model.blocks import Keyword
         | 
| 2624 | 
            -
                from robot.parsing.model.statements import Arguments, KeywordName
         | 
| 2625 | 
            -
                from robot.running.builder.transformers import ResourceBuilder
         | 
| 2626 | 
            -
             | 
| 2627 | 
            -
                if get_robot_version() < (7, 0):
         | 
| 2628 | 
            -
                    from robot.running.model import ResourceFile
         | 
| 2629 | 
            -
                    from robot.running.usererrorhandler import UserErrorHandler
         | 
| 2630 | 
            -
                    from robot.running.userkeyword import UserLibrary
         | 
| 2631 | 
            -
                else:
         | 
| 2632 | 
            -
                    from robot.running.invalidkeyword import (
         | 
| 2633 | 
            -
                        InvalidKeyword as UserErrorHandler,
         | 
| 2634 | 
            -
                    )
         | 
| 2635 | 
            -
                    from robot.running.resourcemodel import ResourceFile
         | 
| 2636 | 
            -
             | 
| 2637 2622 | 
             
                errors: List[Error] = []
         | 
| 2638 2623 | 
             
                keyword_name_nodes: List[KeywordName] = []
         | 
| 2639 2624 | 
             
                keywords_nodes: List[Keyword] = []
         |