)]}'
{
  "commit": "7905d790118254d18ebc1e8fae2ccc887770d028",
  "tree": "be8c34ba979af88f17ec5fcf2f65867cca6356c0",
  "parents": [
    "b1b9bf00f7b9af8ba8a2dab4edef68d5e6e2e536"
  ],
  "author": {
    "name": "Régis Desgroppes",
    "email": "rdesgroppes@gmail.com",
    "time": "Thu Aug 20 07:26:35 2026 +0000"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Thu Aug 20 07:26:35 2026 +0000"
  },
  "message": "fix(toolchain): fix crash on Windows when precompiling is enabled (#4082)\n\n`python/private/py_executable.bzl`\u0027s `_maybe_add_test_main_validation`\nfix (#4079) noted `precompile.bzl` as a remaining user of the same\n`exec_interpreter` relocation issue, needing the same migration.\n\nThere was no existing test exercising `_precompile`\u0027s action at all:\n`tests/base_rules/precompile`\u0027s suite is `analysis_test`-only, checking\ndeclared providers, never actually running the precompiler.\nReproducing this on Windows therefore required a real `bazel build`, via\nthe new `test_precompile_enabled_succeeds`:\n```\nbazel test \\\n  //tests/base_rules/precompile:test_precompile_enabled_succeeds\n...\nERROR: .../tests/base_rules/precompile/BUILD.bazel:3:22: Python\n precompiling .../test_precompile_enabled_succeeds_main.py into\n .../test_precompile_enabled_succeeds_main.cpython-311.pyc\n failed: Worker process did not return a WorkResponse:\n---8\u003c---8\u003c--- Start of log, file at\n .../multiplex-worker-1-PyCompile.log ---8\u003c---8\u003c---\n(empty)\n---8\u003c---8\u003c--- End of log ---8\u003c---8\u003c---\n```\nThe worker crashes at startup, unable to find its DLLs, before it can\nwrite anything to its own log or respond over the worker protocol.\n\n`_precompile` now uses `actions_run()` with `exec_runtime`, exactly as\n`_maybe_add_test_main_validation` does, instead of\n`exec_tools_info.exec_interpreter[DefaultInfo].files_to_run`.\n\nReproducing and fixing this also uncovered two more problems, both\nspecific to the precompiler\u0027s worker mode and unrelated to\n`exec_interpreter`.\n\nFirst, `tools/precompiler/precompiler.py`\u0027s persistent worker reads each\nJSON request as a single line via `asyncio.StreamReader`, whose default\n64KiB limit is exceeded once every interpreter distribution file,\npreviously hidden by relocation into a much smaller symlink tree, shows\nup as an actual, individually-digested action input:\n```\nValueError: Separator is not found, and chunk exceed the limit\n```\nA CPython 3.11 distribution\u0027s ~2,260 inputs measure ~470KiB this way; `1\n\u003c\u003c 22` (4MiB) leaves ample headroom.\n\nSecond, the worker\u0027s default implementation, `_AsyncPersistentWorker`,\ncan\u0027t start on Windows at all: `asyncio`\u0027s `ProactorEventLoop` fails to\nwrap `stdin`/`stdout` as pipe transports, with:\n```\nOSError: [WinError 6] The handle is invalid\n```\nBazel gives workers anonymous pipes (`CreatePipe`) for stdio, which\nnever support overlapped I/O, so `asyncio`\u0027s `ProactorEventLoop` can\u0027t\nregister them with an I/O completion port.\nThis is unrelated to precompiling\u0027s relocation bug: nothing exercises\nthis worker on Windows today.\n`_SerialPersistentWorker`, the blocking-I/O alternative already present\nin the file, has no such issue, so `--worker_impl` now defaults to\n`serial` on Windows.\n\n`tests/base_rules/precompile:test_precompile_enabled_succeeds` is a\nreal, executing `py_test` with `precompile \u003d \"enabled\"`, added alongside\nthe analysis-only suite to close this gap: it forces the precompiler\naction to actually run, and needs no CI wiring since it carries no tag\nexcluding it from the existing Windows job\u0027s default test sweep.",
  "tree_diff": [
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "12c6a51e17e03c28b17d78d272074c723335225d",
      "new_mode": 33188,
      "new_path": "news/4082.fixed.md"
    },
    {
      "type": "modify",
      "old_id": "c12882bf82e768f61329c5b6dc777ed636c2cf5d",
      "old_mode": 33188,
      "old_path": "python/private/precompile.bzl",
      "new_id": "898dc3ee2ac1b8035eb4f4c28332c7aa10891c8a",
      "new_mode": 33188,
      "new_path": "python/private/precompile.bzl"
    },
    {
      "type": "modify",
      "old_id": "bff994aa1a2251e0405f5b9472a858951211d849",
      "old_mode": 33188,
      "old_path": "tests/base_rules/precompile/precompile_tests.bzl",
      "new_id": "d2c1da6b8f874a34c56324f9e41fba49d77fea2a",
      "new_mode": 33188,
      "new_path": "tests/base_rules/precompile/precompile_tests.bzl"
    },
    {
      "type": "modify",
      "old_id": "f83dd15951a8605db4c2100fdfa5bcf739fe8504",
      "old_mode": 33188,
      "old_path": "tools/precompiler/precompiler.py",
      "new_id": "7c44a32631b555b6f0588831ccac90a0929e3b19",
      "new_mode": 33188,
      "new_path": "tools/precompiler/precompiler.py"
    }
  ]
}
