1import unittest 2import idlelib.calltips as ct 3import textwrap 4import types 5 6default_tip = ct._default_callable_argspec 7 8# Test Class TC is used in multiple get_argspec test methods 9class TC(): 10 'doc' 11 tip = "(ai=None, *b)" 12 def __init__(self, ai=None, *b): 'doc' 13 __init__.tip = "(self, ai=None, *b)" 14 def t1(self): 'doc' 15 t1.tip = "(self)" 16 def t2(self, ai, b=None): 'doc' 17 t2.tip = "(self, ai, b=None)" 18 def t3(self, ai, *args): 'doc' 19 t3.tip = "(self, ai, *args)" 20 def t4(self, *args): 'doc' 21 t4.tip = "(self, *args)" 22 def t5(self, ai, b=None, *args, **kw): 'doc' 23 t5.tip = "(self, ai, b=None, *args, **kw)" 24 def t6(no, self): 'doc' 25 t6.tip = "(no, self)" 26 def __call__(self, ci): 'doc' 27 __call__.tip = "(self, ci)" 28 # attaching .tip to wrapped methods does not work 29 @classmethod 30 def cm(cls, a): 'doc' 31 @staticmethod 32 def sm(b): 'doc' 33 34tc = TC() 35 36signature = ct.get_argspec # 2.7 and 3.x use different functions 37class Get_signatureTest(unittest.TestCase): 38 # The signature function must return a string, even if blank. 39 # Test a variety of objects to be sure that none cause it to raise 40 # (quite aside from getting as correct an answer as possible). 41 # The tests of builtins may break if inspect or the docstrings change, 42 # but a red buildbot is better than a user crash (as has happened). 43 # For a simple mismatch, change the expected output to the actual. 44 45 def test_builtins(self): 46 47 # Python class that inherits builtin methods 48 class List(list): "List() doc" 49 # Simulate builtin with no docstring for default tip test 50 class SB: __call__ = None 51 52 def gtest(obj, out): 53 self.assertEqual(signature(obj), out) 54 55 if List.__doc__ is not None: 56 gtest(List, List.__doc__) 57 gtest(list.__new__, 58 'Create and return a new object. See help(type) for accurate signature.') 59 gtest(list.__init__, 60 'Initialize self. See help(type(self)) for accurate signature.') 61 append_doc = "L.append(object) -> None -- append object to end" 62 gtest(list.append, append_doc) 63 gtest([].append, append_doc) 64 gtest(List.append, append_doc) 65 66 gtest(types.MethodType, "method(function, instance)") 67 gtest(SB(), default_tip) 68 69 def test_signature_wrap(self): 70 if textwrap.TextWrapper.__doc__ is not None: 71 self.assertEqual(signature(textwrap.TextWrapper), '''\ 72(width=70, initial_indent='', subsequent_indent='', expand_tabs=True, 73 replace_whitespace=True, fix_sentence_endings=False, break_long_words=True, 74 drop_whitespace=True, break_on_hyphens=True, tabsize=8, *, max_lines=None, 75 placeholder=' [...]')''') 76 77 def test_docline_truncation(self): 78 def f(): pass 79 f.__doc__ = 'a'*300 80 self.assertEqual(signature(f), '()\n' + 'a' * (ct._MAX_COLS-3) + '...') 81 82 def test_multiline_docstring(self): 83 # Test fewer lines than max. 84 self.assertEqual(signature(list), 85 "list() -> new empty list\n" 86 "list(iterable) -> new list initialized from iterable's items") 87 88 # Test max lines 89 self.assertEqual(signature(bytes), '''\ 90bytes(iterable_of_ints) -> bytes 91bytes(string, encoding[, errors]) -> bytes 92bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer 93bytes(int) -> bytes object of size given by the parameter initialized with null bytes 94bytes() -> empty bytes object''') 95 96 # Test more than max lines 97 def f(): pass 98 f.__doc__ = 'a\n' * 15 99 self.assertEqual(signature(f), '()' + '\na' * ct._MAX_LINES) 100 101 def test_functions(self): 102 def t1(): 'doc' 103 t1.tip = "()" 104 def t2(a, b=None): 'doc' 105 t2.tip = "(a, b=None)" 106 def t3(a, *args): 'doc' 107 t3.tip = "(a, *args)" 108 def t4(*args): 'doc' 109 t4.tip = "(*args)" 110 def t5(a, b=None, *args, **kw): 'doc' 111 t5.tip = "(a, b=None, *args, **kw)" 112 113 doc = '\ndoc' if t1.__doc__ is not None else '' 114 for func in (t1, t2, t3, t4, t5, TC): 115 self.assertEqual(signature(func), func.tip + doc) 116 117 def test_methods(self): 118 doc = '\ndoc' if TC.__doc__ is not None else '' 119 for meth in (TC.t1, TC.t2, TC.t3, TC.t4, TC.t5, TC.t6, TC.__call__): 120 self.assertEqual(signature(meth), meth.tip + doc) 121 self.assertEqual(signature(TC.cm), "(a)" + doc) 122 self.assertEqual(signature(TC.sm), "(b)" + doc) 123 124 def test_bound_methods(self): 125 # test that first parameter is correctly removed from argspec 126 doc = '\ndoc' if TC.__doc__ is not None else '' 127 for meth, mtip in ((tc.t1, "()"), (tc.t4, "(*args)"), (tc.t6, "(self)"), 128 (tc.__call__, '(ci)'), (tc, '(ci)'), (TC.cm, "(a)"),): 129 self.assertEqual(signature(meth), mtip + doc) 130 131 def test_starred_parameter(self): 132 # test that starred first parameter is *not* removed from argspec 133 class C: 134 def m1(*args): pass 135 def m2(**kwds): pass 136 c = C() 137 for meth, mtip in ((C.m1, '(*args)'), (c.m1, "(*args)"), 138 (C.m2, "(**kwds)"), (c.m2, "(**kwds)"),): 139 self.assertEqual(signature(meth), mtip) 140 141 def test_non_ascii_name(self): 142 # test that re works to delete a first parameter name that 143 # includes non-ascii chars, such as various forms of A. 144 uni = "(A\u0391\u0410\u05d0\u0627\u0905\u1e00\u3042, a)" 145 assert ct._first_param.sub('', uni) == '(a)' 146 147 def test_no_docstring(self): 148 def nd(s): 149 pass 150 TC.nd = nd 151 self.assertEqual(signature(nd), "(s)") 152 self.assertEqual(signature(TC.nd), "(s)") 153 self.assertEqual(signature(tc.nd), "()") 154 155 def test_attribute_exception(self): 156 class NoCall: 157 def __getattr__(self, name): 158 raise BaseException 159 class Call(NoCall): 160 def __call__(self, ci): 161 pass 162 for meth, mtip in ((NoCall, default_tip), (Call, default_tip), 163 (NoCall(), ''), (Call(), '(ci)')): 164 self.assertEqual(signature(meth), mtip) 165 166 def test_non_callables(self): 167 for obj in (0, 0.0, '0', b'0', [], {}): 168 self.assertEqual(signature(obj), '') 169 170class Get_entityTest(unittest.TestCase): 171 def test_bad_entity(self): 172 self.assertIsNone(ct.get_entity('1/0')) 173 def test_good_entity(self): 174 self.assertIs(ct.get_entity('int'), int) 175 176if __name__ == '__main__': 177 unittest.main(verbosity=2, exit=False) 178