10a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport re
20a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport sys
30a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport types
40a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport unittest
50a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport inspect
60a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport linecache
70a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport datetime
80a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom UserList import UserList
90a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom UserDict import UserDict
100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
110a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom test.test_support import run_unittest, check_py3k_warnings
120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
130a8c90248264a8b26970b4473770bcc3df8515fJosh Gaowith check_py3k_warnings(
140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        ("tuple parameter unpacking has been removed", SyntaxWarning),
150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        quiet=True):
160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    from test import inspect_fodder as mod
170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    from test import inspect_fodder2 as mod2
180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# C module for test_findsource_binary
200a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport unicodedata
210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Functions tested in this suite:
230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# getclasstree, getargspec, getargvalues, formatargspec, formatargvalues,
270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# currentframe, stack, trace, isdatadescriptor
280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# NOTE: There are some additional tests relating to interaction with
300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#       zipimport in the test_zipimport_support test module.
310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
320a8c90248264a8b26970b4473770bcc3df8515fJosh Gaomodfile = mod.__file__
330a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif modfile.endswith(('c', 'o')):
340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    modfile = modfile[:-1]
350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
360a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport __builtin__
370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
380a8c90248264a8b26970b4473770bcc3df8515fJosh Gaotry:
390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    1 // 0
400a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoexcept:
410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    tb = sys.exc_traceback
420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
430a8c90248264a8b26970b4473770bcc3df8515fJosh Gaogit = mod.StupidGit()
440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
450a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass IsTestBase(unittest.TestCase):
460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                      inspect.isframe, inspect.isfunction, inspect.ismethod,
480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                      inspect.ismodule, inspect.istraceback,
490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                      inspect.isgenerator, inspect.isgeneratorfunction])
500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def istest(self, predicate, exp):
520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        obj = eval(exp)
530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for other in self.predicates - set([predicate]):
560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if predicate == inspect.isgeneratorfunction and\
570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao               other == inspect.isfunction:
580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                continue
590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
610a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef generator_function_example(self):
620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    for i in xrange(2):
630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        yield i
640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
650a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestPredicates(IsTestBase):
660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_sixteen(self):
670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        count = len(filter(lambda x:x.startswith('is'), dir(inspect)))
680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # This test is here for remember you to update Doc/library/inspect.rst
690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # which claims there are 16 such functions
700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected = 16
710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        err_msg = "There are %d (not %d) is* functions" % (count, expected)
720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(count, expected, err_msg)
730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_excluding_predicates(self):
760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.istest(inspect.isbuiltin, 'sys.exit')
770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.istest(inspect.isbuiltin, '[].append')
780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.istest(inspect.iscode, 'mod.spam.func_code')
790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.istest(inspect.isframe, 'tb.tb_frame')
800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.istest(inspect.isfunction, 'mod.spam')
810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.istest(inspect.ismethod, 'mod.StupidGit.abuse')
820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.istest(inspect.ismethod, 'git.argue')
830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.istest(inspect.ismodule, 'mod')
840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.istest(inspect.istraceback, 'tb')
850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.istest(inspect.isdatadescriptor, '__builtin__.file.closed')
860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.istest(inspect.isdatadescriptor, '__builtin__.file.softspace')
870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.istest(inspect.isgenerator, '(x for x in xrange(2))')
880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.istest(inspect.isgeneratorfunction, 'generator_function_example')
890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if hasattr(types, 'GetSetDescriptorType'):
900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.istest(inspect.isgetsetdescriptor,
910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        'type(tb.tb_frame).f_locals')
920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if hasattr(types, 'MemberDescriptorType'):
950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_isroutine(self):
1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(inspect.isroutine(mod.spam))
1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(inspect.isroutine([].count))
1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_isclass(self):
1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.istest(inspect.isclass, 'mod.StupidGit')
1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(inspect.isclass(list))
1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class newstyle(object): pass
1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(inspect.isclass(newstyle))
1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class CustomGetattr(object):
1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def __getattr__(self, attr):
1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return None
1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertFalse(inspect.isclass(CustomGetattr()))
1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_get_slot_members(self):
1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class C(object):
1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            __slots__ = ("a", "b")
1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        x = C()
1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        x.a = 42
1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        members = dict(inspect.getmembers(x))
1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn('a', members)
1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertNotIn('b', members)
1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_isabstract(self):
1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        from abc import ABCMeta, abstractmethod
1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class AbstractClassExample(object):
1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            __metaclass__ = ABCMeta
1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            @abstractmethod
1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def foo(self):
1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                pass
1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class ClassExample(AbstractClassExample):
1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def foo(self):
1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                pass
1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a = ClassExample()
1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test general behaviour.
1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(inspect.isabstract(AbstractClassExample))
1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertFalse(inspect.isabstract(ClassExample))
1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertFalse(inspect.isabstract(a))
1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertFalse(inspect.isabstract(int))
1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertFalse(inspect.isabstract(5))
1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestInterpreterStack(IsTestBase):
1500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, *args, **kwargs):
1510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        unittest.TestCase.__init__(self, *args, **kwargs)
1520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        git.abuse(7, 8, 9)
1540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_abuse_done(self):
1560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.istest(inspect.istraceback, 'git.ex[2]')
1570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.istest(inspect.isframe, 'mod.fr')
1580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_stack(self):
1600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(len(mod.st) >= 5)
1610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(mod.st[0][1:],
1620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao             (modfile, 16, 'eggs', ['    st = inspect.stack()\n'], 0))
1630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(mod.st[1][1:],
1640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao             (modfile, 9, 'spam', ['    eggs(b + d, c + f)\n'], 0))
1650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(mod.st[2][1:],
1660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao             (modfile, 43, 'argue', ['            spam(a, b, c)\n'], 0))
1670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(mod.st[3][1:],
1680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao             (modfile, 39, 'abuse', ['        self.argue(a, b, c)\n'], 0))
1690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_trace(self):
1710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(len(git.tr), 3)
1720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(git.tr[0][1:], (modfile, 43, 'argue',
1730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                         ['            spam(a, b, c)\n'], 0))
1740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(git.tr[1][1:], (modfile, 9, 'spam',
1750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                         ['    eggs(b + d, c + f)\n'], 0))
1760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(git.tr[2][1:], (modfile, 18, 'eggs',
1770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                         ['    q = y // 0\n'], 0))
1780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_frame(self):
1800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
1810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(args, ['x', 'y'])
1820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(varargs, None)
1830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(varkw, None)
1840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
1850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
1860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         '(x=11, y=14)')
1870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_previous_frame(self):
1890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
1900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(args, ['a', 'b', 'c', 'd', ['e', ['f']]])
1910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(varargs, 'g')
1920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(varkw, 'h')
1930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
1940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao             '(a=7, b=8, c=9, d=3, (e=4, (f=5,)), *g=(), **h={})')
1950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1960a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass GetSourceBase(unittest.TestCase):
1970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Subclasses must override.
1980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fodderFile = None
1990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, *args, **kwargs):
2010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        unittest.TestCase.__init__(self, *args, **kwargs)
2020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        with open(inspect.getsourcefile(self.fodderFile)) as fp:
2040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.source = fp.read()
2050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def sourcerange(self, top, bottom):
2070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        lines = self.source.split("\n")
2080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return "\n".join(lines[top-1:bottom]) + "\n"
2090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def assertSourceEqual(self, obj, top, bottom):
2110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.getsource(obj),
2120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         self.sourcerange(top, bottom))
2130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2140a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestRetrievingSourceCode(GetSourceBase):
2150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fodderFile = mod
2160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_getclasses(self):
2180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        classes = inspect.getmembers(mod, inspect.isclass)
2190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(classes,
2200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         [('FesteringGob', mod.FesteringGob),
2210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          ('MalodorousPervert', mod.MalodorousPervert),
2220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          ('ParrotDroppings', mod.ParrotDroppings),
2230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          ('StupidGit', mod.StupidGit)])
2240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        tree = inspect.getclasstree([cls[1] for cls in classes], 1)
2250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(tree,
2260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         [(mod.ParrotDroppings, ()),
2270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          (mod.StupidGit, ()),
2280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          [(mod.MalodorousPervert, (mod.StupidGit,)),
2290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           [(mod.FesteringGob, (mod.MalodorousPervert,
2300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                                   mod.ParrotDroppings))
2310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            ]
2320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                           ]
2330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                          ])
2340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_getfunctions(self):
2360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        functions = inspect.getmembers(mod, inspect.isfunction)
2370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(functions, [('eggs', mod.eggs),
2380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                     ('spam', mod.spam)])
2390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @unittest.skipIf(sys.flags.optimize >= 2,
2410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                     "Docstrings are omitted with -O2 and above")
2420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_getdoc(self):
2430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
2440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.getdoc(mod.StupidGit),
2450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         'A longer,\n\nindented\n\ndocstring.')
2460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.getdoc(git.abuse),
2470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         'Another\n\ndocstring\n\ncontaining\n\ntabs')
2480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_cleandoc(self):
2500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.cleandoc('An\n    indented\n    docstring.'),
2510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                         'An\nindented\ndocstring.')
2520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_getcomments(self):
2540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.getcomments(mod), '# line 1\n')
2550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
2560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_getmodule(self):
2580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Check actual module
2590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.getmodule(mod), mod)
2600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Check class (uses __module__ attribute)
2610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
2620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Check a method (no __module__ attribute, falls back to filename)
2630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
2640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Do it again (check the caching isn't broken)
2650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
2660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Check a builtin
2670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.getmodule(str), sys.modules["__builtin__"])
2680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Check filename override
2690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.getmodule(None, modfile), mod)
2700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_getsource(self):
2720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertSourceEqual(git.abuse, 29, 39)
2730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertSourceEqual(mod.StupidGit, 21, 46)
2740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_getsourcefile(self):
2760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.getsourcefile(mod.spam), modfile)
2770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.getsourcefile(git.abuse), modfile)
2780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fn = "_non_existing_filename_used_for_sourcefile_test.py"
2790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        co = compile("None", fn, "exec")
2800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.getsourcefile(co), None)
2810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
2820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.getsourcefile(co), fn)
2830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_getfile(self):
2850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
2860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_getmodule_recursion(self):
2880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        from types import ModuleType
2890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        name = '__inspect_dummy'
2900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        m = sys.modules[name] = ModuleType(name)
2910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        m.__file__ = "<string>" # hopefully not a real filename...
2920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        m.__loader__ = "dummy"  # pretend the filename is understood by a loader
2930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        exec "def x(): pass" in m.__dict__
2940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.getsourcefile(m.x.func_code), '<string>')
2950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        del sys.modules[name]
2960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        inspect.getmodule(compile('a=10','','single'))
2970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_proceed_with_fake_filename(self):
2990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        '''doctest monkeypatches linecache to enable inspection'''
3000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        fn, source = '<test>', 'def x(): pass\n'
3010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        getlines = linecache.getlines
3020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def monkey(filename, module_globals=None):
3030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if filename == fn:
3040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return source.splitlines(True)
3050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
3060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return getlines(filename, module_globals)
3070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        linecache.getlines = monkey
3080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
3090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ns = {}
3100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            exec compile(source, fn, 'single') in ns
3110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            inspect.getsource(ns["x"])
3120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        finally:
3130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            linecache.getlines = getlines
3140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3150a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestDecorators(GetSourceBase):
3160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fodderFile = mod2
3170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_wrapped_decorator(self):
3190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertSourceEqual(mod2.wrapped, 14, 17)
3200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_replacing_decorator(self):
3220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertSourceEqual(mod2.gone, 9, 10)
3230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3240a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestOneliners(GetSourceBase):
3250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fodderFile = mod2
3260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_oneline_lambda(self):
3270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test inspect.getsource with a one-line lambda function.
3280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertSourceEqual(mod2.oll, 25, 25)
3290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_threeline_lambda(self):
3310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test inspect.getsource with a three-line lambda function,
3320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # where the second and third lines are _not_ indented.
3330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertSourceEqual(mod2.tll, 28, 30)
3340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_twoline_indented_lambda(self):
3360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test inspect.getsource with a two-line lambda function,
3370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # where the second line _is_ indented.
3380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertSourceEqual(mod2.tlli, 33, 34)
3390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_onelinefunc(self):
3410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test inspect.getsource with a regular one-line function.
3420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertSourceEqual(mod2.onelinefunc, 37, 37)
3430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_manyargs(self):
3450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test inspect.getsource with a regular function where
3460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # the arguments are on two lines and _not_ indented and
3470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # the body on the second line with the last arguments.
3480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertSourceEqual(mod2.manyargs, 40, 41)
3490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_twolinefunc(self):
3510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test inspect.getsource with a regular function where
3520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # the body is on two lines, following the argument list and
3530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # continued on the next line by a \\.
3540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertSourceEqual(mod2.twolinefunc, 44, 45)
3550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_lambda_in_list(self):
3570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test inspect.getsource with a one-line lambda function
3580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # defined in a list, indented.
3590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertSourceEqual(mod2.a[1], 49, 49)
3600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_anonymous(self):
3620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test inspect.getsource with a lambda function defined
3630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # as argument to another function.
3640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertSourceEqual(mod2.anonymous, 55, 55)
3650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3660a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestBuggyCases(GetSourceBase):
3670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fodderFile = mod2
3680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_with_comment(self):
3700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertSourceEqual(mod2.with_comment, 58, 59)
3710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_multiline_sig(self):
3730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
3740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_nested_class(self):
3760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertSourceEqual(mod2.func69().func71, 71, 72)
3770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_one_liner_followed_by_non_name(self):
3790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertSourceEqual(mod2.func77, 77, 77)
3800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_one_liner_dedent_non_name(self):
3820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertSourceEqual(mod2.cls82.func83, 83, 83)
3830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_with_comment_instead_of_docstring(self):
3850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertSourceEqual(mod2.func88, 88, 90)
3860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_method_in_dynamic_class(self):
3880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
3890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    @unittest.skipIf(
3910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        not hasattr(unicodedata, '__file__') or
3920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            unicodedata.__file__[-4:] in (".pyc", ".pyo"),
3930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        "unicodedata is not an external binary module")
3940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_findsource_binary(self):
3950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(IOError, inspect.getsource, unicodedata)
3960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(IOError, inspect.findsource, unicodedata)
3970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_findsource_code_in_linecache(self):
3990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        lines = ["x=1"]
4000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        co = compile(lines[0], "_dynamically_created_file", "exec")
4010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(IOError, inspect.findsource, co)
4020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(IOError, inspect.getsource, co)
4030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
4040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.findsource(co), (lines,0))
4050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(inspect.getsource(co), lines[0])
4060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_findsource_without_filename(self):
4080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for fname in ['', '<string>']:
4090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            co = compile('x=1', fname, "exec")
4100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(IOError, inspect.findsource, co)
4110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(IOError, inspect.getsource, co)
4120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4140a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass _BrokenDataDescriptor(object):
4150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
4160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    A broken data descriptor. See bug #1785.
4170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
4180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __get__(*args):
4190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise AssertionError("should not __get__ data descriptors")
4200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __set__(*args):
4220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise RuntimeError
4230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __getattr__(*args):
4250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise AssertionError("should not __getattr__ data descriptors")
4260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4280a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass _BrokenMethodDescriptor(object):
4290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
4300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    A broken method descriptor. See bug #1785.
4310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
4320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __get__(*args):
4330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise AssertionError("should not __get__ method descriptors")
4340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __getattr__(*args):
4360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise AssertionError("should not __getattr__ method descriptors")
4370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Helper for testing classify_class_attrs.
4400a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef attrs_wo_objs(cls):
4410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return [t[:3] for t in inspect.classify_class_attrs(cls)]
4420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4440a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestClassesAndFunctions(unittest.TestCase):
4450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_classic_mro(self):
4460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Test classic-class method resolution order.
4470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class A:    pass
4480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class B(A): pass
4490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class C(A): pass
4500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class D(B, C): pass
4510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected = (D, B, A, C)
4530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        got = inspect.getmro(D)
4540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(expected, got)
4550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_newstyle_mro(self):
4570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # The same w/ new-class MRO.
4580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class A(object):    pass
4590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class B(A): pass
4600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class C(A): pass
4610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class D(B, C): pass
4620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        expected = (D, B, C, A, object)
4640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        got = inspect.getmro(D)
4650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(expected, got)
4660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def assertArgSpecEquals(self, routine, args_e, varargs_e = None,
4680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            varkw_e = None, defaults_e = None,
4690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            formatted = None):
4700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        args, varargs, varkw, defaults = inspect.getargspec(routine)
4710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(args, args_e)
4720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(varargs, varargs_e)
4730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(varkw, varkw_e)
4740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(defaults, defaults_e)
4750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if formatted is not None:
4760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
4770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             formatted)
4780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_getargspec(self):
4800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted = '(x, y)')
4810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertArgSpecEquals(mod.spam,
4830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                 ['a', 'b', 'c', 'd', ['e', ['f']]],
4840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                 'g', 'h', (3, (4, (5,))),
4850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                 '(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)')
4860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_getargspec_method(self):
4880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class A(object):
4890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def m(self):
4900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                pass
4910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertArgSpecEquals(A.m, ['self'])
4920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_getargspec_sublistofone(self):
4940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        with check_py3k_warnings(
4950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ("tuple parameter unpacking has been removed", SyntaxWarning),
4960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                ("parenthesized argument names are invalid", SyntaxWarning)):
4970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            exec 'def sublistOfOne((foo,)): return 1'
4980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertArgSpecEquals(sublistOfOne, [['foo']])
4990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            exec 'def fakeSublistOfOne((foo)): return 1'
5010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertArgSpecEquals(fakeSublistOfOne, ['foo'])
5020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def _classify_test(self, newstyle):
5050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """Helper for testing that classify_class_attrs finds a bunch of
5060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        different kinds of attributes on a given class.
5070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if newstyle:
5090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            base = object
5100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
5110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            class base:
5120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                pass
5130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class A(base):
5150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def s(): pass
5160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            s = staticmethod(s)
5170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def c(cls): pass
5190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            c = classmethod(c)
5200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def getp(self): pass
5220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            p = property(getp)
5230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def m(self): pass
5250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def m1(self): pass
5270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            datablob = '1'
5290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            dd = _BrokenDataDescriptor()
5310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            md = _BrokenMethodDescriptor()
5320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        attrs = attrs_wo_objs(A)
5340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('s', 'static method', A), attrs, 'missing static method')
5350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('c', 'class method', A), attrs, 'missing class method')
5360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('p', 'property', A), attrs, 'missing property')
5370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('m', 'method', A), attrs, 'missing plain method')
5380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
5390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('datablob', 'data', A), attrs, 'missing data')
5400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
5410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
5420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class B(A):
5440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def m(self): pass
5450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        attrs = attrs_wo_objs(B)
5470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('s', 'static method', A), attrs, 'missing static method')
5480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('c', 'class method', A), attrs, 'missing class method')
5490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('p', 'property', A), attrs, 'missing property')
5500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('m', 'method', B), attrs, 'missing plain method')
5510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
5520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('datablob', 'data', A), attrs, 'missing data')
5530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
5540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
5550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class C(A):
5580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def m(self): pass
5590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def c(self): pass
5600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        attrs = attrs_wo_objs(C)
5620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('s', 'static method', A), attrs, 'missing static method')
5630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('c', 'method', C), attrs, 'missing plain method')
5640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('p', 'property', A), attrs, 'missing property')
5650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('m', 'method', C), attrs, 'missing plain method')
5660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
5670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('datablob', 'data', A), attrs, 'missing data')
5680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
5690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
5700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class D(B, C):
5720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def m1(self): pass
5730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        attrs = attrs_wo_objs(D)
5750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('s', 'static method', A), attrs, 'missing static method')
5760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if newstyle:
5770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertIn(('c', 'method', C), attrs, 'missing plain method')
5780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
5790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertIn(('c', 'class method', A), attrs, 'missing class method')
5800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('p', 'property', A), attrs, 'missing property')
5810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('m', 'method', B), attrs, 'missing plain method')
5820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
5830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('datablob', 'data', A), attrs, 'missing data')
5840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
5850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
5860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_classify_oldstyle(self):
5890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """classify_class_attrs finds static methods, class methods,
5900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        properties, normal methods, and data attributes on an old-style
5910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class.
5920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._classify_test(False)
5940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_classify_newstyle(self):
5970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """Just like test_classify_oldstyle, but for a new-style class.
5980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._classify_test(True)
6000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_classify_builtin_types(self):
6020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Simple sanity check that all built-in types can have their
6030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # attributes classified.
6040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for name in dir(__builtin__):
6050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            builtin = getattr(__builtin__, name)
6060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if isinstance(builtin, type):
6070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                inspect.classify_class_attrs(builtin)
6080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_getmembers_method(self):
6100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Old-style classes
6110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class B:
6120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def f(self):
6130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                pass
6140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('f', B.f), inspect.getmembers(B))
6160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # contrary to spec, ismethod() is also True for unbound methods
6170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # (see #1785)
6180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
6190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        b = B()
6200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('f', b.f), inspect.getmembers(b))
6210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
6220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # New-style classes
6240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class B(object):
6250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def f(self):
6260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                pass
6270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('f', B.f), inspect.getmembers(B))
6290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
6300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        b = B()
6310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('f', b.f), inspect.getmembers(b))
6320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
6330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6350a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestGetcallargsFunctions(unittest.TestCase):
6360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # tuple parameters are named '.1', '.2', etc.
6380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    is_tuplename = re.compile(r'^\.\d+$').match
6390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def assertEqualCallArgs(self, func, call_params_string, locs=None):
6410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        locs = dict(locs or {}, func=func)
6420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        r1 = eval('func(%s)' % call_params_string, None, locs)
6430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
6440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                  locs)
6450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(r1, r2)
6460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def assertEqualException(self, func, call_param_string, locs=None):
6480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        locs = dict(locs or {}, func=func)
6490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
6500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            eval('func(%s)' % call_param_string, None, locs)
6510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        except Exception, ex1:
6520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
6530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
6540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fail('Exception not raised')
6550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
6560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            eval('inspect.getcallargs(func, %s)' % call_param_string, None,
6570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                 locs)
6580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        except Exception, ex2:
6590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
6600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
6610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.fail('Exception not raised')
6620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertIs(type(ex1), type(ex2))
6630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(str(ex1), str(ex2))
6640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def makeCallable(self, signature):
6660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """Create a function that returns its locals(), excluding the
6670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        autogenerated '.1', '.2', etc. tuple param names (if any)."""
6680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        with check_py3k_warnings(
6690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ("tuple parameter unpacking has been removed", SyntaxWarning),
6700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            quiet=True):
6710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            code = ("lambda %s: dict(i for i in locals().items() "
6720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    "if not is_tuplename(i[0]))")
6730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return eval(code % signature, {'is_tuplename' : self.is_tuplename})
6740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_plain(self):
6760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = self.makeCallable('a, b=1')
6770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '2')
6780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '2, 3')
6790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, 'a=2')
6800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, 'b=3, a=2')
6810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '2, b=3')
6820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # expand *iterable / **mapping
6830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '*(2,)')
6840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '*[2]')
6850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '*(2, 3)')
6860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '*[2, 3]')
6870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '**{"a":2}')
6880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
6890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '2, **{"b":3}')
6900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
6910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # expand UserList / UserDict
6920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '*UserList([2])')
6930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '*UserList([2, 3])')
6940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '**UserDict(a=2)')
6950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '2, **UserDict(b=3)')
6960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, 'b=2, **UserDict(a=3)')
6970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # unicode keyword args
6980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '**{u"a":2}')
6990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, 'b=3, **{u"a":2}')
7000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '2, **{u"b":3}')
7010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '**{u"b":3, u"a":2}')
7020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_varargs(self):
7040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = self.makeCallable('a, b=1, *c')
7050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '2')
7060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '2, 3')
7070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '2, 3, 4')
7080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '*(2,3,4)')
7090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '2, *[3,4]')
7100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '2, 3, *UserList([4])')
7110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_varkw(self):
7130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = self.makeCallable('a, b=1, **c')
7140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, 'a=2')
7150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '2, b=3, c=4')
7160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
7170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
7180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
7190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
7200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '**UserDict(a=2, b=3, c=4)')
7210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '2, c=4, **UserDict(b=3)')
7220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, 'b=2, **UserDict(a=3, c=4)')
7230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # unicode keyword args
7240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, 'c=4, **{u"a":2, u"b":3}')
7250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '2, c=4, **{u"b":3}')
7260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, 'b=2, **{u"a":3, u"c":4}')
7270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_varkw_only(self):
7290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # issue11256:
7300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = self.makeCallable('**c')
7310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '')
7320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, 'a=1')
7330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, 'a=1, b=2')
7340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
7350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '**UserDict(a=1, b=2)')
7360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, 'c=3, **UserDict(a=1, b=2)')
7370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_tupleargs(self):
7390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = self.makeCallable('(b,c), (d,(e,f))=(0,[1,2])')
7400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '(2,3)')
7410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '[2,3]')
7420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, 'UserList([2,3])')
7430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '(2,3), (4,(5,6))')
7440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '(2,3), (4,[5,6])')
7450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '(2,3), [4,UserList([5,6])]')
7460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_multiple_features(self):
7480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = self.makeCallable('a, b=2, (c,(d,e))=(3,[4,5]), *f, **g')
7490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '2, 3, (4,[5,6]), 7')
7500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '2, 3, *[(4,[5,6]), 7], x=8')
7510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
7520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
7530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
7540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, 'x=8, *UserList([2, 3, (4,[5,6])]), '
7550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                 '**{"y":9, "z":10}')
7560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualCallArgs(f, '2, x=8, *UserList([3, (4,[5,6])]), '
7570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                 '**UserDict(y=9, z=10)')
7580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_errors(self):
7600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f0 = self.makeCallable('')
7610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f1 = self.makeCallable('a, b')
7620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f2 = self.makeCallable('a, b=1')
7630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # f0 takes no arguments
7640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualException(f0, '1')
7650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualException(f0, 'x=1')
7660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualException(f0, '1,x=1')
7670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # f1 takes exactly 2 arguments
7680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualException(f1, '')
7690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualException(f1, '1')
7700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualException(f1, 'a=2')
7710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualException(f1, 'b=3')
7720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # f2 takes at least 1 argument
7730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualException(f2, '')
7740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualException(f2, 'b=3')
7750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for f in f1, f2:
7760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # f1/f2 takes exactly/at most 2 arguments
7770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqualException(f, '2, 3, 4')
7780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqualException(f, '1, 2, 3, a=1')
7790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqualException(f, '2, 3, 4, c=5')
7800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqualException(f, '2, 3, 4, a=1, c=5')
7810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # f got an unexpected keyword argument
7820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqualException(f, 'c=2')
7830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqualException(f, '2, c=3')
7840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqualException(f, '2, 3, c=4')
7850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqualException(f, '2, c=4, b=3')
7860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
7870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # f got multiple values for keyword argument
7880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqualException(f, '1, a=2')
7890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqualException(f, '1, **{"a":2}')
7900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqualException(f, '1, 2, b=3')
7910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # XXX: Python inconsistency
7920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # - for functions and bound methods: unexpected keyword 'c'
7930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # - for unbound methods: multiple values for keyword 'a'
7940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            #self.assertEqualException(f, '1, c=3, a=2')
7950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = self.makeCallable('(a,b)=(0,1)')
7960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualException(f, '1')
7970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualException(f, '[1]')
7980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualException(f, '(1,2,3)')
7990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # issue11256:
8000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f3 = self.makeCallable('**c')
8010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualException(f3, '1, 2')
8020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqualException(f3, '1, 2, a=1, b=2')
8030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8040a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestGetcallargsMethods(TestGetcallargsFunctions):
8050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def setUp(self):
8070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class Foo(object):
8080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            pass
8090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.cls = Foo
8100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.inst = Foo()
8110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def makeCallable(self, signature):
8130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        assert 'self' not in signature
8140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        mk = super(TestGetcallargsMethods, self).makeCallable
8150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.cls.method = mk('self, ' + signature)
8160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.inst.method
8170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8180a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass TestGetcallargsUnboundMethods(TestGetcallargsMethods):
8190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def makeCallable(self, signature):
8210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
8220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.cls.method
8230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def assertEqualCallArgs(self, func, call_params_string, locs=None):
8250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
8260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            *self._getAssertEqualParams(func, call_params_string, locs))
8270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def assertEqualException(self, func, call_params_string, locs=None):
8290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return super(TestGetcallargsUnboundMethods, self).assertEqualException(
8300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            *self._getAssertEqualParams(func, call_params_string, locs))
8310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def _getAssertEqualParams(self, func, call_params_string, locs=None):
8330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        assert 'inst' not in call_params_string
8340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        locs = dict(locs or {}, inst=self.inst)
8350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return (func, 'inst,' + call_params_string, locs)
8360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8370a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef test_main():
8380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    run_unittest(
8390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
8400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
8410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        TestGetcallargsFunctions, TestGetcallargsMethods,
8420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        TestGetcallargsUnboundMethods)
8430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8440a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif __name__ == "__main__":
8450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    test_main()
846