Compare commits
No commits in common. "f963e7b6ce4d1435d500ceb9dd22bc75b9665488" and "e90f2f224abac0b47f020c3af2faf85e1c86cdbc" have entirely different histories.
f963e7b6ce
...
e90f2f224a
|
|
@ -162,10 +162,6 @@ jobs:
|
||||||
run: uv run python -c "import sys; import tractor; from tractor.ipc._uds import HAS_UDS; assert sys.platform != 'win32' or not HAS_UDS; print('import tractor OK | HAS_UDS=', HAS_UDS)"
|
run: uv run python -c "import sys; import tractor; from tractor.ipc._uds import HAS_UDS; assert sys.platform != 'win32' or not HAS_UDS; print('import tractor OK | HAS_UDS=', HAS_UDS)"
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
# Actor/PTY scheduling on macOS can fail a different
|
|
||||||
# timing-sensitive node between otherwise-green runs. Retry
|
|
||||||
# only that matrix leg; deterministic failures still fail
|
|
||||||
# after the final attempt.
|
|
||||||
continue-on-error: ${{ matrix.os == 'windows-latest' }}
|
continue-on-error: ${{ matrix.os == 'windows-latest' }}
|
||||||
run: >
|
run: >
|
||||||
uv run
|
uv run
|
||||||
|
|
@ -175,8 +171,6 @@ jobs:
|
||||||
--spawn-backend=${{ matrix.spawn_backend }}
|
--spawn-backend=${{ matrix.spawn_backend }}
|
||||||
--tpt-proto=${{ matrix.tpt_proto }}
|
--tpt-proto=${{ matrix.tpt_proto }}
|
||||||
--capture=fd
|
--capture=fd
|
||||||
--reruns=${{ matrix.os == 'macos-latest' && 2 || 0 }}
|
|
||||||
--reruns-delay=1
|
|
||||||
|
|
||||||
# XXX legacy NOTE XXX
|
# XXX legacy NOTE XXX
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
session: tractor-addr-unpacking
|
|
||||||
timestamp: 2026-08-21T05:20:52Z
|
|
||||||
git_ref: 3690e43a
|
|
||||||
scope: config
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260821T052052Z_3690e43a_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
The human asked for a main-first patch using an off-the-shelf pytest
|
|
||||||
plugin to cope with tractor's changing macOS CI flakes without mixing
|
|
||||||
that mitigation into PR #505.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Added `pytest-rerunfailures` to tractor's testing dependencies and
|
|
||||||
configured the GitHub Actions matrix to retry failures only on macOS.
|
|
||||||
Linux and Windows remain strict first-attempt runs, while persistent
|
|
||||||
macOS failures still fail after two visible reruns.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `.github/workflows/ci.yml` - macOS-only pytest rerun budget.
|
|
||||||
- `pyproject.toml` - testing plugin dependency and rationale.
|
|
||||||
- `uv.lock` - resolved `pytest-rerunfailures` package metadata.
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
The human selected a main-first mitigation after PR #505 failed two
|
|
||||||
different macOS tests on consecutive runs and required the change to
|
|
||||||
remain an incremental patch with its own commit plan. The agent
|
|
||||||
implemented and verified that direction; no direct manual source
|
|
||||||
edits were observed.
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
---
|
|
||||||
model: gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-08-21T05:20:52Z
|
|
||||||
git_ref: 3690e43a
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD
|
|
||||||
---
|
|
||||||
|
|
||||||
# Raw output - retry flaky macOS CI tests
|
|
||||||
|
|
||||||
The human requested an off-the-shelf pytest plugin patch suitable
|
|
||||||
for landing directly on tractor `main` after PR #505's macOS job
|
|
||||||
failed two different timing-sensitive tests on consecutive runs.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- .github/workflows/ci.yml pyproject.toml uv.lock`
|
|
||||||
|
|
||||||
Added the pytest-dev-maintained `pytest-rerunfailures` plugin and
|
|
||||||
gave only the macOS matrix leg two reruns with a one-second delay.
|
|
||||||
Linux and Windows receive a zero retry budget; deterministic macOS
|
|
||||||
failures still fail after the final attempt and reruns remain visible
|
|
||||||
in pytest output.
|
|
||||||
|
|
||||||
The lockfile is current, actionlint passed, all 471 tests collected,
|
|
||||||
and the four tests covering both observed PR #505 failure areas
|
|
||||||
passed with the rerun plugin enabled.
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
session: ses_fd403c9c9ffe625w99Tr0ALQBN
|
|
||||||
timestamp: 2026-08-25T18:11:02Z
|
|
||||||
git_ref: 3690e43a
|
|
||||||
scope: config
|
|
||||||
substantive: true
|
|
||||||
raw_file: 20260825T181102Z_3690e43a_prompt_io.raw.md
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
Enforce the 69-column Python source limit through Ruff and record a
|
|
||||||
follow-up for richer project-specific style checks.
|
|
||||||
|
|
||||||
## Response summary
|
|
||||||
|
|
||||||
Enabled E501 at 69 columns and documented a later changed-line
|
|
||||||
token/AST checker for style rules Ruff cannot represent. Isolated the
|
|
||||||
configuration on a dedicated follow-up branch after measuring the
|
|
||||||
existing repository lint debt.
|
|
||||||
|
|
||||||
## Files changed
|
|
||||||
|
|
||||||
- `ruff.toml` - enables 69-column E501 enforcement and records
|
|
||||||
follow-up lint work.
|
|
||||||
|
|
||||||
## Human edits
|
|
||||||
|
|
||||||
The human initially selected immediate global enforcement and
|
|
||||||
explicitly requested the richer-checker TODO. After review exposed
|
|
||||||
1,548 existing diagnostics, the human directed the work onto an
|
|
||||||
independent linting branch and deferred landing until incremental
|
|
||||||
enforcement is implemented. The agent applied the config and transfer;
|
|
||||||
no direct manual source edits were identified.
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
---
|
|
||||||
model: openai/gpt-5.6-sol
|
|
||||||
service: opencode
|
|
||||||
timestamp: 2026-08-25T18:11:02Z
|
|
||||||
git_ref: main
|
|
||||||
diff_cmd: git diff HEAD~1..HEAD -- ruff.toml
|
|
||||||
---
|
|
||||||
|
|
||||||
## Prompt
|
|
||||||
|
|
||||||
Enable Ruff enforcement of the shared 69-column Python source limit in
|
|
||||||
Modden, Piker, and Tractor. Add a TODO for a later changed-line token/AST
|
|
||||||
checker covering project rules Ruff cannot express.
|
|
||||||
|
|
||||||
## Response
|
|
||||||
|
|
||||||
Configured Ruff's formatter/lint line length to 69 and enabled E501. Added a
|
|
||||||
follow-up TODO for boolean layout, local annotation placement, docstring
|
|
||||||
quoting and rationale, and symbol-qualified technical prose.
|
|
||||||
|
|
||||||
> `git diff HEAD~1..HEAD -- ruff.toml`
|
|
||||||
|
|
||||||
The configuration parses successfully. Existing Tractor package/test debt is
|
|
||||||
1,469 E501 diagnostics; it was reported rather than reformatted implicitly.
|
|
||||||
|
|
@ -1,97 +0,0 @@
|
||||||
# Incremental Python Style Enforcement
|
|
||||||
|
|
||||||
## Objective
|
|
||||||
|
|
||||||
Enforce the mechanically checkable parts of `/py-codestyle` on new and
|
|
||||||
changed Python lines without requiring an immediate repository-wide
|
|
||||||
cleanup. Keep subjective prose guidance in review policy and expose
|
|
||||||
legacy debt separately from blocking CI.
|
|
||||||
|
|
||||||
## Current State
|
|
||||||
|
|
||||||
- `ruff.toml` sets the intended 69-column limit and enables `E501`.
|
|
||||||
- A package-and-test scan reports 1,548 existing violations.
|
|
||||||
- Ruff can enforce line length, ordinary syntax rules, unused f-string
|
|
||||||
prefixes, and configured quote style.
|
|
||||||
- Ruff cannot directly encode several project-specific layout,
|
|
||||||
docstring, annotation, and technical-prose policies.
|
|
||||||
|
|
||||||
The initial configuration is branch scaffolding, not a landable final
|
|
||||||
state. The implementation must make changed-code enforcement usable
|
|
||||||
before this branch targets `main`.
|
|
||||||
|
|
||||||
## Policy Matrix
|
|
||||||
|
|
||||||
Document each `/py-codestyle` rule under one enforcement class:
|
|
||||||
|
|
||||||
1. Ruff lint rule, enabled directly when the repository is clean.
|
|
||||||
2. Ruff formatter setting, used for intentionally formatted files.
|
|
||||||
3. Deterministic token or AST check, enforced on changed lines.
|
|
||||||
4. Review-only guidance where automation would produce false positives.
|
|
||||||
|
|
||||||
Start with native checks for `E501`, `F541`, quote style, import and
|
|
||||||
syntax errors. Use custom checks for exact docstring delimiters and
|
|
||||||
shape, multiline string construction, double-newline source layout,
|
|
||||||
f-string continuation consistency, local annotation placement, and
|
|
||||||
boolean-expression layout. Keep symbol-qualified technical prose and
|
|
||||||
regression-test rationale as review guidance unless a low-noise warning
|
|
||||||
can be demonstrated.
|
|
||||||
|
|
||||||
## Changed-Line Harness
|
|
||||||
|
|
||||||
Add `scripts/check_py_codestyle.py` with these responsibilities:
|
|
||||||
|
|
||||||
- Read a base revision and collect added line ranges from `git diff
|
|
||||||
--unified=0`.
|
|
||||||
- Treat every line in an added Python file as changed.
|
|
||||||
- Run Ruff with JSON output and the incremental native-rule set.
|
|
||||||
- Report only diagnostics intersecting added line ranges.
|
|
||||||
- Run token/AST checks and apply the same changed-line filter.
|
|
||||||
- Return a nonzero status only for changed-code violations.
|
|
||||||
- Offer a separate nonblocking full-tree debt-report mode.
|
|
||||||
|
|
||||||
Keep `E501` out of the default global Ruff selection until the legacy
|
|
||||||
count reaches zero. The harness should request it explicitly so normal
|
|
||||||
repository lint remains useful during migration.
|
|
||||||
|
|
||||||
## Verification
|
|
||||||
|
|
||||||
Add focused checker tests covering:
|
|
||||||
|
|
||||||
- diff range parsing, deleted lines, renames, and new files;
|
|
||||||
- 69-column boundaries with indentation and string syntax;
|
|
||||||
- compliant and noncompliant docstring delimiters and closing shape;
|
|
||||||
- f-string continuation and double-newline source layout;
|
|
||||||
- boolean layout and local annotation placement;
|
|
||||||
- diagnostics on untouched legacy lines being ignored;
|
|
||||||
- diagnostics on newly touched legacy lines becoming blocking.
|
|
||||||
|
|
||||||
Run the checker against a fixture base and against the branch diff. Run
|
|
||||||
the existing Ruff checks without incremental rules to prove the normal
|
|
||||||
lint path remains usable.
|
|
||||||
|
|
||||||
## CI Integration
|
|
||||||
|
|
||||||
Add a dedicated CI step that derives the pull-request base commit from
|
|
||||||
the event payload and invokes the changed-line harness. Preserve a local
|
|
||||||
`--base main` mode for developers. Emit normal file, line, column, and
|
|
||||||
rule identifiers so forge annotations remain navigable.
|
|
||||||
|
|
||||||
Publish the full-tree debt count as nonblocking output. Do not hide or
|
|
||||||
silently rewrite existing source violations.
|
|
||||||
|
|
||||||
## Commit Boundaries
|
|
||||||
|
|
||||||
1. Record the 69-column policy scaffold and provenance.
|
|
||||||
2. Add the changed-line Ruff harness and its tests.
|
|
||||||
3. Add deterministic token/AST policy checks and fixtures.
|
|
||||||
4. Wire the harness into CI and document local usage.
|
|
||||||
5. Enable native rules globally only after their legacy counts reach
|
|
||||||
zero, using separate cleanup commits where needed.
|
|
||||||
|
|
||||||
## Deferred
|
|
||||||
|
|
||||||
Type-checking migration belongs in a separate branch. It should use the
|
|
||||||
same incremental principle: establish the tool configuration and debt
|
|
||||||
inventory, gate new or changed code, publish nonblocking full-tree debt,
|
|
||||||
and tighten global enforcement as annotations and defects are repaired.
|
|
||||||
|
|
@ -100,9 +100,6 @@ testing = [
|
||||||
# cleanup utility (xplatform `Process.memory_maps`,
|
# cleanup utility (xplatform `Process.memory_maps`,
|
||||||
# `Process.open_files`).
|
# `Process.open_files`).
|
||||||
"psutil>=7.0.0",
|
"psutil>=7.0.0",
|
||||||
# rerun timing-sensitive macOS CI nodes without hiding a
|
|
||||||
# deterministic failure after the final attempt.
|
|
||||||
"pytest-rerunfailures>=16.6,<17",
|
|
||||||
]
|
]
|
||||||
repl = [
|
repl = [
|
||||||
"pyperclip>=1.9.0",
|
"pyperclip>=1.9.0",
|
||||||
|
|
|
||||||
10
ruff.toml
10
ruff.toml
|
|
@ -31,8 +31,8 @@ exclude = [
|
||||||
"venv",
|
"venv",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Project source style limit.
|
# Same as Black.
|
||||||
line-length = 69
|
line-length = 88
|
||||||
indent-width = 4
|
indent-width = 4
|
||||||
|
|
||||||
# assume latest minor cpython
|
# assume latest minor cpython
|
||||||
|
|
@ -42,15 +42,11 @@ target-version = "py313"
|
||||||
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
|
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
|
||||||
# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or
|
# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or
|
||||||
# McCabe complexity (`C901`) by default.
|
# McCabe complexity (`C901`) by default.
|
||||||
select = ["E4", "E7", "E9", "E501", "F"]
|
select = ["E4", "E7", "E9", "F"]
|
||||||
ignore = [
|
ignore = [
|
||||||
'E402', # https://docs.astral.sh/ruff/rules/module-import-not-at-top-of-file/
|
'E402', # https://docs.astral.sh/ruff/rules/module-import-not-at-top-of-file/
|
||||||
]
|
]
|
||||||
|
|
||||||
# TODO: add a changed-line token/AST checker for py-codestyle rules
|
|
||||||
# Ruff cannot express: boolean layout, local annotation placement,
|
|
||||||
# docstring quoting/rationale, and symbol-qualified technical prose.
|
|
||||||
|
|
||||||
# Allow fix for all enabled rules (when `--fix`) is provided.
|
# Allow fix for all enabled rules (when `--fix`) is provided.
|
||||||
fixable = ["ALL"]
|
fixable = ["ALL"]
|
||||||
unfixable = []
|
unfixable = []
|
||||||
|
|
|
||||||
17
uv.lock
17
uv.lock
|
|
@ -782,19 +782,6 @@ wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/8b/5a/ba30a81239b909821b3153e303e7def45178bf353da4f72380e6c5e8793b/pytest-9.1.0-py3-none-any.whl", hash = "sha256:8ebb0e7888bdf2bdfc602ec51f8f62d50200af37356c74e503c79a94f5c81f32", size = 386453, upload-time = "2026-06-13T18:52:44.045Z" },
|
{ url = "https://files.pythonhosted.org/packages/8b/5a/ba30a81239b909821b3153e303e7def45178bf353da4f72380e6c5e8793b/pytest-9.1.0-py3-none-any.whl", hash = "sha256:8ebb0e7888bdf2bdfc602ec51f8f62d50200af37356c74e503c79a94f5c81f32", size = 386453, upload-time = "2026-06-13T18:52:44.045Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pytest-rerunfailures"
|
|
||||||
version = "16.6"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "packaging" },
|
|
||||||
{ name = "pytest" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/ed/63/0114e45d4b2fcd5f6297dac655c067b47de28be4d33e088f200f0f2c4c28/pytest_rerunfailures-16.6.tar.gz", hash = "sha256:29dbfee46f542073c888e0ed4e81c51e15b9096f49a299eb1a759629c601684a", size = 42806, upload-time = "2026-08-17T07:11:00.447Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/5d/5e/1e994889673d7a0da11651f17ef789b6c83bfe349f29f871873dd3802445/pytest_rerunfailures-16.6-py3-none-any.whl", hash = "sha256:6af2d1ebd6e5cb79666ac408942cd6a0672a49fefd8523664770718560795e13", size = 19137, upload-time = "2026-08-17T07:10:59.121Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pytest-timeout"
|
name = "pytest-timeout"
|
||||||
version = "2.4.0"
|
version = "2.4.0"
|
||||||
|
|
@ -1144,7 +1131,6 @@ dev = [
|
||||||
{ name = "psutil" },
|
{ name = "psutil" },
|
||||||
{ name = "pyperclip" },
|
{ name = "pyperclip" },
|
||||||
{ name = "pytest" },
|
{ name = "pytest" },
|
||||||
{ name = "pytest-rerunfailures" },
|
|
||||||
{ name = "pytest-timeout" },
|
{ name = "pytest-timeout" },
|
||||||
{ name = "stackscope" },
|
{ name = "stackscope" },
|
||||||
{ name = "typing-extensions" },
|
{ name = "typing-extensions" },
|
||||||
|
|
@ -1184,7 +1170,6 @@ testing = [
|
||||||
{ name = "pexpect" },
|
{ name = "pexpect" },
|
||||||
{ name = "psutil" },
|
{ name = "psutil" },
|
||||||
{ name = "pytest" },
|
{ name = "pytest" },
|
||||||
{ name = "pytest-rerunfailures" },
|
|
||||||
{ name = "pytest-timeout" },
|
{ name = "pytest-timeout" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -1210,7 +1195,6 @@ dev = [
|
||||||
{ name = "psutil", specifier = ">=7.0.0" },
|
{ name = "psutil", specifier = ">=7.0.0" },
|
||||||
{ name = "pyperclip", specifier = ">=1.9.0" },
|
{ name = "pyperclip", specifier = ">=1.9.0" },
|
||||||
{ name = "pytest", specifier = ">=9.0.3" },
|
{ name = "pytest", specifier = ">=9.0.3" },
|
||||||
{ name = "pytest-rerunfailures", specifier = ">=16.6,<17" },
|
|
||||||
{ name = "pytest-timeout", specifier = ">=2.3" },
|
{ name = "pytest-timeout", specifier = ">=2.3" },
|
||||||
{ name = "stackscope", specifier = ">=0.2.2,<0.3" },
|
{ name = "stackscope", specifier = ">=0.2.2,<0.3" },
|
||||||
{ name = "typing-extensions", specifier = ">=4.14.1" },
|
{ name = "typing-extensions", specifier = ">=4.14.1" },
|
||||||
|
|
@ -1242,7 +1226,6 @@ testing = [
|
||||||
{ name = "pexpect", specifier = ">=4.9.0,<5" },
|
{ name = "pexpect", specifier = ">=4.9.0,<5" },
|
||||||
{ name = "psutil", specifier = ">=7.0.0" },
|
{ name = "psutil", specifier = ">=7.0.0" },
|
||||||
{ name = "pytest", specifier = ">=9.0.3" },
|
{ name = "pytest", specifier = ">=9.0.3" },
|
||||||
{ name = "pytest-rerunfailures", specifier = ">=16.6,<17" },
|
|
||||||
{ name = "pytest-timeout", specifier = ">=2.3" },
|
{ name = "pytest-timeout", specifier = ">=2.3" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue