Skip to main content

1707. CPython 3.14.5 sync

Why this spec exists​

Gopy's "behavioural compatibility with CPython 3.14" claim is only as fresh as the upstream tree we last referenced. Two CPython clones live on this machine:

  • $HOME/cpython-314 is the canonical read-only mirror used by the port specs (every // CPython: citation resolves against this tree).
  • $HOME/github/python/cpython is the working clone used to cherry-pick patches and reproduce upstream tests.

Both were behind the v3.14.5 release tag (cut 2026-05-10). The brew formula python@3.14 was also pinned at 3.14.4. On 2026-05-14 all three were bumped to v3.14.5:

TargetBeforeAfter
/opt/homebrew/Cellar/python@3.143.14.4_13.14.5
$HOME/cpython-314 HEADc235654cba2 (2026-04-20)5607950ef23 (v3.14.5)
$HOME/github/python/cpython HEADab2d84fe102 (2026-04-29)5607950ef23 (v3.14.5)

The v3.14.4 → v3.14.5 window covers 56 first-parent commits and touches 257 files. The Lib/, Modules/, Objects/, Python/ subtrees account for 89 of those; the rest are docs, CI, installer, and test files. This spec catalogues the 89 that gopy cares about and breaks them down by whether gopy has a port that needs a refresh.

Rule​

Every CPython upstream change that affects a file gopy already ships a port for (whether a Go translation under module/ or a byte-equal vendor under stdlib/) is treated as a refresh task on this spec. We do not skip patches because they are "small" or "cosmetic". A two-line upstream fix that changes user-visible behaviour is still a divergence if we don't apply it.

A row gets ticked off when:

  1. The gopy port has the upstream fix mirrored (Go code or re-vendored .py).
  2. The accompanying CPython test (or a gopy equivalent) runs green under gopy.

Sync workflow​

# refresh both clones to the next 3.14.x tag
git -C $HOME/cpython-314 fetch --tags origin 3.14
git -C $HOME/cpython-314 checkout v3.14.<n>
git -C $HOME/github/python/cpython fetch --tags origin 3.14
git -C $HOME/github/python/cpython checkout v3.14.<n>

# brew (optional, only matters when running upstream's own tests)
brew upgrade python@3.14

# audit
git -C $HOME/github/python/cpython diff --stat v3.14.<n-1>..v3.14.<n> -- \
'Lib/' 'Modules/' 'Objects/' 'Python/' 'Include/'

# for each changed file, decide: gopy has a port -> add a row below.

Files in scope​

The 89 runtime files that changed between v3.14.4 and v3.14.5 fall into four buckets. Each table below lists the upstream file, the gopy port (if any), the upstream bug + summary, and the work required in gopy.

A. Python stdlib refreshes (stdlib/ vendor)​

Gopy vendors most of these byte-equal. A refresh means re-copying the upstream .py into stdlib/ and re-running the relevant gate test.

#Upstream filegopy targetUpstream changeStatus
A.1Lib/argparse.pystdlib/argparse.pyGH-130750: _check_value quotes each choice via repr(str(choice)) instead of the bare comma-joined form. Error message went from invalid choice: 'x' (choose from a, b) to invalid choice: 'x' (choose from 'a', 'b').pending
A.2Lib/annotationlib.pystdlib/annotationlib.pygh-141388: handle non-function callables as annotate functions. Adds __wrapped__ traversal and _check_no_unevaluated_strings accommodations for partial, lambda, etc. (36 lines). Sister to spec 1706.pending
A.3Lib/configparser.pystdlib/configparser.py17 lines of edge-case fixes.pending
A.4Lib/dataclasses.pystdlib/dataclasses.py (or port at module/dataclasses/)26 lines of bug fixes. Note: gopy ports dataclasses as Go (module/dataclasses/), not vendored. Audit + apply behaviour parity.pending
A.5Lib/inspect.pynot vendored (audit only)Docstring change removes im_* reference (gh-149096). No behavioural impact.n/a
A.6Lib/pickle.pynot vendored (no gopy port)gh-148914: fix PickleBuffer memoization of in-band buffers. Tracked under future pickle port.n/a
A.7Lib/random.pystdlib/random.pygh-149221: sync random.py with main; gh-149276: fix binomialvariate for the n=1 edge case. Re-vendor + add the new tests as a gopy gate.pending
A.8Lib/runpy.pynot vendoredgh-149117: set ImportError.name from runpy.run_module/run_path. Tracked under future runpy port.n/a
A.9Lib/shutil.pystdlib/shutil.py24 lines. Re-vendor.pending
A.10Lib/typing.pynot vendored (no gopy port)gh-149221-adjacent: get_type_hints now detects __wrapped__ loops and raises ValueError. Tracked under future typing port.n/a
A.11Lib/urllib/robotparser.pystdlib/urllib/robotparser.py (if vendored)gh-138908: RFC 9309 support. 209 lines of new behaviour: wildcard handling, group precedence, longest-match. If gopy ships robotparser, re-vendor.pending
A.12Lib/uuid.pystdlib/uuid.py10 lines. Re-vendor.pending
A.13Lib/zipfile/__init__.pystdlib/zipfile/__init__.py21 lines. Re-vendor.pending
A.14Lib/timeit.pystdlib/timeit.py (if vendored)2 lines.pending
A.15Lib/webbrowser.pynot vendored5 lines.n/a
A.16Lib/socket.pystdlib/socket.py (if vendored)28 lines.pending
A.17Lib/http/client.py, Lib/http/cookies.pystdlib/http/11 + 8 lines respectively.pending
A.18Lib/email/_header_value_parser.py, Lib/email/generator.py, Lib/email/quoprimime.pystdlib/email/15 + 2 + small. bpo-39100 _header_value_parser no longer treats Group as invalid mailbox.pending
A.19Lib/smtplib.pynot vendored2 lines.n/a
A.20Lib/pdb.pynot vendoredgh-148615: handle -- separator in argument parsing.n/a
A.21Lib/json/tool.pynot vendored3 lines.n/a
A.22Lib/multiprocessing/* (connection.py, popen_fork.py, resource_tracker.py)not vendoredsmall fixes.n/a
A.23Lib/asyncio/__main__.py, Lib/asyncio/windows_utils.pynot vendoredgh-149388: PipeHandle.close idempotent.n/a
A.24Lib/ensurepip/__init__.py + bundled wheelnot vendoredgh-149148: bump bundled pip from 26.0.1 to 26.1.1.n/a

B. C modules (module/ Go port)​

#Upstream filegopy targetUpstream changeStatus
B.1Modules/_csv.cmodule/_csv/6 lines. Audit for behaviour change.pending
B.2Modules/_struct.cmodule/_struct/gh-148675: add Zd, Zf, Zg, Ze complex format codes (27 lines). Add to gopy's format table. Linked to arraymodule.c and memoryobject.c.pending
B.3Modules/arraymodule.cgopy array module (none yet)gh-148675: Zd/Zf complex formats (10 lines).pending
B.4Modules/binascii.cgopy binascii (none)gh-148093: a2b_uu raises binascii.Error on empty input (8 lines).n/a
B.5Modules/gcmodule.cmodule/gc/30 lines. Knock-on from Python/gc.c generational restoration: new gc.get_stats fields, heap_size in stats. Sync the gc module's getset table.pending
B.6Modules/zlibmodule.cmodule/zlib/1 line cleanup.pending
B.7Modules/_elementtree.cgopy XML (none)45 lines.n/a
B.8Modules/_asynciomodule.cgopy asyncio (none)6 lines.n/a
B.9Modules/_bz2module.c, Modules/_lzmamodule.c, Modules/_zstd/*gopy (none)compression cleanups.n/a
B.10Modules/_ctypes/_ctypes.c, Modules/_ctypes/cfield.cgopy ctypes (none)gh-148675 (Zd/Zf) + gh-148967 (C complex FFI fix).n/a
B.11Modules/_remote_debugging_module.cnone3.14 debugger surface; not in gopy scope.n/a
B.12Modules/overlapped.cnoneWindows IO.n/a
B.13Modules/expat/*gopy (none, uses Go's encoding/xml)gh-149698: bundled expat bumped to 2.8.1.n/a

C. Object protocol (objects/ Go port)​

#Upstream filegopy targetUpstream changeStatus
C.1Objects/codeobject.cobjects/code.go and friends24 lines. Code-object internal cleanups; audit co_* field churn.pending
C.2Objects/dictobject.cobjects/dict.go4 lines. Free-threading lock cleanup.pending
C.3Objects/genericaliasobject.cobjects/genericalias.go3 lines.pending
C.4Objects/memoryobject.cobjects/memoryview.gogh-148675: Zd/Zf complex formats; gh-148390: fix UB in memoryview(...).cast("?"). 8 lines.pending
C.5Objects/object.cobjects/object.go and ports/8 lines. Audit per the 1704 full-port rule.pending
C.6Objects/typevarobject.cobjects/typevar.go9 lines.pending
C.7Objects/unicodeobject.cobjects/str.go and friends56 lines. Three independent fixes: (a) gh-113956: thread-safe intern_common in free-threaded build; (b) gh-147856: bytes.replace() accepts count as a keyword; (c) GH-145668: FOR_ITER specialization for virtual iterators (also touches Python/bytecodes.c). Only (b) is observable from gopy.pending

D. VM / compile (vm/, compile/, module/builtins/)​

#Upstream filegopy targetUpstream changeStatus
D.1Python/bltinmodule.cmodule/builtins/10 lines. Audit for behaviour change.pending
D.2Python/bytecodes.cvm/ opcodes20 lines. Two fixes: (a) gh-137030: YIELD_VALUE assert no longer crashes on instr_ptr reads when the executable is detached; (b) gh-137814: MAKE_FUNCTION_ANNOTATE rewrites the qualname of the __annotate__ function to <parent>.__annotate__. The annotate-qualname fix is on the gopy hot path because spec 1706 just landed; verify our MAKE_FUNCTION_ANNOTATE op sets func_qualname the same way.pending
D.3Python/codegen.ccompile/codegen_*.go9 lines. Two fixes: (a) gh-149122: refleak in codegen; (b) maybe_optimize_function_call now bails out when the generator expression is a coroutine (otherwise the genexp-to-fast-call fold would be wrong). The coroutine guard is observable: a [x async for x in ...] inside list(...) no longer mis-compiles. Re-check compile/codegen_call_optim.go.pending
D.4Python/compile.ccompile/ driver14 lines.pending
D.5Python/flowgraph.ccompile/flowgraph_*.go146 lines. Cleanups and one bug fix in inline_small_or_no_lineno_blocks. Audit gopy's flowgraph.pending
D.6Python/gc.cmodule/gc/ + Go runtimegh-148726: forward-port the generational GC to 3.14 (1076 lines, 330 ins / 746 del, mostly a refactor that re-introduces young/middle/old generations after 3.13's "incremental GC" experiment). gopy's GC is Go's runtime, not a Python-side mark/sweep, so most of this is informational; however, gc.get_stats(), gc.get_count(), gc.collect(generation=...), gc.set_threshold, gc.get_threshold, and gc.freeze/gc.unfreeze are observable from Python and need consistent return shapes. Audit module/gc/.pending
D.7Python/instrumentation.cvm/instrumentation.go (if ported)41 lines. Tracking gh-148178 (validate remote debug offset tables). Mostly debugger surface.pending
D.8Python/legacy_tracing.cnot ported4 lines.n/a
D.9Python/marshal.cgopy marshal (none)gh-148418: reference leak on corrupted TYPE_CODE stream (46 lines). Tracked when marshal lands.n/a
D.10Python/optimizer_analysis.cgopy tier-2 optimizer5 lines.pending
D.11Python/crossinterp.c, Python/parking_lot.c, Python/lock.cnot portedfree-threading internals.n/a
D.12Python/executor_cases.c.h, Python/generated_cases.c.hderivedauto-generated; reflects bytecodes.c changes.n/a

Highlights: patches gopy must land soon​

Pulled out separately because the rest of the table is sortable maintenance work; these are the items that change observable behaviour for code gopy already runs:

  1. MAKE_FUNCTION_ANNOTATE qualname rewrite (D.2 gh-137814). Spec 1706 just landed the deferred-annotation pipeline. The 3.14.5 fix means f.__annotate__.__qualname__ is now <parent>.__annotate__ instead of inherited from the function slot. Without this fix, inspect.signature and typing.get_type_hints reporting will diverge.

  2. argparse choice quoting (A.1 GH-130750). One-line re-vendor; the error message is part of unittest gates.

  3. Lib/annotationlib.py non-function callables (A.2 gh-141388). Spec 1706 Phase 8 just shipped this file byte-equal; we need a re-vendor against v3.14.5 to keep the annotate-callable handling in sync (partial, lambda, decorator-wrapped callables).

  4. bytes.replace(count=…) keyword (C.7 gh-147856). Tests in test_bytes will fail without this.

  5. codegen.c coroutine genexp guard (D.3). If gopy ports maybe_optimize_function_call, the guard prevents a mis-compile of list(x async for x in agen).

  6. gcmodule.c / Python/gc.c generational GC API (B.5, D.6). gc.get_stats() schema changed (now includes heap_size, per-generation counts). gopy's module/gc/ returns its own shape; align with 3.14.5 fields so vendored code (e.g., Lib/test/test_gc.py) compiles.

  7. struct/array/memoryview complex format codes (B.2, B.3, C.4 gh-148675). Zd (complex128), Zf (complex64), Zg, Ze join the existing format chars. gopy's module/_struct/ table currently rejects them.

Files explicitly out of scope​

These changed upstream but gopy does not ship a port, so they are tracked only for future reference:

  • Lib/pickle.py, Lib/typing.py, Lib/runpy.py, Lib/inspect.py, Lib/pdb.py, Lib/json/tool.py, Lib/multiprocessing/*, Lib/asyncio/*, Lib/ensurepip/*
  • Modules/binascii.c, Modules/_elementtree.c, Modules/_asynciomodule.c, Modules/_bz2module.c, Modules/_lzmamodule.c, Modules/_zstd/*, Modules/_ctypes/*, Modules/_remote_debugging_module.c, Modules/overlapped.c, Modules/expat/*
  • Python/marshal.c, Python/crossinterp.c, Python/parking_lot.c, Python/lock.c, Python/legacy_tracing.c
  • All Windows/Apple/Android installer files
  • All Lib/test/* files (we maintain our own gate corpus under spec 1701)
  • Doc/, .github/workflows/, iOS/, Mac/, PCbuild/, Tools/

Gate​

This spec is done when every row marked pending above is either flipped to done (port refreshed + matching test green) or moved to an explicit out-of-scope follow-up with a tracking issue. The audit cadence is per-release: every new 3.14.x tag spawns a fresh 1707_X follow-up spec (e.g., 1707_3146.md) with the v3.14.5 → v3.14.6 delta. The structure above is the template.

Checklist​

  • Pull $HOME/cpython-314 to v3.14.5 tag.
  • Pull $HOME/github/python/cpython to v3.14.5 tag.
  • Upgrade brew python@3.14 from 3.14.4_1 to 3.14.5.
  • Audit git diff --stat v3.14.4..v3.14.5 for Lib/, Modules/, Objects/, Python/, Include/.
  • Bucket each touched file into Stdlib / Modules / Objects / VM and record gopy target + upstream change summary.
  • File a tracking task per pending row above (one task per row, not one per bucket. Each row maps to a discrete port refresh).
  • Land the seven "Highlights" patches before the next release.
  • Flip remaining pending rows as their refreshes land.
  • Open 1707_3146.md when v3.14.6 ships.