robotcode-robot 0.94.0__py3-none-any.whl → 0.95.1__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/data_cache.py +83 -0
- robotcode/robot/diagnostics/entities.py +3 -3
- robotcode/robot/diagnostics/errors.py +1 -1
- robotcode/robot/diagnostics/imports_manager.py +100 -99
- robotcode/robot/diagnostics/keyword_finder.py +69 -43
- robotcode/robot/diagnostics/library_doc.py +197 -151
- robotcode/robot/diagnostics/model_helper.py +10 -6
- robotcode/robot/diagnostics/namespace.py +17 -28
- robotcode/robot/diagnostics/namespace_analyzer.py +120 -43
- robotcode/robot/utils/ast.py +0 -7
- robotcode/robot/utils/match.py +2 -2
- robotcode/robot/utils/robot_path.py +15 -16
- robotcode/robot/utils/stubs.py +1 -19
- robotcode/robot/utils/variables.py +35 -0
- robotcode/robot/utils/visitor.py +0 -27
- {robotcode_robot-0.94.0.dist-info → robotcode_robot-0.95.1.dist-info}/METADATA +2 -2
- robotcode_robot-0.95.1.dist-info/RECORD +32 -0
- robotcode_robot-0.94.0.dist-info/RECORD +0 -31
- {robotcode_robot-0.94.0.dist-info → robotcode_robot-0.95.1.dist-info}/WHEEL +0 -0
- {robotcode_robot-0.94.0.dist-info → robotcode_robot-0.95.1.dist-info}/licenses/LICENSE.txt +0 -0
@@ -1,6 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import ast
|
4
|
+
import functools
|
4
5
|
import hashlib
|
5
6
|
import importlib
|
6
7
|
import importlib.util
|
@@ -61,7 +62,6 @@ from robot.variables import Variables
|
|
61
62
|
from robot.variables.filesetter import PythonImporter, YamlImporter
|
62
63
|
from robot.variables.finders import VariableFinder
|
63
64
|
from robot.variables.replacer import VariableReplacer
|
64
|
-
from robot.variables.search import contains_variable
|
65
65
|
from robotcode.core.lsp.types import Position, Range
|
66
66
|
from robotcode.core.utils.path import normalized_path
|
67
67
|
from robotcode.robot.diagnostics.entities import (
|
@@ -76,12 +76,14 @@ from robotcode.robot.utils import get_robot_version
|
|
76
76
|
from robotcode.robot.utils.ast import (
|
77
77
|
cached_isinstance,
|
78
78
|
get_variable_token,
|
79
|
+
iter_nodes,
|
79
80
|
range_from_token,
|
80
81
|
strip_variable_token,
|
81
82
|
)
|
82
83
|
from robotcode.robot.utils.markdownformatter import MarkDownFormatter
|
83
84
|
from robotcode.robot.utils.match import normalize, normalize_namespace
|
84
|
-
|
85
|
+
|
86
|
+
from ..utils.variables import contains_variable
|
85
87
|
|
86
88
|
if get_robot_version() < (7, 0):
|
87
89
|
from robot.running.handlers import _PythonHandler, _PythonInitHandler # pyright: ignore[reportMissingImports]
|
@@ -197,14 +199,29 @@ def convert_from_rest(text: str) -> str:
|
|
197
199
|
return text
|
198
200
|
|
199
201
|
|
202
|
+
if get_robot_version() >= (6, 0):
|
203
|
+
|
204
|
+
@functools.lru_cache(maxsize=None)
|
205
|
+
def _get_embedded_arguments(name: str) -> Any:
|
206
|
+
try:
|
207
|
+
return EmbeddedArguments.from_name(name)
|
208
|
+
except (VariableError, DataError):
|
209
|
+
return ()
|
210
|
+
|
211
|
+
else:
|
212
|
+
|
213
|
+
@functools.lru_cache(maxsize=None)
|
214
|
+
def _get_embedded_arguments(name: str) -> Any:
|
215
|
+
try:
|
216
|
+
return EmbeddedArguments(name)
|
217
|
+
except (VariableError, DataError):
|
218
|
+
return ()
|
219
|
+
|
220
|
+
|
200
221
|
def is_embedded_keyword(name: str) -> bool:
|
201
222
|
try:
|
202
|
-
if
|
203
|
-
|
204
|
-
return True
|
205
|
-
else:
|
206
|
-
if EmbeddedArguments(name):
|
207
|
-
return True
|
223
|
+
if _get_embedded_arguments(name):
|
224
|
+
return True
|
208
225
|
except (VariableError, DataError):
|
209
226
|
return True
|
210
227
|
|
@@ -222,7 +239,11 @@ class KeywordMatcher:
|
|
222
239
|
self._can_have_embedded = can_have_embedded and not is_namespace
|
223
240
|
self._is_namespace = is_namespace
|
224
241
|
self._normalized_name: Optional[str] = None
|
225
|
-
|
242
|
+
|
243
|
+
self.embedded_arguments: Optional[EmbeddedArguments] = (
|
244
|
+
_get_embedded_arguments(self.name) or None if self._can_have_embedded else None
|
245
|
+
)
|
246
|
+
self._match_cache: Dict[str, bool] = {}
|
226
247
|
|
227
248
|
@property
|
228
249
|
def normalized_name(self) -> str:
|
@@ -231,24 +252,18 @@ class KeywordMatcher:
|
|
231
252
|
|
232
253
|
return self._normalized_name
|
233
254
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
try:
|
239
|
-
if get_robot_version() >= (6, 0):
|
240
|
-
self._embedded_arguments = EmbeddedArguments.from_name(self.name)
|
241
|
-
else:
|
242
|
-
self._embedded_arguments = EmbeddedArguments(self.name)
|
243
|
-
except (VariableError, DataError):
|
244
|
-
self._embedded_arguments = ()
|
245
|
-
else:
|
246
|
-
self._embedded_arguments = ()
|
255
|
+
if get_robot_version() >= (6, 0):
|
256
|
+
|
257
|
+
def __match_embedded(self, name: str) -> bool:
|
258
|
+
return self.embedded_arguments is not None and self.embedded_arguments.match(name) is not None
|
247
259
|
|
248
|
-
|
260
|
+
else:
|
261
|
+
|
262
|
+
def __match_embedded(self, name: str) -> bool:
|
263
|
+
return self.embedded_arguments is not None and self.embedded_arguments.name.match(name) is not None
|
249
264
|
|
250
265
|
def __eq__(self, o: object) -> bool:
|
251
|
-
if
|
266
|
+
if type(o) is KeywordMatcher:
|
252
267
|
if self._is_namespace != o._is_namespace:
|
253
268
|
return False
|
254
269
|
|
@@ -257,14 +272,11 @@ class KeywordMatcher:
|
|
257
272
|
|
258
273
|
o = o.name
|
259
274
|
|
260
|
-
if
|
275
|
+
if type(o) is not str:
|
261
276
|
return False
|
262
277
|
|
263
278
|
if self.embedded_arguments:
|
264
|
-
|
265
|
-
return self.embedded_arguments.match(o) is not None
|
266
|
-
|
267
|
-
return self.embedded_arguments.name.match(o) is not None
|
279
|
+
return self.__match_embedded(o)
|
268
280
|
|
269
281
|
return self.normalized_name == str(normalize_namespace(o) if self._is_namespace else normalize(o))
|
270
282
|
|
@@ -649,13 +661,11 @@ class KeywordDoc(SourceEntity):
|
|
649
661
|
def __str__(self) -> str:
|
650
662
|
return f"{self.name}({', '.join(str(arg) for arg in self.arguments)})"
|
651
663
|
|
652
|
-
@
|
664
|
+
@functools.cached_property
|
653
665
|
def matcher(self) -> KeywordMatcher:
|
654
|
-
|
655
|
-
self.__matcher = KeywordMatcher(self.name)
|
656
|
-
return self.__matcher
|
666
|
+
return KeywordMatcher(self.name)
|
657
667
|
|
658
|
-
@
|
668
|
+
@functools.cached_property
|
659
669
|
def is_deprecated(self) -> bool:
|
660
670
|
return self.deprecated or DEPRECATED_PATTERN.match(self.doc) is not None
|
661
671
|
|
@@ -667,13 +677,13 @@ class KeywordDoc(SourceEntity):
|
|
667
677
|
def is_library_keyword(self) -> bool:
|
668
678
|
return self.libtype == "LIBRARY"
|
669
679
|
|
670
|
-
@
|
680
|
+
@functools.cached_property
|
671
681
|
def deprecated_message(self) -> str:
|
672
682
|
if (m := DEPRECATED_PATTERN.match(self.doc)) is not None:
|
673
683
|
return m.group("message").strip()
|
674
684
|
return ""
|
675
685
|
|
676
|
-
@
|
686
|
+
@functools.cached_property
|
677
687
|
def name_range(self) -> Range:
|
678
688
|
if self.name_token is not None:
|
679
689
|
return range_from_token(self.name_token)
|
@@ -691,7 +701,7 @@ class KeywordDoc(SourceEntity):
|
|
691
701
|
|
692
702
|
return "robot:private" in self.normalized_tags()
|
693
703
|
|
694
|
-
@
|
704
|
+
@functools.cached_property
|
695
705
|
def range(self) -> Range:
|
696
706
|
if self.name_token is not None:
|
697
707
|
return range_from_token(self.name_token)
|
@@ -802,7 +812,7 @@ class KeywordDoc(SourceEntity):
|
|
802
812
|
|
803
813
|
return result
|
804
814
|
|
805
|
-
@
|
815
|
+
@functools.cached_property
|
806
816
|
def signature(self) -> str:
|
807
817
|
return (
|
808
818
|
f'({self.type}) "{self.name}": ('
|
@@ -901,20 +911,13 @@ class KeywordStore:
|
|
901
911
|
source_type: Optional[str] = None
|
902
912
|
keywords: List[KeywordDoc] = field(default_factory=list)
|
903
913
|
|
904
|
-
@property
|
905
|
-
def _matchers(self) -> Dict[KeywordMatcher, KeywordDoc]:
|
906
|
-
if not hasattr(self, "__matchers"):
|
907
|
-
self.__matchers = {v.matcher: v for v in self.keywords}
|
908
|
-
return self.__matchers
|
909
|
-
|
910
914
|
def __getitem__(self, key: str) -> KeywordDoc:
|
911
|
-
|
912
|
-
items = [(k, v) for k, v in self._matchers.items() if k == key_matcher]
|
915
|
+
items = [v for v in self.keywords if v.matcher == key]
|
913
916
|
|
914
917
|
if not items:
|
915
918
|
raise KeyError
|
916
919
|
if len(items) == 1:
|
917
|
-
return items[0]
|
920
|
+
return items[0]
|
918
921
|
|
919
922
|
if self.source and self.source_type:
|
920
923
|
file_info = ""
|
@@ -929,16 +932,14 @@ class KeywordStore:
|
|
929
932
|
else:
|
930
933
|
file_info = "File"
|
931
934
|
error = [f"{file_info} contains multiple keywords matching name '{key}':"]
|
932
|
-
names = sorted(
|
935
|
+
names = sorted(v.name for v in items)
|
933
936
|
raise KeywordError(
|
934
937
|
"\n ".join(error + names),
|
935
|
-
multiple_keywords=[v for
|
938
|
+
multiple_keywords=[v for v in items],
|
936
939
|
)
|
937
940
|
|
938
941
|
def __contains__(self, _x: object) -> bool:
|
939
|
-
|
940
|
-
_x = KeywordMatcher(str(_x))
|
941
|
-
return any(k == _x for k in self._matchers.keys())
|
942
|
+
return any(v.matcher == _x for v in self.keywords)
|
942
943
|
|
943
944
|
def __len__(self) -> int:
|
944
945
|
return len(self.keywords)
|
@@ -968,8 +969,7 @@ class KeywordStore:
|
|
968
969
|
return list(self.iter_all(key))
|
969
970
|
|
970
971
|
def iter_all(self, key: str) -> Iterable[KeywordDoc]:
|
971
|
-
|
972
|
-
yield from (v for k, v in self._matchers.items() if k == key_matcher)
|
972
|
+
yield from (v for v in self.keywords if v.matcher == key)
|
973
973
|
|
974
974
|
|
975
975
|
@dataclass
|
@@ -1282,10 +1282,12 @@ class VariablesDoc(LibraryDoc):
|
|
1282
1282
|
return result
|
1283
1283
|
|
1284
1284
|
|
1285
|
+
@functools.lru_cache(maxsize=256)
|
1285
1286
|
def is_library_by_path(path: str) -> bool:
|
1286
1287
|
return path.lower().endswith((".py", "/", os.sep))
|
1287
1288
|
|
1288
1289
|
|
1290
|
+
@functools.lru_cache(maxsize=256)
|
1289
1291
|
def is_variables_by_path(path: str) -> bool:
|
1290
1292
|
if get_robot_version() >= (6, 1):
|
1291
1293
|
return path.lower().endswith((".py", ".yml", ".yaml", ".json", "/", os.sep))
|
@@ -1656,9 +1658,8 @@ def _find_library_internal(
|
|
1656
1658
|
|
1657
1659
|
robot_variables = None
|
1658
1660
|
|
1659
|
-
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
1660
|
-
|
1661
1661
|
if contains_variable(name, "$@&%"):
|
1662
|
+
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
1662
1663
|
try:
|
1663
1664
|
name = robot_variables.replace_string(name, ignore_errors=False)
|
1664
1665
|
except DataError as error:
|
@@ -1711,6 +1712,52 @@ def get_robot_library_html_doc_str(
|
|
1711
1712
|
return output.getvalue()
|
1712
1713
|
|
1713
1714
|
|
1715
|
+
class _Logger(AbstractLogger):
|
1716
|
+
def __init__(self) -> None:
|
1717
|
+
super().__init__()
|
1718
|
+
self.messages: List[Tuple[str, str, bool]] = []
|
1719
|
+
|
1720
|
+
def write(self, message: str, level: str, html: bool = False) -> None:
|
1721
|
+
self.messages.append((message, level, html))
|
1722
|
+
|
1723
|
+
|
1724
|
+
def _import_test_library(name: str) -> Union[Any, Tuple[Any, str]]:
|
1725
|
+
with OutputCapturer(library_import=True):
|
1726
|
+
importer = Importer("test library", LOGGER)
|
1727
|
+
return importer.import_class_or_module(name, return_source=True)
|
1728
|
+
|
1729
|
+
|
1730
|
+
def _get_test_library(
|
1731
|
+
libcode: Any,
|
1732
|
+
source: str,
|
1733
|
+
name: str,
|
1734
|
+
args: Optional[Tuple[Any, ...]] = None,
|
1735
|
+
variables: Optional[Dict[str, Optional[Any]]] = None,
|
1736
|
+
create_handlers: bool = True,
|
1737
|
+
logger: Any = LOGGER,
|
1738
|
+
) -> Any:
|
1739
|
+
if get_robot_version() < (7, 0):
|
1740
|
+
libclass = robot.running.testlibraries._get_lib_class(libcode)
|
1741
|
+
lib = libclass(libcode, name, args or [], source, logger, variables)
|
1742
|
+
if create_handlers:
|
1743
|
+
lib.create_handlers()
|
1744
|
+
else:
|
1745
|
+
lib = robot.running.testlibraries.TestLibrary.from_code(
|
1746
|
+
libcode,
|
1747
|
+
name,
|
1748
|
+
source=Path(source),
|
1749
|
+
args=args or [],
|
1750
|
+
variables=variables,
|
1751
|
+
create_keywords=create_handlers,
|
1752
|
+
logger=logger,
|
1753
|
+
)
|
1754
|
+
|
1755
|
+
return lib
|
1756
|
+
|
1757
|
+
|
1758
|
+
_T = TypeVar("_T")
|
1759
|
+
|
1760
|
+
|
1714
1761
|
def get_library_doc(
|
1715
1762
|
name: str,
|
1716
1763
|
args: Optional[Tuple[Any, ...]] = None,
|
@@ -1719,45 +1766,6 @@ def get_library_doc(
|
|
1719
1766
|
command_line_variables: Optional[Dict[str, Optional[Any]]] = None,
|
1720
1767
|
variables: Optional[Dict[str, Optional[Any]]] = None,
|
1721
1768
|
) -> LibraryDoc:
|
1722
|
-
class Logger(AbstractLogger):
|
1723
|
-
def __init__(self) -> None:
|
1724
|
-
super().__init__()
|
1725
|
-
self.messages: List[Tuple[str, str, bool]] = []
|
1726
|
-
|
1727
|
-
def write(self, message: str, level: str, html: bool = False) -> None:
|
1728
|
-
self.messages.append((message, level, html))
|
1729
|
-
|
1730
|
-
def import_test_library(name: str) -> Union[Any, Tuple[Any, str]]:
|
1731
|
-
with OutputCapturer(library_import=True):
|
1732
|
-
importer = Importer("test library", LOGGER)
|
1733
|
-
return importer.import_class_or_module(name, return_source=True)
|
1734
|
-
|
1735
|
-
def get_test_library(
|
1736
|
-
libcode: Any,
|
1737
|
-
source: str,
|
1738
|
-
name: str,
|
1739
|
-
args: Optional[Tuple[Any, ...]] = None,
|
1740
|
-
variables: Optional[Dict[str, Optional[Any]]] = None,
|
1741
|
-
create_handlers: bool = True,
|
1742
|
-
logger: Any = LOGGER,
|
1743
|
-
) -> Any:
|
1744
|
-
if get_robot_version() < (7, 0):
|
1745
|
-
libclass = robot.running.testlibraries._get_lib_class(libcode)
|
1746
|
-
lib = libclass(libcode, name, args or [], source, logger, variables)
|
1747
|
-
if create_handlers:
|
1748
|
-
lib.create_handlers()
|
1749
|
-
else:
|
1750
|
-
lib = robot.running.testlibraries.TestLibrary.from_code(
|
1751
|
-
libcode,
|
1752
|
-
name,
|
1753
|
-
source=Path(source),
|
1754
|
-
args=args or [],
|
1755
|
-
variables=variables,
|
1756
|
-
create_keywords=create_handlers,
|
1757
|
-
logger=logger,
|
1758
|
-
)
|
1759
|
-
|
1760
|
-
return lib
|
1761
1769
|
|
1762
1770
|
with _std_capture() as std_capturer:
|
1763
1771
|
import_name, robot_variables = _find_library_internal(
|
@@ -1781,7 +1789,7 @@ def get_library_doc(
|
|
1781
1789
|
|
1782
1790
|
source = None
|
1783
1791
|
try:
|
1784
|
-
libcode, source =
|
1792
|
+
libcode, source = _import_test_library(import_name)
|
1785
1793
|
except (SystemExit, KeyboardInterrupt):
|
1786
1794
|
raise
|
1787
1795
|
except BaseException as e:
|
@@ -1821,13 +1829,17 @@ def get_library_doc(
|
|
1821
1829
|
|
1822
1830
|
lib = None
|
1823
1831
|
try:
|
1824
|
-
lib =
|
1832
|
+
lib = _get_test_library(
|
1825
1833
|
libcode,
|
1826
1834
|
source,
|
1827
1835
|
library_name,
|
1828
1836
|
args,
|
1829
1837
|
create_handlers=False,
|
1830
|
-
variables=
|
1838
|
+
variables=(
|
1839
|
+
robot_variables
|
1840
|
+
if robot_variables is not None
|
1841
|
+
else resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
1842
|
+
),
|
1831
1843
|
)
|
1832
1844
|
if get_robot_version() < (7, 0):
|
1833
1845
|
_ = lib.get_instance()
|
@@ -1847,7 +1859,7 @@ def get_library_doc(
|
|
1847
1859
|
|
1848
1860
|
if args:
|
1849
1861
|
try:
|
1850
|
-
lib =
|
1862
|
+
lib = _get_test_library(libcode, source, library_name, (), create_handlers=False)
|
1851
1863
|
if get_robot_version() < (7, 0):
|
1852
1864
|
_ = lib.get_instance()
|
1853
1865
|
else:
|
@@ -1862,6 +1874,10 @@ def get_library_doc(
|
|
1862
1874
|
libdoc = LibraryDoc(
|
1863
1875
|
name=library_name,
|
1864
1876
|
source=real_source,
|
1877
|
+
line_no=lib.lineno if lib is not None else -1,
|
1878
|
+
version=str(lib.version) if lib is not None else "",
|
1879
|
+
scope=str(lib.scope) if lib is not None else ROBOT_DEFAULT_SCOPE,
|
1880
|
+
doc_format=(str(lib.doc_format) or ROBOT_DOC_FORMAT) if lib is not None else ROBOT_DOC_FORMAT,
|
1865
1881
|
module_spec=(
|
1866
1882
|
module_spec
|
1867
1883
|
if module_spec is not None
|
@@ -1870,16 +1886,33 @@ def get_library_doc(
|
|
1870
1886
|
else None
|
1871
1887
|
),
|
1872
1888
|
python_path=sys.path,
|
1873
|
-
line_no=lib.lineno if lib is not None else -1,
|
1874
|
-
doc=str(lib.doc) if lib is not None else "",
|
1875
|
-
version=str(lib.version) if lib is not None else "",
|
1876
|
-
scope=str(lib.scope) if lib is not None else ROBOT_DEFAULT_SCOPE,
|
1877
|
-
doc_format=(str(lib.doc_format) or ROBOT_DOC_FORMAT) if lib is not None else ROBOT_DOC_FORMAT,
|
1878
1889
|
member_name=module_spec.member_name if module_spec is not None else None,
|
1879
1890
|
)
|
1880
1891
|
|
1881
1892
|
if lib is not None:
|
1882
1893
|
try:
|
1894
|
+
|
1895
|
+
def _get(handler: Callable[[], _T]) -> Optional[_T]:
|
1896
|
+
try:
|
1897
|
+
return handler()
|
1898
|
+
except (SystemExit, KeyboardInterrupt):
|
1899
|
+
raise
|
1900
|
+
except BaseException as e:
|
1901
|
+
errors.append(
|
1902
|
+
error_from_exception(
|
1903
|
+
e,
|
1904
|
+
source or module_spec.origin if module_spec is not None else None,
|
1905
|
+
(
|
1906
|
+
1
|
1907
|
+
if source is not None or module_spec is not None and module_spec.origin is not None
|
1908
|
+
else None
|
1909
|
+
),
|
1910
|
+
)
|
1911
|
+
)
|
1912
|
+
return None
|
1913
|
+
|
1914
|
+
libdoc.doc = _get(lambda: str(lib.doc) if lib is not None else "") or ""
|
1915
|
+
|
1883
1916
|
if get_robot_version() < (7, 0):
|
1884
1917
|
libdoc.has_listener = lib.has_listener
|
1885
1918
|
|
@@ -1909,10 +1942,10 @@ def get_library_doc(
|
|
1909
1942
|
keywords=[
|
1910
1943
|
KeywordDoc(
|
1911
1944
|
name=libdoc.name,
|
1912
|
-
arguments=[ArgumentInfo.from_robot(a) for a in kw[0].args],
|
1913
|
-
doc=kw[0].doc,
|
1914
|
-
tags=list(kw[0].tags),
|
1915
|
-
source=kw[0].source,
|
1945
|
+
arguments=_get(lambda: [ArgumentInfo.from_robot(a) for a in kw[0].args]) or [],
|
1946
|
+
doc=_get(lambda: kw[0].doc) or "",
|
1947
|
+
tags=_get(lambda: list(kw[0].tags)) or [],
|
1948
|
+
source=_get(lambda: kw[0].source) or "",
|
1916
1949
|
line_no=kw[0].lineno if kw[0].lineno is not None else -1,
|
1917
1950
|
col_offset=-1,
|
1918
1951
|
end_col_offset=-1,
|
@@ -1923,20 +1956,23 @@ def get_library_doc(
|
|
1923
1956
|
longname=f"{libdoc.name}.{kw[0].name}",
|
1924
1957
|
doc_format=str(lib.doc_format) or ROBOT_DOC_FORMAT,
|
1925
1958
|
is_initializer=True,
|
1926
|
-
arguments_spec=
|
1927
|
-
|
1959
|
+
arguments_spec=_get(
|
1960
|
+
lambda: ArgumentSpec.from_robot_argument_spec(
|
1961
|
+
kw[1].arguments if get_robot_version() < (7, 0) else kw[1].args
|
1962
|
+
)
|
1928
1963
|
),
|
1929
1964
|
)
|
1930
1965
|
for kw in init_keywords
|
1931
1966
|
]
|
1932
1967
|
)
|
1933
1968
|
|
1934
|
-
logger =
|
1935
|
-
lib.logger = logger
|
1969
|
+
logger = _Logger()
|
1936
1970
|
|
1937
1971
|
if get_robot_version() < (7, 0):
|
1972
|
+
lib.logger = logger
|
1938
1973
|
lib.create_handlers()
|
1939
1974
|
else:
|
1975
|
+
lib._logger = logger
|
1940
1976
|
lib.create_keywords()
|
1941
1977
|
|
1942
1978
|
for m in logger.messages:
|
@@ -1969,10 +2005,10 @@ def get_library_doc(
|
|
1969
2005
|
keywords=[
|
1970
2006
|
KeywordDoc(
|
1971
2007
|
name=kw[0].name,
|
1972
|
-
arguments=[ArgumentInfo.from_robot(a) for a in kw[0].args],
|
1973
|
-
doc=kw[0].doc,
|
1974
|
-
tags=list(kw[0].tags),
|
1975
|
-
source=kw[0].source,
|
2008
|
+
arguments=_get(lambda: [ArgumentInfo.from_robot(a) for a in kw[0].args]) or [],
|
2009
|
+
doc=_get(lambda: kw[0].doc) or "",
|
2010
|
+
tags=_get(lambda: list(kw[0].tags)) or [],
|
2011
|
+
source=_get(lambda: kw[0].source) or "",
|
1976
2012
|
line_no=kw[0].lineno if kw[0].lineno is not None else -1,
|
1977
2013
|
col_offset=-1,
|
1978
2014
|
end_col_offset=-1,
|
@@ -1987,21 +2023,26 @@ def get_library_doc(
|
|
1987
2023
|
is_registered_run_keyword=RUN_KW_REGISTER.is_run_keyword(libdoc.name, kw[0].name),
|
1988
2024
|
args_to_process=get_args_to_process(libdoc.name, kw[0].name),
|
1989
2025
|
deprecated=kw[0].deprecated,
|
1990
|
-
arguments_spec=(
|
1991
|
-
|
1992
|
-
|
2026
|
+
arguments_spec=_get(
|
2027
|
+
lambda: (
|
2028
|
+
ArgumentSpec.from_robot_argument_spec(
|
2029
|
+
kw[1].arguments if get_robot_version() < (7, 0) else kw[1].args
|
2030
|
+
)
|
2031
|
+
if not kw[1].is_error_handler
|
2032
|
+
else None
|
1993
2033
|
)
|
1994
|
-
if not kw[1].is_error_handler
|
1995
|
-
else None
|
1996
2034
|
),
|
1997
|
-
return_type=(
|
1998
|
-
(
|
1999
|
-
|
2000
|
-
|
2035
|
+
return_type=_get(
|
2036
|
+
lambda: (
|
2037
|
+
(
|
2038
|
+
str(kw[1].args.return_type)
|
2039
|
+
if kw[1].args.return_type is not None
|
2040
|
+
and kw[1].args.return_type is not type(None)
|
2041
|
+
else None
|
2042
|
+
)
|
2043
|
+
if get_robot_version() >= (7, 0)
|
2001
2044
|
else None
|
2002
2045
|
)
|
2003
|
-
if get_robot_version() >= (7, 0)
|
2004
|
-
else None
|
2005
2046
|
),
|
2006
2047
|
)
|
2007
2048
|
for kw in keyword_docs
|
@@ -2086,9 +2127,8 @@ def _find_variables_internal(
|
|
2086
2127
|
|
2087
2128
|
_update_env(working_dir)
|
2088
2129
|
|
2089
|
-
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
2090
|
-
|
2091
2130
|
if contains_variable(name, "$@&%"):
|
2131
|
+
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
2092
2132
|
try:
|
2093
2133
|
name = robot_variables.replace_string(name, ignore_errors=False)
|
2094
2134
|
except DataError as error:
|
@@ -2109,12 +2149,18 @@ def resolve_args(
|
|
2109
2149
|
command_line_variables: Optional[Dict[str, Optional[Any]]] = None,
|
2110
2150
|
variables: Optional[Dict[str, Optional[Any]]] = None,
|
2111
2151
|
) -> Tuple[Any, ...]:
|
2112
|
-
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
2152
|
+
# robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
2153
|
+
robot_variables: Any = None
|
2113
2154
|
|
2114
2155
|
result = []
|
2115
2156
|
for arg in args:
|
2116
2157
|
if isinstance(arg, str):
|
2117
|
-
|
2158
|
+
if contains_variable(arg, "$@&%"):
|
2159
|
+
if robot_variables is None:
|
2160
|
+
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
2161
|
+
result.append(robot_variables.replace_string(arg, ignore_errors=True))
|
2162
|
+
else:
|
2163
|
+
result.append(arg)
|
2118
2164
|
else:
|
2119
2165
|
result.append(arg)
|
2120
2166
|
|
@@ -2389,8 +2435,8 @@ def find_file(
|
|
2389
2435
|
) -> str:
|
2390
2436
|
_update_env(working_dir)
|
2391
2437
|
|
2392
|
-
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
2393
2438
|
if contains_variable(name, "$@&%"):
|
2439
|
+
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
2394
2440
|
try:
|
2395
2441
|
name = robot_variables.replace_string(name, ignore_errors=False)
|
2396
2442
|
except DataError as error:
|
@@ -2492,7 +2538,7 @@ def complete_library_import(
|
|
2492
2538
|
if e not in DEFAULT_LIBRARIES
|
2493
2539
|
]
|
2494
2540
|
|
2495
|
-
if name is not None:
|
2541
|
+
if name is not None and contains_variable(name, "$@&%"):
|
2496
2542
|
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
2497
2543
|
|
2498
2544
|
name = robot_variables.replace_string(name, ignore_errors=True)
|
@@ -2568,7 +2614,7 @@ def complete_resource_import(
|
|
2568
2614
|
|
2569
2615
|
result: List[CompleteResult] = []
|
2570
2616
|
|
2571
|
-
if name is not None:
|
2617
|
+
if name is not None and contains_variable(name, "$@&%"):
|
2572
2618
|
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
2573
2619
|
|
2574
2620
|
name = robot_variables.replace_string(name, ignore_errors=True)
|
@@ -2608,7 +2654,7 @@ def complete_variables_import(
|
|
2608
2654
|
|
2609
2655
|
result: List[CompleteResult] = []
|
2610
2656
|
|
2611
|
-
if name is not None:
|
2657
|
+
if name is not None and contains_variable(name, "$@&%"):
|
2612
2658
|
robot_variables = resolve_robot_variables(working_dir, base_dir, command_line_variables, variables)
|
2613
2659
|
|
2614
2660
|
name = robot_variables.replace_string(name, ignore_errors=True)
|
@@ -2656,15 +2702,16 @@ def get_model_doc(
|
|
2656
2702
|
append_model_errors: bool = True,
|
2657
2703
|
) -> LibraryDoc:
|
2658
2704
|
errors: List[Error] = []
|
2659
|
-
keyword_name_nodes:
|
2660
|
-
keywords_nodes:
|
2661
|
-
for node in
|
2662
|
-
if
|
2663
|
-
|
2664
|
-
|
2665
|
-
|
2666
|
-
|
2667
|
-
|
2705
|
+
keyword_name_nodes: Dict[int, KeywordName] = {}
|
2706
|
+
keywords_nodes: Dict[int, Keyword] = {}
|
2707
|
+
for node in iter_nodes(model):
|
2708
|
+
if cached_isinstance(node, Keyword):
|
2709
|
+
node.lineno
|
2710
|
+
keywords_nodes[node.lineno] = node
|
2711
|
+
if cached_isinstance(node, KeywordName):
|
2712
|
+
keyword_name_nodes[node.lineno] = node
|
2713
|
+
|
2714
|
+
error = getattr(node, "error", None)
|
2668
2715
|
if error is not None:
|
2669
2716
|
errors.append(
|
2670
2717
|
Error(
|
@@ -2675,7 +2722,7 @@ def get_model_doc(
|
|
2675
2722
|
)
|
2676
2723
|
)
|
2677
2724
|
if append_model_errors:
|
2678
|
-
node_errors =
|
2725
|
+
node_errors = getattr(node, "errors", None)
|
2679
2726
|
if node_errors is not None:
|
2680
2727
|
for e in node_errors:
|
2681
2728
|
errors.append(
|
@@ -2688,16 +2735,15 @@ def get_model_doc(
|
|
2688
2735
|
)
|
2689
2736
|
|
2690
2737
|
def get_keyword_name_token_from_line(line: int) -> Optional[Token]:
|
2691
|
-
|
2692
|
-
|
2693
|
-
|
2694
|
-
|
2695
|
-
return None
|
2738
|
+
keyword_name = keyword_name_nodes.get(line, None)
|
2739
|
+
if keyword_name is None:
|
2740
|
+
return None
|
2741
|
+
return cast(Token, keyword_name.get_token(RobotToken.KEYWORD_NAME))
|
2696
2742
|
|
2697
2743
|
def get_argument_definitions_from_line(
|
2698
2744
|
line: int,
|
2699
2745
|
) -> List[ArgumentDefinition]:
|
2700
|
-
keyword_node =
|
2746
|
+
keyword_node = keywords_nodes.get(line, None)
|
2701
2747
|
if keyword_node is None:
|
2702
2748
|
return []
|
2703
2749
|
|