PyCForge v1.3.3 — Jedi and autopep8 integration review
14 October 2026

Outcome
Six reproducible integration defects were corrected in the complete current
application. This review concerns editing behavior, safe application of results,
worker lifecycles, and formatting; no dependency version-number rejection was
introduced. Runtime dependency declarations remain unpinned.

The review started from the complete v1.3.1 delivered after the split-view,
Find toggle, window-control hover, Generated C hover, and steady fold-arrow
corrections. Those fixes and all existing conversion engines are retained.
The app, package metadata, release-facing documentation, and current version
assertions now use 1.3.3. Historical release records retain their original dates
and version labels; Ting, PCFC11, and third-party versions are not product versions.

Confirmed defects and corrections

1. HIGH: Completion could remove the selected identifier prefix.
   Reproduction: select `up` in `message.up`, request completion, and accept
   `upper`. The old result was `message.per`, in either source pane.
   Cause: Jedi supplies the missing suffix (`per`), while the Qt cursor retained
   its selection anchor and replaced `up` with that suffix.
   Correction: clear the local edit cursor's selection at the authenticated
   insertion point before inserting the suffix and replacing trailing identifier
   characters. Keyboard and mouse acceptance, Unicode offsets, split panes,
   and single-step undo were checked.
   Source: pycforge/ide/qt_editor_tools.py, _accept_completion.

2. MEDIUM: Dismissed completion and parameter hints could return later.
   Reproduction: submit a request, press Escape, change only the selection,
   or leave and return to the editor; then deliver the original delayed reply.
   The old popup and signature tooltip appeared again.
   Cause: those transitions hid the popup but did not retire its request/context.
   Correction: invalidate the generation and discard the context on selection,
   cursor, focus, hide, and Escape transitions. Typing still retains its pending
   automatic-completion debounce. Cancellation releases held completion data.
   Source: pycforge/ide/qt_editor_tools.py, _cursor_changed,
   _dismiss_assistance, eventFilter, _set_automatic, and close.

3. MEDIUM: A delayed definition result could interrupt newer navigation.
   Reproduction: request Go to Definition, move the caret elsewhere, focus the C
   pane, or press Escape; deliver the original result. The caret jumped back to
   the old destination and added an unwanted return-location entry.
   Correction: cancel pending definition work on these transitions and verify
   focus, caret position, and selection anchor before applying a destination.
   Formatting and rename operations retain their separate document-revision guards.
   Source: pycforge/ide/qt_editor_tools.py, _cancel_definition and
   _operation_finished.

4. MEDIUM: Lambda parameter rename was incorrectly refused.
   Reproduction: rename `amount` in `double = lambda amount: amount * 2` with
   an explicit `double(amount=3)` caller. The old code reported no resolved edits.
   Cause: Jedi can report the parameter's parent as its enclosing module;
   PyCForge's secondary scope filter incorrectly discarded an exact definition.
   Correction: authenticate an exact definition position before checking parent
   scope. Module-level and nested lambdas, sibling lambdas, keyword callers,
   and unrelated outer bindings were checked. Existing nonlocal and shadowing
   regression cases continue to pass.
   Source: pycforge/ide/rename_safety.py, parameter_scope_references.

5. MEDIUM: Ordinary type-ignore comments could block document formatting.
   Reproduction:
       def f():
        return 1
       x=f() # type: ignore
   Adding normal blank lines changed TypeIgnore.lineno, so the old syntax-tree
   comparison rejected a behavior-preserving format.
   Correction: compare syntax plus each ignore directive's tag and covered
   statements, rather than its physical line number. Moving a directive onto
   another statement, changing its tag, changing a type comment, or changing
   executable syntax is still rejected.
   Source: pycforge/ide/editing_operations.py, _format_fingerprint.

6. MEDIUM: Selection formatting falsely crossed boundaries in longer files.
   Reproduction: create 100 lines of `x=1` (also reproduced with unique variable
   names), select line 50, and format it. The old code refused the operation.
   Cause: whole-document character matching used SequenceMatcher's popularity
   heuristic, which can discard common characters and manufacture large edits.
   Correction: first trim unchanged text; accept changes entirely within the
   selected range; otherwise anchor by physical lines and precisely compare
   only boundary-crossing regions. Unselected text and surrounding blank lines
   remain intact, including when autopep8 removes blanks outside its line range.
   Source: pycforge/ide/editing_operations.py, _selected_format.

Validation
- 25 new focused integration checks cover these corrections and their safety
  boundaries. All pass.
- Combined targeted run: 157 tests and 180 subtests passed in 56.86 seconds.
  It covers editing operations, real worker requests, keyboard/mouse completion,
  undo, split views, rendered fold arrows and hover states, stale results,
  process deadlines, cache limits, worker retirement/restart, startup layout,
  release metadata, and the preceding five UI corrections.
- No full regression suite was run for this update.
- This execution used Linux with PySide6's offscreen Qt backend. Native Windows
  execution and actual laptop power measurements were not performed.
- The test process found an obsolete README wording assertion from before its
  earlier rewrite. Its assertion and matching distribution checks now reflect
  the existing dependency list and Ting heading. The README's only content
  change in this update is its versioned title; both screenshots remain intact.
- Source/evidence/editor_integration_1_3_3 contains reproductions, final test
  output/XML, environment details, rename/format probes, and resource results.

Worker resource observations
- Analysis remains in disposable processes; each worker handles requests
  serially. Jedi's mutable fast-parser cache stays disabled. GUI-thread calls
  submit snapshots rather than performing Jedi/autopep8 analysis in the UI.
- Assistance has a four-second deadline; explicit edit operations have six
  seconds. The deadline includes admission and startup wait. Cancellation and
  process retirement do not synchronously wait on the GUI thread.
- Worker replies are cached for at most eight exact requests and eight MiB.
  Idle workers retire after 60 seconds. The lifecycle check accelerated only
  the idle timer and verified retirement followed by a working restart.
- A short, real worker run processed 48 distinct revisions of an approximately
  120-function buffer. It used one thread and exited normally when input closed.
- Worker RSS: 99.15 MiB after the first request; 105.80 MiB after the last.
  The final 16 samples ranged from 105.78 to 105.80 MiB.
  Readings came from the worker's own /proc/self because process-ID namespaces
  differ in this environment. The short run does not prove absence of long-term
  leaks. Document and cache limits are workload limits, not OS memory quotas.

Remaining boundaries demonstrated or inspected
- Rename is document-local static analysis, not whole-project refactoring.
  Demonstrated example: after renaming `value` to `quantity` in `def f(value)`,
  a call through `kwargs = {"value": 3}; f(**kwargs)` still contains the old string
  key and needs manual correction. Dynamic attribute strings and external
  callers likewise require review. The rename preview now states this scope
  explicitly. This review does not claim that the tool solves dynamic Python
  name resolution.
- Lambda support above does not add pattern-matching capture-name resolution;
  the tested match-capture rename was refused safely.
- Assistance deliberately works from the current in-memory document. It does
  not discover installed project packages or other open modules for completion.
- Parameter hints can always be requested explicitly. Automatic triggering is
  based on the current physical line; multiline calls without a qualifying
  prefix on that line may require Ctrl+Shift+Space.
- Formatting requires syntactically valid Python, is requested explicitly,
  and uses conservative autopep8 options. It is not a syntax-repair command.

Native Windows acceptance
1. Select a partial member name in both panes; accept with Tab and by mouse;
   confirm its prefix remains and Undo restores the original text.
2. Request completion/F12 and immediately press Escape or move elsewhere;
   confirm no delayed popup, focus grab, or caret jump occurs.
3. Format a document containing type-ignore comments and a selected line in a
   long repetitive file; confirm surrounding source and Undo remain correct.
4. Rename a lambda parameter and inspect its keyword callers and shadowed names.
5. Check startup/About/Help/main title show 1.3.3 and repeat the prior split-view,
   Find toggle, title-button hover, Generated C hover, and folding interactions.

Primary API references consulted
- Jedi Script API: https://jedi.readthedocs.io/en/latest/docs/api.html
  In particular Script.complete, get_references, get_signatures, and its
  fast_parser/thread-safety note. Jedi documents that sufficiently complicated
  reference searches may stop early; this is relevant to rename's static scope.
- autopep8 public documentation: https://github.com/hhatto/autopep8
  fix_code options, conservative formatting, and line-range behavior.

Environment observed (not new dependency requirements)
{
  "python": "3.12.14",
  "platform": "Linux-6.18.44-x86_64-with-glibc2.39",
  "dependencies": {
    "PySide6": "6.12.0",
    "jedi": "0.20.1",
    "autopep8": "2.3.2",
    "numpy": "2.5.3",
    "numba": "0.68.0"
  }
}
