Python · 2472 bytes Raw Blame History
1 """Typed parser errors with `file:line:col` location reporting.
2
3 All subclasses of `DlmParseError` carry `(path, line, col)` so CLI error
4 reporting can format diagnostics uniformly.
5 """
6
7 from __future__ import annotations
8
9 from pathlib import Path
10
11
12 class DlmParseError(ValueError):
13 """Base class for all `.dlm` parse errors.
14
15 `line` is 1-indexed. `col` is 1-indexed or 0 when column info isn't
16 meaningful (e.g., schema validation errors on whole values).
17 """
18
19 def __init__(
20 self,
21 message: str,
22 *,
23 path: Path | None = None,
24 line: int = 0,
25 col: int = 0,
26 ) -> None:
27 self.message = message
28 self.path = path
29 self.line = line
30 self.col = col
31 super().__init__(self._format())
32
33 def _format(self) -> str:
34 where = str(self.path) if self.path is not None else "<text>"
35 if self.line and self.col:
36 return f"{where}:{self.line}:{self.col}: {self.message}"
37 if self.line:
38 return f"{where}:{self.line}: {self.message}"
39 return f"{where}: {self.message}"
40
41
42 class FrontmatterError(DlmParseError):
43 """YAML-level errors in the frontmatter block (missing delimiters, bad YAML)."""
44
45
46 class SchemaValidationError(DlmParseError):
47 """Pydantic validation failure against the frontmatter schema.
48
49 Unknown keys, wrong types, out-of-range values all land here.
50 """
51
52
53 class DlmVersionError(DlmParseError):
54 """`dlm_version` is present but isn't a version this parser implements.
55
56 The migration framework is the home for promoting older
57 documents; this error's message points there.
58 """
59
60
61 class UnsupportedMigrationError(DlmVersionError):
62 """No migrator is registered for the requested `from_version`.
63
64 Raised by `dlm.doc.migrations.dispatch.apply_pending` when the
65 `MIGRATORS` registry lacks an entry for an intermediate version on
66 the path from `raw.dlm_version` to `CURRENT_SCHEMA_VERSION`. The
67 coverage test catches this at commit time; this error catches the
68 "user forked off the migration path manually" case at runtime.
69 """
70
71
72 class FenceError(DlmParseError):
73 """Malformed or unknown section fence in the body."""
74
75
76 class InstructionGrammarError(DlmParseError):
77 """Malformed `### Q` / `### A` structure inside an instruction section."""
78
79
80 class PreferenceGrammarError(DlmParseError):
81 """Malformed `### Prompt` / `### Chosen` / `### Rejected` structure."""