Visitar URL original
Prepare Python 3.15 with rc3 libraries and native prerequisites by youknowdot · Pull Request #8954 · RustPython/RustPython · GitHub
Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
82e7ccd
Implement the sentinel builtin from PEP 661
youknowdot Oct 2, 2026
006b50b
Add the eager-runtime importlib lazy-attribute hook
youknowdot Oct 2, 2026
85af9a1
Support compile module context across AST warning paths
youknowdot Oct 2, 2026
2e2bc87
Begin the Python 3.15 essential-library bootstrap
youknowdot Oct 2, 2026
90891df
Update import tests and builtin loader validation for Python 3.15
youknowdot Oct 2, 2026
8b0f966
Preserve the validated string key when creating builtins
youknowdot Oct 2, 2026
87aae87
Describe Python 3.15 as the migration target
youknowdot Oct 2, 2026
f443b3b
Upgrade venv and activation scripts to Python 3.15 rc2
youknowdot Oct 3, 2026
70d045e
Implement PEP 814 frozendict
youknowdot Oct 2, 2026
a8c898d
Use native frozendict in the migrated test support tables
youknowdot Oct 3, 2026
6f700f7
Update enum from CPython 3.15.0rc2
youknowdot Oct 2, 2026
ed0ff96
Keep the original RustPython executable across nested venv aliases
youknowdot Oct 3, 2026
916d768
Integrate the Python 3.15 rc2 runtime and standard library upgrade
youknowdot Oct 3, 2026
e18ef0a
Use an object receiver for the JSON array hook descriptor
youknowdot Oct 3, 2026
eb95d73
Complete rc2 copy migration and follow moved standard library tests
youknowdot Oct 3, 2026
a2ca12c
Bring upstream frozendict coverage into the rc2 dictionary suite
youknowdot Oct 3, 2026
f2c0b48
Resolve combined base16 wrapping and migrated test prerequisites
youknowdot Oct 3, 2026
422029a
Refresh core builtin and type regression suites from rc2
youknowdot Oct 3, 2026
4c7b36e
Include the rc2 cross-interpreter test definitions
youknowdot Oct 3, 2026
90303e1
Leave invalid lazy import source fixtures out of frozen bytecode
youknowdot Oct 3, 2026
c71cc02
Guard SET_ADD against rebound annotation tracking objects
youknowdot Oct 3, 2026
5319baa
Complete rc2 AST and core library runtime contracts
youknowdot Oct 3, 2026
dafd695
Cover RLock subclass constructor validation
youknowdot Oct 3, 2026
613b543
Keep AST replacement on the shared native call binding
youknowdot Oct 3, 2026
6d49a6a
Register slice aliases in the Python class implementation
youknowdot Oct 3, 2026
253202f
Clear migration lint findings and shorten weakref lock scopes
youknowdot Oct 3, 2026
ffd4095
Use canonical field shorthand in base-N decoding options
youknowdot Oct 3, 2026
c388522
Clear remaining codec and TLS introspection lint warnings
youknowdot Oct 3, 2026
c3d4816
Preserve runtime code filenames in marshal output
youknowdot Oct 3, 2026
1f90d2e
Refresh the CPython baseline and libraries to 3.15.0rc3
youknowdot Oct 3, 2026
de72441
Keep only distinct native regression coverage in added snippets
youknowdot Oct 3, 2026
2e3dea6
Align lazy imports and runtime prerequisites with Python 3.15 rc3
youknowdot Oct 3, 2026
392a1ba
Enable directory-relative chmod for rc3 temporary cleanup
youknowdot Oct 4, 2026
6ea5bbe
Align formatting and runtime contracts with Python 3.15
youknowdot Oct 4, 2026
1c38cec
Refresh complete Python 3.15 rc3 test sources
youknowdot Oct 4, 2026
521aca9
Implement runtime contracts exposed by complete rc3 tests
youknowdot Oct 4, 2026
7ddbeeb
Enable the passing Linux mmap resize expectation
youknowdot Oct 4, 2026
cc2921b
Follow lint conventions in rc3 runtime updates
youknowdot Oct 4, 2026
427188a
Align the builtin import snippet with Python 3.15
youknowdot Oct 4, 2026
960dd4b
Close Python 3.15 rc3 runtime and compiler test failures
youknowdot Oct 4, 2026
baaa686
Decode typed pointer arguments in ctypes callbacks
youknowdot Oct 4, 2026
d07c1a0
Repair rc3 CI setup and preserve embedding dependencies
youknowdot Oct 5, 2026
405134a
Keep the platform-dependent Expat callback cast explicit
youknowdot Oct 5, 2026
2c03db8
Align rc3 bytecode and remaining CI runtime contracts
youknowdot Oct 5, 2026
1c55e3b
Format the rebased mmap flag binding
youknowdot Oct 8, 2026
6b06759
Use rc3 opcode IDs and close canonical protocol gaps
youknowdot Oct 5, 2026
c1b18f6
Complete rc3 time protocols and remaining parser contracts
youknowdot Oct 5, 2026
cd74281
Keep lazy import hook regressions in stdlib_imp
youknowdot Oct 5, 2026
f593a38
Keep the import bootstrap identical to pinned CPython
youknowdot Oct 5, 2026
ca2ea5a
Repair supported runtime paths and separate C API test cohorts
youknowdot Oct 5, 2026
ac58ff2
Propagate configuration dictionary errors across platforms
youknowdot Oct 5, 2026
12629a5
Keep native fixture conversions explicit for Clippy
youknowdot Oct 5, 2026
631410d
Adapt 3.15 mapping paths to the upstream explicit-hash API
youknowdot Oct 5, 2026
02042ec
Enable the passing monitoring type-call regression
youknowdot Oct 5, 2026
e2cce5a
Run the complete frame test family with C API support
youknowdot Oct 5, 2026
bb0708f
Record CPython source-layout assumptions in Windows tests
youknowdot Oct 6, 2026
b518c42
Use checked conversion for Windows timestamp range
youknowdot Oct 6, 2026
f5ebda1
Export the existing frame-locals C API on Windows
youknowdot Oct 6, 2026
4ad01e8
Preserve CPython 3.15 diagnostics with Ruff 0.16.10
youknowdot Oct 7, 2026
384801d
Preserve wakeup option storage with WASI signal support
youknowdot Oct 7, 2026
d41aa43
Translate WASI signal dispositions through libc sentinels
youknowdot Oct 7, 2026
bfb4727
Preserve lazy import recursion diagnostics after the upstream rebase
youknowdot Oct 7, 2026
b678ea3
Isolate the C API monitoring test from parallel interpreter activity
youknowdot Oct 7, 2026
eeb7cd3
Prevent ContextVar cache hits after Context address reuse
youknowdot Oct 7, 2026
d54a29e
Use the rebased mmap flags binding for anonymous mappings
youknowdot Oct 8, 2026
1ba204e
Keep dev evaluator frames compact during native re-entry
youknowdot Oct 8, 2026
d336de5
Adapt C API method fixtures to native function returns
youknowdot Oct 8, 2026
e14427a
Verify manager XML-RPC regression under coverage
youknowdot Oct 8, 2026
8d4bafc
Ignore invalid descriptors in os.closerange
youknowdot Oct 8, 2026
8cc22f1
Use immediate exit for host process termination
youknowdot Oct 8, 2026
cf01240
Reject negative file descriptors before fstat
youknowdot Oct 8, 2026
cc05fc8
Refresh safe Python 3.15 sources and comparison pins to final
youknowdot Oct 9, 2026
43065e7
Align compile module snippet with merged canonical coverage
youknowdot Oct 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Keep the import bootstrap identical to pinned CPython
Remove the RustPython-only reorder dispatcher and restore the exact rc3 bootstrap. Retain the atomic dictionary primitive and its direct regression assertions, without claiming it fixes import-cache ordering without a caller.

Assisted-by: Codex:model-version-unavailable
  • Loading branch information
youknowdot committed Oct 8, 2026
commit f593a38886ed76b7c2099050c167f43618bf03cf
19 changes: 4 additions & 15 deletions Lib/importlib/_bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -872,19 +872,6 @@ def _module_repr_from_spec(spec):
return f'<module {spec.name!r} ({spec.origin})>'


def _reorder_module(spec):
# RustPython: an exact dict can update shutdown order without exposing a
# temporarily absent module to another importing thread.
modules = sys.modules
if type(modules) is dict and hasattr(_imp, '_dict_move_to_end'):
return _imp._dict_move_to_end(modules, spec.name)
# Preserve custom pop/setitem behavior, including a pop that rebinds
# sys.modules or changes spec.name. CPython also uses this fallback.
module = sys.modules.pop(spec.name)
sys.modules[spec.name] = module
return module


# Used by importlib.reload().
def _exec(spec, module):
"""Execute the spec's specified module in an existing module's namespace."""
Expand All @@ -905,7 +892,8 @@ def _exec(spec, module):
finally:
# Update the order of insertion into sys.modules for module
# clean-up at shutdown.
module = _reorder_module(spec)
module = sys.modules.pop(spec.name)
sys.modules[spec.name] = module
return module

def _load_unlocked(spec):
Expand Down Expand Up @@ -935,7 +923,8 @@ def _load_unlocked(spec):
# We don't ensure that the import-related module attributes get
# set in the sys.modules replacement case. Such modules are on
# their own.
module = _reorder_module(spec)
module = sys.modules.pop(spec.name)
sys.modules[spec.name] = module
_verbose_message('import {!r} # {!r}', spec.name, spec.loader)
finally:
spec._initializing = False
Expand Down
187 changes: 2 additions & 185 deletions extra_tests/snippets/import_atomic_reorder.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
"""Import-cache ordering must not temporarily remove an exact-dict entry.
"""Exercise the native atomic dictionary-relocation primitive.

The native relocation helper and trace-visible presence assertion protect
RustPython's module-cache atomicity and callback reentry boundaries.
The copied CPython import bootstrap does not call this private helper.
"""

import _imp
import os
import sys
import types
from importlib import _bootstrap as frozen


def raises(kind, call, expected=None):
Expand All @@ -21,172 +17,6 @@ def raises(kind, call, expected=None):
raise AssertionError(f"{kind.__name__} was not raised")


def source_bootstrap():
path = os.path.join(
os.path.dirname(os.path.dirname(os.path.dirname(__file__))),
"Lib",
"importlib",
"_bootstrap.py",
)
source = types.ModuleType("atomic_reorder_source_bootstrap")
with open(path, encoding="utf-8") as stream:
exec(compile(stream.read(), path, "exec"), source.__dict__)
for name in (
"sys",
"_imp",
"_thread",
"_warnings",
"_weakref",
"_bootstrap_external",
):
setattr(source, name, getattr(frozen, name))
source._blocking_on = source._WeakValueDictionary()
return source


class Loader:
def __init__(self, action):
self.action = action

def create_module(self, spec):
return None

def exec_module(self, module):
self.action(module)


def check_trace_presence(bootstrap, mode):
original = sys.modules
old_trace = sys.gettrace()
name = "_atomic_reorder_trace"
expected = types.ModuleType(name)
after = "_atomic_reorder_trace_after"
state = {"armed": False, "events": 0}
failure = RuntimeError("legacy loader failed with its entry still present")
codes = {
bootstrap._exec.__code__,
bootstrap._load_unlocked.__code__,
}
if hasattr(bootstrap, "_load_backward_compatible"):
codes.add(bootstrap._load_backward_compatible.__code__)
if hasattr(bootstrap, "_reorder_module"):
codes.add(bootstrap._reorder_module.__code__)

def trace(frame, event, arg):
if event == "line" and state["armed"] and frame.f_code in codes:
state["events"] += 1
assert name in sys.modules, (mode, frame.f_code.co_name, frame.f_lineno)
assert sys.modules[name] is expected
return trace

def finish(module):
sys.modules[name] = expected
sys.modules[after] = object()
state["armed"] = True

class LegacyLoader:
def load_module(self, fullname):
assert fullname == name
finish(expected)
if mode == "legacy_error":
raise failure
return expected

try:
sys.modules = original.copy()
loader = LegacyLoader() if mode.startswith("legacy") else Loader(finish)
spec = bootstrap.ModuleSpec(name, loader)
if mode == "exec":
initial = bootstrap.module_from_spec(spec)
sys.modules[name] = initial
call = lambda: bootstrap._exec(spec, initial)
elif mode.startswith("legacy"):
call = lambda: bootstrap._load_backward_compatible(spec)
else:
call = lambda: bootstrap._load_unlocked(spec)
sys.settrace(trace)
if mode == "legacy_error":
raises(RuntimeError, call, failure)
else:
assert call() is expected
sys.settrace(old_trace)
assert state["events"] > 0, "the successful loader window was not traced"
assert list(sys.modules)[-2:] == [after, name]
finally:
sys.settrace(old_trace)
sys.modules = original


def check_custom_mappings(bootstrap):
original = sys.modules
name = "_atomic_reorder_custom"
value = object()
events = []

class Subclass(dict):
def pop(self, key):
events.append(("pop", key))
return super().pop(key)

def __setitem__(self, key, value):
events.append(("set", key, value))
super().__setitem__(key, value)

class Mapping:
def __init__(self, pairs):
self.data = dict(pairs)

def pop(self, key):
events.append(("pop", key))
return self.data.pop(key)

def __setitem__(self, key, value):
events.append(("set", key, value))
self.data[key] = value

try:
spec = bootstrap.ModuleSpec(name, None)
for cls in (Subclass, Mapping):
events.clear()
modules = cls([(name, value), ("after", None)])
sys.modules = modules
assert bootstrap._reorder_module(spec) is value
assert events == [("pop", name), ("set", name, value)]
assert list(modules if cls is Subclass else modules.data) == ["after", name]

rebound = Subclass()
new_name = "_atomic_reorder_rebound"

class Rebinding(Subclass):
def pop(self, key):
result = super().pop(key)
sys.modules = rebound
spec.name = new_name
return result

events.clear()
modules = Rebinding({name: value})
sys.modules = modules
assert bootstrap._reorder_module(spec) is value
assert events == [("pop", name), ("set", new_name, value)]
assert sys.modules is rebound
assert rebound[new_name] is value
assert name not in modules

failure = KeyError("custom pop exception")

class Raising(Subclass):
def pop(self, key):
raise failure

events.clear()
sys.modules = Raising({new_name: value})
raises(KeyError, lambda: bootstrap._reorder_module(spec), failure)
assert events == []
finally:
sys.modules = original


def check_native_helper():
move = _imp._dict_move_to_end
first, middle, last = object(), object(), object()
Expand Down Expand Up @@ -343,18 +173,5 @@ def __del__(self):
assert mapping == {"finalized": True}


source = source_bootstrap()
for bootstrap in (frozen, source):
if sys.implementation.name == "rustpython":
# Run this before inspecting the new helper so a baseline executable
# fails on the actual pop/set gap, not just a missing private API.
modes = ("load", "exec")
if hasattr(bootstrap, "_load_backward_compatible"):
modes += ("legacy", "legacy_error")
for mode in modes:
check_trace_presence(bootstrap, mode)
if hasattr(bootstrap, "_reorder_module"):
check_custom_mappings(bootstrap)

if sys.implementation.name == "rustpython":
check_native_helper()