The getstate test called Summary.__getstate__(), which rebuilt the
PagedList pages in tools.CACHE_PATH/summary_dir with exist_ok=True.
Since CACHE_PATH is relative to the current directory, running the
tests clobbered the real .eris cache and caused eris to crash on the
next startup when sync_with_filesystem hit the stale summary.
flock on .eris/lock prevents two eris processes racing the cache, which
previously produced a mixed-format summary (int-list pages) and crashed
sync_with_filesystem. The lock is acquired before manage_cache, the lock
file survives checksum-mismatch cleanup, and the holder's PID is written
to the lock file so a refused instance can report it.
Removes the shell's "Killed" message and lets fill3's terminal-restore
codes flush via normal interpreter exit. Worker.kill() now SIGKILLs only
the worker thread's subprocess descendants (via /proc/PID/task/TID/children,
recursing through shell=True grandchildren), so editor and xdg-open spawns
from the main thread survive quit. A _killed flag skips persisting result
pickles for aborted tool runs. start_new_session=True is no longer needed
on editor/xdg-open launches since the kill is worker-thread-scoped.
Verify the interpreter is free-threaded (Py_GIL_DISABLED) and the GIL is
not re-enabled after loading the full eris module chain, so a dependency
that re-enables the GIL (PEP 703) or a non-free-threaded interpreter
fails the suite.
__getstate__ emitted an empty entry list whenever the cursor was on the
top row (y == 0), so quitting from the top silently discarded all
previously calculated results. The guard was intended to rotate the
cursor row to the front, but the y == 0 case should simply keep the whole
list as-is. Remove the guard so all entries are always persisted.
Convert each Worker from a subprocess to a thread running the tool in a
ThreadPoolExecutor, so eris can run free-threaded under CPython 3.14t.
Bump fill3 and lscolors deps to 2026.8.3 for the GIL-free cwcwidth chain.
ProcessPoolExecutor relied on private API, lost os.setpriority and
auto-restart. Revert to the subprocess worker but spawn the current
executable with --worker instead of a separate eris-worker console
script, keeping a single entry point for shiv/pyinstaller. Bump
.python-version to 3.14.
Replace the native pydoc() function (+ @in_separate_process, _call_in_process)
with a TOML tool definition running python3 -m pydoc directly. No ANSI
styling, no TermDoc, no process isolation decorator. This eliminates the
grandchild worker process (from nested ProcessPoolExecutor) that caused
TUI corruption on shutdown.
Also remove now-unused import concurrent.futures from tools.py.
Regenerate the pydoc golden file to match plain-text output.
- Rewrite worker.py: each Worker uses a ProcessPoolExecutor(max_workers=1),
tools run via loop.run_in_executor() in a forked OS subprocess
- Remove create_process(), main(), stdin/stdout IPC, os.killpg
- Remove eris-worker entry point from [project.scripts] in pyproject.toml
- Update tests/worker_test.py for new Worker API
- Guard _sweep_up/_sweep_down against IndexError when _entries is empty;
keep cursor_position() try/except for stale y after row deletion
- Update readme.
- php7 -> php8.
- Fix python-coverage.
- Also need python decorator module.
- Replaced Mcrt1 with rotatingtree since Mcrt1 started raising
a new warning.
- Made termstr's length match the on-screen width.
- Achieved by adding a zero width character after each wide
character.
- This fixes ljust and rjust, so that there is correct padding,
otherwise Portal appearances aren't the correct width.
- When getting a sub-string containing half a wide character,
the half character is a space.
- Some wide characters are still broken. e.g. country flags
- Changed all normal results to ok.
- Normal results were intended for tools that produced info and
weren't expected to have problem results.
- Ultimately not worth distinguishing from tools that sometimes
show problems.
- One less color status makes the summary table simpler.
- Also changed the not-applicable status color to the lighter grey
that normal used to have.
- Made the success status non-configurable since ok status is the
only sensible status at the moment.
- In portrait mode.
- In the average project there was a bit of wasted space.
Python files (with lots of statuses) in a subdirectory had
space left over. They can still be seen with the summary
pane narrowed.
- Puts emphasis on viewing the listing over the summary pane.
- Contents were often a little too wide for the listing pane
and now fit.
- Using the ast module to correctly determine the line numbers
of the function bodies.
- Should have done it this way in the beginning, but didn't know
about ast module tracking line numbers.
- No more heuristics.
- Copes with different size indentations.