Skip to content

Commit

Permalink
sphinx-agent: Ensure diagnostics are reported only once
Browse files Browse the repository at this point in the history
  • Loading branch information
alcarney committed Sep 12, 2023
1 parent bbfaebf commit 83711dc
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 10 deletions.
5 changes: 4 additions & 1 deletion lib/esbonio/esbonio/sphinx_agent/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,10 @@ def build_sphinx_app(self, request: types.BuildRequest):

diagnostics = {}
if self.log_handler:
diagnostics = self.log_handler.diagnostics
diagnostics = {
fpath: list(items)
for fpath, items in self.log_handler.diagnostics.items()
}

response = types.BuildResponse(
id=request.id,
Expand Down
14 changes: 8 additions & 6 deletions lib/esbonio/esbonio/sphinx_agent/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from typing import Dict
from typing import List
from typing import Optional
from typing import Set
from typing import Tuple
from typing import Union

Expand Down Expand Up @@ -35,7 +36,7 @@ def __init__(self, app, *args, **kwargs):
self.app = app
self.translator = WarningLogRecordTranslator(app)
self.only_once = OnceFilter()
self.diagnostics: Dict[str, List[types.Diagnostic]] = {}
self.diagnostics: Dict[str, Set[types.Diagnostic]] = {}

def get_location(self, location: str) -> Tuple[str, Optional[int]]:
if not location:
Expand Down Expand Up @@ -108,21 +109,22 @@ def emit(self, record: logging.LogRecord) -> None:
conditions = [
"sphinx" not in record.name,
record.levelno not in {logging.WARNING, logging.ERROR},
# not self.translator,
]

if any(conditions):
# Log the record as normal
self.do_emit(record)
return

# Let sphinx extract location info for warning/error messages
self.translator.filter(record) # type: ignore

# Only process errors/warnings once.
# Note: This isn't a silver bullet as it only catches messages that are explicitly
# marked as to be logged only once e.g. logger.warning(..., once=True).
if not self.only_once.filter(record):
return

# Let sphinx do what it does to warning/error messages
self.translator.filter(record) # type: ignore

loc = record.location if isinstance(record, SphinxLogRecord) else ""
doc, lineno = self.get_location(loc)
line = lineno or 1
Expand Down Expand Up @@ -153,7 +155,7 @@ def emit(self, record: logging.LogRecord) -> None:
),
)

self.diagnostics.setdefault(doc, []).append(diagnostic)
self.diagnostics.setdefault(doc, set()).add(diagnostic)
self.do_emit(record)

def do_emit(self, record):
Expand Down
6 changes: 3 additions & 3 deletions lib/esbonio/esbonio/sphinx_agent/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
from typing import Union


@dataclasses.dataclass
@dataclasses.dataclass(frozen=True)
class Position:
line: int
character: int


@dataclasses.dataclass
@dataclasses.dataclass(frozen=True)
class Range:
start: Position
end: Position
Expand All @@ -29,7 +29,7 @@ class DiagnosticSeverity(enum.IntEnum):
Hint = 4


@dataclasses.dataclass
@dataclasses.dataclass(frozen=True)
class Diagnostic:
range: Range
message: str
Expand Down

0 comments on commit 83711dc

Please sign in to comment.