robotcode-robot 0.68.0__py3-none-any.whl → 0.68.2__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.
@@ -1,8 +1,7 @@
1
1
  from typing import Optional
2
2
 
3
- from robotcode.core.utils.version import Version, create_version_from_str
4
-
5
3
  import robot.version
4
+ from robotcode.core.utils.version import Version, create_version_from_str
6
5
 
7
6
  _robot_version: Optional[Version] = None
8
7
 
@@ -2,24 +2,15 @@ from __future__ import annotations
2
2
 
3
3
  import ast
4
4
  import itertools
5
- from typing import (
6
- Any,
7
- AsyncIterator,
8
- Iterator,
9
- List,
10
- Optional,
11
- Sequence,
12
- Set,
13
- Tuple,
14
- )
15
-
16
- from robotcode.core.lsp.types import Position, Range
5
+ from typing import Any, Iterator, List, Optional, Sequence, Set, Tuple
17
6
 
18
7
  from robot.errors import VariableError
19
8
  from robot.parsing.lexer.tokens import Token
20
9
  from robot.parsing.model.statements import EmptyLine, Statement
10
+ from robotcode.core.lsp.types import Position, Range
21
11
 
22
- from . import get_robot_version, visitors
12
+ from . import get_robot_version
13
+ from .visitor import Visitor
23
14
 
24
15
  if get_robot_version() < (7, 0):
25
16
  from robot.variables.search import VariableIterator
@@ -45,14 +36,11 @@ def iter_nodes(node: ast.AST, descendants: bool = True) -> Iterator[ast.AST]:
45
36
  def range_from_token(token: Token) -> Range:
46
37
  return Range(
47
38
  start=Position(line=token.lineno - 1, character=token.col_offset),
48
- end=Position(
49
- line=token.lineno - 1,
50
- character=token.end_col_offset,
51
- ),
39
+ end=Position(line=token.lineno - 1, character=token.end_col_offset),
52
40
  )
53
41
 
54
42
 
55
- class FirstAndLastRealStatementFinder(visitors.Visitor):
43
+ class FirstAndLastRealStatementFinder(Visitor):
56
44
  def __init__(self) -> None:
57
45
  super().__init__()
58
46
  self.first_statement: Optional[ast.AST] = None
@@ -113,12 +101,18 @@ def _get_non_data_range_from_node(
113
101
  None,
114
102
  )
115
103
  if start_token is not None and end_token is not None:
116
- return Range(start=range_from_token(start_token).start, end=range_from_token(end_token).end)
104
+ return Range(
105
+ start=range_from_token(start_token).start,
106
+ end=range_from_token(end_token).end,
107
+ )
117
108
  return None
118
109
 
119
110
 
120
111
  def range_from_node(
121
- node: ast.AST, skip_non_data: bool = False, only_start: bool = False, allow_comments: bool = False
112
+ node: ast.AST,
113
+ skip_non_data: bool = False,
114
+ only_start: bool = False,
115
+ allow_comments: bool = False,
122
116
  ) -> Range:
123
117
  if skip_non_data:
124
118
  if isinstance(node, Statement) and node.tokens:
@@ -206,20 +200,20 @@ def get_tokens_at_position(node: Statement, position: Position, include_end: boo
206
200
  ]
207
201
 
208
202
 
209
- def iter_nodes_at_position(node: ast.AST, position: Position, include_end: bool = False) -> AsyncIterator[ast.AST]:
203
+ def iter_nodes_at_position(node: ast.AST, position: Position, include_end: bool = False) -> Iterator[ast.AST]:
210
204
  return (
211
205
  n
212
- async for n in visitors.iter_nodes(node)
206
+ for n in iter_nodes(node)
213
207
  if position.is_in_range(range := range_from_node(n), include_end) or include_end and range.end == position
214
208
  )
215
209
 
216
210
 
217
- async def get_nodes_at_position(node: ast.AST, position: Position, include_end: bool = False) -> List[ast.AST]:
218
- return [n async for n in iter_nodes_at_position(node, position, include_end)]
211
+ def get_nodes_at_position(node: ast.AST, position: Position, include_end: bool = False) -> List[ast.AST]:
212
+ return [n for n in iter_nodes_at_position(node, position, include_end)]
219
213
 
220
214
 
221
- async def get_node_at_position(node: ast.AST, position: Position, include_end: bool = False) -> Optional[ast.AST]:
222
- result_nodes = await get_nodes_at_position(node, position, include_end)
215
+ def get_node_at_position(node: ast.AST, position: Position, include_end: bool = False) -> Optional[ast.AST]:
216
+ result_nodes = get_nodes_at_position(node, position, include_end)
223
217
  if not result_nodes:
224
218
  return None
225
219
 
@@ -231,7 +225,11 @@ def _tokenize_no_variables(token: Token) -> Iterator[Token]:
231
225
 
232
226
 
233
227
  def tokenize_variables(
234
- token: Token, identifiers: str = "$@&%", ignore_errors: bool = False, *, extra_types: Optional[Set[str]] = None
228
+ token: Token,
229
+ identifiers: str = "$@&%",
230
+ ignore_errors: bool = False,
231
+ *,
232
+ extra_types: Optional[Set[str]] = None,
235
233
  ) -> Iterator[Token]:
236
234
  if token.type not in {
237
235
  *Token.ALLOW_VARIABLES,
@@ -281,7 +279,9 @@ else:
281
279
  yield Token(token.type, after, lineno, col_offset)
282
280
 
283
281
 
284
- def iter_over_keyword_names_and_owners(full_name: str) -> Iterator[Tuple[Optional[str], ...]]:
282
+ def iter_over_keyword_names_and_owners(
283
+ full_name: str,
284
+ ) -> Iterator[Tuple[Optional[str], ...]]:
285
285
  yield None, full_name
286
286
 
287
287
  tokens = full_name.split(".")
@@ -301,7 +301,12 @@ def strip_variable_token(token: Token) -> Token:
301
301
 
302
302
  stripped_value = value.lstrip()
303
303
  stripped_offset = len(value) - len(stripped_value)
304
- return Token(token.type, stripped_value.rstrip(), token.lineno, token.col_offset + 2 + stripped_offset)
304
+ return Token(
305
+ token.type,
306
+ stripped_value.rstrip(),
307
+ token.lineno,
308
+ token.col_offset + 2 + stripped_offset,
309
+ )
305
310
 
306
311
  return token
307
312
 
@@ -150,7 +150,7 @@ class LinkFormatter:
150
150
  return "".join(f(t) for f, t in zip(formatters, tokens))
151
151
 
152
152
  def _format_link(self, text: str) -> str:
153
- link, content = [t.strip() for t in text.split("|", 1)]
153
+ link, content = (t.strip() for t in text.split("|", 1))
154
154
  if self._is_image(content):
155
155
  content = self._get_image(content, link)
156
156
  elif self._is_image(link):
@@ -171,7 +171,7 @@ class LinkFormatter:
171
171
  if "|" not in text:
172
172
  return text
173
173
 
174
- link, content = [t.strip() for t in text.split("|", 1)]
174
+ link, content = (t.strip() for t in text.split("|", 1))
175
175
  if self._is_image(content):
176
176
  return self._get_image(content, link)
177
177
 
@@ -0,0 +1,23 @@
1
+ from functools import lru_cache
2
+
3
+
4
+ @lru_cache(maxsize=5000)
5
+ def normalize(text: str) -> str:
6
+ return text.lower().replace("_", "").replace(" ", "")
7
+
8
+
9
+ @lru_cache(maxsize=5000)
10
+ def normalize_namespace(text: str) -> str:
11
+ return text.lower().replace(" ", "")
12
+
13
+
14
+ def eq(str1: str, str2: str) -> bool:
15
+ str1 = normalize(str1)
16
+ str2 = normalize(str2)
17
+ return str1 == str2
18
+
19
+
20
+ def eq_namespace(str1: str, str2: str) -> bool:
21
+ str1 = normalize_namespace(str1)
22
+ str2 = normalize_namespace(str2)
23
+ return str1 == str2
@@ -0,0 +1,70 @@
1
+ from __future__ import annotations
2
+
3
+ import sys
4
+ from os import PathLike
5
+ from pathlib import Path
6
+ from typing import Optional, Union
7
+
8
+
9
+ def find_file(
10
+ path: Union[Path, PathLike[str], str],
11
+ basedir: Union[Path, PathLike[str], str] = ".",
12
+ file_type: Optional[str] = None,
13
+ ) -> str:
14
+ return find_file_ex(path, basedir, file_type)
15
+
16
+
17
+ def find_file_ex(
18
+ path: Union[Path, PathLike[str], str],
19
+ basedir: Union[Path, PathLike[str], str] = ".",
20
+ file_type: Optional[str] = None,
21
+ ) -> str:
22
+ from robot.errors import DataError
23
+
24
+ path = Path(path)
25
+ ret = _find_absolute_path(path) if path.is_absolute() else _find_relative_path(path, basedir)
26
+ if ret:
27
+ return str(ret)
28
+ default = file_type or "File"
29
+
30
+ file_type = (
31
+ {
32
+ "Library": "Test library",
33
+ "Variables": "Variable file",
34
+ "Resource": "Resource file",
35
+ }.get(file_type, default)
36
+ if file_type
37
+ else default
38
+ )
39
+
40
+ raise DataError("%s '%s' does not exist." % (file_type, path))
41
+
42
+
43
+ def _find_absolute_path(path: Union[Path, PathLike[str], str]) -> Optional[str]:
44
+ if _is_valid_file(path):
45
+ return str(path)
46
+ return None
47
+
48
+
49
+ def _find_relative_path(
50
+ path: Union[Path, PathLike[str], str],
51
+ basedir: Union[Path, PathLike[str], str],
52
+ ) -> Optional[str]:
53
+ for base in [basedir, *sys.path]:
54
+ if not base:
55
+ continue
56
+ base_path = Path(base)
57
+
58
+ if not base_path.is_dir():
59
+ continue
60
+
61
+ ret = Path(base, path).absolute()
62
+
63
+ if _is_valid_file(ret):
64
+ return str(ret)
65
+ return None
66
+
67
+
68
+ def _is_valid_file(path: Union[Path, PathLike[str], str]) -> bool:
69
+ path = Path(path)
70
+ return path.is_file() or (path.is_dir() and Path(path, "__init__.py").is_fifo())
@@ -0,0 +1,24 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, List, Optional, Protocol, runtime_checkable
4
+
5
+
6
+ @runtime_checkable
7
+ class HasError(Protocol):
8
+ error: Optional[str]
9
+
10
+
11
+ @runtime_checkable
12
+ class HasErrors(Protocol):
13
+ errors: Optional[List[str]]
14
+
15
+
16
+ @runtime_checkable
17
+ class HeaderAndBodyBlock(Protocol):
18
+ header: Any
19
+ body: List[Any]
20
+
21
+
22
+ @runtime_checkable
23
+ class BodyBlock(Protocol):
24
+ body: List[Any]
@@ -0,0 +1,37 @@
1
+ BUILTIN_VARIABLES = [
2
+ "${CURDIR}",
3
+ "${EMPTY}",
4
+ "${TEMPDIR}",
5
+ "${EXECDIR}",
6
+ "${/}",
7
+ "${:}",
8
+ "${\\n}",
9
+ "${SPACE}",
10
+ "${True}",
11
+ "${False}",
12
+ "${None}",
13
+ "${null}",
14
+ "${OPTIONS}",
15
+ "${TEST_NAME}",
16
+ "@{TEST_TAGS}",
17
+ "${TEST_DOCUMENTATION}",
18
+ "${TEST_STATUS}",
19
+ "${TEST_MESSAGE}",
20
+ "${PREV_TEST_NAME}",
21
+ "${PREV_TEST_STATUS}",
22
+ "${PREV_TEST_MESSAGE}",
23
+ "${SUITE_NAME}",
24
+ "${SUITE_SOURCE}",
25
+ "${SUITE_DOCUMENTATION}",
26
+ "&{SUITE_METADATA}",
27
+ "${SUITE_STATUS}",
28
+ "${SUITE_MESSAGE}",
29
+ "${KEYWORD_STATUS}",
30
+ "${KEYWORD_MESSAGE}",
31
+ "${LOG_LEVEL}",
32
+ "${OUTPUT_FILE}",
33
+ "${LOG_FILE}",
34
+ "${REPORT_FILE}",
35
+ "${DEBUG_FILE}",
36
+ "${OUTPUT_DIR}",
37
+ ]
@@ -1,13 +1,19 @@
1
1
  import ast
2
2
  from abc import ABC
3
3
  from collections import defaultdict
4
-
5
- from typing_extensions import Any, AsyncIterator, Callable, Dict, Iterator, Optional, Type, Union
4
+ from typing import (
5
+ Any,
6
+ AsyncIterator,
7
+ Callable,
8
+ Dict,
9
+ Iterator,
10
+ Optional,
11
+ Type,
12
+ Union,
13
+ )
6
14
 
7
15
  from robot.parsing.model.statements import Statement
8
16
 
9
- __all__ = ["iter_fields", "iter_child_nodes", "AsyncVisitor"]
10
-
11
17
 
12
18
  def _patch_robot() -> None:
13
19
  if hasattr(Statement, "_fields"):
@@ -93,23 +99,6 @@ class VisitorFinder(ABC):
93
99
  return result # type: ignore[return-value]
94
100
 
95
101
 
96
- class AsyncVisitor(VisitorFinder):
97
- async def visit(self, node: ast.AST) -> None:
98
- visitor = self._find_visitor(type(node)) or self.__class__.generic_visit
99
- await visitor(self, node)
100
-
101
- async def generic_visit(self, node: ast.AST) -> None:
102
- for value in iter_field_values(node):
103
- if value is None:
104
- continue
105
- if isinstance(value, ast.AST):
106
- await self.visit(value)
107
- elif isinstance(value, list):
108
- for item in value:
109
- if isinstance(item, ast.AST):
110
- await self.visit(item)
111
-
112
-
113
102
  class Visitor(VisitorFinder):
114
103
  def visit(self, node: ast.AST) -> None:
115
104
  visitor = self._find_visitor(type(node)) or self.__class__.generic_visit
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: robotcode-robot
3
- Version: 0.68.0
3
+ Version: 0.68.2
4
4
  Summary: Support classes for RobotCode for handling Robot Framework projects.
5
5
  Project-URL: Homepage, https://robotcode.io
6
6
  Project-URL: Donate, https://github.com/sponsors/d-biehl
@@ -9,7 +9,7 @@ Project-URL: Changelog, https://github.com/d-biehl/robotcode/blob/main/CHANGELOG
9
9
  Project-URL: Issues, https://github.com/d-biehl/robotcode/issues
10
10
  Project-URL: Source, https://github.com/d-biehl/robotcode
11
11
  Author-email: Daniel Biehl <dbiehl@live.de>
12
- License-Expression: Apache-2.0
12
+ License: Apache-2.0
13
13
  License-File: LICENSE.txt
14
14
  Classifier: Development Status :: 5 - Production/Stable
15
15
  Classifier: Framework :: Robot Framework
@@ -25,8 +25,8 @@ Classifier: Programming Language :: Python :: Implementation :: PyPy
25
25
  Classifier: Topic :: Utilities
26
26
  Classifier: Typing :: Typed
27
27
  Requires-Python: >=3.8
28
- Requires-Dist: platformdirs<3.12.0,>=3.2.0
29
- Requires-Dist: robotcode-core==0.68.0
28
+ Requires-Dist: platformdirs<4.2.0,>=3.2.0
29
+ Requires-Dist: robotcode-core==0.68.2
30
30
  Requires-Dist: robotframework>=4.1.0
31
31
  Requires-Dist: tomli>=1.1.0; python_version < '3.11'
32
32
  Description-Content-Type: text/markdown
@@ -0,0 +1,22 @@
1
+ robotcode/robot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ robotcode/robot/__version__.py,sha256=L1uo5mxlPb32TYSeQYo02HehpkMuc4yGjlhnwLOypps,23
3
+ robotcode/robot/py.typed,sha256=bWew9mHgMy8LqMu7RuqQXFXLBxh2CRx0dUbSx-3wE48,27
4
+ robotcode/robot/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ robotcode/robot/config/loader.py,sha256=RvFjU3fu5U4VlTSVDa0uUzZNAnpVdZwIy_4a0sXh6d0,5777
6
+ robotcode/robot/config/model.py,sha256=MsLye21oCpjSeaaeU1VqhKomGX3GUqZ43eaFgf3OVXg,81856
7
+ robotcode/robot/config/utils.py,sha256=mNNE8Uq5U78_OPwhOdZjtt1HufczyEHogGMB0azRcC4,2651
8
+ robotcode/robot/diagnostics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ robotcode/robot/diagnostics/entities.py,sha256=nyItwiHQVHOAmocvCS6C0lQZhNTdt_L7CUzYQQEHsus,10456
10
+ robotcode/robot/diagnostics/library_doc.py,sha256=tPssawTnT9fLS7c28T9Wb63DThiBpjIMlil8gqvXJ-s,96906
11
+ robotcode/robot/utils/__init__.py,sha256=OjNPMn_XSnfaMCyKd8Kmq6vlRt6mIGlzW4qiiD3ykUg,447
12
+ robotcode/robot/utils/ast.py,sha256=FlRFAUtBYEKLlT7N7T2kpK0UuZ-uL5ayYZ_MBG39NqY,10119
13
+ robotcode/robot/utils/markdownformatter.py,sha256=h4s18lQ8auHLxsMKYIgJQ2p5d_K_PTaJuCtG-xdS-cg,11653
14
+ robotcode/robot/utils/match.py,sha256=jxKXVpv0SHw_LxsDc1vgOxSGGtcV_9eO9cOVj4MAgIo,527
15
+ robotcode/robot/utils/robot_path.py,sha256=qKBh1cEnReBBLKkWu4gB9EzM-scAwE4xJc1m6v2LRN0,1786
16
+ robotcode/robot/utils/stubs.py,sha256=zFMAAl3xitfVW4tS2AMNpS8KAG9IRp6pZ8AQLL9FT_4,417
17
+ robotcode/robot/utils/variables.py,sha256=fEl8S37lb_mD4hn2MZRAlkiuLGBjAOeZVK0r2o2CfPw,742
18
+ robotcode/robot/utils/visitor.py,sha256=uYLqEhGPmzWKWI3SSrmCaYMwtKvNShvbiPZ4b3FavX8,3241
19
+ robotcode_robot-0.68.2.dist-info/METADATA,sha256=LX0RWrOvcWul8q1fX1L_71yNZ8w2c2C8xo_LBs0wYcE,2209
20
+ robotcode_robot-0.68.2.dist-info/WHEEL,sha256=mRYSEL3Ih6g5a_CVMIcwiF__0Ae4_gLYh01YFNwiq1k,87
21
+ robotcode_robot-0.68.2.dist-info/licenses/LICENSE.txt,sha256=B05uMshqTA74s-0ltyHKI6yoPfJ3zYgQbvcXfDVGFf8,10280
22
+ robotcode_robot-0.68.2.dist-info/RECORD,,
@@ -1,15 +0,0 @@
1
- robotcode/robot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- robotcode/robot/__version__.py,sha256=HxxTcUQtaiYOEEtr3P4K4pOTRoC_pmpqzV7TOSUOpSQ,23
3
- robotcode/robot/py.typed,sha256=bWew9mHgMy8LqMu7RuqQXFXLBxh2CRx0dUbSx-3wE48,27
4
- robotcode/robot/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- robotcode/robot/config/loader.py,sha256=7HSpMU5uCSOVzg9cIuKPShiwmbdvL7ITH6G6P1iHKzY,5661
6
- robotcode/robot/config/model.py,sha256=ijjwhSgo-k7fvBnomxw-jGs9LR1mwZuNNb64tnoWjEo,80958
7
- robotcode/robot/config/utils.py,sha256=hX-bMn9CFqxrcwQo-WPnRXh1PK434HYbLQgZp89ZHeE,2447
8
- robotcode/robot/utils/__init__.py,sha256=aW_jxCqt1PR1LYu2LLWsm8lIqIqAi2ZBinACGdiLelE,448
9
- robotcode/robot/utils/ast.py,sha256=qeTq6Em8bjE6urAZR5HlLDuqz-XNP6yG1eq-lVeay90,10098
10
- robotcode/robot/utils/markdownformatter.py,sha256=3RHkP8JCg0IzeIY6iIp533V6ZQTaonpTqKdYaAjscpM,11653
11
- robotcode/robot/utils/visitors.py,sha256=YuQuW228cxhUAdsI1TEXz0vT4QNubD037RDEftQ1FDg,3898
12
- robotcode_robot-0.68.0.dist-info/METADATA,sha256=R1J4EUYoUqJM3GrtP8CLsNHM1FyCpCY3o17UpyO18qc,2221
13
- robotcode_robot-0.68.0.dist-info/WHEEL,sha256=mRYSEL3Ih6g5a_CVMIcwiF__0Ae4_gLYh01YFNwiq1k,87
14
- robotcode_robot-0.68.0.dist-info/licenses/LICENSE.txt,sha256=B05uMshqTA74s-0ltyHKI6yoPfJ3zYgQbvcXfDVGFf8,10280
15
- robotcode_robot-0.68.0.dist-info/RECORD,,