Skip to content

Commit 25fd442

Browse files
committed
fix: expose name of module instead of SimpleNamespace
1 parent 805c693 commit 25fd442

6 files changed

Lines changed: 53 additions & 5 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "avrae-ls"
7-
version = "0.9.6"
7+
version = "0.10.0"
88
description = "Language server for Avrae draconic aliases"
99
authors = [
1010
{ name = "1drturtle" }

src/avrae_ls/runtime/errors.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import re
4+
import ast
45
from dataclasses import asdict, dataclass
56
from typing import Any
67

@@ -253,11 +254,45 @@ def _error_line_col(error: BaseException) -> tuple[int | None, int | None]:
253254

254255

255256
def _error_message(error: BaseException) -> str:
257+
module_attr_message = _module_attribute_error_message(error)
258+
if module_attr_message is not None:
259+
return module_attr_message
256260
if isinstance(error, draconic.DraconicException):
257261
return str(error.msg)
258262
return str(error)
259263

260264

265+
def _module_attribute_error_message(error: BaseException) -> str | None:
266+
if not isinstance(error, draconic.NotDefined):
267+
return None
268+
message = str(error.msg)
269+
attr_match = re.fullmatch(r"'SimpleNamespace' object has no attribute (.+)", message)
270+
if attr_match is None:
271+
return None
272+
273+
node = getattr(error, "node", None)
274+
if not isinstance(node, ast.Attribute):
275+
return None
276+
277+
module_name = _module_attribute_base_name(node.value, getattr(error, "expr", None))
278+
if module_name is None:
279+
return None
280+
return f"Module '{module_name}' has no attribute '{attr_match.group(1)}'"
281+
282+
283+
def _module_attribute_base_name(node: ast.AST, expr: Any) -> str | None:
284+
if isinstance(node, ast.Name):
285+
return node.id
286+
if isinstance(expr, str):
287+
segment = ast.get_source_segment(expr, node)
288+
if segment:
289+
return segment
290+
try:
291+
return ast.unparse(node)
292+
except Exception:
293+
return None
294+
295+
261296
def _kind_for_error(error: BaseException) -> str:
262297
if _circular_import_details(error) is not None:
263298
return "circular_import"

tests/test_runtime_errors.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,19 @@ async def test_nested_module_function_error_details_use_module_sources(tmp_path:
9191
assert details.cause and "Expecting value" in details.cause
9292

9393

94+
@pytest.mark.asyncio
95+
async def test_module_missing_attribute_error_uses_local_binding_name(tmp_path: Path):
96+
resolver = _resolver(tmp_path, {"abc123": "value = 1"})
97+
98+
result = await MockExecutor().run('using(local_mod="abc123")\nlocal_mod.missing', _ctx(), resolver)
99+
100+
assert result.error is not None
101+
details = runtime_error_details(result.error)
102+
assert details.kind == "runtime"
103+
assert details.message == "Module 'local_mod' has no attribute 'missing'"
104+
assert "SimpleNamespace" not in details.message
105+
106+
94107
@pytest.mark.asyncio
95108
async def test_circular_import_error_details(tmp_path: Path):
96109
resolver = _resolver(

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vscode-extension/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vscode-extension/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "avrae-ls-client",
33
"displayName": "Avrae Draconic Alias Language Server",
44
"description": "VS Code client for avrae-ls (draconic alias diagnostics and mock execution).",
5-
"version": "0.9.6",
5+
"version": "0.10.0",
66
"engines": {
77
"vscode": "^1.84.0"
88
},

0 commit comments

Comments
 (0)