Coverage for graphica/core/plugin_types.py: 100.0%
79 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-12 16:38 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-12 16:38 +0000
1"""プラグイン API で共有する型。登録されたフックの記録と、失敗の表し方。"""
2from dataclasses import dataclass
3from enum import Enum
4from typing import Any, Callable
7class PluginHookKind(Enum):
8 IMPORTER = "importer"
9 EXPORTER = "exporter"
10 PROCESSOR = "processor"
11 ANALYZER = "analyzer"
12 PANEL = "panel"
13 PLOT_TYPE = "plot_type"
14 FIT_FUNCTION = "fit_function"
15 MENU_ACTION = "menu_action"
16 RENDER_BACKEND = "render_backend"
19@dataclass
20class PluginRegistrationError:
21 """register_xxx の1回の呼び出しが失敗したこと。"""
22 plugin_name: str
23 hook_kind: PluginHookKind
24 message: str
25 exception: Exception | None = None
28@dataclass
29class PluginMenuAction:
30 text: str
31 callback: Callable[..., Any] # (PluginContext) -> None
32 shortcut: str | None
33 plugin_name: str
36@dataclass
37class PluginImporter:
38 extension: str # ピリオド付きの小文字(例: ".jdx")
39 loader: Callable[[str], Any] # (パス) -> pandas.DataFrame
40 name: str # エラー表示用(通常はプラグイン名)
41 priority: int = 0
44@dataclass
45class PluginExporter:
46 format_name: str
47 extension: str # ピリオド付きの小文字
48 writer: Callable[[Any, str], Any] # (matplotlib の Figure, 出力パス) -> None
49 name: str
52@dataclass
53class PluginProcessor:
54 name: str
55 fn: Callable[[Any, dict[str, Any]], Any] # (Dataset, 入力値) -> Dataset。元の Dataset は変えない
56 category: str
57 param_schema: list[dict[str, Any]] # 入力フォームの定義(register_processor の説明を参照)
58 plugin_name: str
61@dataclass
62class AnalysisResult:
63 """
64 register_analyzer の fn が返す解析結果。どれも省略できる。
66 Attributes:
67 table (pandas.DataFrame | None): 結果の表。CSV に保存できる形で表示する。
68 annotations (list[dict] | None): 現在の軸に追加する注釈(Undo できる)。
69 new_datasets (list[Dataset] | None): 追加するデータセット(Undo できる)。
70 """
71 table: Any = None
72 annotations: list[dict[str, Any]] | None = None
73 new_datasets: list[Any] | None = None
76@dataclass
77class PluginAnalyzer:
78 name: str
79 fn: Callable[[Any, dict[str, Any]], Any] # (Dataset, 入力値) -> AnalysisResult
80 output_kind: str # 表示上の分類だけ
81 param_schema: list[dict[str, Any]]
82 plugin_name: str
85@dataclass
86class PluginPanel:
87 name: str
88 widget_factory: Callable[..., Any] # (PluginContext) -> QWidget。タブごとに1回呼ぶ
89 area: str # "right"/"left"/"top"/"bottom"。Qt への対応付けは GUI 側(core は Qt に依存しない)
90 plugin_name: str
93@dataclass
94class PluginPlotType:
95 type_name: str
96 drawer: Callable[..., Any] # (Dataset, Axes, x, y) -> Artist | None
97 requires_2d: bool # 予約(動作に影響しない)
98 plugin_name: str
101class RenderBackend:
102 """描画バックエンドの型の予約。描画には未接続で、持つべきメソッドも未定。"""
105@dataclass
106class PluginRenderBackend:
107 name: str
108 backend: "RenderBackend"
109 plugin_name: str
112class PluginExecutionError(Exception):
113 """プラグインのフックの実行時の失敗。文字列にするとプラグイン名が付くので、そのまま表示に使える。"""
115 def __init__(self, plugin_name: str, message: str) -> None:
116 self.plugin_name = plugin_name
117 self.message = message
118 super().__init__(f"[{plugin_name}] {message}")