1"""
2Tests for the new-style metadata format interface.
3
4Note: Tests for calling from ObjC into python are in test_metadata_py.py
5
6TODO:
7- Add tests for calling functions instead of methods
8- The python->C interface (that is the contents of the metadata object) is
9  likely to change when the bridge is feature-complete.
10- Probably need special-casing for arrays (numarray and array.array)!
11"""
12import objc
13from PyObjCTools.TestSupport import *
14import warnings
15import array
16import sys
17
18from PyObjCTest.metadata import *
19
20def setupMetaData():
21    # Note to self: what we think of as the first argument of a method is
22    # actually the third one, the objc runtime implicitly passed 'self' and
23    # the selector as well. Therefore we need to start counting at 2 instead
24    # of 0.
25    #
26    # Note2: the code below would normally be done using a metadata file
27    # instead of hardcoding.
28    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"boolClassMethod",
29            dict(
30                retval=dict(type=objc._C_NSBOOL)
31            ))
32
33    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"unknownLengthArray",
34            dict(
35                retval=dict(c_array_of_variable_length=True),
36        ))
37    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"unknownLengthMutable",
38            dict(
39                retval=dict(c_array_of_variable_length=True),
40        ))
41    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"makeVariableLengthArray:halfCount:",
42            dict(
43                arguments={
44                    2+0: dict(c_array_of_variable_length=True, type_modifier=objc._C_IN),
45                }
46        ))
47
48    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"varargsMethodWithObjects:",
49            dict(
50                variadic=True,
51            ))
52
53    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"ignoreMethod",
54            dict(
55                suggestion='please ignore me',
56            ))
57
58    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"makeArrayWithFormat:",
59            dict(
60                variadic=True,
61                arguments={
62                    2+0: dict(printf_format=True),
63                }
64            ))
65    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"makeArrayWithCFormat:",
66            dict(
67                variadic=True,
68                arguments={
69                    2+0: dict(printf_format=True),
70                }
71            ))
72
73    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"makeArrayWithArguments:",
74            dict(
75                variadic=True,
76                c_array_delimited_by_null=True
77            ))
78
79    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"make4Tuple:",
80            dict(
81                arguments={
82                  2+0:  dict(type_modifier=objc._C_IN, c_array_of_fixed_length=4, null_accepted=False),
83                }
84            )
85        )
86    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"null4Tuple:",
87            dict(
88                arguments={
89                  2+0:  dict(type_modifier=objc._C_IN, c_array_of_fixed_length=4, null_accepted=True),
90                }
91            )
92        )
93
94    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"makeObjectArray:",
95            dict(
96                arguments={
97                  2+0:  dict(type_modifier=objc._C_IN, c_array_delimited_by_null=True, null_accepted=False),
98                }
99            )
100        )
101    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"makeStringArray:",
102            dict(
103                arguments={
104                  2+0:  dict(type_modifier=objc._C_IN, c_array_delimited_by_null=True, null_accepted=False),
105                }
106            )
107        )
108    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"nullStringArray:",
109            dict(
110                arguments={
111                  2+0:  dict(type_modifier=objc._C_IN, c_array_delimited_by_null=True, null_accepted=True),
112                }
113            )
114        )
115    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"makeIntArray:count:",
116            dict(
117                arguments={
118                  2+0:  dict(type_modifier=objc._C_IN, c_array_length_in_arg=2+1, null_accepted=False),
119                }
120            )
121        )
122    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"makeIntArray:halfCount:",
123            dict(
124                arguments={
125                  2+0:  dict(type_modifier=objc._C_IN, c_array_of_variable_length=True, null_accepted=False),
126                }
127            )
128        )
129    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"makeIntArray:countPtr:",
130            dict(
131                arguments={
132                  2+0:  dict(type_modifier=objc._C_IN, c_array_length_in_arg=2+1, null_accepted=False),
133                  2+1:  dict(type_modifier=objc._C_IN, null_accepted=False),
134                }
135            )
136        )
137    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"nullIntArray:count:",
138            dict(
139                arguments={
140                  2+0:  dict(type_modifier=objc._C_IN, c_array_length_in_arg=2+1, null_accepted=True),
141                }
142            )
143        )
144
145    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"fillArray:uptoCount:",
146            dict(
147                arguments={
148                    2+0: dict(type_modifier=objc._C_OUT, c_array_length_in_arg=2+1, c_array_length_in_result=True, null_accepted=False),
149                }
150            )
151        )
152
153    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"fillArray:count:",
154            dict(
155                arguments={
156                    2+0: dict(type_modifier=objc._C_OUT, c_array_length_in_arg=2+1, null_accepted=False),
157                }
158            )
159        )
160    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"nullfillArray:count:",
161            dict(
162                arguments={
163                    2+0: dict(type_modifier=objc._C_OUT, c_array_length_in_arg=2+1, null_accepted=True),
164                }
165            )
166        )
167
168    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"maybeFillArray:",
169            dict(
170                arguments={
171                    2+0: dict(type_modifier=objc._C_OUT, c_array_of_fixed_length=4, c_array_length_in_result=True, null_accepted=False),
172                }
173            )
174        )
175    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"fill4Tuple:",
176            dict(
177                arguments={
178                    2+0: dict(type_modifier=objc._C_OUT, c_array_of_fixed_length=4, null_accepted=False),
179                }
180            )
181        )
182    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"nullfill4Tuple:",
183            dict(
184                arguments={
185                    2+0: dict(type_modifier=objc._C_OUT, c_array_of_fixed_length=4, null_accepted=True),
186                }
187            )
188        )
189    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"fillStringArray:",
190            dict(
191                arguments={
192                    2+0: dict(type_modifier=objc._C_OUT, c_array_delimited_by_null=True, null_accepted=False),
193                }
194            )
195        )
196    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"nullfillStringArray:",
197            dict(
198                arguments={
199                    2+0: dict(type_modifier=objc._C_OUT, c_array_delimited_by_null=True, null_accepted=True),
200                }
201            )
202        )
203
204    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"reverseArray:uptoCount:",
205            dict(
206                arguments={
207                    2+0: dict(type_modifier=objc._C_INOUT, c_array_length_in_arg=2+1, c_array_length_in_result=True, null_accepted=False),
208                }
209            )
210        )
211    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"reverseArray:count:",
212            dict(
213                arguments={
214                    2+0: dict(type_modifier=objc._C_INOUT, c_array_length_in_arg=2+1, null_accepted=False),
215                }
216            )
217        )
218    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"nullreverseArray:count:",
219            dict(
220                arguments={
221                    2+0: dict(type_modifier=objc._C_INOUT, c_array_length_in_arg=2+1, null_accepted=True),
222                }
223            )
224        )
225
226    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"reverseStrings:",
227            dict(
228                arguments={
229                    2+0: dict(type_modifier=objc._C_INOUT, c_array_delimited_by_null=True, null_accepted=False),
230                }
231            )
232        )
233    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"nullreverseStrings:",
234            dict(
235                arguments={
236                    2+0: dict(type_modifier=objc._C_INOUT, c_array_delimited_by_null=True, null_accepted=True),
237                }
238            )
239        )
240
241    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"maybeReverseArray:",
242            dict(
243                arguments={
244                    2+0: dict(type_modifier=objc._C_INOUT, c_array_of_fixed_length=4, c_array_length_in_result=True, null_accepted=False),
245                }
246            )
247        )
248    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"reverse4Tuple:",
249            dict(
250                arguments={
251                    2+0: dict(type_modifier=objc._C_INOUT, c_array_of_fixed_length=4, null_accepted=False),
252                }
253            )
254        )
255    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"nullreverse4Tuple:",
256            dict(
257                arguments={
258                    2+0: dict(type_modifier=objc._C_INOUT, c_array_of_fixed_length=4, null_accepted=True),
259                }
260            )
261        )
262
263
264
265
266    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"makeIntArrayOf5",
267            dict(
268                retval=dict(c_array_of_fixed_length=5)
269            ),
270        )
271
272    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"makeStringArray",
273            dict(
274                retval=dict(c_array_delimited_by_null=True),
275            ),
276        )
277
278    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"makeIntArrayOf:",
279            dict(
280                retval=dict(c_array_length_in_arg=2+0)
281            ),
282        )
283
284    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"nullIntArrayOf5",
285            dict(
286                retval=dict(c_array_of_fixed_length=5)
287            ),
288        )
289
290    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"nullStringArray",
291            dict(
292                retval=dict(c_array_delimited_by_null=True),
293            ),
294        )
295
296    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"nullIntArrayOf:",
297            dict(
298                retval=dict(c_array_length_in_arg=2+0)
299            ),
300        )
301
302
303    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"sumX:andY:",
304            dict(arguments={
305                    2+0: dict(type_modifier=objc._C_IN, null_accepted=False),
306                    2+1: dict(type_modifier=objc._C_IN, null_accepted=False),
307                }))
308    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"divBy5:remainder:",
309            dict(arguments={
310                    2+1: dict(type_modifier=objc._C_OUT, null_accepted=False),
311                }))
312    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"swapX:andY:",
313            dict(arguments={
314                    2+0: dict(type_modifier=objc._C_INOUT, null_accepted=False),
315                    2+1: dict(type_modifier=objc._C_INOUT, null_accepted=False),
316                }))
317    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"input:output:inputAndOutput:",
318            dict(arguments={
319                    2+0: dict(type_modifier=objc._C_IN, null_accepted=True),
320                    2+1: dict(type_modifier=objc._C_OUT, null_accepted=True),
321                    2+2: dict(type_modifier=objc._C_INOUT, null_accepted=True),
322            }))
323
324    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"makeDataForBytes:count:",
325            dict(arguments={
326                2+0: dict(type_modifier=objc._C_IN, c_array_length_in_arg=2+1, null_accepted=False),
327            }))
328    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"makeDataForVoids:count:",
329            dict(arguments={
330                2+0: dict(type_modifier=objc._C_IN, c_array_length_in_arg=2+1, null_accepted=False),
331            }))
332    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"addOneToBytes:count:",
333            dict(arguments={
334                2+0: dict(type_modifier=objc._C_INOUT, c_array_length_in_arg=2+1, null_accepted=False),
335            }))
336    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"addOneToVoids:count:",
337            dict(arguments={
338                2+0: dict(type_modifier=objc._C_INOUT, c_array_length_in_arg=2+1, null_accepted=False),
339            }))
340    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"fillBuffer:count:",
341            dict(arguments={
342                2+0: dict(type_modifier=objc._C_OUT, c_array_length_in_arg=2+1, null_accepted=False),
343            }))
344    objc.registerMetaDataForSelector(b"OC_MetaDataTest", b"fillVoids:count:",
345            dict(arguments={
346                2+0: dict(type_modifier=objc._C_OUT, c_array_length_in_arg=2+1, null_accepted=False),
347            }))
348
349
350setupMetaData()
351
352class TestArrayDefault (TestCase):
353    # TODO: what is the default anyway?
354    pass
355
356class TestArraysOut (TestCase):
357    def testFixedSize(self):
358        o = OC_MetaDataTest.new()
359
360        v = o.fill4Tuple_(None)
361        self.assertEquals(list(v), [0, -1, -8, -27])
362
363        self.assertRaises(ValueError, o.fill4Tuple_, objc.NULL)
364
365        n, v = o.nullfill4Tuple_(None)
366        self.assertEquals(n, 1)
367        self.assertEquals(list(v), [0, -1, -8, -27])
368
369        n, v = o.nullfill4Tuple_(objc.NULL)
370        self.assertEquals(n, 0)
371        self.assertIs(v, objc.NULL)
372
373        a = array.array('i', [0]* 4)
374        v = o.fill4Tuple_(a);
375        self.assertIs(a, v)
376        self.assertEquals(list(a), [0, -1, -8, -27])
377
378        a = array.array('i', [0]* 5)
379        self.assertRaises(ValueError, o.fill4Tuple_, a)
380        a = array.array('i', [0]* 3)
381        self.assertRaises(ValueError, o.fill4Tuple_, a)
382
383    def testNullTerminated(self):
384        o = OC_MetaDataTest.new()
385
386        # Output only arrays of null-terminated arrays cannot be
387        # wrapped automaticly. How is the bridge supposed to know
388        # how much memory it should allocate for the C-array?
389        self.assertRaises(TypeError, o.fillStringArray_, None)
390        self.assertRaises(ValueError, o.fillStringArray_, objc.NULL)
391
392        self.assertRaises(TypeError, o.nullfillStringArray_)
393        self.assertRaises(TypeError, o.nullfillStringArray_, None)
394        n, v = o.nullfillStringArray_(objc.NULL)
395        self.assertEquals(n, 0)
396        self.assertIs(v, objc.NULL)
397
398    def testWithCount(self):
399        o = OC_MetaDataTest.new()
400
401        v = o.fillArray_count_(None, 3)
402        self.assertEquals(list(v),  [0,1,4])
403
404        v = o.fillArray_count_(None, 3)
405        self.assertEquals(list(v),  [0,1,4])
406
407        v = o.fillArray_count_(None, 5)
408        self.assertEquals(list(v),  [0,1,4,9,16])
409
410        v = o.fillArray_count_(None, 0)
411        self.assertEquals(list(v),  [])
412
413        self.assertRaises(ValueError, o.fillArray_count_, objc.NULL, 0)
414
415        n, v = o.nullfillArray_count_(None, 4)
416        self.assertEquals(n, 1)
417        self.assertEquals(list(v),  [0,1,4,9])
418        n, v = o.nullfillArray_count_(None, 3)
419        self.assertEquals(n, 1)
420        self.assertEquals(list(v),  [0,1,4])
421
422        n, v = o.nullfillArray_count_(objc.NULL, 3)
423        self.assertEquals(n, 0)
424        self.assertIs(v, objc.NULL)
425
426        a = array.array('i', [0]* 10)
427        v = o.fillArray_count_(a, 10);
428        self.assertIs(a, v)
429        self.assertEquals(list(a), [0, 1, 4, 9, 16, 25, 36, 49, 64, 81 ])
430
431    def testWithCountInResult(self):
432        o = OC_MetaDataTest.new()
433
434        c, v = o.fillArray_uptoCount_(None, 20)
435        self.assertEquals(c, 10)
436        self.assertEquals(list(v),  [i+2 for i in range(10)])
437
438        c, v = o.maybeFillArray_(None)
439        self.assertEquals(c, 2)
440        self.assertEquals(list(v),  [10, 11])
441
442
443class TestArraysInOut (TestCase):
444    def testFixedSize(self):
445        o = OC_MetaDataTest.new()
446
447        a = (1,2,3,4)
448        v = o.reverse4Tuple_(a)
449        self.assertEquals(a, (1,2,3,4))
450        self.assertEquals(v, (4,3,2,1))
451
452        self.assertRaises(ValueError, o.reverse4Tuple_, (1,2,3))
453        self.assertRaises(ValueError, o.reverse4Tuple_, (1,2,3,4,5))
454        self.assertRaises(ValueError, o.reverse4Tuple_, objc.NULL)
455
456        a = (1,2,3,4)
457        n, v = o.nullreverse4Tuple_(a)
458        self.assertEquals(n, 1)
459        self.assertEquals(a, (1,2,3,4))
460        self.assertEquals(v, (4,3,2,1))
461
462        n, v = o.nullreverse4Tuple_(objc.NULL)
463        self.assertEquals(n, 0)
464        self.assertIs(v, objc.NULL)
465
466        a = array.array('h', [1, 2, 3, 4])
467        v = o.reverse4Tuple_(a)
468        self.assertIs(v, a)
469        self.assertEquals(list(a), [4,3,2,1])
470
471        a = array.array('h', [1, 2, 3, 4, 5])
472        self.assertRaises(ValueError, o.reverse4Tuple_, a)
473        a = array.array('h', [1, 2, 3])
474        self.assertRaises(ValueError, o.reverse4Tuple_, a)
475
476    def testNullTerminated(self):
477        o = OC_MetaDataTest.new()
478
479        a = (b'a', b'b', b'c')
480        v = o.reverseStrings_(a)
481        self.assertEquals(a, (b'a', b'b', b'c'))
482        self.assertEquals(v, (b'c', b'b', b'a'))
483
484        self.assertRaises(ValueError, o.reverseStrings_, (1,2))
485        self.assertRaises(ValueError, o.reverseStrings_, objc.NULL)
486
487        a = (b'a', b'b', b'c')
488        n, v = o.nullreverseStrings_(a)
489        self.assertEquals(n, 1)
490        self.assertEquals(a, (b'a', b'b', b'c'))
491        self.assertEquals(v, (b'c', b'b', b'a'))
492
493        n, v = o.nullreverseStrings_(objc.NULL)
494        self.assertEquals(n, 0)
495        self.assertIs(v, objc.NULL)
496
497    def testWithCount(self):
498        o = OC_MetaDataTest.new()
499
500        a = (1.0, 2.0, 3.0, 4.0, 5.0)
501        v = o.reverseArray_count_(a, 4)
502        self.assertEquals(a, (1.0, 2.0, 3.0, 4.0, 5.0))
503        self.assertEquals(v, (4.0, 3.0, 2.0, 1.0))
504
505        a = (1.0, 2.0, 3.0, 4.0, 5.0)
506        v = o.reverseArray_count_(a, 5)
507        self.assertEquals(a, (1.0, 2.0, 3.0, 4.0, 5.0))
508        self.assertEquals(v, (5.0, 4.0, 3.0, 2.0, 1.0))
509
510        # Nice to have, but doesn't work without major
511        # surgery:
512        #a = (1.0, 2.0, 3.0, 4.0, 5.0)
513        #v = o.reverseArray_count_(a, None)
514        #self.assertEquals(a, (1.0, 2.0, 3.0, 4.0, 5.0))
515        #self.assertEquals(v, (5.0, 4.0, 3.0, 2.0, 1.0))
516
517        self.assertRaises(ValueError, o.reverseArray_count_, (1.0, 2.0), 5)
518        self.assertRaises(ValueError, o.reverseArray_count_, objc.NULL, 0)
519
520        a = (1.0, 2.0, 3.0, 4.0, 5.0)
521        n, v = o.nullreverseArray_count_(a, 4)
522        self.assertEquals(n, 1)
523        self.assertEquals(a, (1.0, 2.0, 3.0, 4.0, 5.0))
524        self.assertEquals(v, (4.0, 3.0, 2.0, 1.0))
525
526        a = (1.0, 2.0, 3.0, 4.0, 5.0)
527        n, v = o.nullreverseArray_count_(a, 5)
528        self.assertEquals(n, 1)
529        self.assertEquals(a, (1.0, 2.0, 3.0, 4.0, 5.0))
530        self.assertEquals(v, (5.0, 4.0, 3.0, 2.0, 1.0))
531
532        n, v = o.nullreverseArray_count_(objc.NULL, 0)
533        self.assertEquals(n, 0)
534        self.assertIs(v, objc.NULL)
535
536        a = array.array('f', [5.0, 7.0, 9.0, 11.0, 13.0])
537        v = o.reverseArray_count_(a, 5)
538        self.assertIs(a, v)
539        self.assertEquals(list(a), [13.0, 11.0, 9.0, 7.0, 5.0])
540
541    def testWithCountInResult(self):
542        o = OC_MetaDataTest.new()
543
544        c, v = o.reverseArray_uptoCount_(range(10), 10)
545        self.assertEquals(c, 5)
546        self.assertEquals(len(v), 5)
547        self.assertEquals(list(v),  [9, 8, 7, 6, 5])
548
549        c, v = o.maybeReverseArray_([1,2,3,4])
550        self.assertEquals(c, 2)
551        self.assertEquals(len(v), 2)
552        self.assertEquals(list(v),  [4, 3])
553
554class TestArraysIn (TestCase):
555    def testFixedSize(self):
556        o = OC_MetaDataTest.new()
557
558        v = o.make4Tuple_((1.0, 4.0, 8.0, 12.5))
559        self.assertEquals(len(v), 4)
560        self.assertEquals(list(v), [1.0, 4.0, 8.0, 12.5])
561
562        v = o.make4Tuple_((1, 2, 3, 4))
563        self.assertEquals(len(v), 4)
564        self.assertEquals(list(v), [1.0, 2.0, 3.0, 4.0])
565
566        self.assertRaises(ValueError, o.make4Tuple_, (1, 2, 3))
567        self.assertRaises(ValueError, o.make4Tuple_, (1, 2, 3, 4, 5))
568        self.assertRaises(ValueError, o.make4Tuple_, objc.NULL)
569
570        v = o.null4Tuple_(objc.NULL)
571        self.assertIsNone(v)
572
573        a = array.array('d', [2.5, 3.5, 4.5, 5.5])
574        v = o.make4Tuple_(a)
575        self.assertEquals(list(v), [2.5, 3.5, 4.5, 5.5])
576
577    def testNullTerminated(self):
578        o = OC_MetaDataTest.new()
579
580        v = o.makeStringArray_((b"hello", b"world", b"there"))
581        self.assertEquals(len(v), 3)
582        self.assertEquals(list(v), [u"hello", u"world", u"there"])
583        self.assertIsInstance(v, objc.lookUpClass("NSArray"))
584        self.assertIsInstance(v[0], unicode)
585
586        NSObject = objc.lookUpClass('NSObject')
587        p, q, r = NSObject.new(), NSObject.new(), NSObject.new()
588        v = o.makeObjectArray_((p, q, r))
589        self.assertEquals(len(v), 3)
590        self.assertIs(v[0], p)
591        self.assertIs(v[1], q)
592        self.assertIs(v[2], r)
593
594
595        v = o.makeStringArray_(())
596        self.assertEquals(len(v), 0)
597
598        self.assertRaises(ValueError, o.makeStringArray_, [1,2])
599        self.assertRaises(ValueError, o.makeStringArray_, objc.NULL)
600
601        v = o.nullStringArray_(objc.NULL)
602        self.assertEquals(v, None)
603
604    def testWithCount(self):
605        o = OC_MetaDataTest.new()
606
607        v = o.makeIntArray_count_((1,2,3,4), 3)
608        self.assertEquals(len(v), 3)
609        self.assertEquals(list(v), [1,2,3])
610
611        # XXX: This one would be nice to have, but not entirely trivial
612        #v = o.makeIntArray_count_((1,2,3,4), None)
613        #self.assertEquals(len(v), 3)
614        #self.assertEquals(list(v), [1,2,3,4])
615
616        self.assertRaises(ValueError, o.makeIntArray_count_, [1,2,3], 4)
617        self.assertRaises(ValueError, o.makeIntArray_count_, objc.NULL, 0)
618        self.assertRaises(ValueError, o.makeIntArray_count_, objc.NULL, 1)
619
620        v = o.nullIntArray_count_(objc.NULL, 0)
621        self.assertEquals(v, None)
622
623        self.assertRaises(ValueError, o.makeIntArray_count_, objc.NULL, 1)
624
625        # Make sure this also works when the length is in a pass-by-reference argument
626        v = o.makeIntArray_countPtr_((1,2,3,4), 4)
627        self.assertEquals(len(v), 4)
628        self.assertEquals(list(v), [1,2,3,4])
629
630        a = array.array('i', range(20))
631        v = o.makeIntArray_count_(a, 7)
632        self.assertEquals(list(v), list(range(7)))
633
634        self.assertRaises(ValueError, o.makeIntArray_count_, a, 21)
635
636
637class TestArrayReturns (TestCase):
638    # TODO:
639    # - Add null-terminated arrays of various supported types:
640    #   -> integers
641    #   -> CF-types
642
643    def testFixedSize(self):
644        o = OC_MetaDataTest.new()
645
646        v = o.makeIntArrayOf5()
647        self.assertEquals( len(v), 5 )
648        self.assertEquals( v[0], 0 )
649        self.assertEquals( v[1], 1 )
650        self.assertEquals( v[2], 4 )
651        self.assertEquals( v[3], 9 )
652        self.assertEquals( v[4], 16 )
653
654        v = o.nullIntArrayOf5()
655        self.assertEquals(v, objc.NULL)
656
657    def testSizeInArgument(self):
658        o = OC_MetaDataTest.new()
659        v = o.makeIntArrayOf_(3)
660        self.assertEquals(len(v), 3)
661        self.assertEquals(v[0], 0)
662        self.assertEquals(v[1], 1)
663        self.assertEquals(v[2], 8)
664
665        v = o.makeIntArrayOf_(10)
666        self.assertEquals(len(v), 10)
667        for i in range(10):
668            self.assertEquals(v[i], i**3)
669
670        v = o.nullIntArrayOf_(100)
671        self.assertEquals(v, objc.NULL)
672
673    def testNULLterminated(self):
674        o  = OC_MetaDataTest.new()
675
676        v = o.makeStringArray()
677        self.assertEquals(len(v), 4)
678        self.assertEquals(list(v), [b"hello", b"world", b"out", b"there"])
679
680        v = o.nullStringArray()
681        self.assertEquals(v, objc.NULL)
682
683class TestByReference (TestCase):
684    # Pass by reference arguments.
685    # Note that these tests aren't exhaustive, we have test_methods and
686    # test_methods2 for that :-)
687
688    def testInput(self):
689        o = OC_MetaDataTest.new()
690
691        r = o.sumX_andY_(1, 2)
692        self.assertEquals(r, 1+2)
693
694        r = o.sumX_andY_(2535, 5325)
695        self.assertEquals(r, 2535 + 5325)
696
697        self.assertRaises(ValueError, o.sumX_andY_, 42, objc.NULL)
698
699    def testOutput(self):
700        o = OC_MetaDataTest.new()
701
702        div, rem = o.divBy5_remainder_(55, None)
703        self.assertEquals(div, 11)
704        self.assertEquals(rem, 0)
705
706        div, rem = o.divBy5_remainder_(13, None)
707        self.assertEquals(div, 2)
708        self.assertEquals(rem, 3)
709
710        self.assertRaises(ValueError, o.divBy5_remainder_, 42, objc.NULL)
711
712    def testInputOutput(self):
713        o = OC_MetaDataTest.new()
714        x, y = o.swapX_andY_(42, 284)
715        self.assertEquals(x, 284)
716        self.assertEquals(y, 42)
717
718        self.assertRaises(ValueError, o.swapX_andY_, 42, objc.NULL)
719
720    def testNullAccepted(self):
721        o = OC_MetaDataTest.new();
722
723        def makeNum(value):
724            return int(value, 0)
725
726        # All arguments present
727        r, y, z = o.input_output_inputAndOutput_(1, None, 2)
728        self.assertEquals(len(r), 3)
729        self.assertEquals(len(filter(None, map(makeNum, r))), 3)
730        self.assertEquals(y, 3)
731        self.assertEquals(z, -1)
732
733        r, y, z = o.input_output_inputAndOutput_(1, None, 2)
734        self.assertEquals(len(r), 3)
735        self.assertEquals(len(filter(None, map(makeNum, r))), 3)
736        self.assertEquals(y, 3)
737        self.assertEquals(z, -1)
738
739        # Argument 1 is NULL
740        r, y, z = o.input_output_inputAndOutput_(objc.NULL, None, 2)
741        self.assertEquals(len(r), 3)
742        self.assertEquals(len(filter(None, map(makeNum, r))), 2)
743        self.assertEquals(y, 40)
744        self.assertEquals(z, -2)
745
746        r, y, z = o.input_output_inputAndOutput_(objc.NULL, None, 2)
747        self.assertEquals(len(r), 3)
748        self.assertEquals(len(filter(None, map(makeNum, r))), 2)
749        self.assertEquals(y, 40)
750        self.assertEquals(z, -2)
751
752        # Argument 2 is NULL
753        r, y, z = o.input_output_inputAndOutput_(1, objc.NULL, 2)
754        self.assertEquals(len(r), 3)
755        self.assertEquals(len(filter(None, map(makeNum, r))), 2)
756        self.assertEquals(y, objc.NULL)
757        self.assertEquals(z, -1)
758
759        # Argument 3 is NULL
760        r, y, z = o.input_output_inputAndOutput_(1, None, objc.NULL)
761        self.assertEquals(len(r), 3)
762        self.assertEquals(len(filter(None, map(makeNum, r))), 2)
763        self.assertEquals(y, 43)
764        self.assertEquals(z, objc.NULL)
765
766        r, y, z = o.input_output_inputAndOutput_(1, None, objc.NULL)
767        self.assertEquals(len(r), 3)
768        self.assertEquals(len(filter(None, map(makeNum, r))), 2)
769        self.assertEquals(y, 43)
770        self.assertEquals(z, objc.NULL)
771
772class TestPrintfFormat (TestCase):
773    def test_nsformat(self):
774        o = OC_MetaDataTest.new()
775
776        v = o.makeArrayWithFormat_("%3d", 10)
777        self.assertEquals(list(v), [ "%3d", " 10"])
778
779        v = o.makeArrayWithFormat_("%s", b"foo")
780        self.assertEquals(list(v), [ "%s", "foo"])
781
782        v = o.makeArrayWithFormat_("hello %s", b"world")
783        self.assertEquals(list(v), [ "hello %s", "hello world"])
784
785        v = o.makeArrayWithFormat_(u"hello %s", b"world")
786        self.assertEquals(list(v), [ "hello %s", u"hello world"])
787
788        self.assertRaises(ValueError, o.makeArrayWithFormat_, "%s")
789
790    def test_cformat(self):
791        o = OC_MetaDataTest.new()
792
793        v = o.makeArrayWithCFormat_(b"%3d", 10)
794        self.assertEquals(list(v), [ "%3d", " 10"])
795
796        v = o.makeArrayWithCFormat_(b"hello %s", b"world")
797        self.assertEquals(list(v), [ "hello %s", "hello world"])
798
799        v = o.makeArrayWithCFormat_(b"hello %s x %d", b"world", 42)
800        self.assertEquals(list(v), [ "hello %s x %d", "hello world x 42"])
801
802        # As we implement a format string parser we'd better make sure that
803        # that code is correct...
804
805        # Generic table below doesn't work for these
806        for fmt, args in [
807            ( b'%#+x', (99,)),
808            ( b'%+#x', (99,)),
809            ( b'% #x', (99,)),
810            ]:
811
812                v = o.makeArrayWithCFormat_(fmt, *args)
813                self.assertEquals(map(unicode, list(v)), [fmt.decode('latin'), (fmt.decode('latin')%args)[1:]] )
814
815        # Insert thousands seperator, the one in the C locale is ''
816        v = o.makeArrayWithCFormat_(b"%'d", 20000)
817        self.assertEquals(list(v), [ "%'d", '20000'])
818        v = o.makeArrayWithCFormat_(b"%hhd", 20)
819        self.assertEquals(list(v), [ "%hhd", '20'])
820        v = o.makeArrayWithCFormat_(b"%lld", 20)
821        self.assertEquals(list(v), [ "%lld", '20'])
822        v = o.makeArrayWithCFormat_(b"%lld", -20)
823        self.assertEquals(list(v), [ "%lld", '-20'])
824        v = o.makeArrayWithCFormat_(b"%zd", 20)
825        self.assertEquals(list(v), [ "%zd", '20'])
826        v = o.makeArrayWithCFormat_(b"%td", 20)
827        self.assertEquals(list(v), [ "%td", '20'])
828        v = o.makeArrayWithCFormat_(b"%qd", 20)
829        self.assertEquals(list(v), [ "%qd", '20'])
830        v = o.makeArrayWithCFormat_(b"%qd", -20)
831        self.assertEquals(list(v), [ "%qd", '-20'])
832        v = o.makeArrayWithCFormat_(b"%D", -20)
833        self.assertEquals(list(v), [ "%D", '-20'])
834        v = o.makeArrayWithCFormat_(b"%O", 8)
835        self.assertEquals(list(v), [ "%O", '10'])
836        v = o.makeArrayWithCFormat_(b"%U", 8)
837        self.assertEquals(list(v), [ "%U", '8'])
838
839        obj = object()
840        v = o.makeArrayWithCFormat_(b"%p", obj)
841        self.assertEquals(list(v), [ "%p", '%#x'%(id(obj),)])
842
843        v = o.makeArrayWithCFormat_(b"%lc%lc", 'd', 'e')
844        self.assertEquals(list(v), [ "%lc%lc", 'de'])
845
846        v = o.makeArrayWithCFormat_(b"%C", 'A')
847        self.assertEquals(list(v), [ "%C", 'A'])
848
849        v = o.makeArrayWithCFormat_(b"%C%C%c", 'A', 90, 'b')
850        self.assertEquals(list(v), [ "%C%C%c", 'A%cb'%(90,)])
851
852        v = o.makeArrayWithCFormat_(b"%S", 'hello world')
853        self.assertEquals(list(v), [ "%S", 'hello world'])
854        v = o.makeArrayWithCFormat_(b"%S", u'hello world')
855        self.assertEquals(list(v), [ "%S", 'hello world'])
856
857        v = o.makeArrayWithCFormat_(b"%ls", 'hello world')
858        self.assertEquals(list(v), [ "%ls", 'hello world'])
859        v = o.makeArrayWithCFormat_(b"%ls", u'hello world')
860        self.assertEquals(list(v), [ "%ls", 'hello world'])
861
862        TEST_TAB = [
863            ( b'% #d', (99,)),
864            ( b'%0#4x', (99,)),
865            ( b'%#+d', (99,)),
866            ( b'%+#d', (99,)),
867            ( b'%o', (20,) ),
868            ( b'%10o', (9,) ),
869            ( b'%d %.*o', (2, 5, 7,) ),
870            ( b'%*o', (5, 7,) ),
871            ( b'%.*o', (5, 7,) ),
872            ( b'%.*f', (3, 0.23424)),
873            ( b'%*.*f', (12, 3, 0.23424)),
874            ( b'%F', (-4.6,)),
875            ( b'%f', (2.7,)),
876            ( b'%e', (2.7,)),
877            ( b'%E', (-4.6,)),
878            ( b'%g', (2.7,)),
879            ( b'%G', (-4.6,)),
880            ( b'%.9f', (0.249,)),
881            ( b'%ld', (42,)),
882            ( b'%c', (42,)),
883            ( b'%hd', (42,)),
884            ( b'%lx', (42,)),
885            ( b'%%%d%%', (99,)),
886            ( b'%c', ('a',) ),
887            ( b'%c%c', ('c', 'd')),
888            ( b'%c%c', (90, 'd')),
889            ( b'%f %f %f %f %f %f %f %f', (1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5))
890
891            # We don't have long double support at all
892            #( '%Lg', (42.0,)),
893        ]
894
895        for fmt, args in TEST_TAB:
896            v = o.makeArrayWithCFormat_(fmt, *args)
897            self.assertEquals(list(v), [ fmt.decode('latin1'), fmt.decode('latin1')%args ])
898
899
900class TestVariadic (TestCase):
901    def testRaises(self):
902        o = OC_MetaDataTest.new()
903
904        self.assertRaises(TypeError, o.varargsMethodWithObjects_, 1)
905        self.assertRaises(TypeError, o.varargsMethodWithObjects_, 1, 2, 3)
906
907class TestIgnore (TestCase):
908    def testRaises(self):
909        o = OC_MetaDataTest.new()
910
911        self.assertRaises(TypeError, o.ignoreMethod)
912
913    def testClassmethods(self):
914        self.assertResultIsBOOL(OC_MetaDataTest.boolClassMethod)
915
916class TestMetaDataAccess (TestCase):
917    def testNew(self):
918        self.assertResultIsRetained(OC_MetaDataTest.new)
919
920    def testSuggestions(self):
921        meta = OC_MetaDataTest.varargsMethodWithObjects_.__metadata__()
922        self.assertIsInstance(meta, dict)
923        self.assertIn('suggestion', meta)
924        self.assertEquals(meta['suggestion'], "Variadic functions/methods are not supported")
925
926        meta = OC_MetaDataTest.ignoreMethod.__metadata__()
927        self.assertIsInstance(meta, dict)
928        self.assertIn('suggestion', meta)
929        self.assertEquals(meta['suggestion'], "please ignore me")
930
931    def testPrintfFormat(self):
932        meta = OC_MetaDataTest.makeArrayWithFormat_.__metadata__()
933        self.assertEquals(meta['variadic'], True)
934        self.assertNotIn('printf_format', meta['arguments'][0])
935        self.assertEquals(meta['arguments'][2]['printf_format'], True)
936
937    def testVariadic(self):
938        meta = OC_MetaDataTest.makeArrayWithFormat_.__metadata__()
939        self.assertEquals(meta['variadic'], True)
940
941        meta = OC_MetaDataTest.ignoreMethod.__metadata__()
942        self.assertEquals(meta['variadic'], False)
943
944    def testTypes(self):
945        meta = OC_MetaDataTest.ignoreMethod.__metadata__()
946        self.assertEquals(meta['retval']['type'], objc._C_INT)
947        self.assertEquals(meta['arguments'][0]['type'], objc._C_ID)
948        self.assertEquals(meta['arguments'][1]['type'], objc._C_SEL)
949
950
951        meta = OC_MetaDataTest.make4Tuple_.__metadata__()
952        self.assertEquals(meta['retval']['type'], objc._C_ID)
953        self.assertEquals(meta['arguments'][0]['type'], objc._C_ID)
954        self.assertEquals(meta['arguments'][1]['type'], objc._C_SEL)
955        self.assertEquals(meta['arguments'][2]['type'], objc._C_IN + objc._C_PTR + objc._C_DBL)
956
957    def testAllowNull(self):
958        meta = OC_MetaDataTest.make4Tuple_.__metadata__()
959        self.assertNotIn('null_accepted', meta['retval'])
960        self.assertNotIn( 'null_accepted', meta['arguments'][0])
961
962        meta = OC_MetaDataTest.make4Tuple_.__metadata__()
963        self.assertEquals(meta['arguments'][2]['null_accepted'], False)
964
965        meta = OC_MetaDataTest.null4Tuple_.__metadata__()
966        self.assertEquals(meta['arguments'][2]['null_accepted'], True)
967
968    def alreadyRetained(self):
969        meta = OC_MetaDataTest.null4Tuple_.__metadata__()
970        self.assertEquals(meta['already_retained'], False)
971
972        meta = OC_MetaDataTest.alloc.__metadata__()
973        self.assertEquals(meta['already_retained'], True)
974
975    def testClassMethod(self):
976        meta = OC_MetaDataTest.alloc.__metadata__()
977        self.assertEquals(meta['classmethod'], True)
978
979        meta = OC_MetaDataTest.pyobjc_instanceMethods.init.__metadata__()
980        self.assertEquals(meta['classmethod'], False)
981
982if sys.version_info[0] == 3:
983    def buffer_as_bytes(v):
984        if isinstance(v, bytes):
985            return v
986        return bytes(v)
987else:
988    def buffer_as_bytes(v):
989        return str(buffer(v))
990
991class TestBuffers (TestCase):
992    # Some tests that check if buffer APIs get sane treatment
993
994    def testInChars(self):
995        o = OC_MetaDataTest.alloc().init()
996
997        v = o.makeDataForBytes_count_(b"hello world", len(b"hello world"))
998        self.assertIsInstance(v, objc.lookUpClass("NSData"))
999
1000        self.assertEquals(v.length(), len(b"hello world"))
1001        self.assertEquals(buffer_as_bytes(v), b"hello world")
1002
1003        v = o.makeDataForBytes_count_(b"hello\0world", len(b"hello\0world"))
1004        self.assertIsInstance(v, objc.lookUpClass("NSData"))
1005
1006        self.assertEquals(v.length(), len(b"hello\0world"))
1007        self.assertEquals(buffer_as_bytes(v), b"hello\0world")
1008
1009        a = array.array('b', b'foobar monday')
1010        v = o.makeDataForBytes_count_(a, len(a))
1011        self.assertIsInstance(v, objc.lookUpClass("NSData"))
1012
1013        self.assertEquals(v.length(), len(a))
1014        self.assertEquals(buffer_as_bytes(v), buffer_as_bytes(a))
1015
1016    def testInVoids(self):
1017        o = OC_MetaDataTest.alloc().init()
1018
1019        v = o.makeDataForBytes_count_(b"hello world", len(b"hello world"))
1020        self.assertIsInstance(v, objc.lookUpClass("NSData"))
1021
1022        self.assertEquals(v.length(), len(b"hello world"))
1023        self.assertEquals(buffer_as_bytes(v), b"hello world")
1024
1025        v = o.makeDataForBytes_count_(b"hello\0world", len(b"hello\0world"))
1026        self.assertIsInstance(v, objc.lookUpClass("NSData"))
1027
1028        self.assertEquals(v.length(), len(b"hello\0world"))
1029        self.assertEquals(buffer_as_bytes(v), b"hello\0world")
1030
1031        a = array.array('b', b'foobar monday')
1032        v = o.makeDataForBytes_count_(a, len(a))
1033        self.assertIsInstance(v, objc.lookUpClass("NSData"))
1034
1035        self.assertEquals(v.length(), len(a))
1036        self.assertEquals(buffer_as_bytes(v), buffer_as_bytes(a))
1037
1038    def testInOutChars(self):
1039        o = OC_MetaDataTest.alloc().init()
1040
1041        input = b"hello " + b"world"
1042        v = o.addOneToBytes_count_(input, len(input))
1043        self.assertIsInstance(v, bytes)
1044
1045        self.assertEquals(input, b"hello world")
1046        self.assertEquals(input[0:5], b"hello")
1047        if sys.version_info[0] == 2:
1048            self.assertEquals(
1049                [ ord(x)+1 for x in input ],
1050                [ ord(x) for x in v ])
1051        else:
1052            self.assertEquals(
1053                [ x+1 for x in input ],
1054                [ x for x in v ])
1055
1056        input = array.array('b', b"hello\0world")
1057        v = o.addOneToBytes_count_(input, len(input))
1058        self.assertIs(v, input)
1059        self.assertNotEquals(input[0:5], b"hello")
1060        if sys.version_info[0] == 2:
1061            self.assertEquals(
1062                [ ord(x)+1 for x in "hello\0world" ],
1063                [ x for x in v ])
1064        else:
1065            self.assertEquals(
1066                [ x+1 for x in b"hello\0world" ],
1067                [ x for x in v ])
1068
1069
1070    def testInOutVoids(self):
1071        o = OC_MetaDataTest.alloc().init()
1072
1073        input = b"hello " + b"world"
1074        v = o.addOneToVoids_count_(input, len(input))
1075        self.assertIsInstance(v, type(b""))
1076
1077        self.assertEquals(input, b"hello world")
1078        self.assertEquals(input[0:5], b"hello")
1079
1080        if sys.version_info[0] == 2:
1081            self.assertEquals(
1082                [ ord(x)+2 for x in input ],
1083                [ ord(x) for x in v ])
1084        else:
1085            self.assertEquals(
1086                [ x+2 for x in input ],
1087                [ x for x in v ])
1088
1089        input = array.array('b', b"hello\0world")
1090        v = o.addOneToVoids_count_(input, len(input))
1091        self.assertIs(v, input)
1092        self.assertNotEquals(input[0:5], b"hello")
1093        if sys.version_info[0] == 2:
1094            self.assertEquals(
1095                [ ord(x)+2 for x in b"hello\0world" ],
1096                [ x for x in v ])
1097        else:
1098            self.assertEquals(
1099                [ x+2 for x in b"hello\0world" ],
1100                [ x for x in v ])
1101
1102    def testOutChars(self):
1103        o = OC_MetaDataTest.alloc().init()
1104
1105        v = o.fillBuffer_count_(None, 44);
1106        self.assertEquals(v, b'\xfe'*44);
1107
1108        a = array.array('b', b'0' * 44)
1109        v = o.fillBuffer_count_(a, 44);
1110        self.assertEquals(buffer_as_bytes(v), b'\xfe'*44);
1111        self.assertIs(v, a)
1112
1113    def testOutVoids(self):
1114        o = OC_MetaDataTest.alloc().init()
1115
1116        v = o.fillVoids_count_(None, 44);
1117        self.assertEquals(v, b'\xab'*44);
1118
1119        if sys.version_info[0] == 2:
1120            a = array.array('c', '0' * 44)
1121        else:
1122            a = array.array('b', (0,) * 44)
1123        v = o.fillVoids_count_(a, 44);
1124        self.assertEquals(buffer_as_bytes(v), b'\xab'*44);
1125        self.assertIs(v, a)
1126
1127class TestVariableLengthValue (TestCase):
1128
1129    def testResult(self):
1130        o = OC_MetaDataTest.alloc().init()
1131
1132        v = o.unknownLengthArray()
1133        self.assertIsInstance(v, objc.varlist)
1134
1135        self.assertEquals(v[0], 1)
1136        self.assertEquals(v[1], 3)
1137        self.assertEquals(v[5], 13)
1138
1139        #self.fail((type(v), v))
1140        #self.fail((v[0:2], type(v[0:2])))
1141        self.assertEquals(v[0:2], (1,3))
1142
1143        self.assertEquals(v.as_tuple(5), (1, 3, 5, 7, 11))
1144        self.assertEquals(v.as_tuple(0), ())
1145        self.assertEquals(v.as_tuple(8), (1, 3, 5, 7, 11, 13, 17, 19))
1146
1147        v = o.unknownLengthMutable()
1148        self.assertIsInstance(v, objc.varlist)
1149
1150        v[1] = 42
1151        self.assertEquals(v[1], 42)
1152        v[0:10] = range(10)
1153        self.assertEquals(v[0], 0)
1154        self.assertEquals(v[5], 5)
1155        self.assertEquals(v[8], 8)
1156
1157    def testInput(self):
1158        o = OC_MetaDataTest.alloc().init()
1159
1160        v = o.makeIntArray_halfCount_((1,2,3,4,5,6), 2)
1161        self.assertEquals(list(v), [1,2,3,4])
1162
1163        # XXX: Hard crash when using o.makeVariableLengthArray_halfCount_???
1164
1165class TestVariadicArray (TestCase):
1166    def testObjects(self):
1167        o = OC_MetaDataTest.alloc().init()
1168
1169        v = o.makeArrayWithArguments_()
1170        self.assertEquals(v, [])
1171
1172        v = o.makeArrayWithArguments_(1, 2, 3)
1173        self.assertEquals(v, [1, 2, 3])
1174
1175        v = o.makeArrayWithArguments_(4, None, 5)
1176        self.assertEquals(v, [4])
1177
1178        v = o.makeArrayWithArguments_(*range(40))
1179        self.assertEquals(v, list(range(40)))
1180
1181if __name__ == "__main__":
1182    main()
1183