robotcode-robot 0.108.0__tar.gz → 0.109.0__tar.gz

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.
Files changed (34) hide show
  1. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/.gitignore +34 -0
  2. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/PKG-INFO +2 -2
  3. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/pyproject.toml +1 -1
  4. robotcode_robot-0.109.0/src/robotcode/robot/__version__.py +1 -0
  5. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/diagnostics/data_cache.py +12 -5
  6. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/diagnostics/entities.py +36 -0
  7. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/diagnostics/imports_manager.py +2 -1
  8. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/diagnostics/library_doc.py +26 -14
  9. robotcode_robot-0.108.0/src/robotcode/robot/__version__.py +0 -1
  10. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/LICENSE.txt +0 -0
  11. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/README.md +0 -0
  12. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/__init__.py +0 -0
  13. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/config/__init__.py +0 -0
  14. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/config/loader.py +0 -0
  15. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/config/model.py +0 -0
  16. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/config/utils.py +0 -0
  17. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/diagnostics/__init__.py +0 -0
  18. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/diagnostics/diagnostics_modifier.py +0 -0
  19. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/diagnostics/document_cache_helper.py +0 -0
  20. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/diagnostics/errors.py +0 -0
  21. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/diagnostics/keyword_finder.py +0 -0
  22. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/diagnostics/model_helper.py +0 -0
  23. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/diagnostics/namespace.py +0 -0
  24. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/diagnostics/namespace_analyzer.py +0 -0
  25. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/diagnostics/workspace_config.py +0 -0
  26. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/py.typed +0 -0
  27. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/utils/__init__.py +0 -0
  28. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/utils/ast.py +0 -0
  29. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/utils/markdownformatter.py +0 -0
  30. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/utils/match.py +0 -0
  31. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/utils/robot_path.py +0 -0
  32. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/utils/stubs.py +0 -0
  33. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/utils/variables.py +0 -0
  34. {robotcode_robot-0.108.0 → robotcode_robot-0.109.0}/src/robotcode/robot/utils/visitor.py +0 -0
@@ -1,3 +1,37 @@
1
+ # Created by https://www.toptal.com/developers/gitignore/api/macos
2
+ # Edit at https://www.toptal.com/developers/gitignore?templates=macos
3
+
4
+ ### macOS ###
5
+ # General
6
+ .DS_Store
7
+ .AppleDouble
8
+ .LSOverride
9
+
10
+ # Thumbnails
11
+ ._*
12
+
13
+ # Files that might appear in the root of a volume
14
+ .DocumentRevisions-V100
15
+ .fseventsd
16
+ .Spotlight-V100
17
+ .TemporaryItems
18
+ .Trashes
19
+ .VolumeIcon.icns
20
+ .com.apple.timemachine.donotpresent
21
+
22
+ # Directories potentially created on remote AFP share
23
+ .AppleDB
24
+ .AppleDesktop
25
+ Network Trash Folder
26
+ Temporary Items
27
+ .apdisk
28
+
29
+ ### macOS Patch ###
30
+ # iCloud generated files
31
+ *.icloud
32
+
33
+ # End of https://www.toptal.com/developers/gitignore/api/macos
34
+
1
35
  # Byte-compiled / optimized / DLL files
2
36
  __pycache__/
3
37
  *.py[cod]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: robotcode-robot
3
- Version: 0.108.0
3
+ Version: 0.109.0
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://opencollective.com/robotcode
@@ -26,7 +26,7 @@ Classifier: Topic :: Utilities
26
26
  Classifier: Typing :: Typed
27
27
  Requires-Python: >=3.8
28
28
  Requires-Dist: platformdirs<4.4.0,>=3.2.0
29
- Requires-Dist: robotcode-core==0.108.0
29
+ Requires-Dist: robotcode-core==0.109.0
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
@@ -30,7 +30,7 @@ dependencies = [
30
30
  "robotframework>=4.1.0",
31
31
  "tomli>=1.1.0; python_version < '3.11'",
32
32
  "platformdirs>=3.2.0,<4.4.0",
33
- "robotcode-core==0.108.0",
33
+ "robotcode-core==0.109.0",
34
34
  ]
35
35
  dynamic = ["version"]
36
36
 
@@ -0,0 +1 @@
1
+ __version__ = "0.109.0"
@@ -27,10 +27,20 @@ class DataCache(ABC):
27
27
  def save_cache_data(self, section: CacheSection, entry_name: str, data: Any) -> None: ...
28
28
 
29
29
 
30
- class JsonDataCache(DataCache):
30
+ class FileCacheDataBase(DataCache, ABC):
31
31
  def __init__(self, cache_dir: Path) -> None:
32
32
  self.cache_dir = cache_dir
33
33
 
34
+ if not Path.exists(self.cache_dir):
35
+ Path.mkdir(self.cache_dir, parents=True)
36
+ Path(self.cache_dir / ".gitignore").write_text(
37
+ "# Created by robotcode\n*\n",
38
+ "utf-8",
39
+ )
40
+
41
+
42
+ class JsonDataCache(FileCacheDataBase):
43
+
34
44
  def build_cache_data_filename(self, section: CacheSection, entry_name: str) -> Path:
35
45
  return self.cache_dir / section.value / (entry_name + ".json")
36
46
 
@@ -51,10 +61,7 @@ class JsonDataCache(DataCache):
51
61
  cached_file.write_text(as_json(data), "utf-8")
52
62
 
53
63
 
54
- class PickleDataCache(DataCache):
55
- def __init__(self, cache_dir: Path) -> None:
56
- self.cache_dir = cache_dir
57
-
64
+ class PickleDataCache(FileCacheDataBase):
58
65
  def build_cache_data_filename(self, section: CacheSection, entry_name: str) -> Path:
59
66
  return self.cache_dir / section.value / (entry_name + ".pkl")
60
67
 
@@ -5,6 +5,7 @@ from typing import (
5
5
  TYPE_CHECKING,
6
6
  Any,
7
7
  Callable,
8
+ Generic,
8
9
  List,
9
10
  Optional,
10
11
  Tuple,
@@ -12,6 +13,8 @@ from typing import (
12
13
  cast,
13
14
  )
14
15
 
16
+ from typing_extensions import Concatenate, ParamSpec
17
+
15
18
  from robot.parsing.lexer.tokens import Token
16
19
  from robotcode.core.lsp.types import Position, Range
17
20
  from robotcode.robot.utils.match import normalize
@@ -41,6 +44,39 @@ def single_call(func: _F) -> _F:
41
44
  return cast(_F, wrapper)
42
45
 
43
46
 
47
+ P = ParamSpec("P")
48
+ R = TypeVar("R")
49
+
50
+
51
+ class cached_method(Generic[P, R]): # noqa: N801
52
+ def __init__(
53
+ self, func: Optional[Callable[Concatenate[Any, P], R]] = None, *, maxsize: Optional[int] = None
54
+ ) -> None:
55
+ self.func: Optional[Callable[Concatenate[Any, P], R]] = func
56
+ self._maxsize = maxsize
57
+ self.cache_name: Optional[str] = None
58
+ if func is not None:
59
+ functools.update_wrapper(self, func)
60
+
61
+ def __set_name__(self, owner: type, name: str) -> None:
62
+ self.cache_name = f"__cached_{owner.__name__}_{name}"
63
+
64
+ def __call__(self, func: Callable[Concatenate[Any, P], R]) -> "cached_method[P, R]":
65
+ self.func = func
66
+ functools.update_wrapper(self, func)
67
+ return self
68
+
69
+ def __get__(self, instance: Any, owner: Optional[type] = None) -> Callable[P, R]:
70
+ cached = instance.__dict__.get(self.cache_name, _NOT_SET)
71
+ if cached is _NOT_SET:
72
+ assert self.func is not None
73
+
74
+ bound_method = self.func.__get__(instance, owner)
75
+ cached = functools.lru_cache(maxsize=self._maxsize)(bound_method)
76
+ instance.__dict__[self.cache_name] = cached
77
+ return cast(Callable[P, R], cached)
78
+
79
+
44
80
  @dataclass
45
81
  class SourceEntity:
46
82
  line_no: int
@@ -610,7 +610,8 @@ class ImportsManager:
610
610
 
611
611
  def clear_cache(self) -> None:
612
612
  if self.cache_path.exists():
613
- shutil.rmtree(self.cache_path)
613
+ shutil.rmtree(self.cache_path, ignore_errors=True)
614
+
614
615
  self._logger.debug(lambda: f"Cleared cache {self.cache_path}")
615
616
 
616
617
  @_logger.call
@@ -80,6 +80,7 @@ from .entities import (
80
80
  LibraryArgumentDefinition,
81
81
  NativeValue,
82
82
  SourceEntity,
83
+ cached_method,
83
84
  single_call,
84
85
  )
85
86
 
@@ -362,7 +363,8 @@ class TypeDoc:
362
363
  )
363
364
  )
364
365
 
365
- def to_markdown(self, header_level: int = 2) -> str:
366
+ @cached_method
367
+ def to_markdown(self, header_level: int = 2, only_doc: bool = False) -> str:
366
368
  result = ""
367
369
 
368
370
  result += f"##{'#' * header_level} {self.name} ({self.type})\n\n"
@@ -378,19 +380,22 @@ class TypeDoc:
378
380
  else:
379
381
  result += self.doc
380
382
 
381
- if self.members:
382
- result += f"\n\n###{'#' * header_level} Allowed Values:\n\n"
383
- result += "- " + "\n- ".join(f"`{m.name}`" for m in self.members)
384
-
385
- if self.items:
386
- result += f"\n\n###{'#' * header_level} Dictionary Structure:\n\n"
387
- result += "```\n{"
388
- result += "\n ".join(f"'{m.key}': <{m.type}> {'# optional' if not m.required else ''}" for m in self.items)
389
- result += "\n}\n```"
383
+ if not only_doc:
384
+ if self.members:
385
+ result += f"\n\n###{'#' * header_level} Allowed Values:\n\n"
386
+ result += "- " + "\n- ".join(f"`{m.name}`" for m in self.members)
387
+
388
+ if self.items:
389
+ result += f"\n\n###{'#' * header_level} Dictionary Structure:\n\n"
390
+ result += "```\n{"
391
+ result += "\n ".join(
392
+ f"'{m.key}': <{m.type}> {'# optional' if not m.required else ''}" for m in self.items
393
+ )
394
+ result += "\n}\n```"
390
395
 
391
- if self.accepts:
392
- result += f"\n\n###{'#' * header_level} Converted Types:\n\n"
393
- result += "- " + "\n- ".join(self.accepts)
396
+ if self.accepts:
397
+ result += f"\n\n###{'#' * header_level} Converted Types:\n\n"
398
+ result += "- " + "\n- ".join(self.accepts)
394
399
 
395
400
  return result
396
401
 
@@ -475,6 +480,7 @@ class ArgumentInfo:
475
480
  def __str__(self) -> str:
476
481
  return self.signature()
477
482
 
483
+ @cached_method
478
484
  def signature(self, add_types: bool = True) -> str:
479
485
  prefix = ""
480
486
  if self.kind == KeywordArgumentKind.POSITIONAL_ONLY_MARKER:
@@ -721,6 +727,7 @@ class KeywordDoc(SourceEntity):
721
727
  ),
722
728
  )
723
729
 
730
+ @cached_method
724
731
  def to_markdown(
725
732
  self,
726
733
  add_signature: bool = True,
@@ -796,7 +803,7 @@ class KeywordDoc(SourceEntity):
796
803
 
797
804
  result += (
798
805
  f"\n| `{prefix}{a.name!s}`"
799
- f'| {": " if a.types else " "}'
806
+ f"| {': ' if a.types else ' '}"
800
807
  f"{escaped_pipe.join(f'`{escape_pipe(s)}`' for s in a.types) if a.types else ''} "
801
808
  f"| {'=' if a.default_value is not None else ''} "
802
809
  f"| {f'`{a.default_value!s}`' if a.default_value else ''} |"
@@ -832,6 +839,7 @@ class KeywordDoc(SourceEntity):
832
839
  + ")"
833
840
  )
834
841
 
842
+ @cached_method
835
843
  def parameter_signature(self, full_signatures: Optional[Sequence[int]] = None) -> str:
836
844
  return (
837
845
  "("
@@ -1094,6 +1102,7 @@ class LibraryDoc:
1094
1102
  ),
1095
1103
  )
1096
1104
 
1105
+ @cached_method
1097
1106
  def to_markdown(
1098
1107
  self,
1099
1108
  add_signature: bool = True,
@@ -1250,6 +1259,7 @@ class VariablesDoc(LibraryDoc):
1250
1259
 
1251
1260
  variables: List[ImportedVariableDefinition] = field(default_factory=list)
1252
1261
 
1262
+ @cached_method
1253
1263
  def to_markdown(
1254
1264
  self,
1255
1265
  add_signature: bool = True,
@@ -2081,6 +2091,7 @@ def get_library_doc(
2081
2091
  td.usages,
2082
2092
  [EnumMember(m.name, m.value) for m in td.members] if td.members else None,
2083
2093
  [TypedDictItem(i.key, i.type, i.required) for i in td.items] if td.items else None,
2094
+ # TODO nested types like Literals
2084
2095
  libname=libdoc.name,
2085
2096
  libtype=libdoc.type,
2086
2097
  doc_format=libdoc.doc_format,
@@ -2453,6 +2464,7 @@ class CompleteResultKind(Enum):
2453
2464
  VARIABLES_MODULE = "Variables Module"
2454
2465
  FOLDER = "Directory"
2455
2466
  KEYWORD = "Keyword"
2467
+ DOC_CACHE = "DOC_CACHE"
2456
2468
 
2457
2469
 
2458
2470
  class CompleteResult(NamedTuple):
@@ -1 +0,0 @@
1
- __version__ = "0.108.0"