pycforge 0.15.2__py3-none-any.whl
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.
- pycforge/__init__.py +8 -0
- pycforge/__main__.py +2 -0
- pycforge/_version.py +1 -0
- pycforge/converter/__init__.py +0 -0
- pycforge/converter/analysis/__init__.py +5 -0
- pycforge/converter/analysis/functions.py +723 -0
- pycforge/converter/analysis/model.py +158 -0
- pycforge/converter/analysis/planning.py +464 -0
- pycforge/converter/analysis/stage.py +1976 -0
- pycforge/converter/analysis/symbols.py +237 -0
- pycforge/converter/analysis/validation.py +2166 -0
- pycforge/converter/c_output/__init__.py +2 -0
- pycforge/converter/c_output/conformance.py +297 -0
- pycforge/converter/c_output/renderer.py +220 -0
- pycforge/converter/conditional_regions/__init__.py +71 -0
- pycforge/converter/conditional_regions/analysis.py +481 -0
- pycforge/converter/conditional_regions/lowering.py +579 -0
- pycforge/converter/conditional_regions/model.py +243 -0
- pycforge/converter/conditional_regions/validation.py +690 -0
- pycforge/converter/containers/__init__.py +19 -0
- pycforge/converter/containers/analysis.py +542 -0
- pycforge/converter/containers/lowering.py +290 -0
- pycforge/converter/containers/model.py +146 -0
- pycforge/converter/contracts/__init__.py +0 -0
- pycforge/converter/contracts/configuration.py +178 -0
- pycforge/converter/contracts/identifiers.py +68 -0
- pycforge/converter/contracts/versions.py +71 -0
- pycforge/converter/core/__init__.py +0 -0
- pycforge/converter/core/artifact_io.py +87 -0
- pycforge/converter/core/cancellation.py +7 -0
- pycforge/converter/core/canonicalization.py +254 -0
- pycforge/converter/core/context.py +13 -0
- pycforge/converter/core/diagnostics.py +95 -0
- pycforge/converter/core/enums.py +23 -0
- pycforge/converter/core/fingerprint.py +22 -0
- pycforge/converter/core/pipeline.py +8 -0
- pycforge/converter/core/progress.py +25 -0
- pycforge/converter/core/request.py +50 -0
- pycforge/converter/core/resource_policy.py +31 -0
- pycforge/converter/core/result.py +23 -0
- pycforge/converter/core/serialization.py +36 -0
- pycforge/converter/core/stage.py +10 -0
- pycforge/converter/core/stage_artifact.py +80 -0
- pycforge/converter/core/stage_outcome.py +15 -0
- pycforge/converter/decision_trace/__init__.py +0 -0
- pycforge/converter/decision_trace/recorder.py +52 -0
- pycforge/converter/facade.py +459 -0
- pycforge/converter/frontend/__init__.py +4 -0
- pycforge/converter/frontend/normalizer.py +59 -0
- pycforge/converter/frontend/parser.py +20 -0
- pycforge/converter/frontend/source_document.py +93 -0
- pycforge/converter/frontend/stages.py +518 -0
- pycforge/converter/frontend/validation.py +76 -0
- pycforge/converter/io/__init__.py +0 -0
- pycforge/converter/io/atomic_writer.py +33 -0
- pycforge/converter/ir/__init__.py +1 -0
- pycforge/converter/ir/c_ir/__init__.py +4 -0
- pycforge/converter/ir/c_ir/builder.py +26 -0
- pycforge/converter/ir/c_ir/model.py +318 -0
- pycforge/converter/ir/c_ir/serialization.py +88 -0
- pycforge/converter/ir/c_ir/validation.py +834 -0
- pycforge/converter/ir/python_ir/__init__.py +17 -0
- pycforge/converter/ir/python_ir/nodes.py +86 -0
- pycforge/converter/keyword_calls/__init__.py +68 -0
- pycforge/converter/keyword_calls/analysis.py +458 -0
- pycforge/converter/keyword_calls/lowering.py +271 -0
- pycforge/converter/keyword_calls/model.py +304 -0
- pycforge/converter/keyword_calls/validation.py +802 -0
- pycforge/converter/keyword_only_calls/__init__.py +68 -0
- pycforge/converter/keyword_only_calls/analysis.py +640 -0
- pycforge/converter/keyword_only_calls/lowering.py +376 -0
- pycforge/converter/keyword_only_calls/model.py +328 -0
- pycforge/converter/keyword_only_calls/validation.py +1357 -0
- pycforge/converter/lowering.py +1000 -0
- pycforge/converter/modules/__init__.py +13 -0
- pycforge/converter/modules/analysis.py +1250 -0
- pycforge/converter/modules/lowering.py +200 -0
- pycforge/converter/modules/model.py +73 -0
- pycforge/converter/modules/stage.py +192 -0
- pycforge/converter/numeric_semantics/__init__.py +23 -0
- pycforge/converter/numeric_semantics/analysis.py +420 -0
- pycforge/converter/numeric_semantics/lowering.py +153 -0
- pycforge/converter/numeric_semantics/model.py +123 -0
- pycforge/converter/records/__init__.py +34 -0
- pycforge/converter/records/analysis.py +1394 -0
- pycforge/converter/records/lowering.py +393 -0
- pycforge/converter/records/model.py +319 -0
- pycforge/converter/rules/__init__.py +3 -0
- pycforge/converter/support_templates/__init__.py +49 -0
- pycforge/converter/support_templates/assembly.py +106 -0
- pycforge/converter/support_templates/factories.py +348 -0
- pycforge/converter/support_templates/model.py +159 -0
- pycforge/converter/support_templates/registry.py +388 -0
- pycforge/converter/telemetry/__init__.py +0 -0
- pycforge/converter/telemetry/sink.py +39 -0
- pycforge/ide/__init__.py +19 -0
- pycforge/ide/__main__.py +5 -0
- pycforge/ide/_worker_event_codec.py +276 -0
- pycforge/ide/_worker_protocol_json.py +197 -0
- pycforge/ide/_worker_protocol_types.py +90 -0
- pycforge/ide/_worker_request_codec.py +200 -0
- pycforge/ide/_worker_request_data.py +260 -0
- pycforge/ide/_worker_result_data.py +343 -0
- pycforge/ide/action_contract.py +469 -0
- pycforge/ide/action_validation.py +229 -0
- pycforge/ide/command_palette.py +223 -0
- pycforge/ide/controller.py +904 -0
- pycforge/ide/controller_conversion.py +546 -0
- pycforge/ide/controller_io.py +205 -0
- pycforge/ide/editor.py +951 -0
- pycforge/ide/editor_commands_qt.py +274 -0
- pycforge/ide/editor_lexical.py +43 -0
- pycforge/ide/editor_sidebars.py +236 -0
- pycforge/ide/editor_syntax.py +243 -0
- pycforge/ide/find_replace.py +535 -0
- pycforge/ide/icons.py +91 -0
- pycforge/ide/io_service.py +196 -0
- pycforge/ide/model.py +164 -0
- pycforge/ide/panels.py +903 -0
- pycforge/ide/positions.py +220 -0
- pycforge/ide/process_worker.py +130 -0
- pycforge/ide/qt.py +230 -0
- pycforge/ide/qt_actions.py +418 -0
- pycforge/ide/qt_close.py +169 -0
- pycforge/ide/qt_command_palette.py +297 -0
- pycforge/ide/qt_contract.py +220 -0
- pycforge/ide/qt_documents.py +590 -0
- pycforge/ide/qt_editor_buffers.py +113 -0
- pycforge/ide/qt_editor_surfaces.py +112 -0
- pycforge/ide/qt_menus.py +324 -0
- pycforge/ide/qt_projection.py +500 -0
- pycforge/ide/qt_shell.py +348 -0
- pycforge/ide/qt_shell_interactions.py +320 -0
- pycforge/ide/qt_state.py +393 -0
- pycforge/ide/qt_workspace_features.py +398 -0
- pycforge/ide/qt_workspace_navigation.py +208 -0
- pycforge/ide/qt_workspace_observers.py +173 -0
- pycforge/ide/qt_workspace_panels.py +545 -0
- pycforge/ide/qt_workspace_widgets.py +228 -0
- pycforge/ide/resources/icons/about.svg +1 -0
- pycforge/ide/resources/icons/add-document.svg +1 -0
- pycforge/ide/resources/icons/brand-mark.svg +1 -0
- pycforge/ide/resources/icons/bundle-search.svg +1 -0
- pycforge/ide/resources/icons/cancel.svg +1 -0
- pycforge/ide/resources/icons/check.svg +1 -0
- pycforge/ide/resources/icons/chevron-right.svg +1 -0
- pycforge/ide/resources/icons/close.svg +1 -0
- pycforge/ide/resources/icons/collapse-all.svg +1 -0
- pycforge/ide/resources/icons/command-palette.svg +1 -0
- pycforge/ide/resources/icons/convert.svg +1 -0
- pycforge/ide/resources/icons/copy.svg +1 -0
- pycforge/ide/resources/icons/cut.svg +1 -0
- pycforge/ide/resources/icons/decision-trace.svg +1 -0
- pycforge/ide/resources/icons/details.svg +1 -0
- pycforge/ide/resources/icons/diagnostics.svg +1 -0
- pycforge/ide/resources/icons/duplicate-line.svg +1 -0
- pycforge/ide/resources/icons/exit.svg +1 -0
- pycforge/ide/resources/icons/expand-all.svg +1 -0
- pycforge/ide/resources/icons/export.svg +1 -0
- pycforge/ide/resources/icons/find.svg +1 -0
- pycforge/ide/resources/icons/go-to-line.svg +1 -0
- pycforge/ide/resources/icons/go-to-output.svg +1 -0
- pycforge/ide/resources/icons/go-to-source.svg +1 -0
- pycforge/ide/resources/icons/history.svg +1 -0
- pycforge/ide/resources/icons/indent.svg +1 -0
- pycforge/ide/resources/icons/link-c.svg +1 -0
- pycforge/ide/resources/icons/mappings.svg +1 -0
- pycforge/ide/resources/icons/module.svg +1 -0
- pycforge/ide/resources/icons/move-down.svg +1 -0
- pycforge/ide/resources/icons/move-line-down.svg +1 -0
- pycforge/ide/resources/icons/move-line-up.svg +1 -0
- pycforge/ide/resources/icons/move-up.svg +1 -0
- pycforge/ide/resources/icons/next.svg +1 -0
- pycforge/ide/resources/icons/open.svg +1 -0
- pycforge/ide/resources/icons/outdent.svg +1 -0
- pycforge/ide/resources/icons/outline.svg +1 -0
- pycforge/ide/resources/icons/paste.svg +1 -0
- pycforge/ide/resources/icons/previous.svg +1 -0
- pycforge/ide/resources/icons/primary-module.svg +1 -0
- pycforge/ide/resources/icons/redo.svg +1 -0
- pycforge/ide/resources/icons/remove-document.svg +1 -0
- pycforge/ide/resources/icons/replace.svg +1 -0
- pycforge/ide/resources/icons/save-as.svg +1 -0
- pycforge/ide/resources/icons/save.svg +1 -0
- pycforge/ide/resources/icons/select-all.svg +1 -0
- pycforge/ide/resources/icons/settings.svg +1 -0
- pycforge/ide/resources/icons/show-c.svg +1 -0
- pycforge/ide/resources/icons/split-view.svg +1 -0
- pycforge/ide/resources/icons/summary.svg +1 -0
- pycforge/ide/resources/icons/telemetry.svg +1 -0
- pycforge/ide/resources/icons/toggle-comment.svg +1 -0
- pycforge/ide/resources/icons/toggle-fold.svg +1 -0
- pycforge/ide/resources/icons/undo.svg +1 -0
- pycforge/ide/resources/icons/whitespace.svg +1 -0
- pycforge/ide/revisions.py +400 -0
- pycforge/ide/search_service.py +280 -0
- pycforge/ide/session_history.py +150 -0
- pycforge/ide/source_editing.py +417 -0
- pycforge/ide/source_structure.py +558 -0
- pycforge/ide/source_structure_async.py +191 -0
- pycforge/ide/supervisor.py +503 -0
- pycforge/ide/theme.py +119 -0
- pycforge/ide/theme_stylesheet.py +598 -0
- pycforge/ide/theme_workspace_stylesheet.py +155 -0
- pycforge/ide/visual_tokens.py +142 -0
- pycforge/ide/worker_protocol.py +80 -0
- pycforge/ide/workspace_search.py +462 -0
- pycforge/ide/workspace_session.py +256 -0
- pycforge/laboratory/__init__.py +6 -0
- pycforge/laboratory/audits.py +2244 -0
- pycforge/laboratory/checkpoint_e.py +2685 -0
- pycforge/laboratory/cli.py +119 -0
- pycforge/laboratory/exit_codes.py +11 -0
- pycforge/laboratory/keyword_audit.py +661 -0
- pycforge/laboratory/keyword_only_audit.py +481 -0
- pycforge-0.15.2.dist-info/METADATA +209 -0
- pycforge-0.15.2.dist-info/RECORD +221 -0
- pycforge-0.15.2.dist-info/WHEEL +5 -0
- pycforge-0.15.2.dist-info/entry_points.txt +5 -0
- pycforge-0.15.2.dist-info/licenses/LICENSE +674 -0
- pycforge-0.15.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"""Phase 15C editor-workspace additions to the PyCForge visual system."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from string import Template
|
|
6
|
+
|
|
7
|
+
from .visual_tokens import (
|
|
8
|
+
PYCFORGE_COLORS,
|
|
9
|
+
PyCForgeColors,
|
|
10
|
+
color_tokens,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
_WORKSPACE_QSS = Template(
|
|
15
|
+
r"""
|
|
16
|
+
QTabBar#SourceDocumentTabs {
|
|
17
|
+
background: qlineargradient(x1:0,y1:0,x2:1,y2:0,
|
|
18
|
+
stop:0 ${void},stop:0.55 ${canvas},stop:1 ${surface_raised});
|
|
19
|
+
border: 1px solid ${border};
|
|
20
|
+
border-bottom: 1px solid ${border_strong};
|
|
21
|
+
border-radius: 7px;
|
|
22
|
+
padding: 3px 4px 0 4px;
|
|
23
|
+
}
|
|
24
|
+
QTabBar#SourceDocumentTabs::tab {
|
|
25
|
+
color: ${text_soft};
|
|
26
|
+
background: ${surface};
|
|
27
|
+
border: 1px solid ${border};
|
|
28
|
+
border-bottom: 2px solid ${border};
|
|
29
|
+
border-top-left-radius: 6px;
|
|
30
|
+
border-top-right-radius: 6px;
|
|
31
|
+
padding: 7px 12px;
|
|
32
|
+
min-width: 110px;
|
|
33
|
+
}
|
|
34
|
+
QTabBar#SourceDocumentTabs::tab:hover {
|
|
35
|
+
color: #FFFFFF;
|
|
36
|
+
background: ${surface_hover};
|
|
37
|
+
border-bottom: 2px solid ${blue};
|
|
38
|
+
}
|
|
39
|
+
QTabBar#SourceDocumentTabs::tab:selected {
|
|
40
|
+
color: #FFFFFF;
|
|
41
|
+
background: qlineargradient(x1:0,y1:0,x2:1,y2:0,
|
|
42
|
+
stop:0 ${selection},stop:0.75 ${violet_dim},stop:1 ${warm_dim});
|
|
43
|
+
border-color: ${blue};
|
|
44
|
+
border-bottom: 2px solid ${violet_bright};
|
|
45
|
+
}
|
|
46
|
+
QTabBar#SourceDocumentTabs:focus {
|
|
47
|
+
border: 1px solid ${focus_ring};
|
|
48
|
+
border-bottom: 2px solid ${violet};
|
|
49
|
+
}
|
|
50
|
+
QWidget#SourceBreadcrumbBar {
|
|
51
|
+
background: qlineargradient(x1:0,y1:0,x2:1,y2:0,
|
|
52
|
+
stop:0 ${canvas},stop:0.72 ${surface},stop:1 ${violet_dim});
|
|
53
|
+
border: 1px solid ${border};
|
|
54
|
+
border-left: 2px solid ${blue};
|
|
55
|
+
border-radius: 6px;
|
|
56
|
+
}
|
|
57
|
+
QToolButton#BreadcrumbButton {
|
|
58
|
+
color: ${text_soft};
|
|
59
|
+
background: transparent;
|
|
60
|
+
border: 1px solid transparent;
|
|
61
|
+
border-radius: 5px;
|
|
62
|
+
padding: 3px 7px;
|
|
63
|
+
}
|
|
64
|
+
QToolButton#BreadcrumbButton:hover {
|
|
65
|
+
color: #FFFFFF;
|
|
66
|
+
background: ${surface_hover};
|
|
67
|
+
border-color: ${blue_dim};
|
|
68
|
+
}
|
|
69
|
+
QToolButton#BreadcrumbButton:focus {
|
|
70
|
+
color: #FFFFFF;
|
|
71
|
+
border: 1px solid ${focus_ring};
|
|
72
|
+
background: ${selection};
|
|
73
|
+
}
|
|
74
|
+
QLabel#BreadcrumbSeparator {
|
|
75
|
+
color: ${violet_bright};
|
|
76
|
+
padding: 0 1px;
|
|
77
|
+
}
|
|
78
|
+
QDialog#CommandPaletteDialog {
|
|
79
|
+
background: qlineargradient(x1:0,y1:0,x2:0,y2:1,
|
|
80
|
+
stop:0 ${surface_raised},stop:0.55 ${canvas},stop:1 ${void});
|
|
81
|
+
border: 1px solid ${blue};
|
|
82
|
+
border-radius: 10px;
|
|
83
|
+
}
|
|
84
|
+
QLineEdit#CommandPaletteQuery {
|
|
85
|
+
color: #FFFFFF;
|
|
86
|
+
background: ${void};
|
|
87
|
+
border: 1px solid ${blue};
|
|
88
|
+
border-bottom: 2px solid ${violet};
|
|
89
|
+
border-radius: 8px;
|
|
90
|
+
padding: 9px 11px;
|
|
91
|
+
}
|
|
92
|
+
QTreeWidget#CommandPaletteResults,
|
|
93
|
+
QTreeWidget#BundleSearchTree,
|
|
94
|
+
QTreeWidget#OutlineTree,
|
|
95
|
+
QTreeWidget#SessionHistoryTree {
|
|
96
|
+
color: ${text_soft};
|
|
97
|
+
background: ${void};
|
|
98
|
+
border: 1px solid ${border_strong};
|
|
99
|
+
border-radius: 7px;
|
|
100
|
+
}
|
|
101
|
+
QTreeWidget#CommandPaletteResults::item,
|
|
102
|
+
QTreeWidget#BundleSearchTree::item,
|
|
103
|
+
QTreeWidget#OutlineTree::item,
|
|
104
|
+
QTreeWidget#SessionHistoryTree::item {
|
|
105
|
+
border-bottom: 1px solid ${surface_raised};
|
|
106
|
+
padding: 6px 5px;
|
|
107
|
+
}
|
|
108
|
+
QTreeWidget#CommandPaletteResults::item:hover,
|
|
109
|
+
QTreeWidget#BundleSearchTree::item:hover,
|
|
110
|
+
QTreeWidget#OutlineTree::item:hover,
|
|
111
|
+
QTreeWidget#SessionHistoryTree::item:hover {
|
|
112
|
+
color: #FFFFFF;
|
|
113
|
+
background: ${surface_hover};
|
|
114
|
+
}
|
|
115
|
+
QTreeWidget#CommandPaletteResults::item:selected,
|
|
116
|
+
QTreeWidget#BundleSearchTree::item:selected,
|
|
117
|
+
QTreeWidget#OutlineTree::item:selected,
|
|
118
|
+
QTreeWidget#SessionHistoryTree::item:selected {
|
|
119
|
+
color: #FFFFFF;
|
|
120
|
+
background: qlineargradient(x1:0,y1:0,x2:1,y2:0,
|
|
121
|
+
stop:0 ${selection},stop:1 ${violet_dim});
|
|
122
|
+
border-left: 3px solid ${blue_bright};
|
|
123
|
+
}
|
|
124
|
+
QWidget#BundleSearchView,
|
|
125
|
+
QWidget#OutlineView,
|
|
126
|
+
QWidget#SessionHistoryView {
|
|
127
|
+
background: qlineargradient(x1:0,y1:0,x2:0,y2:1,
|
|
128
|
+
stop:0 ${surface_raised},stop:1 ${canvas});
|
|
129
|
+
}
|
|
130
|
+
QFrame#SourceSplitSurface {
|
|
131
|
+
background: ${void};
|
|
132
|
+
border: 1px solid ${border};
|
|
133
|
+
border-top: 2px solid ${blue_dim};
|
|
134
|
+
border-radius: 7px;
|
|
135
|
+
}
|
|
136
|
+
QLabel#GeneratedCWindowLabel {
|
|
137
|
+
color: ${warning_bright};
|
|
138
|
+
background: ${warning_dim};
|
|
139
|
+
border: 1px solid ${warm_dim};
|
|
140
|
+
border-radius: 7px;
|
|
141
|
+
padding: 3px 8px;
|
|
142
|
+
}
|
|
143
|
+
"""
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def build_workspace_stylesheet(
|
|
148
|
+
colors: PyCForgeColors = PYCFORGE_COLORS,
|
|
149
|
+
) -> str:
|
|
150
|
+
"""Return deterministic styling for the Phase 15C workspace surfaces."""
|
|
151
|
+
|
|
152
|
+
return _WORKSPACE_QSS.substitute(dict(color_tokens(colors))).strip() + "\n"
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
__all__ = ["build_workspace_stylesheet"]
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"""Headless-safe semantic tokens for the PyCForge desktop visual system.
|
|
2
|
+
|
|
3
|
+
The optional Qt workspace and its tests share these values without importing
|
|
4
|
+
PyQt5. Colors are named for their role rather than a particular widget so the
|
|
5
|
+
visual language remains coherent across menus, editors, panels, and future
|
|
6
|
+
presentation surfaces.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from dataclasses import asdict, dataclass
|
|
12
|
+
from types import MappingProxyType
|
|
13
|
+
from typing import Mapping
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True, slots=True)
|
|
17
|
+
class PyCForgeColors:
|
|
18
|
+
"""Professional graphite palette with restrained operational accents."""
|
|
19
|
+
|
|
20
|
+
void: str = "#070A10"
|
|
21
|
+
canvas: str = "#0B0F16"
|
|
22
|
+
surface: str = "#111823"
|
|
23
|
+
surface_raised: str = "#172130"
|
|
24
|
+
surface_active: str = "#1D2939"
|
|
25
|
+
surface_hover: str = "#243348"
|
|
26
|
+
border: str = "#29384A"
|
|
27
|
+
border_strong: str = "#3B526A"
|
|
28
|
+
text: str = "#F1F5FA"
|
|
29
|
+
text_soft: str = "#C8D2DE"
|
|
30
|
+
text_muted: str = "#9BAABC"
|
|
31
|
+
text_disabled: str = "#748497"
|
|
32
|
+
blue: str = "#4FB6FF"
|
|
33
|
+
blue_bright: str = "#7BCCFF"
|
|
34
|
+
blue_dim: str = "#1B425D"
|
|
35
|
+
cyan: str = "#4FB6FF"
|
|
36
|
+
cyan_bright: str = "#7BCCFF"
|
|
37
|
+
cyan_dim: str = "#1B425D"
|
|
38
|
+
violet: str = "#A58BFF"
|
|
39
|
+
violet_bright: str = "#C0AEFF"
|
|
40
|
+
violet_dim: str = "#443B70"
|
|
41
|
+
warm: str = "#FF9A52"
|
|
42
|
+
warm_bright: str = "#FFB878"
|
|
43
|
+
warm_dim: str = "#55321F"
|
|
44
|
+
success: str = "#5AD8A6"
|
|
45
|
+
success_bright: str = "#91EDC8"
|
|
46
|
+
success_dim: str = "#173C30"
|
|
47
|
+
warning: str = "#FFC56F"
|
|
48
|
+
warning_bright: str = "#FFDEA3"
|
|
49
|
+
warning_dim: str = "#49371B"
|
|
50
|
+
error: str = "#FF7085"
|
|
51
|
+
error_bright: str = "#FFABB8"
|
|
52
|
+
error_dim: str = "#49212A"
|
|
53
|
+
selection: str = "#244F70"
|
|
54
|
+
selection_active: str = "#2C638B"
|
|
55
|
+
focus_ring: str = "#7BCCFF"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@dataclass(frozen=True, slots=True)
|
|
59
|
+
class PyCForgeMetrics:
|
|
60
|
+
"""Logical-pixel metrics; Qt applies the effective display scale."""
|
|
61
|
+
|
|
62
|
+
radius_small: int = 4
|
|
63
|
+
radius_control: int = 6
|
|
64
|
+
radius_panel: int = 8
|
|
65
|
+
radius_menu: int = 9
|
|
66
|
+
icon_menu: int = 18
|
|
67
|
+
icon_toolbar: int = 20
|
|
68
|
+
icon_navigator: int = 18
|
|
69
|
+
focus_width: int = 2
|
|
70
|
+
menu_outer_padding: int = 6
|
|
71
|
+
menu_item_vertical_padding: int = 7
|
|
72
|
+
menu_item_left_padding: int = 38
|
|
73
|
+
menu_item_right_padding: int = 36
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
PYCFORGE_COLORS = PyCForgeColors()
|
|
77
|
+
PYCFORGE_METRICS = PyCForgeMetrics()
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def color_tokens(
|
|
81
|
+
colors: PyCForgeColors = PYCFORGE_COLORS,
|
|
82
|
+
) -> Mapping[str, str]:
|
|
83
|
+
"""Return an immutable token mapping suitable for stylesheet expansion."""
|
|
84
|
+
|
|
85
|
+
return MappingProxyType(asdict(colors))
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def relative_luminance(color: str) -> float:
|
|
89
|
+
"""Return WCAG relative luminance for an exact ``#RRGGBB`` color."""
|
|
90
|
+
|
|
91
|
+
red, green, blue = _rgb_channels(color)
|
|
92
|
+
linear = tuple(
|
|
93
|
+
channel / 12.92
|
|
94
|
+
if channel <= 0.04045
|
|
95
|
+
else ((channel + 0.055) / 1.055) ** 2.4
|
|
96
|
+
for channel in (red, green, blue)
|
|
97
|
+
)
|
|
98
|
+
return (
|
|
99
|
+
0.2126 * linear[0]
|
|
100
|
+
+ 0.7152 * linear[1]
|
|
101
|
+
+ 0.0722 * linear[2]
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def contrast_ratio(first: str, second: str) -> float:
|
|
106
|
+
"""Return the WCAG contrast ratio between two exact RGB colors."""
|
|
107
|
+
|
|
108
|
+
lighter, darker = sorted(
|
|
109
|
+
(relative_luminance(first), relative_luminance(second)),
|
|
110
|
+
reverse=True,
|
|
111
|
+
)
|
|
112
|
+
return (lighter + 0.05) / (darker + 0.05)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def _rgb_channels(color: str) -> tuple[float, float, float]:
|
|
116
|
+
if (
|
|
117
|
+
not isinstance(color, str)
|
|
118
|
+
or len(color) != 7
|
|
119
|
+
or not color.startswith("#")
|
|
120
|
+
):
|
|
121
|
+
raise ValueError("color must use exact #RRGGBB notation")
|
|
122
|
+
try:
|
|
123
|
+
values = tuple(
|
|
124
|
+
int(color[index : index + 2], 16) / 255.0
|
|
125
|
+
for index in (1, 3, 5)
|
|
126
|
+
)
|
|
127
|
+
except ValueError as exc:
|
|
128
|
+
raise ValueError(
|
|
129
|
+
"color must use exact #RRGGBB notation"
|
|
130
|
+
) from exc
|
|
131
|
+
return values # type: ignore[return-value]
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
__all__ = [
|
|
135
|
+
"PYCFORGE_COLORS",
|
|
136
|
+
"PYCFORGE_METRICS",
|
|
137
|
+
"PyCForgeColors",
|
|
138
|
+
"PyCForgeMetrics",
|
|
139
|
+
"color_tokens",
|
|
140
|
+
"contrast_ratio",
|
|
141
|
+
"relative_luminance",
|
|
142
|
+
]
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""Public facade for the bounded isolated-converter worker protocol.
|
|
2
|
+
|
|
3
|
+
Frames are canonical JSON transported through ``send_bytes`` and
|
|
4
|
+
``recv_bytes`` only. The cohesive private codec modules keep request,
|
|
5
|
+
result/event, and low-level JSON validation responsibilities separate while
|
|
6
|
+
this module preserves the original Phase 15A import surface.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from ._worker_event_codec import (
|
|
12
|
+
decode_event,
|
|
13
|
+
encode_failure,
|
|
14
|
+
encode_progress,
|
|
15
|
+
encode_terminal,
|
|
16
|
+
receive_event,
|
|
17
|
+
send_event,
|
|
18
|
+
)
|
|
19
|
+
from ._worker_protocol_types import (
|
|
20
|
+
FAILURE_CLASSIFICATIONS,
|
|
21
|
+
MAX_CONTROL_BYTES,
|
|
22
|
+
MAX_DIAGNOSTICS,
|
|
23
|
+
MAX_EVENT_BYTES,
|
|
24
|
+
MAX_FAILURE_MESSAGE_CHARS,
|
|
25
|
+
MAX_JSON_DEPTH,
|
|
26
|
+
MAX_REQUEST_BYTES,
|
|
27
|
+
MAX_SOURCE_BYTES,
|
|
28
|
+
MAX_SOURCE_DOCUMENTS,
|
|
29
|
+
PROTOCOL_SCHEMA,
|
|
30
|
+
ByteConnection,
|
|
31
|
+
WorkerControl,
|
|
32
|
+
WorkerEvent,
|
|
33
|
+
WorkerProtocolError,
|
|
34
|
+
WorkerRequest,
|
|
35
|
+
)
|
|
36
|
+
from ._worker_request_codec import (
|
|
37
|
+
decode_control,
|
|
38
|
+
decode_request,
|
|
39
|
+
encode_cancel,
|
|
40
|
+
encode_request,
|
|
41
|
+
receive_control,
|
|
42
|
+
receive_request,
|
|
43
|
+
send_cancel,
|
|
44
|
+
send_request,
|
|
45
|
+
)
|
|
46
|
+
from ._worker_request_data import bundle_fingerprint_for_request
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
__all__ = [
|
|
50
|
+
"FAILURE_CLASSIFICATIONS",
|
|
51
|
+
"MAX_CONTROL_BYTES",
|
|
52
|
+
"MAX_DIAGNOSTICS",
|
|
53
|
+
"MAX_EVENT_BYTES",
|
|
54
|
+
"MAX_FAILURE_MESSAGE_CHARS",
|
|
55
|
+
"MAX_JSON_DEPTH",
|
|
56
|
+
"MAX_REQUEST_BYTES",
|
|
57
|
+
"MAX_SOURCE_BYTES",
|
|
58
|
+
"MAX_SOURCE_DOCUMENTS",
|
|
59
|
+
"PROTOCOL_SCHEMA",
|
|
60
|
+
"ByteConnection",
|
|
61
|
+
"WorkerControl",
|
|
62
|
+
"WorkerEvent",
|
|
63
|
+
"WorkerProtocolError",
|
|
64
|
+
"WorkerRequest",
|
|
65
|
+
"bundle_fingerprint_for_request",
|
|
66
|
+
"decode_control",
|
|
67
|
+
"decode_event",
|
|
68
|
+
"decode_request",
|
|
69
|
+
"encode_cancel",
|
|
70
|
+
"encode_failure",
|
|
71
|
+
"encode_progress",
|
|
72
|
+
"encode_request",
|
|
73
|
+
"encode_terminal",
|
|
74
|
+
"receive_control",
|
|
75
|
+
"receive_event",
|
|
76
|
+
"receive_request",
|
|
77
|
+
"send_cancel",
|
|
78
|
+
"send_event",
|
|
79
|
+
"send_request",
|
|
80
|
+
]
|