Skip to content

Commit 32ce8f5

Browse files
committed
some correction for python 3.10, use protocol for node/token errors instead if getattr
1 parent 623767a commit 32ce8f5

File tree

5 files changed

+41
-9
lines changed

5 files changed

+41
-9
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Cython = "^0.29.24"
2929
robotframework-robocop = "^1.7.1"
3030
robotframework-tidy = "^1.5.1"
3131
orjson = "^3.6.3"
32+
types-orjson = "^3.6.0"
3233

3334

3435
[tool.poetry-dynamic-versioning]

robotcode/language_server/robotframework/diagnostics/imports_manager.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -526,15 +526,17 @@ async def get_libdoc_from_model(
526526
from robot.running.usererrorhandler import UserErrorHandler
527527
from robot.running.userkeyword import UserLibrary
528528

529+
from ..utils.ast import HasError, HasErrors
530+
529531
errors: List[Error] = []
530532

531533
async for node in walk(model):
532-
error = getattr(node, "error", None)
534+
error = node.error if isinstance(node, HasError) else None
533535
if error is not None:
534536
errors.append(Error(message=error, type_name="ModelError", source=source, line_no=node.lineno))
535-
node_error = getattr(node, "errors", None)
536-
if node_error is not None:
537-
for e in node_error:
537+
node_errors = node.errors if isinstance(node, HasErrors) else None
538+
if node_errors is not None:
539+
for e in node_errors:
538540
errors.append(Error(message=e, type_name="ModelError", source=source, line_no=node.lineno))
539541

540542
res = ResourceFile(source=source)

robotcode/language_server/robotframework/parts/diagnostics.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ async def collect_token_errors(self, sender: Any, document: TextDocument) -> Dia
9292
@language_id("robotframework")
9393
@_logger.call
9494
async def collect_model_errors(self, sender: Any, document: TextDocument) -> DiagnosticsResult:
95+
from ..utils.ast import HasError, HasErrors
9596
from ..utils.async_ast import AsyncVisitor
9697

9798
class Visitor(AsyncVisitor):
@@ -107,10 +108,11 @@ async def find_from(cls, model: ast.AST, parent: RobotDiagnosticsProtocolPart) -
107108
return finder.errors
108109

109110
async def generic_visit(self, node: ast.AST) -> None:
110-
error = getattr(node, "error", None)
111+
error = node.error if isinstance(node, HasError) else None
111112
if error is not None:
112113
self.errors.append(self.parent._create_error_from_node(node, error))
113-
errors = getattr(node, "errors", None)
114+
errors = node.errors if isinstance(node, HasErrors) else None
115+
114116
if errors is not None:
115117
for e in errors:
116118
self.errors.append(self.parent._create_error_from_node(node, e))
@@ -124,15 +126,16 @@ async def generic_visit(self, node: ast.AST) -> None:
124126
@language_id("robotframework")
125127
@_logger.call
126128
async def collect_walk_model_errors(self, sender: Any, document: TextDocument) -> DiagnosticsResult:
129+
from ..utils.ast import HasError, HasErrors
127130
from ..utils.async_ast import walk
128131

129132
result: List[Diagnostic] = []
130133

131134
async for node in walk(await self.parent.documents_cache.get_model(document)):
132-
error = getattr(node, "error", None)
135+
error = node.error if isinstance(node, HasError) else None
133136
if error is not None:
134137
result.append(self._create_error_from_node(node, error))
135-
errors = getattr(node, "errors", None)
138+
errors = node.errors if isinstance(node, HasErrors) else None
136139
if errors is not None:
137140
for e in errors:
138141
result.append(self._create_error_from_node(node, e))

robotcode/language_server/robotframework/utils/ast.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ class HasTokens(Protocol):
6262
tokens: Tuple[Token, ...]
6363

6464

65+
@runtime_checkable
66+
class HasError(Protocol):
67+
error: Optional[str]
68+
69+
70+
@runtime_checkable
71+
class HasErrors(Protocol):
72+
errors: Optional[List[str]]
73+
74+
6575
@runtime_checkable
6676
class Statement(Protocol):
6777
def get_token(self, type: str) -> Token:

robotcode/language_server/robotframework/utils/async_ast.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ async def iter_child_nodes(node: ast.AST) -> AsyncGenerator[ast.AST, None]:
2121
Yield all direct child nodes of *node*, that is, all fields that are nodes
2222
and all items of fields that are lists of nodes.
2323
"""
24-
async for name, field in iter_fields(node):
24+
async for _name, field in iter_fields(node):
2525
if isinstance(field, ast.AST):
2626
yield field
2727
elif isinstance(field, list):
@@ -40,6 +40,22 @@ async def walk(node: ast.AST) -> AsyncGenerator[ast.AST, None]:
4040
yield node
4141

4242

43+
async def iter_nodes(node: ast.AST) -> AsyncGenerator[ast.AST, None]:
44+
async for _name, value in iter_fields(node):
45+
if isinstance(value, list):
46+
for item in value:
47+
if isinstance(item, ast.AST):
48+
yield item
49+
async for n in iter_nodes(item):
50+
yield n
51+
52+
elif isinstance(value, ast.AST):
53+
yield value
54+
55+
async for n in iter_nodes(value):
56+
yield n
57+
58+
4359
class VisitorFinder:
4460
def _find_visitor(self, cls: Type[Any]) -> Optional[Callable[..., Any]]:
4561
if cls is ast.AST:

0 commit comments

Comments
 (0)