- Nested fan-out under the fork start method is fixed: a worker that
performed a second submit() while a sibling Future was still registered
crashed with "can only join a child process" because under fork no
pickling occurs, so __setstate__ never ran and the worker inherited the
parent's selector (and sibling Process objects belonging to an ancestor).
The selector is now built lazily through a single _lazy_selector()
accessor that rebuilds a clean per-process selector whenever
_selector_pid no longer matches os.getpid(), so a forked worker discards
the inherited selector before reclaim_resources() or submit() can touch a
non-child process. A regression test exercises nested fan-out across all
start methods.
- Pickle-dump error handling is shared rather than duplicated: the
(PicklingError, AttributeError, TypeError) classification, previously
spelled out in both _worker_entrypoint and the executor's
_responses_put_failed with comments asking the two sites to agree, is
hoisted into a single PICKLE_DUMP_ERRORS constant in _compat so the
contract is enforced by one definition.
- An EnvItems type alias deduplicates the env signature: the four-line env
Union previously repeated verbatim across __init__, submit, map,
_env_coerce, and _map_generate is collapsed into one alias (and
Optional[EnvItems] where None means "use the instance default") so the
signatures read uniformly.
- A draft benchmark harness is added under draft/bench.py: a stdlib-only
program that exercises six semi-realistic CPU-bound workflows (flat,
nested, callbacks, sleepfn, executor, and cancel) and prints aligned
tables of wall time, throughput, and speedup versus a serial baseline.
All kernels are module-level and picklable under spawn/forkserver, it
supports --quick/--full/--slots/--context/--only, and it runs via
PYTHONPATH=src. It lives under draft/ so the CI script does not pay its
multi-second runtime.