4
4
import unittest
5
5
import textwrap
6
6
import types
7
-
8
- default_tip = calltip ._default_callable_argspec
7
+ import re
9
8
10
9
11
10
# Test Class TC is used in multiple get_argspec test methods
@@ -28,6 +27,7 @@ def t6(no, self): 'doc'
28
27
t6 .tip = "(no, self)"
29
28
def __call__ (self , ci ): 'doc'
30
29
__call__ .tip = "(self, ci)"
30
+ def nd (self ): pass # No doc.
31
31
# attaching .tip to wrapped methods does not work
32
32
@classmethod
33
33
def cm (cls , a ): 'doc'
@@ -36,11 +36,12 @@ def sm(b): 'doc'
36
36
37
37
38
38
tc = TC ()
39
- signature = calltip .get_argspec # 2.7 and 3.x use different functions
39
+ default_tip = calltip ._default_callable_argspec
40
+ get_spec = calltip .get_argspec
40
41
41
42
42
- class Get_signatureTest (unittest .TestCase ):
43
- # The signature function must return a string, even if blank.
43
+ class Get_argspecTest (unittest .TestCase ):
44
+ # The get_spec function must return a string, even if blank.
44
45
# Test a variety of objects to be sure that none cause it to raise
45
46
# (quite aside from getting as correct an answer as possible).
46
47
# The tests of builtins may break if inspect or the docstrings change,
@@ -49,57 +50,59 @@ class Get_signatureTest(unittest.TestCase):
49
50
50
51
def test_builtins (self ):
51
52
53
+ def tiptest (obj , out ):
54
+ self .assertEqual (get_spec (obj ), out )
55
+
52
56
# Python class that inherits builtin methods
53
57
class List (list ): "List() doc"
54
58
55
59
# Simulate builtin with no docstring for default tip test
56
60
class SB : __call__ = None
57
61
58
- def gtest (obj , out ):
59
- self .assertEqual (signature (obj ), out )
60
-
61
62
if List .__doc__ is not None :
62
- gtest (List , '(iterable=(), /)' + calltip ._argument_positional
63
- + '\n ' + List .__doc__ )
64
- gtest (list .__new__ ,
63
+ tiptest (List ,
64
+ f'(iterable=(), /){ calltip ._argument_positional } '
65
+ f'\n { List .__doc__ } ' )
66
+ tiptest (list .__new__ ,
65
67
'(*args, **kwargs)\n '
66
68
'Create and return a new object. '
67
69
'See help(type) for accurate signature.' )
68
- gtest (list .__init__ ,
70
+ tiptest (list .__init__ ,
69
71
'(self, /, *args, **kwargs)'
70
72
+ calltip ._argument_positional + '\n ' +
71
73
'Initialize self. See help(type(self)) for accurate signature.' )
72
74
append_doc = (calltip ._argument_positional
73
75
+ "\n Append object to the end of the list." )
74
- gtest (list .append , '(self, object, /)' + append_doc )
75
- gtest (List .append , '(self, object, /)' + append_doc )
76
- gtest ([].append , '(object, /)' + append_doc )
76
+ tiptest (list .append , '(self, object, /)' + append_doc )
77
+ tiptest (List .append , '(self, object, /)' + append_doc )
78
+ tiptest ([].append , '(object, /)' + append_doc )
79
+
80
+ tiptest (types .MethodType , "method(function, instance)" )
81
+ tiptest (SB (), default_tip )
77
82
78
- gtest (types .MethodType , "method(function, instance)" )
79
- gtest (SB (), default_tip )
80
- import re
81
83
p = re .compile ('' )
82
- gtest (re .sub , '''\
84
+ tiptest (re .sub , '''\
83
85
(pattern, repl, string, count=0, flags=0)
84
86
Return the string obtained by replacing the leftmost
85
87
non-overlapping occurrences of the pattern in string by the
86
88
replacement repl. repl can be either a string or a callable;
87
89
if a string, backslash escapes in it are processed. If it is
88
90
a callable, it's passed the Match object and must return''' )
89
- gtest (p .sub , '''\
91
+ tiptest (p .sub , '''\
90
92
(repl, string, count=0)
91
93
Return the string obtained by replacing the leftmost \
92
94
non-overlapping occurrences o...''' )
93
95
94
96
def test_signature_wrap (self ):
95
97
if textwrap .TextWrapper .__doc__ is not None :
96
- self .assertEqual (signature (textwrap .TextWrapper ), '''\
98
+ self .assertEqual (get_spec (textwrap .TextWrapper ), '''\
97
99
(width=70, initial_indent='', subsequent_indent='', expand_tabs=True,
98
100
replace_whitespace=True, fix_sentence_endings=False, break_long_words=True,
99
101
drop_whitespace=True, break_on_hyphens=True, tabsize=8, *, max_lines=None,
100
102
placeholder=' [...]')''' )
101
103
102
104
def test_properly_formated (self ):
105
+
103
106
def foo (s = 'a' * 100 ):
104
107
pass
105
108
@@ -112,35 +115,35 @@ def baz(s='a'*100, z='b'*100):
112
115
113
116
indent = calltip ._INDENT
114
117
115
- str_foo = "(s='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
116
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n " + indent + "aaaaaaaaa" \
117
- "aaaaaaaaaa')"
118
- str_bar = "(s='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
119
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n " + indent + "aaaaaaaaa" \
120
- "aaaaaaaaaa')\n Hello Guido"
121
- str_baz = "(s='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
122
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n " + indent + "aaaaaaaaa" \
123
- "aaaaaaaaaa', z='bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" \
124
- "bbbbbbbbbbbbbbbbb\n " + indent + "bbbbbbbbbbbbbbbbbbbbbb" \
125
- "bbbbbbbbbbbbbbbbbbbbbb')"
126
-
127
- self . assertEqual ( calltip . get_argspec ( foo ), str_foo )
128
- self .assertEqual ( calltip . get_argspec ( bar ), str_bar )
129
- self .assertEqual (calltip . get_argspec ( baz ), str_baz )
118
+ sfoo = "(s='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
119
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n " + indent + "aaaaaaaaa" \
120
+ "aaaaaaaaaa')"
121
+ sbar = "(s='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
122
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n " + indent + "aaaaaaaaa" \
123
+ "aaaaaaaaaa')\n Hello Guido"
124
+ sbaz = "(s='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
125
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n " + indent + "aaaaaaaaa" \
126
+ "aaaaaaaaaa', z='bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" \
127
+ "bbbbbbbbbbbbbbbbb\n " + indent + "bbbbbbbbbbbbbbbbbbbbbb" \
128
+ "bbbbbbbbbbbbbbbbbbbbbb')"
129
+
130
+ for func , doc in [( foo , sfoo ), ( bar , sbar ), ( baz , sbaz )]:
131
+ with self .subTest ( func = func , doc = doc ):
132
+ self .assertEqual (get_spec ( func ), doc )
130
133
131
134
def test_docline_truncation (self ):
132
135
def f (): pass
133
136
f .__doc__ = 'a' * 300
134
- self .assertEqual (signature (f ), ' ()\n ' + 'a' * (calltip ._MAX_COLS - 3 ) + '...' )
137
+ self .assertEqual (get_spec (f ), f" ()\n { 'a' * (calltip ._MAX_COLS - 3 ) + '...' } " )
135
138
136
139
def test_multiline_docstring (self ):
137
140
# Test fewer lines than max.
138
- self .assertEqual (signature (range ),
141
+ self .assertEqual (get_spec (range ),
139
142
"range(stop) -> range object\n "
140
143
"range(start, stop[, step]) -> range object" )
141
144
142
145
# Test max lines
143
- self .assertEqual (signature (bytes ), '''\
146
+ self .assertEqual (get_spec (bytes ), '''\
144
147
bytes(iterable_of_ints) -> bytes
145
148
bytes(string, encoding[, errors]) -> bytes
146
149
bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer
@@ -150,7 +153,7 @@ def test_multiline_docstring(self):
150
153
# Test more than max lines
151
154
def f (): pass
152
155
f .__doc__ = 'a\n ' * 15
153
- self .assertEqual (signature (f ), '()' + '\n a' * calltip ._MAX_LINES )
156
+ self .assertEqual (get_spec (f ), '()' + '\n a' * calltip ._MAX_LINES )
154
157
155
158
def test_functions (self ):
156
159
def t1 (): 'doc'
@@ -166,40 +169,44 @@ def t5(a, b=None, *args, **kw): 'doc'
166
169
167
170
doc = '\n doc' if t1 .__doc__ is not None else ''
168
171
for func in (t1 , t2 , t3 , t4 , t5 , TC ):
169
- self .assertEqual (signature (func ), func .tip + doc )
172
+ with self .subTest (func = func ):
173
+ self .assertEqual (get_spec (func ), func .tip + doc )
170
174
171
175
def test_methods (self ):
172
176
doc = '\n doc' if TC .__doc__ is not None else ''
173
177
for meth in (TC .t1 , TC .t2 , TC .t3 , TC .t4 , TC .t5 , TC .t6 , TC .__call__ ):
174
- self .assertEqual (signature (meth ), meth .tip + doc )
175
- self .assertEqual (signature (TC .cm ), "(a)" + doc )
176
- self .assertEqual (signature (TC .sm ), "(b)" + doc )
178
+ with self .subTest (meth = meth ):
179
+ self .assertEqual (get_spec (meth ), meth .tip + doc )
180
+ self .assertEqual (get_spec (TC .cm ), "(a)" + doc )
181
+ self .assertEqual (get_spec (TC .sm ), "(b)" + doc )
177
182
178
183
def test_bound_methods (self ):
179
184
# test that first parameter is correctly removed from argspec
180
185
doc = '\n doc' if TC .__doc__ is not None else ''
181
186
for meth , mtip in ((tc .t1 , "()" ), (tc .t4 , "(*args)" ),
182
187
(tc .t6 , "(self)" ), (tc .__call__ , '(ci)' ),
183
188
(tc , '(ci)' ), (TC .cm , "(a)" ),):
184
- self .assertEqual (signature (meth ), mtip + doc )
189
+ with self .subTest (meth = meth , mtip = mtip ):
190
+ self .assertEqual (get_spec (meth ), mtip + doc )
185
191
186
192
def test_starred_parameter (self ):
187
193
# test that starred first parameter is *not* removed from argspec
188
194
class C :
189
195
def m1 (* args ): pass
190
196
c = C ()
191
197
for meth , mtip in ((C .m1 , '(*args)' ), (c .m1 , "(*args)" ),):
192
- self .assertEqual (signature (meth ), mtip )
198
+ with self .subTest (meth = meth , mtip = mtip ):
199
+ self .assertEqual (get_spec (meth ), mtip )
193
200
194
- def test_invalid_method_signature (self ):
201
+ def test_invalid_method_get_spec (self ):
195
202
class C :
196
203
def m2 (** kwargs ): pass
197
204
class Test :
198
205
def __call__ (* , a ): pass
199
206
200
207
mtip = calltip ._invalid_method
201
- self .assertEqual (signature (C ().m2 ), mtip )
202
- self .assertEqual (signature (Test ()), mtip )
208
+ self .assertEqual (get_spec (C ().m2 ), mtip )
209
+ self .assertEqual (get_spec (Test ()), mtip )
203
210
204
211
def test_non_ascii_name (self ):
205
212
# test that re works to delete a first parameter name that
@@ -208,12 +215,9 @@ def test_non_ascii_name(self):
208
215
assert calltip ._first_param .sub ('' , uni ) == '(a)'
209
216
210
217
def test_no_docstring (self ):
211
- def nd (s ):
212
- pass
213
- TC .nd = nd
214
- self .assertEqual (signature (nd ), "(s)" )
215
- self .assertEqual (signature (TC .nd ), "(s)" )
216
- self .assertEqual (signature (tc .nd ), "()" )
218
+ for meth , mtip in ((TC .nd , "(self)" ), (tc .nd , "()" )):
219
+ with self .subTest (meth = meth , mtip = mtip ):
220
+ self .assertEqual (get_spec (meth ), mtip )
217
221
218
222
def test_attribute_exception (self ):
219
223
class NoCall :
@@ -229,11 +233,13 @@ def __call__(self, ci):
229
233
for meth , mtip in ((NoCall , default_tip ), (CallA , default_tip ),
230
234
(NoCall (), '' ), (CallA (), '(a, b, c)' ),
231
235
(CallB (), '(ci)' )):
232
- self .assertEqual (signature (meth ), mtip )
236
+ with self .subTest (meth = meth , mtip = mtip ):
237
+ self .assertEqual (get_spec (meth ), mtip )
233
238
234
239
def test_non_callables (self ):
235
240
for obj in (0 , 0.0 , '0' , b'0' , [], {}):
236
- self .assertEqual (signature (obj ), '' )
241
+ with self .subTest (obj = obj ):
242
+ self .assertEqual (get_spec (obj ), '' )
237
243
238
244
239
245
class Get_entityTest (unittest .TestCase ):
0 commit comments