4040import array
4141import collections
4242import mmap
43- import os
4443import sys
4544import unittest
46- from unittest import skipIf
45+ from collections import OrderedDict
4746
4847from . import CPyExtTestCase , CPyExtFunction , CPyExtType , unhandled_error_compare
4948
49+ ORDERED_DICT = OrderedDict ({'c' : 3 , 'a' : 1 , 'b' : 2 })
50+ ORDERED_DICT .move_to_end ('c' )
51+ assert list (ORDERED_DICT .items ()) == [('a' , 1 ), ('b' , 2 ), ('c' , 3 )]
5052
5153def _safe_check (v , type_check ):
5254 try :
@@ -110,58 +112,58 @@ def raise_type_error():
110112
111113def _reference_seq_size (args ):
112114 seq = args [0 ]
113-
115+
114116 if istypeof (seq , [dict , type (type .__dict__ )]):
115- # checking for the exact type
117+ # checking for the exact type
116118 # even if a dict or mappingproxy isn't accepted
117- # a subclass with overriden __len__ is
118- raise_type_error ()
119-
119+ # a subclass with overriden __len__ is
120+ raise_type_error ()
121+
120122 return len (seq )
121123
122124def _reference_mapping_size (args ):
123125 m = args [0 ]
124-
126+
125127 if istypeof (m , [set , frozenset , collections .deque ]):
126- # checking for the exact type
128+ # checking for the exact type
127129 # even if a set or deque isn't accepted
128- # a subclass with overriden __len__ is
129- raise_type_error ()
130-
130+ # a subclass with overriden __len__ is
131+ raise_type_error ()
132+
131133 try :
132- return len (m )
134+ return len (m )
133135 except :
134136 pass
135-
137+
136138 raise_type_error ()
137-
139+
138140def _reference_object_size (args ):
139- obj = args [0 ]
140-
141+ obj = args [0 ]
142+
141143 try :
142144 return len (obj )
143145 except :
144146 pass
145-
147+
146148 raise_type_error ()
147149
148150def _reference_sequence_check (args ):
149151 obj = args [0 ]
150152
151153 if isinstanceof (obj , [dict , type (type .__dict__ ), set , frozenset ]):
152- return False
153-
154+ return False
155+
154156 return hasattr (obj , '__getitem__' )
155157
156158def _reference_mapping_check (args ):
157159 obj = args [0 ]
158-
160+
159161 if isinstanceof (obj , [collections .deque ]):
160- return False
161-
162+ return False
163+
162164 if isinstanceof (obj , [array .array , bytearray , bytes , dict , type (type .__dict__ ), list , memoryview , range ]):
163165 return True
164-
166+
165167 return hasattr (obj , '__getitem__' )
166168
167169def isinstanceof (obj , types ):
@@ -257,37 +259,37 @@ class DummySequence():
257259
258260 def __getitem__ (self , idx ):
259261 raise IndexError
260-
262+
261263class DummyLen ():
262264 def __len__ (self ):
263265 return 42
264-
266+
265267class DummyDict (dict ):
266268 pass
267269
268- class DummyDictLen (dict ):
270+ class DummyDictLen (dict ):
269271 def __len__ (self ):
270272 return 42
271-
273+
272274
273275class DummyListSubclass (list ):
274276 pass
275277
276- class DummyListLen (list ):
278+ class DummyListLen (list ):
277279 def __len__ (self ):
278280 return 42
279-
280- class DummySet (set ):
281+
282+ class DummySet (set ):
281283 pass
282-
283- class DummySetLen (set ):
284+
285+ class DummySetLen (set ):
284286 def __len__ (self ):
285287 return 42
286-
287- class DummyDeque (set ):
288+
289+ class DummyDeque (set ):
288290 pass
289-
290- class DummyDequeLen (set ):
291+
292+ class DummyDequeLen (set ):
291293 def __len__ (self ):
292294 return 42
293295
@@ -401,7 +403,7 @@ def _size_and_check_args():
401403 (DummySet ([1 ,2 ,3 ]),),
402404 (DummySetLen (),),
403405 (DummySetLen ([1 ,2 ,3 ]),),
404- ({1 ,2 ,3 },),
406+ ({1 ,2 ,3 },),
405407 (frozenset ({1 ,2 ,3 }),),
406408 (dict (),),
407409 ({'a' :0 , 'b' :1 },),
@@ -417,14 +419,14 @@ def _size_and_check_args():
417419 (bytearray (b'abc' ),),
418420 (memoryview (b'abc' ),),
419421 (array .array ('I' , [1 ,2 ,3 ]),),
420- (collections .deque ([1 ,2 ,3 ,]),),
421- (DummyDeque (),),
422- (DummyDeque ([1 ,2 ,3 ]),),
423- (DummyDequeLen (),),
422+ (collections .deque ([1 ,2 ,3 ,]),),
423+ (DummyDeque (),),
424+ (DummyDeque ([1 ,2 ,3 ]),),
425+ (DummyDequeLen (),),
424426 (DummyDequeLen ([1 ,2 ,3 ]),),
425427 (DictSubclassWithSequenceMethods (),),
426428 )
427-
429+
428430class TestAbstractWithNative (unittest .TestCase ):
429431 def test_sequence_check (self ):
430432 TestSequenceCheck = CPyExtType ("TestSequenceCheck" ,
@@ -462,7 +464,7 @@ def test_sequence_size(self):
462464 )
463465 tester = TestSequenceSize ()
464466 assert tester .callSize (tester ) == 10
465-
467+
466468 def test_sequence_size_err (self ):
467469 TestSequenceSizeErr = CPyExtType ("TestSequenceSizeErr" ,
468470 """
@@ -481,14 +483,14 @@ def test_sequence_size_err(self):
481483 tp_methods = '{"callSize", (PyCFunction)callSize, METH_O, ""}' ,
482484 sq_length = "&test_sq_length" ,
483485 )
484- tester = TestSequenceSizeErr ()
486+ tester = TestSequenceSizeErr ()
485487 try :
486488 tester .callSize (tester )
487489 except TypeError :
488490 assert True
489491 else :
490492 assert False
491-
493+
492494 def test_sequence_size_err2 (self ):
493495 TestSequenceSizeErr2 = CPyExtType ("TestSequenceSizeErr2" ,
494496 """
@@ -507,14 +509,14 @@ def test_sequence_size_err2(self):
507509 tp_methods = '{"callSize", (PyCFunction)callSize, METH_O, ""}' ,
508510 sq_length = "&test_sq_length" ,
509511 )
510- tester = TestSequenceSizeErr2 ()
512+ tester = TestSequenceSizeErr2 ()
511513 try :
512514 tester .callSize (tester )
513515 except TypeError :
514516 assert True
515517 else :
516- assert False
517-
518+ assert False
519+
518520 def test_mapping_check (self ):
519521 TestMappingCheck = CPyExtType ("TestMappingCheck" ,
520522 """
@@ -531,7 +533,7 @@ def test_mapping_check(self):
531533 )
532534 tester = TestMappingCheck ()
533535 assert tester .callCheck (tester )
534-
536+
535537 def test_mapping_size (self ):
536538 TestMappingSize = CPyExtType ("TestMappingSize" ,
537539 """
@@ -551,7 +553,7 @@ def test_mapping_size(self):
551553 )
552554 tester = TestMappingSize ()
553555 assert tester .callSize (tester ) == 11
554-
556+
555557 def test_mapping_size_err (self ):
556558 TestMappingSizeErr = CPyExtType ("TestMappingSizeErr" ,
557559 """
@@ -570,14 +572,14 @@ def test_mapping_size_err(self):
570572 tp_methods = '{"callSize", (PyCFunction)callSize, METH_O, ""}' ,
571573 mp_length = "&test_mp_length" ,
572574 )
573- tester = TestMappingSizeErr ()
575+ tester = TestMappingSizeErr ()
574576 try :
575577 tester .callSize (tester )
576578 except TypeError :
577579 assert True
578580 else :
579581 assert False
580-
582+
581583 def test_object_size_sq (self ):
582584 TestObjectSizeSQ = CPyExtType ("TestObjectSizeSQ" ,
583585 """
@@ -597,7 +599,7 @@ def test_object_size_sq(self):
597599 )
598600 tester = TestObjectSizeSQ ()
599601 assert tester .callSize (tester ) == 12
600-
602+
601603 def test_object_size_mp (self ):
602604 TestObjectSizeMP = CPyExtType ("TestObjectSizeMP" ,
603605 """
@@ -616,8 +618,8 @@ def test_object_size_mp(self):
616618 mp_length = "&test_sq_length" ,
617619 )
618620 tester = TestObjectSizeMP ()
619- assert tester .callSize (tester ) == 13
620-
621+ assert tester .callSize (tester ) == 13
622+
621623 def test_object_size_err (self ):
622624 TestObjectSizeErr = CPyExtType ("TestObjectSizeErr" ,
623625 """
@@ -1085,7 +1087,7 @@ class TestAbstract(CPyExtTestCase):
10851087
10861088 test_PySequence_Fast_GET_SIZE = CPyExtFunction (
10871089 lambda args : len (args [0 ]),
1088- lambda : (
1090+ lambda : (
10891091 (tuple (),),
10901092 (list (),),
10911093 ((1 , 2 , 3 ),),
@@ -1240,7 +1242,7 @@ class TestAbstract(CPyExtTestCase):
12401242 arguments = ["PyObject* sequence" , "Py_ssize_t ilow" , "Py_ssize_t ihigh" ],
12411243 cmpfunc = unhandled_error_compare
12421244 )
1243-
1245+
12441246 test_PySequence_Contains = CPyExtFunction (
12451247 lambda args : args [1 ] in args [0 ],
12461248 lambda : (
@@ -1422,7 +1424,7 @@ def _reference_delslice(args):
14221424 arguments = ["PyObject* sequence" ],
14231425 cmpfunc = unhandled_error_compare
14241426 )
1425-
1427+
14261428 test_PySequence_List = CPyExtFunction (
14271429 lambda args : list (args [0 ]),
14281430 lambda : (
@@ -1528,16 +1530,52 @@ def _reference_delslice(args):
15281530 argspec = 'O' ,
15291531 arguments = ["PyObject* mapping" ],
15301532 )
1531-
1533+
15321534 test_PyMapping_Size = CPyExtFunction (
15331535 _reference_mapping_size ,
15341536 _size_and_check_args ,
15351537 resultspec = "n" ,
15361538 argspec = 'O' ,
15371539 arguments = ["PyObject* mapping" ],
15381540 cmpfunc = unhandled_error_compare
1539- )
1540-
1541+ )
1542+
1543+ test_PyMapping_Keys = CPyExtFunction (
1544+ lambda args : list (args [0 ].keys ()),
1545+ lambda : (
1546+ ({'a' : 1 , 'b' : 2 },),
1547+ (ORDERED_DICT ,),
1548+ ),
1549+ argspec = 'O' ,
1550+ resultspec = 'O' ,
1551+ arguments = ["PyObject* mapping" ],
1552+ cmpfunc = unhandled_error_compare ,
1553+ )
1554+
1555+ test_PyMapping_Values = CPyExtFunction (
1556+ lambda args : list (args [0 ].values ()),
1557+ lambda : (
1558+ ({'a' : 1 , 'b' : 2 },),
1559+ (ORDERED_DICT ,),
1560+ ),
1561+ argspec = 'O' ,
1562+ resultspec = 'O' ,
1563+ arguments = ["PyObject* mapping" ],
1564+ cmpfunc = unhandled_error_compare ,
1565+ )
1566+
1567+ test_PyMapping_Items = CPyExtFunction (
1568+ lambda args : list (args [0 ].items ()),
1569+ lambda : (
1570+ ({'a' : 1 , 'b' : 2 },),
1571+ (ORDERED_DICT ,),
1572+ ),
1573+ argspec = 'O' ,
1574+ resultspec = 'O' ,
1575+ arguments = ["PyObject* mapping" ],
1576+ cmpfunc = unhandled_error_compare ,
1577+ )
1578+
15411579 test_PyIndex_Check = CPyExtFunction (
15421580 lambda args : hasattr (args [0 ], "__index__" ),
15431581 lambda : (
0 commit comments