Skip to content

Generic Qt machinery from OpenHCS; open path-cache family; header timer leak (0.5.0) - #22

Merged
trissim merged 16 commits into
mainfrom
refactor/U3-generic-qt-machinery
Oct 11, 2026
Merged

trissim merged 16 commits into
mainfrom
refactor/U3-generic-qt-machinery

Conversation

@trissim

@trissim trissim commented Oct 11, 2026

Copy link
Copy Markdown
Contributor

Part of OpenHCS surface U3 + L4: generic Qt machinery moves from OpenHCS into pyqt-reactive, with the application's choices injected instead of named. Version 0.5.0. Commits, each reviewable alone:

  1. Path cache contexts and path-name roles are open class families. PathCacheKey subclasses (stored key = snake-case class name, so existing cache files load); PathNameRole subclasses. Deleted: the enum members naming OpenHCS file kinds, unused keys, get_cached_path/clear_cache/remove_cached_path and the four backward-compatibility alias functions.
  2. Manager header status marquee owns one timer (the header-timer leak): each long status message used to leave another live QTimer child on the manager widget. The test fails without the fix.
  3. Refuse malformed function-pattern entries instead of returning (None, {}) and dropping them on save.
  4. Editable tables (widgets.editable_table) moved from OpenHCS's source-binding editor: cell-editor family keyed by annotation, dataclass-derived columns (labels via python-introspect FieldLabel), record picker, table controller.
  5. Scope operations call objectstate.ScopeKey; containment by whole segments (ScopeTokenService.clear_scope no longer clears /plate10 with /plate1). Duplicate root-scope helpers and the never-produced tree:: flash namespace deleted.
  6. AbstractManagerWidget no longer requires get_event_bus() (it stored it and never read it).
  7. Dock panes and application shortcuts (widgets.shared.dock_layout, services.application_shortcuts).
  8. Time travel: widgets.time_travel (TimeTravelCommands, TimeTravelWidget), windows.snapshot_browser_window, services.time_travel_navigation (TimeTravelNavigator; targets as a class family). Library reads the restore flag through ObjectStateRegistry.is_restoring_snapshot().
  9. Grid selector (widgets.grid_selector) over a GridAddressing ABC; cell looks and event targets are class families.
  10. Config windows (windows.config_window: ConfigWindow, ConfigEditSession, ConfigCodeDocumentDriver, ConfigDocumentFormat ABC), services.code_editor_form_updater, and use_external_code_editor() reading FormGenConfig.external_editor_env_var (the library no longer reads OPENHCS_USE_EXTERNAL_EDITOR).
  11. Smaller follow-ups (ScopeKey in flash debug keys; target_shown), then release 0.5.0 with a CHANGELOG entry.

Requires objectstate 1.4 and python-introspect 0.2.6. requirements-ci.txt pins their unreleased branch heads (ObjectState#27, python-introspect#21) until they are published; repoint or drop those lines when releasing.

Local tests: 649 passed; 1 failed, test_release_dependency_declarations.py::test_published_runtime_is_not_overridden_by_a_source_candidate, because the local venv's installed zmqruntime metadata is 0.4.1 (the check reads importlib.metadata), not because of this branch. Ruff on added lines is clean (scripts/check_ruff_added_lines.py --base 269e896).

Release order for the U3 train: python-introspect 0.2.6 → ObjectState 1.4.0 → pyqt-reactive 0.5.0 → OpenHCS repin. Not tagged or released; the owner releases.

🤖 Generated with Claude Code

trissim and others added 14 commits October 11, 2026 03:15
PathCacheKey was a closed enum that restated one application's file kinds and
was copied verbatim into that application to add its own key. Each context is
now a PathCacheKey subclass whose stored key is its snake-case class name, so
applications declare contexts where they use them and existing cache files load
unchanged. PathNameRole moves its tokens and behaviour onto subclasses; the
pipeline, step and function roles named file formats the library does not own.
The backward-compatibility alias functions and the unused keys are deleted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each status message too wide for the header created a new QTimer parented to
the manager widget and only stopped the previous one, so the widget collected
one live timer per long message. The controller now creates the timer once and
restarts it, and measures the message with font metrics instead of a throwaway
label.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
extract_func_and_kwargs answered (None, {}) for anything that was not a
callable or a (callable, kwargs) pair, and six callers skipped such entries,
so a malformed entry vanished from the pattern on the next save. It now raises
TypeError; validate_pattern_structure reports it as invalid.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Moved from OpenHCS's source-binding editor, where it was generic code waiting
for its library: the CellEditor family keyed by field annotation, columns
derived from dataclass fields (labels from python-introspect's FieldLabel,
tooltips from field docstrings), the typed record-list picker, and the table
controller with its ObjectState semantic chrome and placeholder styling.
Requires python-introspect 0.2.6 for FieldLabel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Root, parent, last segment, child joins and descendant tests were written as
'::' string operations in eleven places. They call ScopeKey, so containment is
by whole segments: ScopeTokenService.clear_scope no longer clears /plate10's
generators when /plate1 is cleared. Two copies of the root-scope extraction and
the never-produced 'tree::' flash namespace are deleted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… bus

The widget stored service_adapter.get_event_bus() and never read it, which
forced every host's service adapter to provide an event bus.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Moved from OpenHCS's main window, where they knew nothing of the application:
- widgets.shared.dock_layout: DockPane (a QDockWidget whose manager header is
  its title bar, with a float button), DockFloatController (float and redock to
  the exact pre-float workspace slot), DockPanes (panes by window id) and
  DockLayoutStore (native dock state in QSettings; the key and version are the
  application's).
- services.application_shortcuts: ShortcutLifecycle, generic over the config
  type, projects key sequences onto menu actions and application-wide commands,
  validates them and rejects duplicates before rebinding; commands yield while
  a code editor has focus.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Moved from OpenHCS, with the application's choices injected instead of named:
- widgets.time_travel: TimeTravelCommands (guarded restore operations, the
  history listing with the application's hidden scopes) and TimeTravelWidget.
- windows.snapshot_browser_window: the snapshot table; its history-changed
  subscription is now released through its handle.
- services.time_travel_navigation: TimeTravelNavigator reopens the editor of
  the scope a restore changed and focuses the changed field or function. The
  application supplies which scopes are function-pattern children. Navigation
  targets are a class family (FieldPathTarget, FunctionTokenTarget) instead of
  a kind string.
Form managers and the manager time-travel binding read the restore flag through
ObjectStateRegistry.is_restoring_snapshot().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Moved from OpenHCS's plate view, where only the cell addressing was the
application's. GridSelectorWidget lays out the available cells by an injected
GridAddressing (default grid, cell position, row label) or by given positions,
and selects by click, drag, rectangle, row and column header and invert. Cell
looks and event targets are small class families instead of enums dispatched
through side tables.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The library's contracts are nominal ABCs, not typing protocols; applications
implement GridAddressing for their cell ids.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nt format

Moved from OpenHCS, which keeps only its document format and window ids:
- windows.config_window: ConfigWindow (tree + form per config tab, Reset,
  View Code, transactional Save with save participants, Cancel restore),
  ConfigEditSession (live/saved global-config context around an edit),
  ConfigCodeDocumentDriver and the ConfigDocumentFormat ABC the application
  implements for View Code.
- services.code_editor_form_updater: CodeEditorFormUpdater applies an edited
  object's changed fields to a form; its patch_lazy_constructors wrapper is
  gone (callers use objectstate.patch_lazy_constructors).
- use_external_code_editor(): one reading of the host's external-editor
  environment switch, named by FormGenConfig.external_editor_env_var; the
  function editor and manager actions no longer read an application's
  variable name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
requirements-ci.txt validates against the unreleased ObjectState and
python-introspect branch heads until they are published.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n a target

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 11, 2026 08:18

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

trissim and others added 2 commits October 11, 2026 04:35
…I ObjectState head

Application shortcuts yield inside either code editor dialog, so the check no
longer imports PyQt6.Qsci, an optional dependency the CI does not install.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@trissim
trissim merged commit 1bce7de into main Oct 11, 2026
23 of 24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants