Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
48 changes: 48 additions & 0 deletions Lib/test/test_call.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -47,6 +47,54 @@ def fn(**kw):
self.assertIsInstance(res, dict)
self.assertEqual(list(res.items()), expected)

def test_kwargs_order_preserved(self):
# PEP 468: Preserving Keyword Argument Order
def fn(**kw):
return list(kw)

self.assertEqual(fn(b=1, a=2, c=3), ['b', 'a', 'c'])
self.assertEqual(fn(c=3, a=2, b=1), ['c', 'a', 'b'])
# Unpacked mappings are merged in place, keeping their own order.
self.assertEqual(fn(z=0, **{'x': 1, 'a': 2}, y=3),
['z', 'x', 'a', 'y'])
self.assertEqual(fn(**{'b': 1}, **{'a': 2}), ['b', 'a'])
# Named parameters are removed from **kwargs without reordering
# the rest.
def fn2(a, c=None, **kw):
return list(kw)

self.assertEqual(fn2(d=1, a=2, b=3, c=4, e=5), ['d', 'b', 'e'])

def test_kwargs_order_preserved_in_methods(self):
# PEP 468: Preserving Keyword Argument Order
class C:
def __init__(self, **kw):
self.init_kw = list(kw)

def meth(self, **kw):
return list(kw)

@classmethod
def cmeth(cls, **kw):
return list(kw)

@staticmethod
def smeth(**kw):
return list(kw)

c = C(b=1, a=2, c=3)
self.assertEqual(c.init_kw, ['b', 'a', 'c'])
self.assertEqual(c.meth(b=1, a=2, c=3), ['b', 'a', 'c'])
self.assertEqual(C.cmeth(b=1, a=2, c=3), ['b', 'a', 'c'])
self.assertEqual(C.smeth(b=1, a=2, c=3), ['b', 'a', 'c'])

def test_kwargs_order_preserved_in_c_functions(self):
# PEP 468: Preserving Keyword Argument Order
self.assertEqual(list(dict(b=1, a=2, c=3)), ['b', 'a', 'c'])
self.assertEqual(list(dict(**{'b': 1}, a=2)), ['b', 'a'])
self.assertEqual(list(collections.OrderedDict(b=1, a=2, c=3)),
['b', 'a', 'c'])

def test_frames_are_popped_after_failed_calls(self):
# GH-93252: stuff blows up if we don't pop the new frame after
# recovering from failed calls:
Expand Down
60 changes: 60 additions & 0 deletions Lib/test/test_class.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -1052,5 +1052,65 @@ def __init__(self):
self.fail("MemoryError was not raised during deallocation")
self.fail("the dictionary was not cleared")

class DefinitionOrderTests(unittest.TestCase):
# PEP 520: Preserving Class Attribute Definition Order

@staticmethod
def defined_names(namespace):
# Skip the names added by the compiler, like __firstlineno__.
return [name for name in namespace if not name.startswith('__')]

def test_definition_order(self):
class C:
b = 1
a = 2
def m(self): pass
@staticmethod
def s(): pass
z = 3

self.assertEqual(self.defined_names(C.__dict__),
['b', 'a', 'm', 's', 'z'])

def test_definition_order_redefinition(self):
class C:
b = 1
a = 2
b = 3

self.assertEqual(self.defined_names(C.__dict__), ['b', 'a'])
self.assertEqual(C.b, 3)

def test_definition_order_after_deletion(self):
class C:
a = 1
b = 2
del a
a = 3

self.assertEqual(self.defined_names(C.__dict__), ['b', 'a'])

def test_definition_order_in_namespace(self):
namespaces = []
class Meta(type):
def __new__(mcls, name, bases, namespace, **kwds):
namespaces.append(list(namespace))
return super().__new__(mcls, name, bases, namespace, **kwds)

class C(metaclass=Meta):
b = 1
a = 2
def m(self): pass

self.assertEqual(self.defined_names(namespaces[0]), ['b', 'a', 'm'])

def test_prepare_preserves_order(self):
namespace = type.__prepare__('C', ())
namespace['b'] = 1
namespace['a'] = 2
namespace['b'] = 3
self.assertEqual(list(namespace), ['b', 'a'])


if __name__ == '__main__':
unittest.main()
Loading