Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
67a137e
Implement _collections.OrderedDict
moreal Sep 22, 2026
dc8e92d
Add OrderedDict, warnings source lines, and socket sendmsg
youknowone Sep 21, 2026
182ad24
Load marshal via readinto and dump sets in dumps order
youknowone Sep 21, 2026
d8be145
Add classmethod_descriptor and ABC IS_ABSTRACT flags
youknowone Sep 22, 2026
6867000
address review: odict reuse, descr call, new wrapper
youknowone Sep 22, 2026
58791c4
Represent chflags bits with bitflagset
youknowone Sep 22, 2026
1fe22ce
Represent access and mode bits with bitflagset
youknowone Sep 22, 2026
3de8a8f
Continue unfinished REPL suites as incomplete input
youknowone Sep 22, 2026
f63b772
Add pickle and os.stat inspect signatures
youknowone Sep 22, 2026
44a1cf5
Add Unpickler, dump/load, and lstat signatures
youknowone Sep 22, 2026
a3fb270
Complete OrderedDict with insertion-order links
youknowone Sep 22, 2026
ce35d46
address CI: stat casts, HCI_DATA_DIR, passing xfails
youknowone Sep 22, 2026
498dae1
Fix wasm teardown deadlock and bluetooth constants
youknowone Sep 22, 2026
38909e2
Clear process-wide eval breaker bits in STW test
youknowone Sep 22, 2026
fdce5f2
Drop exclusive-held panic that tripped wasm clippy
youknowone Sep 22, 2026
0c38852
Fix OrderedDict contains and export Windows BDADDR
youknowone Sep 22, 2026
fddfe4b
Add cmp_to_key and hash-once LRU cache
youknowone Sep 23, 2026
305a502
Allow subclass keywords on list, tuple, and float
youknowone Sep 23, 2026
56a912f
Fix CI lint, test re-export, and structseq members
youknowone Sep 23, 2026
e47a535
Allow subclass keywords on itertools and filter
youknowone Sep 23, 2026
c7b6022
Remove text_signature derive parameter
youknowone Sep 23, 2026
5976f3a
Rename set contains_method to __contains__
youknowone Sep 23, 2026
207fa0b
Use MonitoringEvent instead of EVENT_* aliases
youknowone Sep 23, 2026
4cfcd7f
Store warnings filters as PyListRef
youknowone Sep 23, 2026
16c6d77
Re-export clear_eval_breaker_for_test after rebase
youknowone Sep 23, 2026
dc10fca
Fix groupby reentrancy and islice arguments
youknowone Sep 23, 2026
0d0c26f
SETREF warnings filters, onceregistry, and defaultaction
youknowone Sep 23, 2026
af31e63
Iterate OrderedDict inner dict via next_entry
youknowone Sep 23, 2026
299879d
Remove expectedFailure from testBluetoothConstants
youknowone Sep 23, 2026
277a5f5
Borrow get_filter arguments as PyObject
youknowone Sep 23, 2026
acd78e7
Fix bool slots and SemHandle safety docs
youknowone Sep 23, 2026
ac2e463
Keep sendmsg errors and drop duplicate linecache
youknowone Sep 24, 2026
1234e88
Nest REPL parse or-patterns for clippy
youknowone Sep 24, 2026
15f3bf4
Mark pydoc os.stat signature test expectedFailure
youknowone Sep 24, 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
3 changes: 3 additions & 0 deletions .cspell.dict/cpython.txt
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ mimalloc
miscompiles
mult
multibytecodec
mycmp
mystricmp
mystrnicmp
nameobj
Expand Down Expand Up @@ -187,6 +188,8 @@ numkwonly
numposorkw
nvars
obmalloc
odict
ODICT
opname
opnames
orelse
Expand Down
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Lib/test/test_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,6 @@ def method_two(self):
msg = r"class C without an implementation for abstract methods 'method_one', 'method_two'"
self.assertRaisesRegex(TypeError, msg, C)

@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: False is not true
def test_abstractmethod_integration(self):
for abstractthing in [abc.abstractmethod, abc.abstractproperty,
abc.abstractclassmethod,
Expand Down
9 changes: 0 additions & 9 deletions Lib/test/test_builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2711,43 +2711,35 @@ def detach_readline(self):
else:
yield

@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: got 0 lines in pipe but expected 2, child output was: quux
def test_input_tty(self):
# Test input() functionality when wired to a tty
self.check_input_tty("prompt", b"quux")

@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: got 0 lines in pipe but expected 2, child output was: quux
def test_input_tty_non_ascii(self):
# Check stdin/stdout encoding is used when invoking PyOS_Readline()
self.check_input_tty("prompté", b"quux\xc3\xa9", "utf-8")

@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: got 0 lines in pipe but expected 2, child output was: quux
def test_input_tty_non_ascii_unicode_errors(self):
# Check stdin/stdout error handler is used when invoking PyOS_Readline()
self.check_input_tty("prompté", b"quux\xe9", "ascii")

@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: got 0 lines in pipe but expected 2, child output was: quux
def test_input_tty_null_in_prompt(self):
self.check_input_tty("prompt\0", b"",
expected='ValueError: input: prompt string cannot contain '
'null characters')

@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: got 0 lines in pipe but expected 2, child output was: quux
def test_input_tty_nonencodable_prompt(self):
self.check_input_tty("prompté", b"quux", "ascii", stdout_errors='strict',
expected="UnicodeEncodeError: 'ascii' codec can't encode "
"character '\\xe9' in position 6: ordinal not in "
"range(128)")

@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: got 0 lines in pipe but expected 2, child output was: quux
def test_input_tty_nondecodable_input(self):
self.check_input_tty("prompt", b"quux\xe9", "ascii", stdin_errors='strict',
expected="UnicodeDecodeError: 'ascii' codec can't decode "
"byte 0xe9 in position 4: ordinal not in "
"range(128)")

@unittest.skip("TODO: RUSTPYTHON; FAILURE, WORKER BUG")
@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: got 0 lines in pipe but expected 2, child output was: quux
def test_input_no_stdout_fileno(self):
# Issue #24402: If stdin is the original terminal but stdout.fileno()
# fails, do not use the original stdout file descriptor
Expand Down Expand Up @@ -3036,7 +3028,6 @@ class B:
with self.assertRaises(TypeError):
type('A', (B,), {'__slots__': '__weakref__'})

@unittest.skip("TODO: RUSTPYTHON; random failure")
def test_namespace_order(self):
# bpo-34320: namespace should preserve order
od = collections.OrderedDict([('a', 1), ('b', 2)])
Expand Down
1 change: 0 additions & 1 deletion Lib/test/test_dataclasses/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5000,7 +5000,6 @@ class Date(Ordered):
self.assertFalse(inspect.isabstract(Date))
self.assertGreater(Date(2020,12,25), Date(2020,8,31))

@unittest.expectedFailure # TODO: RUSTPYTHON
def test_maintain_abc(self):
class A(abc.ABC):
@abc.abstractmethod
Expand Down
1 change: 0 additions & 1 deletion Lib/test/test_float.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,6 @@ def test_keyword_args(self):
with self.assertRaisesRegex(TypeError, 'keyword argument'):
float(x='3.14')

@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: Unexpected keyword argument newarg
def test_keywords_in_subclass(self):
class subclass(float):
pass
Expand Down
41 changes: 8 additions & 33 deletions Lib/test/test_functools.py
Original file line number Diff line number Diff line change
Expand Up @@ -1238,45 +1238,17 @@ class TestCmpToKeyC(TestCmpToKey, unittest.TestCase):
if c_functools:
cmp_to_key = c_functools.cmp_to_key

@unittest.expectedFailure # TODO: RUSTPYTHON; inspect.signature reports (args, /) until FromArgs fields generate __text_signature__
def test_cmp_to_signature(self):
super().test_cmp_to_signature()

@support.cpython_only
def test_disallow_instantiation(self):
# Ensure that the type disallows instantiation (bpo-43916)
support.check_disallow_instantiation(
self, type(c_functools.cmp_to_key(None))
)

@unittest.expectedFailure # TODO: RUSTPYTHON; + (mycmp)
def test_cmp_to_signature(self):
return super().test_cmp_to_signature()

@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: cmp_to_key() got multiple values for argument 'mycmp'
def test_cmp_to_key_arguments(self):
return super().test_cmp_to_key_arguments()

@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: cmp_to_key() got multiple values for argument 'mycmp'
def test_obj_field(self):
return super().test_obj_field()

@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: cmp_to_key() takes 1 positional argument but 2 were given
def test_bad_cmp(self):
return super().test_bad_cmp()

@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: cmp_to_key() takes 1 positional argument but 2 were given
def test_cmp_to_key(self):
return super().test_cmp_to_key()

@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: cmp_to_key() takes 1 positional argument but 2 were given
def test_hash(self):
return super().test_hash()

@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: cmp_to_key() takes 1 positional argument but 2 were given
def test_sort_int(self):
return super().test_sort_int()

@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: cmp_to_key() takes 1 positional argument but 2 were given
def test_sort_int_str(self):
return super().test_sort_int_str()


class TestCmpToKeyPy(TestCmpToKey, unittest.TestCase):
cmp_to_key = staticmethod(py_functools.cmp_to_key)
Expand Down Expand Up @@ -1763,7 +1735,6 @@ def f(x):
f(0, **{})
self.assertEqual(f.cache_info().hits, 1)

@unittest.expectedFailure # TODO: RUSTPYTHON; Python lru_cache impl doesn't cache hash like C impl
def test_lru_hash_only_once(self):
# To protect against weird reentrancy bugs and to improve
# efficiency when faced with slow __hash__ methods, the
Expand Down Expand Up @@ -2266,6 +2237,10 @@ def cached_meth(self, x, y):
def cached_staticmeth(x, y):
return 3 * x + y

@unittest.expectedFailure # TODO: RUSTPYTHON; Python lru_cache impl doesn't cache hash like C impl
def test_lru_hash_only_once(self):
return super().test_lru_hash_only_once()


@unittest.skipUnless(c_functools, 'requires the C _functools module')
class TestLRUC(TestLRU, unittest.TestCase):
Expand Down
19 changes: 5 additions & 14 deletions Lib/test/test_inspect/test_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import os
import dis
from os.path import normcase
# import _pickle # TODO: RUSTPYTHON
import _pickle
import pickle
import shutil
import stat
Expand Down Expand Up @@ -123,7 +123,6 @@ def istest(self, predicate, exp):
else:
self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))

@unittest.expectedFailure # TODO: RUSTPYTHON; First has 0, Second has 1: 'iskeyword'
def test__all__(self):
support.check__all__(self, inspect, not_exported=("modulesbyfile",), extra=("get_annotations",))

Expand Down Expand Up @@ -176,7 +175,7 @@ def __get__(self, instance, owner):

class TestPredicates(IsTestBase):

@unittest.expectedFailure # TODO: RUSTPYTHON; AttributeError: type object 'defaultdict' has no attribute 'default_factory'
@unittest.expectedFailure # TODO: RUSTPYTHON; datetime.timedelta.days is a property until _datetime members exist
def test_excluding_predicates(self):
global tb
self.istest(inspect.isbuiltin, 'sys.exit')
Expand Down Expand Up @@ -480,7 +479,6 @@ class C(object):
self.assertIn('a', members)
self.assertNotIn('b', members)

@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: False is not true
def test_isabstract(self):
from abc import ABCMeta, abstractmethod

Expand All @@ -503,7 +501,6 @@ def foo(self):
self.assertFalse(inspect.isabstract(int))
self.assertFalse(inspect.isabstract(5))

@unittest.expectedFailure # TODO: RUSTPYTHON; + [True, False]
def test_isabstract_during_init_subclass(self):
from abc import ABCMeta, abstractmethod
isabstract_checks = []
Expand Down Expand Up @@ -1366,7 +1363,7 @@ def test(): pass
spec = inspect.getfullargspec(test)
self.assertEqual(test.__annotations__, spec.annotations)

@unittest.expectedFailure # TODO: RUSTPYTHON; NameError: name '_pickle' is not defined. Did you mean: 'pickle'? Or did you forget to import '_pickle'?
@unittest.expectedFailure # TODO: RUSTPYTHON; os.stat signature is generated as (path, dir_fd, follow_symlinks, /)
@unittest.skipIf(MISSING_C_DOCSTRINGS,
"Signature information for builtins requires docstrings")
def test_getfullargspec_builtin_methods(self):
Expand Down Expand Up @@ -1531,7 +1528,6 @@ def m1(self): pass
self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')

@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: ('to_bytes', 'method', <class 'int'>) not found in [('__abs__', 'method', <class 'bool'>), ('__add__', 'method', <class 'bool'>), ('__and__', 'method', <class 'bool'>), ('__bool__', 'method', <class 'bool'>), ('__ceil__', 'class method', <class 'int'>), ('__class__', 'data', <class 'object'>), ('__delattr__', 'class method', <class 'object'>), ('__dir__', 'class method', <class 'object'>), ('__divmod__', 'method', <class 'bool'>), ('__doc__', 'data', <class 'bool'>), ('__eq__', 'class method', <class 'int'>), ('__float__', 'method', <class 'bool'>), ('__floor__', 'class method', <class 'int'>), ('__floordiv__', 'method', <class 'bool'>), ('__format__', 'class method', <class 'bool'>), ('__ge__', 'class method', <class 'int'>), ('__getattribute__', 'class method', <class 'object'>), ('__getnewargs__', 'class method', <class 'int'>), ('__getstate__', 'class method', <class 'object'>), ('__gt__', 'class method', <class 'int'>), ('__hash__', 'method', <class 'int'>), ('__index__', 'method', <class 'bool'>), ('__init__', 'method', <class 'object'>), ('__init_subclass__', 'class method', <class 'object'>), ('__int__', 'method', <class 'bool'>), ('__invert__', 'method', <class 'bool'>), ('__le__', 'class method', <class 'int'>), ('__lshift__', 'method', <class 'bool'>), ('__lt__', 'class method', <class 'int'>), ('__mod__', 'method', <class 'bool'>), ('__mul__', 'method', <class 'bool'>), ('__ne__', 'class method', <class 'int'>), ('__neg__', 'method', <class 'bool'>), ('__new__', 'static method', <class 'bool'>), ('__or__', 'method', <class 'bool'>), ('__pos__', 'method', <class 'bool'>), ('__pow__', 'method', <class 'bool'>), ('__radd__', 'method', <class 'bool'>), ('__rand__', 'method', <class 'bool'>), ('__rdivmod__', 'method', <class 'bool'>), ('__reduce__', 'class method', <class 'object'>), ('__reduce_ex__', 'class method', <class 'object'>), ('__repr__', 'method', <class 'bool'>), ('__rfloordiv__', 'method', <class 'bool'>), ('__rlshift__', 'method', <class 'bool'>), ('__rmod__', 'method', <class 'bool'>), ('__rmul__', 'method', <class 'bool'>), ('__ror__', 'method', <class 'bool'>), ('__round__', 'class method', <class 'int'>), ('__rpow__', 'method', <class 'bool'>), ('__rrshift__', 'method', <class 'bool'>), ('__rshift__', 'method', <class 'bool'>), ('__rsub__', 'method', <class 'bool'>), ('__rtruediv__', 'method', <class 'bool'>), ('__rxor__', 'method', <class 'bool'>), ('__setattr__', 'class method', <class 'object'>), ('__sizeof__', 'class method', <class 'int'>), ('__str__', 'method', <class 'object'>), ('__sub__', 'method', <class 'bool'>), ('__subclasshook__', 'class method', <class 'object'>), ('__truediv__', 'method', <class 'bool'>), ('__trunc__', 'class method', <class 'int'>), ('__xor__', 'method', <class 'bool'>), ('as_integer_ratio', 'class method', <class 'int'>), ('bit_count', 'class method', <class 'int'>), ('bit_length', 'class method', <class 'int'>), ('conjugate', 'class method', <class 'int'>), ('denominator', 'data', <class 'int'>), ('from_bytes', 'class method', <class 'int'>), ('imag', 'data', <class 'int'>), ('is_integer', 'class method', <class 'int'>), ('numerator', 'data', <class 'int'>), ('real', 'data', <class 'int'>), ('to_bytes', 'class method', <class 'int'>)] : missing plain method
def test_classify_builtin_types(self):
# Simple sanity check that all built-in types can have their
# attributes classified.
Expand Down Expand Up @@ -4210,7 +4206,6 @@ def __init__(self, b):
self.assertEqual(self.signature(C.__call__, follow_wrapped=False),
varargs_signature)

@unittest.expectedFailure # TODO: RUSTPYTHON
def test_signature_on_class_with_wrapped_init(self):
class C:
@identity_wrapper
Expand Down Expand Up @@ -4460,7 +4455,6 @@ def _init(self, x, a):
((('a', ..., ..., "positional_or_keyword"),),
...))

@unittest.expectedFailure # TODO: RUSTPYTHON
def test_signature_on_class_with_new(self):
with self.subTest('FunctionType'):
class C:
Expand Down Expand Up @@ -4621,7 +4615,7 @@ class D(C): pass
with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
self.assertEqual(inspect.signature(D), None)

@unittest.expectedFailure # TODO: RUSTPYTHON; NameError: name '_pickle' is not defined. Did you mean: 'pickle'? Or did you forget to import '_pickle'?
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: no signature found for builtin type <class '_pickle.Pickler'>
@unittest.skipIf(MISSING_C_DOCSTRINGS,
"Signature information for builtins requires docstrings")
def test_signature_on_builtin_class(self):
Expand All @@ -4647,7 +4641,6 @@ class P4(P2, metaclass=MetaP):
pass
self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')

@unittest.expectedFailure # TODO: RUSTPYTHON
def test_signature_on_callable_objects(self):
class Foo:
def __call__(self, a):
Expand Down Expand Up @@ -5164,7 +5157,7 @@ class foo: pass
foo_sig = MySignature.from_callable(foo)
self.assertIsInstance(foo_sig, MySignature)

@unittest.expectedFailure # TODO: RUSTPYTHON; NameError: name '_pickle' is not defined. Did you mean: 'pickle'? Or did you forget to import '_pickle'?
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: no signature found for builtin type <class '_pickle.Pickler'>
@unittest.skipIf(MISSING_C_DOCSTRINGS,
"Signature information for builtins requires docstrings")
def test_signature_from_callable_builtin_obj(self):
Expand Down Expand Up @@ -6335,7 +6328,6 @@ def func(*args, **kwargs):
with self.assertRaises(ValueError):
inspect.signature(func)

@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: None != '(raw, buffer_size=DEFAULT_BUFFER_SIZE)'
@support.requires_docstrings
def test_base_class_have_text_signature(self):
# see issue 43118
Expand Down Expand Up @@ -6567,7 +6559,6 @@ def run_on_interactive_mode(self, source):
raise ValueError("Process didn't exit properly.")
return output

@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: 'The source is: <<<def f():\n print(0)\n return 1 + 2\n>>>' not found in 'Traceback (most recent call last):\n File "<stdin>", line 1, in <module>\n File "crates/pylib/Lib/inspect.py", line 1161, in getsource\n lines, lnum = getsourcelines(object)\n ~~~~~~~~~~~~~~^^^^^^^^\n File "crates/pylib/Lib/inspect.py", line 1143, in getsourcelines\n lines, lnum = findsource(object)\n ~~~~~~~~~~^^^^^^^^\n File "crates/pylib/Lib/inspect.py", line 978, in findsource\n raise OSError(\'could not get source code\')\nOSError: could not get source code\n'
@unittest.skipIf(not has_subprocess_support, "test requires subprocess")
def test_getsource(self):
output = self.run_on_interactive_mode(textwrap.dedent("""\
Expand Down
3 changes: 0 additions & 3 deletions Lib/test/test_itertools.py
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,6 @@ def keys():
next(g)
next(g) # must pass with address sanitizer

@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: 4 != 1
def test_grouper_reentrant_eq_does_not_crash(self):
# regression test for gh-146613
grouper_iter = None
Expand Down Expand Up @@ -1167,7 +1166,6 @@ def test_starmap(self):
self.assertRaises(ValueError, next, starmap(errfunc, [(4,5)]))
self.assertRaises(TypeError, next, starmap(onearg, [(4,5)]))

@unittest.expectedFailure # TODO: RUSTPYTHON
def test_islice(self):
for args in [ # islice(args) should agree with range(args)
(10, 20, 3),
Expand Down Expand Up @@ -2493,7 +2491,6 @@ def __eq__(self, other):


class SubclassWithKwargsTest(unittest.TestCase):
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_keywords_in_subclass(self):
# count is not subclassable...
testcases = [
Expand Down
1 change: 0 additions & 1 deletion Lib/test/test_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ def test_keyword_args(self):
with self.assertRaisesRegex(TypeError, 'keyword argument'):
list(sequence=[])

@unittest.expectedFailure # TODO: RUSTPYTHON
def test_keywords_in_subclass(self):
class subclass(list):
pass
Expand Down
3 changes: 1 addition & 2 deletions Lib/test/test_marshal.py
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,6 @@ def test_loads_reject_unicode_strings(self):
unicode_string = 'T'
self.assertRaises(TypeError, marshal.loads, unicode_string)

@unittest.expectedFailure # TODO: RUSTPYTHON
def test_bad_reader(self):
class BadReader(io.BytesIO):
def readinto(self, buf):
Expand All @@ -510,7 +509,7 @@ def test_eof(self):
for i in range(len(data)):
self.assertRaises(EOFError, marshal.loads, data[0: i])

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; set iteration is insertion order, so PYTHONHASHSEED does not scramble repr
def test_deterministic_sets(self):
# bpo-37596: To support reproducible builds, sets and frozensets need to
# have their elements serialized in a consistent order (even when they
Expand Down
Loading
Loading