Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/Lib/test/test_inspect.py

    r2 r391  
     1import re
    12import sys
    23import types
    34import unittest
    45import inspect
     6import linecache
    57import datetime
    6 
    7 from test.test_support import TESTFN, run_unittest
    8 
    9 from test import inspect_fodder as mod
    10 from test import inspect_fodder2 as mod2
     8from UserList import UserList
     9from UserDict import UserDict
     10
     11from test.test_support import run_unittest, check_py3k_warnings
     12
     13with check_py3k_warnings(
     14        ("tuple parameter unpacking has been removed", SyntaxWarning),
     15        quiet=True):
     16    from test import inspect_fodder as mod
     17    from test import inspect_fodder2 as mod2
     18
     19# C module for test_findsource_binary
     20import unicodedata
    1121
    1222# Functions tested in this suite:
     
    2737
    2838try:
    29     1/0
     39    1 // 0
    3040except:
    3141    tb = sys.exc_traceback
     
    4151    def istest(self, predicate, exp):
    4252        obj = eval(exp)
    43         self.failUnless(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
     53        self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
    4454
    4555        for other in self.predicates - set([predicate]):
     
    4757               other == inspect.isfunction:
    4858                continue
    49             self.failIf(other(obj), 'not %s(%s)' % (other.__name__, exp))
     59            self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
    5060
    5161def generator_function_example(self):
     
    6676        self.istest(inspect.isbuiltin, 'sys.exit')
    6777        self.istest(inspect.isbuiltin, '[].append')
    68         self.istest(inspect.isclass, 'mod.StupidGit')
    6978        self.istest(inspect.iscode, 'mod.spam.func_code')
    7079        self.istest(inspect.isframe, 'tb.tb_frame')
     
    8291                        'type(tb.tb_frame).f_locals')
    8392        else:
    84             self.failIf(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
     93            self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
    8594        if hasattr(types, 'MemberDescriptorType'):
    8695            self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
    8796        else:
    88             self.failIf(inspect.ismemberdescriptor(datetime.timedelta.days))
     97            self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
    8998
    9099    def test_isroutine(self):
    91         self.assert_(inspect.isroutine(mod.spam))
    92         self.assert_(inspect.isroutine([].count))
     100        self.assertTrue(inspect.isroutine(mod.spam))
     101        self.assertTrue(inspect.isroutine([].count))
     102
     103    def test_isclass(self):
     104        self.istest(inspect.isclass, 'mod.StupidGit')
     105        self.assertTrue(inspect.isclass(list))
     106
     107        class newstyle(object): pass
     108        self.assertTrue(inspect.isclass(newstyle))
     109
     110        class CustomGetattr(object):
     111            def __getattr__(self, attr):
     112                return None
     113        self.assertFalse(inspect.isclass(CustomGetattr()))
     114
     115    def test_get_slot_members(self):
     116        class C(object):
     117            __slots__ = ("a", "b")
     118
     119        x = C()
     120        x.a = 42
     121        members = dict(inspect.getmembers(x))
     122        self.assertIn('a', members)
     123        self.assertNotIn('b', members)
     124
     125    def test_isabstract(self):
     126        from abc import ABCMeta, abstractmethod
     127
     128        class AbstractClassExample(object):
     129            __metaclass__ = ABCMeta
     130
     131            @abstractmethod
     132            def foo(self):
     133                pass
     134
     135        class ClassExample(AbstractClassExample):
     136            def foo(self):
     137                pass
     138
     139        a = ClassExample()
     140
     141        # Test general behaviour.
     142        self.assertTrue(inspect.isabstract(AbstractClassExample))
     143        self.assertFalse(inspect.isabstract(ClassExample))
     144        self.assertFalse(inspect.isabstract(a))
     145        self.assertFalse(inspect.isabstract(int))
     146        self.assertFalse(inspect.isabstract(5))
     147
    93148
    94149class TestInterpreterStack(IsTestBase):
     
    103158
    104159    def test_stack(self):
    105         self.assert_(len(mod.st) >= 5)
     160        self.assertTrue(len(mod.st) >= 5)
    106161        self.assertEqual(mod.st[0][1:],
    107162             (modfile, 16, 'eggs', ['    st = inspect.stack()\n'], 0))
     
    120175                                         ['    eggs(b + d, c + f)\n'], 0))
    121176        self.assertEqual(git.tr[2][1:], (modfile, 18, 'eggs',
    122                                          ['    q = y / 0\n'], 0))
     177                                         ['    q = y // 0\n'], 0))
    123178
    124179    def test_frame(self):
     
    146201        unittest.TestCase.__init__(self, *args, **kwargs)
    147202
    148         self.source = file(inspect.getsourcefile(self.fodderFile)).read()
     203        with open(inspect.getsourcefile(self.fodderFile)) as fp:
     204            self.source = fp.read()
    149205
    150206    def sourcerange(self, top, bottom):
     
    165221                          ('MalodorousPervert', mod.MalodorousPervert),
    166222                          ('ParrotDroppings', mod.ParrotDroppings),
    167                           ('StupidGit', mod.StupidGit)])
    168         tree = inspect.getclasstree([cls[1] for cls in classes], 1)
     223                          ('StupidGit', mod.StupidGit),
     224                          ('Tit', mod.MalodorousPervert),
     225                         ])
     226        tree = inspect.getclasstree([cls[1] for cls in classes])
     227        self.assertEqual(tree,
     228                         [(mod.ParrotDroppings, ()),
     229                          [(mod.FesteringGob, (mod.MalodorousPervert,
     230                                                  mod.ParrotDroppings))
     231                           ],
     232                          (mod.StupidGit, ()),
     233                          [(mod.MalodorousPervert, (mod.StupidGit,)),
     234                           [(mod.FesteringGob, (mod.MalodorousPervert,
     235                                                   mod.ParrotDroppings))
     236                            ]
     237                           ]
     238                          ])
     239        tree = inspect.getclasstree([cls[1] for cls in classes], True)
    169240        self.assertEqual(tree,
    170241                         [(mod.ParrotDroppings, ()),
     
    182253                                     ('spam', mod.spam)])
    183254
     255    @unittest.skipIf(sys.flags.optimize >= 2,
     256                     "Docstrings are omitted with -O2 and above")
    184257    def test_getdoc(self):
    185258        self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
     
    218291        self.assertEqual(inspect.getsourcefile(mod.spam), modfile)
    219292        self.assertEqual(inspect.getsourcefile(git.abuse), modfile)
     293        fn = "_non_existing_filename_used_for_sourcefile_test.py"
     294        co = compile("None", fn, "exec")
     295        self.assertEqual(inspect.getsourcefile(co), None)
     296        linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
     297        self.assertEqual(inspect.getsourcefile(co), fn)
    220298
    221299    def test_getfile(self):
     
    233311        inspect.getmodule(compile('a=10','','single'))
    234312
     313    def test_proceed_with_fake_filename(self):
     314        '''doctest monkeypatches linecache to enable inspection'''
     315        fn, source = '<test>', 'def x(): pass\n'
     316        getlines = linecache.getlines
     317        def monkey(filename, module_globals=None):
     318            if filename == fn:
     319                return source.splitlines(True)
     320            else:
     321                return getlines(filename, module_globals)
     322        linecache.getlines = monkey
     323        try:
     324            ns = {}
     325            exec compile(source, fn, 'single') in ns
     326            inspect.getsource(ns["x"])
     327        finally:
     328            linecache.getlines = getlines
     329
    235330class TestDecorators(GetSourceBase):
    236331    fodderFile = mod2
     
    308403        self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
    309404
     405    @unittest.skipIf(
     406        not hasattr(unicodedata, '__file__') or
     407            unicodedata.__file__[-4:] in (".pyc", ".pyo"),
     408        "unicodedata is not an external binary module")
     409    def test_findsource_binary(self):
     410        self.assertRaises(IOError, inspect.getsource, unicodedata)
     411        self.assertRaises(IOError, inspect.findsource, unicodedata)
     412
     413    def test_findsource_code_in_linecache(self):
     414        lines = ["x=1"]
     415        co = compile(lines[0], "_dynamically_created_file", "exec")
     416        self.assertRaises(IOError, inspect.findsource, co)
     417        self.assertRaises(IOError, inspect.getsource, co)
     418        linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
     419        self.assertEqual(inspect.findsource(co), (lines,0))
     420        self.assertEqual(inspect.getsource(co), lines[0])
     421
     422    def test_findsource_without_filename(self):
     423        for fname in ['', '<string>']:
     424            co = compile('x=1', fname, "exec")
     425            self.assertRaises(IOError, inspect.findsource, co)
     426            self.assertRaises(IOError, inspect.getsource, co)
     427
     428
     429class _BrokenDataDescriptor(object):
     430    """
     431    A broken data descriptor. See bug #1785.
     432    """
     433    def __get__(*args):
     434        raise AssertionError("should not __get__ data descriptors")
     435
     436    def __set__(*args):
     437        raise RuntimeError
     438
     439    def __getattr__(*args):
     440        raise AssertionError("should not __getattr__ data descriptors")
     441
     442
     443class _BrokenMethodDescriptor(object):
     444    """
     445    A broken method descriptor. See bug #1785.
     446    """
     447    def __get__(*args):
     448        raise AssertionError("should not __get__ method descriptors")
     449
     450    def __getattr__(*args):
     451        raise AssertionError("should not __getattr__ method descriptors")
     452
     453
    310454# Helper for testing classify_class_attrs.
    311455def attrs_wo_objs(cls):
    312456    return [t[:3] for t in inspect.classify_class_attrs(cls)]
     457
    313458
    314459class TestClassesAndFunctions(unittest.TestCase):
     
    362507
    363508    def test_getargspec_sublistofone(self):
    364         def sublistOfOne((foo,)): return 1
    365         self.assertArgSpecEquals(sublistOfOne, [['foo']])
    366 
    367         def fakeSublistOfOne((foo)): return 1
    368         self.assertArgSpecEquals(fakeSublistOfOne, ['foo'])
    369 
    370     def test_classify_oldstyle(self):
    371         class A:
     509        with check_py3k_warnings(
     510                ("tuple parameter unpacking has been removed", SyntaxWarning),
     511                ("parenthesized argument names are invalid", SyntaxWarning)):
     512            exec 'def sublistOfOne((foo,)): return 1'
     513            self.assertArgSpecEquals(sublistOfOne, [['foo']])
     514
     515            exec 'def fakeSublistOfOne((foo)): return 1'
     516            self.assertArgSpecEquals(fakeSublistOfOne, ['foo'])
     517
     518
     519    def _classify_test(self, newstyle):
     520        """Helper for testing that classify_class_attrs finds a bunch of
     521        different kinds of attributes on a given class.
     522        """
     523        if newstyle:
     524            base = object
     525        else:
     526            class base:
     527                pass
     528
     529        class A(base):
    372530            def s(): pass
    373531            s = staticmethod(s)
     
    385543            datablob = '1'
    386544
     545            dd = _BrokenDataDescriptor()
     546            md = _BrokenMethodDescriptor()
     547
    387548        attrs = attrs_wo_objs(A)
    388         self.assert_(('s', 'static method', A) in attrs, 'missing static method')
    389         self.assert_(('c', 'class method', A) in attrs, 'missing class method')
    390         self.assert_(('p', 'property', A) in attrs, 'missing property')
    391         self.assert_(('m', 'method', A) in attrs, 'missing plain method')
    392         self.assert_(('m1', 'method', A) in attrs, 'missing plain method')
    393         self.assert_(('datablob', 'data', A) in attrs, 'missing data')
     549        self.assertIn(('s', 'static method', A), attrs, 'missing static method')
     550        self.assertIn(('c', 'class method', A), attrs, 'missing class method')
     551        self.assertIn(('p', 'property', A), attrs, 'missing property')
     552        self.assertIn(('m', 'method', A), attrs, 'missing plain method')
     553        self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
     554        self.assertIn(('datablob', 'data', A), attrs, 'missing data')
     555        self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
     556        self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
    394557
    395558        class B(A):
     
    397560
    398561        attrs = attrs_wo_objs(B)
    399         self.assert_(('s', 'static method', A) in attrs, 'missing static method')
    400         self.assert_(('c', 'class method', A) in attrs, 'missing class method')
    401         self.assert_(('p', 'property', A) in attrs, 'missing property')
    402         self.assert_(('m', 'method', B) in attrs, 'missing plain method')
    403         self.assert_(('m1', 'method', A) in attrs, 'missing plain method')
    404         self.assert_(('datablob', 'data', A) in attrs, 'missing data')
     562        self.assertIn(('s', 'static method', A), attrs, 'missing static method')
     563        self.assertIn(('c', 'class method', A), attrs, 'missing class method')
     564        self.assertIn(('p', 'property', A), attrs, 'missing property')
     565        self.assertIn(('m', 'method', B), attrs, 'missing plain method')
     566        self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
     567        self.assertIn(('datablob', 'data', A), attrs, 'missing data')
     568        self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
     569        self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
    405570
    406571
     
    410575
    411576        attrs = attrs_wo_objs(C)
    412         self.assert_(('s', 'static method', A) in attrs, 'missing static method')
    413         self.assert_(('c', 'method', C) in attrs, 'missing plain method')
    414         self.assert_(('p', 'property', A) in attrs, 'missing property')
    415         self.assert_(('m', 'method', C) in attrs, 'missing plain method')
    416         self.assert_(('m1', 'method', A) in attrs, 'missing plain method')
    417         self.assert_(('datablob', 'data', A) in attrs, 'missing data')
     577        self.assertIn(('s', 'static method', A), attrs, 'missing static method')
     578        self.assertIn(('c', 'method', C), attrs, 'missing plain method')
     579        self.assertIn(('p', 'property', A), attrs, 'missing property')
     580        self.assertIn(('m', 'method', C), attrs, 'missing plain method')
     581        self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
     582        self.assertIn(('datablob', 'data', A), attrs, 'missing data')
     583        self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
     584        self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
    418585
    419586        class D(B, C):
     
    421588
    422589        attrs = attrs_wo_objs(D)
    423         self.assert_(('s', 'static method', A) in attrs, 'missing static method')
    424         self.assert_(('c', 'class method', A) in attrs, 'missing class method')
    425         self.assert_(('p', 'property', A) in attrs, 'missing property')
    426         self.assert_(('m', 'method', B) in attrs, 'missing plain method')
    427         self.assert_(('m1', 'method', D) in attrs, 'missing plain method')
    428         self.assert_(('datablob', 'data', A) in attrs, 'missing data')
    429 
    430     # Repeat all that, but w/ new-style classes.
     590        self.assertIn(('s', 'static method', A), attrs, 'missing static method')
     591        if newstyle:
     592            self.assertIn(('c', 'method', C), attrs, 'missing plain method')
     593        else:
     594            self.assertIn(('c', 'class method', A), attrs, 'missing class method')
     595        self.assertIn(('p', 'property', A), attrs, 'missing property')
     596        self.assertIn(('m', 'method', B), attrs, 'missing plain method')
     597        self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
     598        self.assertIn(('datablob', 'data', A), attrs, 'missing data')
     599        self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
     600        self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
     601
     602
     603    def test_classify_oldstyle(self):
     604        """classify_class_attrs finds static methods, class methods,
     605        properties, normal methods, and data attributes on an old-style
     606        class.
     607        """
     608        self._classify_test(False)
     609
     610
    431611    def test_classify_newstyle(self):
    432         class A(object):
    433 
    434             def s(): pass
    435             s = staticmethod(s)
    436 
    437             def c(cls): pass
    438             c = classmethod(c)
    439 
    440             def getp(self): pass
    441             p = property(getp)
    442 
    443             def m(self): pass
    444 
    445             def m1(self): pass
    446 
    447             datablob = '1'
    448 
    449         attrs = attrs_wo_objs(A)
    450         self.assert_(('s', 'static method', A) in attrs, 'missing static method')
    451         self.assert_(('c', 'class method', A) in attrs, 'missing class method')
    452         self.assert_(('p', 'property', A) in attrs, 'missing property')
    453         self.assert_(('m', 'method', A) in attrs, 'missing plain method')
    454         self.assert_(('m1', 'method', A) in attrs, 'missing plain method')
    455         self.assert_(('datablob', 'data', A) in attrs, 'missing data')
    456 
    457         class B(A):
    458 
    459             def m(self): pass
    460 
    461         attrs = attrs_wo_objs(B)
    462         self.assert_(('s', 'static method', A) in attrs, 'missing static method')
    463         self.assert_(('c', 'class method', A) in attrs, 'missing class method')
    464         self.assert_(('p', 'property', A) in attrs, 'missing property')
    465         self.assert_(('m', 'method', B) in attrs, 'missing plain method')
    466         self.assert_(('m1', 'method', A) in attrs, 'missing plain method')
    467         self.assert_(('datablob', 'data', A) in attrs, 'missing data')
    468 
    469 
    470         class C(A):
    471 
    472             def m(self): pass
    473             def c(self): pass
    474 
    475         attrs = attrs_wo_objs(C)
    476         self.assert_(('s', 'static method', A) in attrs, 'missing static method')
    477         self.assert_(('c', 'method', C) in attrs, 'missing plain method')
    478         self.assert_(('p', 'property', A) in attrs, 'missing property')
    479         self.assert_(('m', 'method', C) in attrs, 'missing plain method')
    480         self.assert_(('m1', 'method', A) in attrs, 'missing plain method')
    481         self.assert_(('datablob', 'data', A) in attrs, 'missing data')
    482 
    483         class D(B, C):
    484 
    485             def m1(self): pass
    486 
    487         attrs = attrs_wo_objs(D)
    488         self.assert_(('s', 'static method', A) in attrs, 'missing static method')
    489         self.assert_(('c', 'method', C) in attrs, 'missing plain method')
    490         self.assert_(('p', 'property', A) in attrs, 'missing property')
    491         self.assert_(('m', 'method', B) in attrs, 'missing plain method')
    492         self.assert_(('m1', 'method', D) in attrs, 'missing plain method')
    493         self.assert_(('datablob', 'data', A) in attrs, 'missing data')
     612        """Just like test_classify_oldstyle, but for a new-style class.
     613        """
     614        self._classify_test(True)
     615
     616    def test_classify_builtin_types(self):
     617        # Simple sanity check that all built-in types can have their
     618        # attributes classified.
     619        for name in dir(__builtin__):
     620            builtin = getattr(__builtin__, name)
     621            if isinstance(builtin, type):
     622                inspect.classify_class_attrs(builtin)
     623
     624    def test_getmembers_method(self):
     625        # Old-style classes
     626        class B:
     627            def f(self):
     628                pass
     629
     630        self.assertIn(('f', B.f), inspect.getmembers(B))
     631        # contrary to spec, ismethod() is also True for unbound methods
     632        # (see #1785)
     633        self.assertIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
     634        b = B()
     635        self.assertIn(('f', b.f), inspect.getmembers(b))
     636        self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
     637
     638        # New-style classes
     639        class B(object):
     640            def f(self):
     641                pass
     642
     643        self.assertIn(('f', B.f), inspect.getmembers(B))
     644        self.assertIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
     645        b = B()
     646        self.assertIn(('f', b.f), inspect.getmembers(b))
     647        self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
     648
     649
     650class TestGetcallargsFunctions(unittest.TestCase):
     651
     652    # tuple parameters are named '.1', '.2', etc.
     653    is_tuplename = re.compile(r'^\.\d+$').match
     654
     655    def assertEqualCallArgs(self, func, call_params_string, locs=None):
     656        locs = dict(locs or {}, func=func)
     657        r1 = eval('func(%s)' % call_params_string, None, locs)
     658        r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
     659                  locs)
     660        self.assertEqual(r1, r2)
     661
     662    def assertEqualException(self, func, call_param_string, locs=None):
     663        locs = dict(locs or {}, func=func)
     664        try:
     665            eval('func(%s)' % call_param_string, None, locs)
     666        except Exception, ex1:
     667            pass
     668        else:
     669            self.fail('Exception not raised')
     670        try:
     671            eval('inspect.getcallargs(func, %s)' % call_param_string, None,
     672                 locs)
     673        except Exception, ex2:
     674            pass
     675        else:
     676            self.fail('Exception not raised')
     677        self.assertIs(type(ex1), type(ex2))
     678        self.assertEqual(str(ex1), str(ex2))
     679
     680    def makeCallable(self, signature):
     681        """Create a function that returns its locals(), excluding the
     682        autogenerated '.1', '.2', etc. tuple param names (if any)."""
     683        with check_py3k_warnings(
     684            ("tuple parameter unpacking has been removed", SyntaxWarning),
     685            quiet=True):
     686            code = ("lambda %s: dict(i for i in locals().items() "
     687                    "if not is_tuplename(i[0]))")
     688            return eval(code % signature, {'is_tuplename' : self.is_tuplename})
     689
     690    def test_plain(self):
     691        f = self.makeCallable('a, b=1')
     692        self.assertEqualCallArgs(f, '2')
     693        self.assertEqualCallArgs(f, '2, 3')
     694        self.assertEqualCallArgs(f, 'a=2')
     695        self.assertEqualCallArgs(f, 'b=3, a=2')
     696        self.assertEqualCallArgs(f, '2, b=3')
     697        # expand *iterable / **mapping
     698        self.assertEqualCallArgs(f, '*(2,)')
     699        self.assertEqualCallArgs(f, '*[2]')
     700        self.assertEqualCallArgs(f, '*(2, 3)')
     701        self.assertEqualCallArgs(f, '*[2, 3]')
     702        self.assertEqualCallArgs(f, '**{"a":2}')
     703        self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
     704        self.assertEqualCallArgs(f, '2, **{"b":3}')
     705        self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
     706        # expand UserList / UserDict
     707        self.assertEqualCallArgs(f, '*UserList([2])')
     708        self.assertEqualCallArgs(f, '*UserList([2, 3])')
     709        self.assertEqualCallArgs(f, '**UserDict(a=2)')
     710        self.assertEqualCallArgs(f, '2, **UserDict(b=3)')
     711        self.assertEqualCallArgs(f, 'b=2, **UserDict(a=3)')
     712        # unicode keyword args
     713        self.assertEqualCallArgs(f, '**{u"a":2}')
     714        self.assertEqualCallArgs(f, 'b=3, **{u"a":2}')
     715        self.assertEqualCallArgs(f, '2, **{u"b":3}')
     716        self.assertEqualCallArgs(f, '**{u"b":3, u"a":2}')
     717
     718    def test_varargs(self):
     719        f = self.makeCallable('a, b=1, *c')
     720        self.assertEqualCallArgs(f, '2')
     721        self.assertEqualCallArgs(f, '2, 3')
     722        self.assertEqualCallArgs(f, '2, 3, 4')
     723        self.assertEqualCallArgs(f, '*(2,3,4)')
     724        self.assertEqualCallArgs(f, '2, *[3,4]')
     725        self.assertEqualCallArgs(f, '2, 3, *UserList([4])')
     726
     727    def test_varkw(self):
     728        f = self.makeCallable('a, b=1, **c')
     729        self.assertEqualCallArgs(f, 'a=2')
     730        self.assertEqualCallArgs(f, '2, b=3, c=4')
     731        self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
     732        self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
     733        self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
     734        self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
     735        self.assertEqualCallArgs(f, '**UserDict(a=2, b=3, c=4)')
     736        self.assertEqualCallArgs(f, '2, c=4, **UserDict(b=3)')
     737        self.assertEqualCallArgs(f, 'b=2, **UserDict(a=3, c=4)')
     738        # unicode keyword args
     739        self.assertEqualCallArgs(f, 'c=4, **{u"a":2, u"b":3}')
     740        self.assertEqualCallArgs(f, '2, c=4, **{u"b":3}')
     741        self.assertEqualCallArgs(f, 'b=2, **{u"a":3, u"c":4}')
     742
     743    def test_varkw_only(self):
     744        # issue11256:
     745        f = self.makeCallable('**c')
     746        self.assertEqualCallArgs(f, '')
     747        self.assertEqualCallArgs(f, 'a=1')
     748        self.assertEqualCallArgs(f, 'a=1, b=2')
     749        self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
     750        self.assertEqualCallArgs(f, '**UserDict(a=1, b=2)')
     751        self.assertEqualCallArgs(f, 'c=3, **UserDict(a=1, b=2)')
     752
     753    def test_tupleargs(self):
     754        f = self.makeCallable('(b,c), (d,(e,f))=(0,[1,2])')
     755        self.assertEqualCallArgs(f, '(2,3)')
     756        self.assertEqualCallArgs(f, '[2,3]')
     757        self.assertEqualCallArgs(f, 'UserList([2,3])')
     758        self.assertEqualCallArgs(f, '(2,3), (4,(5,6))')
     759        self.assertEqualCallArgs(f, '(2,3), (4,[5,6])')
     760        self.assertEqualCallArgs(f, '(2,3), [4,UserList([5,6])]')
     761
     762    def test_multiple_features(self):
     763        f = self.makeCallable('a, b=2, (c,(d,e))=(3,[4,5]), *f, **g')
     764        self.assertEqualCallArgs(f, '2, 3, (4,[5,6]), 7')
     765        self.assertEqualCallArgs(f, '2, 3, *[(4,[5,6]), 7], x=8')
     766        self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
     767        self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
     768        self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
     769        self.assertEqualCallArgs(f, 'x=8, *UserList([2, 3, (4,[5,6])]), '
     770                                 '**{"y":9, "z":10}')
     771        self.assertEqualCallArgs(f, '2, x=8, *UserList([3, (4,[5,6])]), '
     772                                 '**UserDict(y=9, z=10)')
     773
     774    def test_errors(self):
     775        f0 = self.makeCallable('')
     776        f1 = self.makeCallable('a, b')
     777        f2 = self.makeCallable('a, b=1')
     778        # f0 takes no arguments
     779        self.assertEqualException(f0, '1')
     780        self.assertEqualException(f0, 'x=1')
     781        self.assertEqualException(f0, '1,x=1')
     782        # f1 takes exactly 2 arguments
     783        self.assertEqualException(f1, '')
     784        self.assertEqualException(f1, '1')
     785        self.assertEqualException(f1, 'a=2')
     786        self.assertEqualException(f1, 'b=3')
     787        # f2 takes at least 1 argument
     788        self.assertEqualException(f2, '')
     789        self.assertEqualException(f2, 'b=3')
     790        for f in f1, f2:
     791            # f1/f2 takes exactly/at most 2 arguments
     792            self.assertEqualException(f, '2, 3, 4')
     793            self.assertEqualException(f, '1, 2, 3, a=1')
     794            self.assertEqualException(f, '2, 3, 4, c=5')
     795            self.assertEqualException(f, '2, 3, 4, a=1, c=5')
     796            # f got an unexpected keyword argument
     797            self.assertEqualException(f, 'c=2')
     798            self.assertEqualException(f, '2, c=3')
     799            self.assertEqualException(f, '2, 3, c=4')
     800            self.assertEqualException(f, '2, c=4, b=3')
     801            self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
     802            # f got multiple values for keyword argument
     803            self.assertEqualException(f, '1, a=2')
     804            self.assertEqualException(f, '1, **{"a":2}')
     805            self.assertEqualException(f, '1, 2, b=3')
     806            # XXX: Python inconsistency
     807            # - for functions and bound methods: unexpected keyword 'c'
     808            # - for unbound methods: multiple values for keyword 'a'
     809            #self.assertEqualException(f, '1, c=3, a=2')
     810        f = self.makeCallable('(a,b)=(0,1)')
     811        self.assertEqualException(f, '1')
     812        self.assertEqualException(f, '[1]')
     813        self.assertEqualException(f, '(1,2,3)')
     814        # issue11256:
     815        f3 = self.makeCallable('**c')
     816        self.assertEqualException(f3, '1, 2')
     817        self.assertEqualException(f3, '1, 2, a=1, b=2')
     818
     819class TestGetcallargsMethods(TestGetcallargsFunctions):
     820
     821    def setUp(self):
     822        class Foo(object):
     823            pass
     824        self.cls = Foo
     825        self.inst = Foo()
     826
     827    def makeCallable(self, signature):
     828        assert 'self' not in signature
     829        mk = super(TestGetcallargsMethods, self).makeCallable
     830        self.cls.method = mk('self, ' + signature)
     831        return self.inst.method
     832
     833class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
     834
     835    def makeCallable(self, signature):
     836        super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
     837        return self.cls.method
     838
     839    def assertEqualCallArgs(self, func, call_params_string, locs=None):
     840        return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
     841            *self._getAssertEqualParams(func, call_params_string, locs))
     842
     843    def assertEqualException(self, func, call_params_string, locs=None):
     844        return super(TestGetcallargsUnboundMethods, self).assertEqualException(
     845            *self._getAssertEqualParams(func, call_params_string, locs))
     846
     847    def _getAssertEqualParams(self, func, call_params_string, locs=None):
     848        assert 'inst' not in call_params_string
     849        locs = dict(locs or {}, inst=self.inst)
     850        return (func, 'inst,' + call_params_string, locs)
    494851
    495852def test_main():
    496     run_unittest(TestDecorators, TestRetrievingSourceCode, TestOneliners,
    497                  TestBuggyCases,
    498                  TestInterpreterStack, TestClassesAndFunctions, TestPredicates)
     853    run_unittest(
     854        TestDecorators, TestRetrievingSourceCode, TestOneliners, TestBuggyCases,
     855        TestInterpreterStack, TestClassesAndFunctions, TestPredicates,
     856        TestGetcallargsFunctions, TestGetcallargsMethods,
     857        TestGetcallargsUnboundMethods)
    499858
    500859if __name__ == "__main__":
Note: See TracChangeset for help on using the changeset viewer.