]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/py/tests/test_introspect.py
It's now wx._core
[wxWidgets.git] / wxPython / wx / py / tests / test_introspect.py
1 #!/usr/bin/env python
2
3 __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
4 __cvsid__ = "$Id$"
5 __revision__ = "$Revision$"[11:-2]
6
7 import unittest
8
9 # Import from this module's parent directory.
10 import os
11 import sys
12 sys.path.insert(0, os.pardir)
13 import introspect
14 del sys.path[0]
15 del sys
16 del os
17
18
19 """
20 These unittest methods are preferred:
21 -------------------------------------
22 self.assert_(expr, msg=None)
23 self.assertEqual(first, second, msg=None)
24 self.assertRaises(excClass, callableObj, *args, **kwargs)
25 self.fail(msg=None)
26 self.failIf(expr, msg=None)
27 """
28
29
30 class ModuleTestCase(unittest.TestCase):
31
32 def test_module(self):
33 module = introspect
34 self.assert_(module.__author__)
35 self.assert_(module.__cvsid__)
36 self.assert_(module.__revision__)
37 self.assert_(module.getAllAttributeNames)
38 self.assert_(module.getAttributeNames)
39 self.assert_(module.getAutoCompleteList)
40 self.assert_(module.getBaseObject)
41 self.assert_(module.getCallTip)
42 self.assert_(module.getConstructor)
43 self.assert_(module.getRoot)
44 self.assert_(module.rtrimTerminus)
45
46
47 class RtrimTerminusTestCase(unittest.TestCase):
48
49 def test_rtrimTerminus(self):
50 values = (
51 ('', '', ''),
52 ('', None, ''),
53 ('', '.', ''),
54 ('', '(', ''),
55
56 ('.', '', '.'),
57 ('.', None, '.'),
58 ('.', '.', '.'),
59 ('.', '(', '.'),
60
61 ('(', '', '('),
62 ('(', None, '('),
63 ('(', '.', '('),
64 ('(', '(', '('),
65
66 ('spam', '', 'spam'),
67 ('spam', None, 'spam'),
68 ('spam', '.', 'spam'),
69 ('spam', '(', 'spam'),
70
71 ('spam.', '', 'spam.'),
72 ('spam.', None, 'spam.'),
73 ('spam.', '.', 'spam.'),
74 ('spam.', '(', 'spam.'),
75
76 ('spam(', '', 'spam('),
77 ('spam(', None, 'spam('),
78 ('spam(', '.', 'spam('),
79 ('spam(', '(', 'spam('),
80
81 ('spam.eggs', '.', 'spam.'),
82 ('spam.eggs.', '.', 'spam.eggs.'),
83 ('spam.eggs(', '(', 'spam.eggs('),
84 ('spam.eggs.', '(', 'spam.eggs.'),
85 ('spam.eggs(', '.', 'spam.'),
86
87 ('x = spam.', '.', 'x = spam.'),
88 ('x = spam.eggs', '.', 'x = spam.'),
89 ('x = spam.eggs.', '.', 'x = spam.eggs.'),
90 ('x = spam.eggs(', '(', 'x = spam.eggs('),
91 )
92 for input, terminator, output in values:
93 result = introspect.rtrimTerminus(input, terminator)
94 self.assertEqual(result, output,
95 ':in: %r :t: %r :out: %r :result: %r' %
96 (input, terminator, output, result))
97
98
99 class GetRootTestCase(unittest.TestCase):
100
101 def _checkRoot(self, input, terminator, output):
102 root = introspect.getRoot(command=input, terminator=terminator)
103 self.assertEqual(root, output,
104 ':in: %r :t: %r :out: %r :root: %r' %
105 (input, terminator, output, root))
106
107 def test_getRoot(self):
108 values = (
109 ('', '', ''),
110 ('', None, ''),
111 ('', '.', ''),
112 ('', '(', ''),
113
114 ('.', '', '.'),
115 ('.', None, '.'),
116 ('.', '.', ''),
117 ('.', '(', '.'),
118
119 ('(', '', ''),
120 ('(', None, ''),
121 ('(', '.', ''),
122 ('(', '(', ''),
123
124 ('spam', '', 'spam'),
125 ('spam', None, 'spam'),
126 ('spam', '.', ''),
127 ('spam', '(', 'spam'),
128
129 ('spam.', '', 'spam.'),
130 ('spam.', None, 'spam.'),
131 ('spam.', '.', 'spam'),
132 ('spam.', '(', 'spam.'),
133
134 ('spam(', '', ''),
135 ('spam(', None, ''),
136 ('spam(', '.', ''),
137 ('spam(', '(', 'spam'),
138
139 ('spam.eggs', '.', 'spam'),
140 ('spam.eggs.', '.', 'spam.eggs'),
141 ('spam.eggs(', '(', 'spam.eggs'),
142 ('spam.eggs.', '(', 'spam.eggs.'),
143 ('spam.eggs(', '.', 'spam'),
144
145 ('x = spam.', '.', 'spam'),
146 ('x = spam.eggs', '.', 'spam'),
147 ('x = spam.eggs.', '.', 'spam.eggs'),
148 ('x = spam.eggs(', '(', 'spam.eggs'),
149
150 ('for n in range(3):\n d.', '.', 'd'),
151 ('for n in range(3):\n... d.', '.', 'd'),
152 )
153 for input, terminator, output in values:
154 self._checkRoot(input, terminator, output)
155
156 def test_getRoot_Advanced(self):
157 values = (
158 ('spam_', '', 'spam_'),
159 ('spam_', None, 'spam_'),
160 ('spam_', '.', ''),
161 ('spam_', '(', 'spam_'),
162
163 ('_spam', '', '_spam'),
164 ('_spam', None, '_spam'),
165 ('_spam', '.', ''),
166 ('_spam', '(', '_spam'),
167
168 ('spam_eggs', '', 'spam_eggs'),
169 ('spam_eggs', None, 'spam_eggs'),
170 ('spam_eggs', '.', ''),
171 ('spam_eggs', '(', 'spam_eggs'),
172
173 ('spam123', '', 'spam123'),
174 ('spam123', None, 'spam123'),
175 ('spam123', '.', ''),
176 ('spam123', '(', 'spam123'),
177
178 ('spam_123', '', 'spam_123'),
179 ('spam_123', None, 'spam_123'),
180 ('spam_123', '.', ''),
181 ('spam_123', '(', 'spam_123'),
182 )
183 for input, terminator, output in values:
184 self._checkRoot(input, terminator, output)
185
186 ## The original intent was to detect when we were inside a string.
187 ## That has proven to be very difficult, for little benefit.
188 ## The fact that autocomplete or calltips might be triggered inside
189 ## a string is not a big deal. Sometimes it is even helpful.
190
191 ## def test_getRoot_InsideStrings(self):
192 ## values = (
193 ## ('x = ".', '.', ''),
194 ## ("x = '.", '.', ''),
195 ## ('x = """.', '.', ''),
196 ## ("x = '''.", '.', ''),
197 ##
198 ## ('x = "(', '(', ''),
199 ## ("x = '(", '(', ''),
200 ## ('x = """(', '(', ''),
201 ## ("x = '''(", '(', ''),
202 ##
203 ## ('x = "spam', '.', ''),
204 ## ('x = "spam.', '.', ''),
205 ## ("x = 'spam.", '.', ''),
206 ## ('x = """spam.', '.', ''),
207 ## ("x = '''spam.", '.', ''),
208 ##
209 ## ('x = "spam', '(', ''),
210 ## ('x = "spam(', '(', ''),
211 ## ("x = 'spam(", '(', ''),
212 ## ('x = """spam(', '(', ''),
213 ## ("x = '''spam(", '(', ''),
214 ##
215 ## ('x = "spam.eggs.', '.', ''),
216 ## ("x = 'spam.eggs.", '.', ''),
217 ## ('x = """spam.eggs.', '.', ''),
218 ## ("x = '''spam.eggs.", '.', ''),
219 ##
220 ## ('x = "spam.eggs(', '(', ''),
221 ## ("x = 'spam.eggs(", '(', ''),
222 ## ('x = """spam.eggs(', '(', ''),
223 ## ("x = '''spam.eggs(", '(', ''),
224 ## )
225 ## for input, terminator, output in values:
226 ## self._checkRoot(input, terminator, output)
227
228 def test_getRoot_EmptyTypes(self):
229 values = (
230 ("''.", '.', "''"),
231 ('"".', '.', '""'),
232 ('"""""".', '.', '""""""'),
233 ("''''''.", '.', "''''''"),
234
235 ('[].', '.', '[]'),
236 ('().', '.', '()'),
237 ('{}.', '.', '{}'),
238
239 ('[](', '(', '[]'),
240 ('()(', '(', '()'),
241 ('{}(', '(', '{}'),
242
243 ("x = ''.", '.', "''"),
244 ('x = "".', '.', '""'),
245 ('x = """""".', '.', '""""""'),
246 ("x = ''''''.", '.', "''''''"),
247
248 ('x = [].', '.', '[]'),
249 ('x = ().', '.', '()'),
250 ('x = {}.', '.', '{}'),
251
252 ('x = [](', '(', '[]'),
253 ('x = ()(', '(', '()'),
254 ('x = {}(', '(', '{}'),
255
256 ('print [].', '.', '[]'),
257 ('print ().', '.', '()'),
258 ('print {}.', '.', '{}'),
259
260 ('print [](', '(', '[]'),
261 ('print ()(', '(', '()'),
262 ('print {}(', '(', '{}'),
263
264 ("''.attr.", '.', "''.attr"),
265 ('"".attr.', '.', '"".attr'),
266 ('"""""".attr.', '.', '"""""".attr'),
267 ("''''''.attr.", '.', "''''''.attr"),
268
269 ('[].attr.', '.', '[].attr'),
270 ('().attr.', '.', '().attr'),
271 ('{}.attr.', '.', '{}.attr'),
272
273 ('[].attr(', '(', '[].attr'),
274 ('().attr(', '(', '().attr'),
275 ('{}.attr(', '(', '{}.attr'),
276
277 ('spam().', '.', ''),
278 ('spam_().', '.', ''),
279 ('spam5().', '.', ''),
280 ('spam[]().', '.', ''),
281 ('spam()[].', '.', ''),
282 ('spam[]{}.', '.', ''),
283
284 ("spam(''.", '.', "''"),
285 ('spam("".', '.', '""'),
286 ('spam("""""".', '.', '""""""'),
287 ("spam(''''''.", '.', "''''''"),
288
289 ('spam([].', '.', '[]'),
290 ('spam(().', '.', '()'),
291 ('spam({}.', '.', '{}'),
292 ('spam[[].', '.', '[]'),
293 ('spam[().', '.', '()'),
294 ('spam[{}.', '.', '{}'),
295 ('x = {[].', '.', '[]'),
296 ('x = {().', '.', '()'),
297 ('x = {{}.', '.', '{}'),
298
299 ('spam,[].', '.', '[]'),
300 ('spam+[].', '.', '[]'),
301 ('spam-[].', '.', '[]'),
302 ('spam*[].', '.', '[]'),
303 ('spam/[].', '.', '[]'),
304 ('spam=[].', '.', '[]'),
305 ('spam%[].', '.', '[]'),
306 ('spam<[].', '.', '[]'),
307 ('spam>[].', '.', '[]'),
308 ('spam&[].', '.', '[]'),
309 ('spam|[].', '.', '[]'),
310 ('spam^[].', '.', '[]'),
311 ('spam~[].', '.', '[]'),
312 ('spam:[].', '.', '[]'),
313
314 ('spam,().', '.', '()'),
315 ('spam+().', '.', '()'),
316 ('spam-().', '.', '()'),
317 ('spam*().', '.', '()'),
318 ('spam/().', '.', '()'),
319 ('spam=().', '.', '()'),
320 ('spam%().', '.', '()'),
321 ('spam<().', '.', '()'),
322 ('spam>().', '.', '()'),
323 ('spam&().', '.', '()'),
324 ('spam|().', '.', '()'),
325 ('spam^().', '.', '()'),
326 ('spam~().', '.', '()'),
327 ('spam:().', '.', '()'),
328
329 ('spam,{}.', '.', '{}'),
330 ('spam+{}.', '.', '{}'),
331 ('spam-{}.', '.', '{}'),
332 ('spam*{}.', '.', '{}'),
333 ('spam/{}.', '.', '{}'),
334 ('spam={}.', '.', '{}'),
335 ('spam%{}.', '.', '{}'),
336 ('spam<{}.', '.', '{}'),
337 ('spam>{}.', '.', '{}'),
338 ('spam&{}.', '.', '{}'),
339 ('spam|{}.', '.', '{}'),
340 ('spam^{}.', '.', '{}'),
341 ('spam~{}.', '.', '{}'),
342 ('spam:{}.', '.', '{}'),
343 )
344 for input, terminator, output in values:
345 self._checkRoot(input, terminator, output)
346
347
348 # Support for GetBaseObjectTestCase and GetAttributeNamesTestCase.
349
350 class Foo:
351 def __init__(self):
352 pass
353
354 def __del__(self):
355 pass
356
357 def _private(self):
358 pass
359
360 class Bar:
361 pass
362
363 class Spam:
364 def __call__(self):
365 pass
366
367 def foo(self):
368 pass
369
370 def bar(spam):
371 # It shouldn't matter what we call "self".
372 pass
373
374 def eggs(self):
375 pass
376
377 def ham(eggs):
378 pass
379
380 class GetBaseObjectTestCase(unittest.TestCase):
381
382 def test_getBaseObject(self):
383 spam = Spam()
384 eggs = Spam.eggs
385 listappend = [].append
386 spamda = lambda: None
387 values = (
388 ('spam', 'spam', 0),
389 (123, 123, 0),
390 (12.3, 12.3, 0),
391 ([], [], 0),
392 ((), (), 0),
393 ({}, {}, 0),
394 # Builtin function.
395 (len, len, 0),
396 # Builtin method.
397 (listappend, listappend, 0),
398 # User function.
399 (ham, ham, 0),
400 # Byte-compiled code.
401 (ham.func_code, ham.func_code, 0),
402 # Lambda.
403 (spamda, spamda, 0),
404 # Class with init.
405 (Foo, Foo.__init__.im_func, 1),
406 # Class with no init.
407 (Bar, Bar, 0),
408 # Bound method.
409 (spam.foo, spam.foo.im_func, 1),
410 # Bound method with self named something else (spam).
411 (spam.bar, spam.bar.im_func, 1),
412 # Unbound method. (Do not drop the self argument.)
413 (eggs, eggs.im_func, 0),
414 # Callable instance.
415 (spam, spam.__call__.im_func, 1),
416 )
417 for object, baseObject, dropSelf in values:
418 result = introspect.getBaseObject(object)
419 self.assertEqual(result, (baseObject, dropSelf))
420
421
422 class GetAttributeTestCase(unittest.TestCase):
423 """Base class for other test case classes."""
424
425 def setUp(self):
426 self.values = (
427 '__abs__',
428 '__add__',
429 '__and__',
430 '__base__',
431 '__bases__',
432 '__basicsize__',
433 '__builtins__',
434 '__call__',
435 '__class__',
436 '__cmp__',
437 '__coerce__',
438 '__contains__',
439 '__del__',
440 '__delattr__',
441 '__delitem__',
442 '__delslice__',
443 '__dict__',
444 '__dictoffset__',
445 '__div__',
446 '__divmod__',
447 '__doc__',
448 '__eq__',
449 '__file__',
450 '__flags__',
451 '__float__',
452 '__floordiv__',
453 '__ge__',
454 '__get__',
455 '__getattr__',
456 '__getattribute__',
457 '__getitem__',
458 '__getslice__',
459 '__gt__',
460 '__hash__',
461 '__hex__',
462 '__iadd__',
463 '__imul__',
464 '__init__',
465 '__int__',
466 '__invert__',
467 '__itemsize__',
468 '__iter__',
469 '__le__',
470 '__len__',
471 '__long__',
472 '__lshift__',
473 '__lt__',
474 '__mod__',
475 '__module__',
476 '__mro__',
477 '__mul__',
478 '__name__',
479 '__ne__',
480 '__neg__',
481 '__new__',
482 '__nonzero__',
483 '__oct__',
484 '__or__',
485 '__path__',
486 '__pos__',
487 '__pow__',
488 '__radd__',
489 '__rand__',
490 '__rdiv__',
491 '__rdivmod__',
492 '__reduce__',
493 '__repr__',
494 '__rfloordiv__',
495 '__rlshift__',
496 '__rmod__',
497 '__rmul__',
498 '__ror__',
499 '__rpow__',
500 '__rrshift__',
501 '__rshift__',
502 '__rsub__',
503 '__rtruediv__',
504 '__rxor__',
505 '__self__',
506 '__setattr__',
507 '__setitem__',
508 '__setslice__',
509 '__str__',
510 '__sub__',
511 '__subclasses__',
512 '__truediv__',
513 '__warningregistry__',
514 '__weakrefoffset__',
515 '__xor__',
516 'append',
517 'capitalize',
518 'center',
519 'clear',
520 'close',
521 'closed',
522 'co_argcount',
523 'co_cellvars',
524 'co_code',
525 'co_consts',
526 'co_filename',
527 'co_firstlineno',
528 'co_flags',
529 'co_freevars',
530 'co_lnotab',
531 'co_name',
532 'co_names',
533 'co_nlocals',
534 'co_stacksize',
535 'co_varnames',
536 'conjugate',
537 'copy',
538 'count',
539 'decode',
540 'encode',
541 'endswith',
542 'expandtabs',
543 'extend',
544 'fileno',
545 'find',
546 'flush',
547 'func_closure',
548 'func_code',
549 'func_defaults',
550 'func_dict',
551 'func_doc',
552 'func_globals',
553 'func_name',
554 'get',
555 'has_key',
556 'im_class',
557 'im_func',
558 'im_self',
559 'imag',
560 'index',
561 'insert',
562 'isalnum',
563 'isalpha',
564 'isatty',
565 'isdigit',
566 'islower',
567 'isspace',
568 'istitle',
569 'isupper',
570 'items',
571 'iteritems',
572 'iterkeys',
573 'itervalues',
574 'join',
575 'keys',
576 'ljust',
577 'lower',
578 'lstrip',
579 'mode',
580 'mro',
581 'name',
582 'pop',
583 'popitem',
584 'real',
585 'read',
586 'readinto',
587 'readline',
588 'readlines',
589 'remove',
590 'replace',
591 'reverse',
592 'rfind',
593 'rindex',
594 'rjust',
595 'rstrip',
596 'seek',
597 'setdefault',
598 'softspace',
599 'sort',
600 'split',
601 'splitlines',
602 'start',
603 'startswith',
604 'step',
605 'stop',
606 'strip',
607 'swapcase',
608 'tell',
609 'title',
610 'tolist',
611 'translate',
612 'truncate',
613 'update',
614 'upper',
615 'values',
616 'write',
617 'writelines',
618 'xreadlines',
619 )
620
621 # Since getAllAttributeNames() calls str(object),
622 # we need to test for a broken __str__ method.
623 class BrokenStr:
624 def __str__(self):
625 raise Exception
626
627 brokenStr = BrokenStr()
628
629 class GetAttributeNamesTestCase(GetAttributeTestCase):
630
631 def setUp(self):
632 GetAttributeTestCase.setUp(self)
633 from wx import py
634 spam = Spam()
635 self.f = open('test_introspect.py')
636 self.items = (
637 None,
638 int(123),
639 long(123),
640 float(123),
641 complex(123),
642 "",
643 unicode(""),
644 [],
645 (),
646 xrange(0),
647 {},
648 # Builtin function.
649 len,
650 # Builtin method.
651 [].append,
652 # User function.
653 ham,
654 # Byte-compiled code.
655 ham.func_code,
656 # Lambda.
657 lambda: None,
658 # Class with no init.
659 Bar,
660 # Instance with no init.
661 Bar(),
662 # Class with init and del.
663 Foo,
664 # Instance with init and del.
665 Foo(),
666 # Bound method.
667 spam.foo,
668 # Unbound method.
669 Spam.eggs,
670 # Callable instance.
671 spam,
672 # Module.
673 introspect,
674 # Package.
675 py,
676 # Buffer.
677 buffer(''),
678 # File.
679 self.f,
680 # Slice.
681 slice(0),
682 # Ellipsis.
683 Ellipsis,
684 # BrokenStr class.
685 BrokenStr,
686 # BrokenStr instance.
687 brokenStr,
688 )
689
690 def tearDown(self):
691 self.items = None
692 self.f.close()
693
694 def test_getAttributeNames(self):
695 for item in self.items:
696 self._checkAttributeNames(item)
697 if __builtins__.has_key('object'):
698 self._checkAttributeNames(object)
699
700 def test_getAttributeNames_NoSingle(self):
701 for item in self.items:
702 result = introspect.getAttributeNames(item, includeSingle=0)
703 attributes = [attribute for attribute in result \
704 if attribute[0] != '_' or attribute[:2] == '__']
705 self.assertEqual(result, attributes,
706 ':item: %r' % (item,))
707
708 def test_getAttributeNames_NoDouble(self):
709 for item in self.items:
710 result = introspect.getAttributeNames(item, includeDouble=0)
711 attributes = [attribute for attribute in result \
712 if attribute[:2] != '__']
713 self.assertEqual(result, attributes,
714 ':item: %r' % (item,))
715
716 def test_getAttributeNames_NoSingleOrDouble(self):
717 for item in self.items:
718 result = introspect.getAttributeNames(item, includeSingle=0,
719 includeDouble=0)
720 attributes = [attribute for attribute in result \
721 if attribute[0] != '_']
722 self.assertEqual(result, attributes,
723 ':item: %r' % (item,))
724
725 def _checkAttributeNames(self, item):
726 result = introspect.getAttributeNames(item)
727 attributes = [attribute for attribute in self.values \
728 if hasattr(item, attribute)]
729 for attribute in attributes:
730 self.assert_(attribute in result,
731 ':item: %r :attribute: %r' % (item, attribute))
732
733
734 class GetAutoCompleteListTestCase(GetAttributeTestCase):
735
736 def setUp(self):
737 GetAttributeTestCase.setUp(self)
738 self.items = (
739 'None.',
740 '123 .',
741 '"".',
742 '[].',
743 '().',
744 '{}.',
745 # Builtin function.
746 'len.',
747 # Builtin method.
748 '[].append.',
749 )
750
751 def test_getAutoCompleteList(self):
752 for item in self.items:
753 result = introspect.getAutoCompleteList(item)
754 object = eval(item[:-1])
755 attributes = [attribute for attribute in self.values \
756 if hasattr(object, attribute)]
757 for attribute in attributes:
758 self.assert_(attribute in result,
759 ':item: %r :attribute: %r' % (item, attribute))
760
761 def test_getAutoCompleteList_NoSingle(self):
762 for item in self.items:
763 result = introspect.getAutoCompleteList(item, includeSingle=0)
764 attributes = [attribute for attribute in result \
765 if attribute[0] != '_' or attribute[:2] == '__']
766 self.assertEqual(result, attributes,
767 ':item: %r' % (item,))
768
769 def test_getAutoCompleteList_NoDouble(self):
770 for item in self.items:
771 result = introspect.getAutoCompleteList(item, includeDouble=0)
772 attributes = [attribute for attribute in result \
773 if attribute[:2] != '__']
774 self.assertEqual(result, attributes,
775 ':item: %r' % (item,))
776
777 def test_getAutoCompleteList_NoSingleOrDouble(self):
778 for item in self.items:
779 result = introspect.getAutoCompleteList(item, includeSingle=0,
780 includeDouble=0)
781 attributes = [attribute for attribute in result \
782 if attribute[0] != '_']
783 self.assertEqual(result, attributes,
784 ':item: %r' % (item,))
785
786
787 # Support for GetConstructorTestCase.
788
789 class A1:
790 def __init__(self, a):
791 self.a = a
792
793 class B1(A1):
794 def __init__(self, b):
795 self.b = b
796
797 class C1(A1):
798 pass
799
800 class D1(C1, B1):
801 pass
802
803 if __builtins__.has_key('object'):
804 class A2(object):
805 def __init__(self, a):
806 self.a = a
807
808 class B2(A2):
809 def __init__(self, b):
810 self.b = b
811
812 class C2(A2):
813 pass
814
815 class D2(C2, B2):
816 pass
817
818 class N:
819 pass
820
821 class O:
822 def __init__(self, a, b=2, *args, **kwargs):
823 pass
824
825 class P(O):
826 pass
827
828 class Q(P):
829 def __init__(self, c, d=4):
830 pass
831
832 class GetConstructorTestCase(unittest.TestCase):
833
834 def test_getConstructor(self):
835 args = ('self', 'a', 'b', 'args', 'kwargs')
836 varnames = introspect.getConstructor(O).func_code.co_varnames
837 self.assertEqual(varnames, args)
838 varnames = introspect.getConstructor(P).func_code.co_varnames
839 self.assertEqual(varnames, args)
840 args = ('self', 'c', 'd')
841 varnames = introspect.getConstructor(Q).func_code.co_varnames
842 self.assertEqual(varnames, args)
843
844 def test_getConstructor_None(self):
845 values = (N, 1, 'spam', {}, [], (), dir)
846 for value in values:
847 self.assertEqual(introspect.getConstructor(N), None)
848
849 def test_getConstructor_MultipleInheritance(self):
850 # Test old style inheritance rules.
851 args = ('self', 'a')
852 varnames = introspect.getConstructor(D1).func_code.co_varnames
853 self.assertEqual(varnames, args)
854 if __builtins__.has_key('object'):
855 # Test new style inheritance rules as well.
856 args = ('self', 'b')
857 varnames = introspect.getConstructor(D2).func_code.co_varnames
858 self.assertEqual(varnames, args)
859
860
861 if __name__ == '__main__':
862 unittest.main()