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
Update enum from CPython 3.15.0rc2
Sync enum and its regression tests from CPython v3.15.0rc2 (435c9e5a798c99653e3ab64ce29baed0e4f3dfee). Preserve the two existing RustPython expected-failure decorators. Keep this first migration slice limited to enum without changing the declared Python target or native runtime.

AI assistance: Codex/OpenAI reconstructed the upstream sync, reviewed the diff, and ran validation. The runtime did not expose the exact model version.

Assisted-by: Codex:model-version-unavailable
  • Loading branch information
youknowdot committed Oct 8, 2026
commit 6f700f7e903992497f79216ed44e33f25cdb5e46
43 changes: 36 additions & 7 deletions Lib/enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@
'FlagBoundary', 'STRICT', 'CONFORM', 'EJECT', 'KEEP',
'global_flag_repr', 'global_enum_repr', 'global_str', 'global_enum',
'EnumCheck', 'CONTINUOUS', 'NAMED_FLAGS', 'UNIQUE',
'pickle_by_global_name', 'pickle_by_enum_name',
'pickle_by_global_name', 'pickle_by_enum_name', 'show_flag_values',
'bin',
]


# Dummy value for Enum and Flag as there are explicit checks for them
# before they have been created.
# This is also why there are checks in EnumType like `if Enum is not None`
Enum = Flag = EJECT = _stdlib_enums = ReprEnum = None
Enum = Flag = EJECT = ReprEnum = None

class nonmember(object):
"""
Expand Down Expand Up @@ -536,7 +537,7 @@ def __new__(metacls, cls, bases, classdict, *, boundary=None, _simple=False, **k
# now set the __repr__ for the value
classdict['_value_repr_'] = metacls._find_data_repr_(cls, bases)
#
# Flag structures (will be removed if final class is not a Flag
# Flag structures (will be removed if final class is not a Flag)
classdict['_boundary_'] = (
boundary
or getattr(first_enum, '_boundary_', None)
Expand All @@ -545,6 +546,29 @@ def __new__(metacls, cls, bases, classdict, *, boundary=None, _simple=False, **k
classdict['_singles_mask_'] = 0
classdict['_all_bits_'] = 0
classdict['_inverted_'] = None
# check for negative flag values and invert if found (using _proto_members)
if Flag is not None and bases and issubclass(bases[-1], Flag):
bits = 0
inverted = []
for n in member_names:
p = classdict[n]
if isinstance(p.value, int):
if p.value < 0:
inverted.append(p)
else:
bits |= p.value
elif p.value is None:
pass
elif isinstance(p.value, tuple) and p.value and isinstance(p.value[0], int):
if p.value[0] < 0:
inverted.append(p)
else:
bits |= p.value[0]
for p in inverted:
if isinstance(p.value, int):
p.value = bits & p.value
else:
p.value = (bits & p.value[0], ) + p.value[1:]
try:
classdict['_%s__in_progress' % cls] = True
enum_class = super().__new__(metacls, cls, bases, classdict, **kwds)
Expand Down Expand Up @@ -752,12 +776,16 @@ def __delattr__(cls, attr):
super().__delattr__(attr)

def __dir__(cls):
if issubclass(cls, Flag):
members = list(cls._member_map_.keys())
else:
members = cls._member_names_
interesting = set([
'__class__', '__contains__', '__doc__', '__getitem__',
'__iter__', '__len__', '__members__', '__module__',
'__name__', '__qualname__',
]
+ cls._member_names_
+ members
)
if cls._new_member_ is not object.__new__:
interesting.add('__new__')
Expand Down Expand Up @@ -1489,7 +1517,10 @@ def _missing_(cls, value):
)
if value < 0:
neg_value = value
value = all_bits + 1 + value
if cls._boundary_ in (EJECT, KEEP):
value = all_bits + 1 + value
else:
value = singles_mask & value
# get members and unknown
unknown = value & ~flag_mask
aliases = value & ~singles_mask
Expand Down Expand Up @@ -2165,5 +2196,3 @@ def _old_convert_(etype, name, module, filter, source=None, *, boundary=None):
members.sort(key=lambda t: t[0])
cls = etype(name, members, module=module, boundary=boundary or KEEP)
return cls

_stdlib_enums = IntEnum, StrEnum, IntFlag
47 changes: 44 additions & 3 deletions Lib/test/test_enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -1002,12 +1002,18 @@ class OpenAB(self.enum_type):
self.assertIs(~(A|B), OpenAB(252))
self.assertIs(~AB_MASK, OpenAB(0))
self.assertIs(~OpenAB(0), AB_MASK)
self.assertIs(OpenAB(~4), OpenAB(251))
else:
self.assertIs(~A, B)
self.assertIs(~B, A)
self.assertIs(OpenAB(~1), B)
self.assertIs(OpenAB(~2), A)
self.assertIs(~(A|B), OpenAB(0))
self.assertIs(~AB_MASK, OpenAB(0))
self.assertIs(~OpenAB(0), (A|B))
self.assertIs(OpenAB(~3), OpenAB(0))
self.assertIs(OpenAB(~4), OpenAB(3))
self.assertIs(OpenAB(~33), B)
#
class OpenXYZ(self.enum_type):
X = 4
Expand All @@ -1031,13 +1037,38 @@ class OpenXYZ(self.enum_type):
self.assertIs(~X, Y|Z)
self.assertIs(~Y, X|Z)
self.assertIs(~Z, X|Y)
self.assertIs(OpenXYZ(~4), Y|Z)
self.assertIs(OpenXYZ(~2), X|Z)
self.assertIs(OpenXYZ(~1), X|Y)
self.assertIs(~(X|Y), Z)
self.assertIs(~(X|Z), Y)
self.assertIs(~(Y|Z), X)
self.assertIs(~(X|Y|Z), OpenXYZ(0))
self.assertIs(~XYZ_MASK, OpenXYZ(0))
self.assertTrue(~OpenXYZ(0), (X|Y|Z))

def test_assigned_negative_value(self):
class X(self.enum_type):
A = auto()
B = auto()
C = A | B
D = ~A
self.assertEqual(list(X), [X.A, X.B])
self.assertIs(~X.A, X.B)
self.assertIs(X.D, X.B)
self.assertEqual(X.D.value, 2)
#
class Y(self.enum_type):
A = auto()
B = auto()
C = A | B
D = ~A
E = auto()
self.assertEqual(list(Y), [Y.A, Y.B, Y.E])
self.assertIs(~Y.A, Y.B|Y.E)
self.assertIs(Y.D, Y.B|Y.E)
self.assertEqual(Y.D.value, 6)


class TestPlainEnumClass(_EnumTests, _PlainOutputTests, unittest.TestCase):
enum_type = Enum
Expand Down Expand Up @@ -3681,6 +3712,8 @@ class SkipFlag(enum.Flag):
C = 4 | B
#
self.assertTrue(SkipFlag.C in (SkipFlag.A|SkipFlag.C))
self.assertTrue(SkipFlag.B in SkipFlag.C)
self.assertIs(SkipFlag(~1), SkipFlag.B)
self.assertRaisesRegex(ValueError, 'SkipFlag.. invalid value 42', SkipFlag, 42)
#
class SkipIntFlag(enum.IntFlag):
Expand All @@ -3689,6 +3722,8 @@ class SkipIntFlag(enum.IntFlag):
C = 4 | B
#
self.assertTrue(SkipIntFlag.C in (SkipIntFlag.A|SkipIntFlag.C))
self.assertTrue(SkipIntFlag.B in SkipIntFlag.C)
self.assertIs(SkipIntFlag(~1), SkipIntFlag.B|SkipIntFlag.C)
self.assertEqual(SkipIntFlag(42).value, 42)
#
class MethodHint(Flag):
Expand Down Expand Up @@ -4728,6 +4763,8 @@ class Color(Flag):
BLUE = 4
WHITE = -1
# no error means success
self.assertEqual(list(Color.WHITE), [Color.RED, Color.GREEN, Color.BLUE])
self.assertEqual(Color.WHITE.value, 7)


class TestInternals(unittest.TestCase):
Expand Down Expand Up @@ -4851,7 +4888,7 @@ class Color(Enum):
def _generate_next_value_(name, start, count, last):
return name

def test_auto_order_wierd(self):
def test_auto_order_weird(self):
weird_auto = auto()
weird_auto.value = 'pathological case'
class Color(Enum):
Expand Down Expand Up @@ -5288,7 +5325,7 @@ def __new__(cls, value, label):
class MiscTestCase(unittest.TestCase):

def test__all__(self):
support.check__all__(self, enum, not_exported={'bin', 'show_flag_values'})
support.check__all__(self, enum)

@cpython_only
def test_lazy_import(self):
Expand Down Expand Up @@ -5493,12 +5530,16 @@ def test_enum_dict_standalone(self):
# helpers

def enum_dir(cls):
if issubclass(cls, Flag):
members = list(cls._member_map_.keys())
else:
members = cls._member_names_
interesting = set([
'__class__', '__contains__', '__doc__', '__getitem__',
'__iter__', '__len__', '__members__', '__module__',
'__name__', '__qualname__',
]
+ cls._member_names_
+ members
)
if cls._new_member_ is not object.__new__:
interesting.add('__new__')
Expand Down