@pineforge/codegen-pyodide 1.1.0 → 1.2.0

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.
@@ -32,6 +32,29 @@ class Diagnostic:
32
32
  message: str
33
33
  hint: str | None = None
34
34
 
35
+ # The stable code (``PF-E1203`` / ``PF-W0412``) and named arguments of the
36
+ # catalog template the English ``message`` and ``hint`` render from
37
+ # (``diagnostic_codes``, ``diagnostics_catalog.json``). Both are read off
38
+ # the text when first asked for, after the transpile: the text and the
39
+ # C++ never depend on them.
40
+ @property
41
+ def code(self) -> str:
42
+ return self._coded()[0]
43
+
44
+ @property
45
+ def args(self) -> dict:
46
+ return self._coded()[1]
47
+
48
+ def _coded(self) -> tuple[str, dict]:
49
+ severity = getattr(self.level, "value", self.level)
50
+ key = (severity, self.message, self.hint)
51
+ cached = self.__dict__.get("_pf_coded")
52
+ if cached is None or cached[0] != key:
53
+ from .diagnostic_codes import classify
54
+ cached = (key, classify(severity, self.message, self.hint))
55
+ self.__dict__["_pf_coded"] = cached
56
+ return cached[1]
57
+
35
58
 
36
59
  class CompileError(Exception):
37
60
  def __init__(self, diagnostics: list[Diagnostic]):
@@ -85,6 +85,19 @@ _RECORDED_PARAMS = {
85
85
  # RequestRef}``: the run stops there only when no data is installed for the
86
86
  # request that carries the same ref (``REQUEST_REF_ANNOTATION``).
87
87
  UNPINNED_ANNOTATION = "pf_request_unpinned"
88
+ CAPABILITY_UNPINNED_ANNOTATION = "pf_capability_unpinned_requests"
89
+
90
+
91
+ def _record_unpinned_capability(program, request):
92
+ notes = program.annotations = dict(program.annotations or {})
93
+ sites = notes.setdefault(CAPABILITY_UNPINNED_ANNOTATION, [])
94
+ sites.append({
95
+ "function": f"request.{request.callee.member}",
96
+ "symbol_node": request.args[0] if request.args else request.kwargs.get("symbol"),
97
+ "tf_node": request.args[1] if len(request.args) > 1 else request.kwargs.get("timeframe"),
98
+ "lookahead_node": request.kwargs.get("lookahead"),
99
+ "gaps_node": request.kwargs.get("gaps"),
100
+ })
88
101
  REQUEST_REF_ANNOTATION = "pf_request_ref"
89
102
  # On a request whose symbol can select the chart's or another symbol's: it
90
103
  # read the chart before it read a feed, and keeps that lowering where no feed
@@ -785,10 +798,12 @@ def lower_no_data_requests(program: Program) -> Program:
785
798
  backed.append(node)
786
799
  continue
787
800
  if lowering == ABSENT_LOWERING:
801
+ _record_unpinned_capability(program, node)
788
802
  node.annotations = {**node.annotations, UNPINNED_ANNOTATION: unpinned_message(node)}
789
803
  continue
790
804
  swaps[id(node)] = _na_of(node, funcs)
791
805
  if lowering == "unpinned":
806
+ _record_unpinned_capability(program, node)
792
807
  unpinned.append(node)
793
808
  if unpinned or backed:
794
809
  index = ScriptIndex(program)
@@ -853,6 +868,7 @@ def unpin_requests(program: Program, reasons: dict[int, str]) -> None:
853
868
  "results."))
854
869
  continue
855
870
  lowered = _na_of(request, funcs)
871
+ _record_unpinned_capability(program, request)
856
872
  marker = (request.annotations or {}).get(UNPINNED_ANNOTATION)
857
873
  if isinstance(marker, dict):
858
874
  lowered.annotations = {**(lowered.annotations or {}),
Binary file
package/release.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
- "codegen": "1.1.0",
2
+ "codegen": "1.2.0",
3
3
  "pyodide": "314.0.0",
4
4
  "python": "3.14.0",
5
5
  "emscripten": "emscripten_5_0_3",
6
- "sha256": "37b1ca85a2006f6f07d52074a7180187536047bfbb857681978a372b1d7f9bef"
6
+ "sha256": "7c9654f79d188babd5034d3ebedd2cdd60a8ec2866b70d8ad863a9f06341420e"
7
7
  }
package/tables.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "CODEGEN_VERSION": "1.1.0",
2
+ "CODEGEN_VERSION": "1.2.0",
3
3
  "TA_CLASS_MAP_KEYS": [
4
4
  "sma",
5
5
  "ema",
@@ -32,6 +32,10 @@ def _diagnostic_entries(diagnostics) -> list:
32
32
  "col": loc.col if loc else 1,
33
33
  "message": message,
34
34
  "severity": getattr(d.level, "value", "error"),
35
+ # The stable code and named arguments of the catalog templates the
36
+ # message (and the hint after " — ") render from.
37
+ "code": d.code,
38
+ "args": d.args,
35
39
  }
36
40
  end_col = getattr(loc, "end_col", None) if loc else None
37
41
  if end_col is not None:
Binary file