Changeset 391 for python/trunk/Lib/test/test_inspect.py
- Timestamp:
- Mar 19, 2014, 11:31:01 PM (11 years ago)
- Location:
- python/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
python/trunk
-
Property svn:mergeinfo
set to
/python/vendor/Python-2.7.6 merged eligible /python/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
python/trunk/Lib/test/test_inspect.py
r2 r391 1 import re 1 2 import sys 2 3 import types 3 4 import unittest 4 5 import inspect 6 import linecache 5 7 import 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 8 from UserList import UserList 9 from UserDict import UserDict 10 11 from test.test_support import run_unittest, check_py3k_warnings 12 13 with 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 20 import unicodedata 11 21 12 22 # Functions tested in this suite: … … 27 37 28 38 try: 29 1 /039 1 // 0 30 40 except: 31 41 tb = sys.exc_traceback … … 41 51 def istest(self, predicate, exp): 42 52 obj = eval(exp) 43 self. failUnless(predicate(obj), '%s(%s)' % (predicate.__name__, exp))53 self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp)) 44 54 45 55 for other in self.predicates - set([predicate]): … … 47 57 other == inspect.isfunction: 48 58 continue 49 self. failIf(other(obj), 'not %s(%s)' % (other.__name__, exp))59 self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp)) 50 60 51 61 def generator_function_example(self): … … 66 76 self.istest(inspect.isbuiltin, 'sys.exit') 67 77 self.istest(inspect.isbuiltin, '[].append') 68 self.istest(inspect.isclass, 'mod.StupidGit')69 78 self.istest(inspect.iscode, 'mod.spam.func_code') 70 79 self.istest(inspect.isframe, 'tb.tb_frame') … … 82 91 'type(tb.tb_frame).f_locals') 83 92 else: 84 self. failIf(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))93 self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals)) 85 94 if hasattr(types, 'MemberDescriptorType'): 86 95 self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days') 87 96 else: 88 self. failIf(inspect.ismemberdescriptor(datetime.timedelta.days))97 self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days)) 89 98 90 99 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 93 148 94 149 class TestInterpreterStack(IsTestBase): … … 103 158 104 159 def test_stack(self): 105 self.assert _(len(mod.st) >= 5)160 self.assertTrue(len(mod.st) >= 5) 106 161 self.assertEqual(mod.st[0][1:], 107 162 (modfile, 16, 'eggs', [' st = inspect.stack()\n'], 0)) … … 120 175 [' eggs(b + d, c + f)\n'], 0)) 121 176 self.assertEqual(git.tr[2][1:], (modfile, 18, 'eggs', 122 [' q = y / 0\n'], 0))177 [' q = y // 0\n'], 0)) 123 178 124 179 def test_frame(self): … … 146 201 unittest.TestCase.__init__(self, *args, **kwargs) 147 202 148 self.source = file(inspect.getsourcefile(self.fodderFile)).read() 203 with open(inspect.getsourcefile(self.fodderFile)) as fp: 204 self.source = fp.read() 149 205 150 206 def sourcerange(self, top, bottom): … … 165 221 ('MalodorousPervert', mod.MalodorousPervert), 166 222 ('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) 169 240 self.assertEqual(tree, 170 241 [(mod.ParrotDroppings, ()), … … 182 253 ('spam', mod.spam)]) 183 254 255 @unittest.skipIf(sys.flags.optimize >= 2, 256 "Docstrings are omitted with -O2 and above") 184 257 def test_getdoc(self): 185 258 self.assertEqual(inspect.getdoc(mod), 'A module docstring.') … … 218 291 self.assertEqual(inspect.getsourcefile(mod.spam), modfile) 219 292 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) 220 298 221 299 def test_getfile(self): … … 233 311 inspect.getmodule(compile('a=10','','single')) 234 312 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 235 330 class TestDecorators(GetSourceBase): 236 331 fodderFile = mod2 … … 308 403 self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97) 309 404 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 429 class _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 443 class _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 310 454 # Helper for testing classify_class_attrs. 311 455 def attrs_wo_objs(cls): 312 456 return [t[:3] for t in inspect.classify_class_attrs(cls)] 457 313 458 314 459 class TestClassesAndFunctions(unittest.TestCase): … … 362 507 363 508 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): 372 530 def s(): pass 373 531 s = staticmethod(s) … … 385 543 datablob = '1' 386 544 545 dd = _BrokenDataDescriptor() 546 md = _BrokenMethodDescriptor() 547 387 548 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') 394 557 395 558 class B(A): … … 397 560 398 561 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') 405 570 406 571 … … 410 575 411 576 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') 418 585 419 586 class D(B, C): … … 421 588 422 589 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 431 611 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 650 class 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 819 class 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 833 class 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) 494 851 495 852 def 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) 499 858 500 859 if __name__ == "__main__":
Note:
See TracChangeset
for help on using the changeset viewer.