##// END OF EJS Templates
remove nose.assert_equal from IPython/core/tests/test_oinspect.py
Matthias Bussonnier -
Show More
@@ -1,447 +1,455 b''
1 """Tests for the object inspection functionality.
1 """Tests for the object inspection functionality.
2 """
2 """
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7
7
8 from inspect import signature, Signature, Parameter
8 from inspect import signature, Signature, Parameter
9 import os
9 import os
10 import re
10 import re
11
11
12 import nose.tools as nt
12 import nose.tools as nt
13
13
14 from .. import oinspect
14 from .. import oinspect
15
15
16 from decorator import decorator
16 from decorator import decorator
17
17
18 from IPython.testing.tools import AssertPrints, AssertNotPrints
18 from IPython.testing.tools import AssertPrints, AssertNotPrints
19 from IPython.utils.path import compress_user
19 from IPython.utils.path import compress_user
20
20
21
21
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Globals and constants
23 # Globals and constants
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 inspector = None
26 inspector = None
27
27
28 def setup_module():
28 def setup_module():
29 global inspector
29 global inspector
30 inspector = oinspect.Inspector()
30 inspector = oinspect.Inspector()
31
31
32
32
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34 # Local utilities
34 # Local utilities
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36
36
37 # WARNING: since this test checks the line number where a function is
37 # WARNING: since this test checks the line number where a function is
38 # defined, if any code is inserted above, the following line will need to be
38 # defined, if any code is inserted above, the following line will need to be
39 # updated. Do NOT insert any whitespace between the next line and the function
39 # updated. Do NOT insert any whitespace between the next line and the function
40 # definition below.
40 # definition below.
41 THIS_LINE_NUMBER = 41 # Put here the actual number of this line
41 THIS_LINE_NUMBER = 41 # Put here the actual number of this line
42
42
43 from unittest import TestCase
43 from unittest import TestCase
44
44
45 class Test(TestCase):
45 class Test(TestCase):
46
46
47 def test_find_source_lines(self):
47 def test_find_source_lines(self):
48 self.assertEqual(oinspect.find_source_lines(Test.test_find_source_lines),
48 self.assertEqual(oinspect.find_source_lines(Test.test_find_source_lines),
49 THIS_LINE_NUMBER+6)
49 THIS_LINE_NUMBER+6)
50
50
51
51
52 # A couple of utilities to ensure these tests work the same from a source or a
52 # A couple of utilities to ensure these tests work the same from a source or a
53 # binary install
53 # binary install
54 def pyfile(fname):
54 def pyfile(fname):
55 return os.path.normcase(re.sub('.py[co]$', '.py', fname))
55 return os.path.normcase(re.sub('.py[co]$', '.py', fname))
56
56
57
57
58 def match_pyfiles(f1, f2):
58 def match_pyfiles(f1, f2):
59 nt.assert_equal(pyfile(f1), pyfile(f2))
59 assert pyfile(f1) == pyfile(f2)
60
60
61
61
62 def test_find_file():
62 def test_find_file():
63 match_pyfiles(oinspect.find_file(test_find_file), os.path.abspath(__file__))
63 match_pyfiles(oinspect.find_file(test_find_file), os.path.abspath(__file__))
64
64
65
65
66 def test_find_file_decorated1():
66 def test_find_file_decorated1():
67
67
68 @decorator
68 @decorator
69 def noop1(f):
69 def noop1(f):
70 def wrapper(*a, **kw):
70 def wrapper(*a, **kw):
71 return f(*a, **kw)
71 return f(*a, **kw)
72 return wrapper
72 return wrapper
73
73
74 @noop1
74 @noop1
75 def f(x):
75 def f(x):
76 "My docstring"
76 "My docstring"
77
77
78 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
78 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
79 nt.assert_equal(f.__doc__, "My docstring")
79 assert f.__doc__ == "My docstring"
80
80
81
81
82 def test_find_file_decorated2():
82 def test_find_file_decorated2():
83
83
84 @decorator
84 @decorator
85 def noop2(f, *a, **kw):
85 def noop2(f, *a, **kw):
86 return f(*a, **kw)
86 return f(*a, **kw)
87
87
88 @noop2
88 @noop2
89 @noop2
89 @noop2
90 @noop2
90 @noop2
91 def f(x):
91 def f(x):
92 "My docstring 2"
92 "My docstring 2"
93
93
94 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
94 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
95 nt.assert_equal(f.__doc__, "My docstring 2")
95 assert f.__doc__ == "My docstring 2"
96
96
97
97
98 def test_find_file_magic():
98 def test_find_file_magic():
99 run = ip.find_line_magic('run')
99 run = ip.find_line_magic('run')
100 nt.assert_not_equal(oinspect.find_file(run), None)
100 nt.assert_not_equal(oinspect.find_file(run), None)
101
101
102
102
103 # A few generic objects we can then inspect in the tests below
103 # A few generic objects we can then inspect in the tests below
104
104
105 class Call(object):
105 class Call(object):
106 """This is the class docstring."""
106 """This is the class docstring."""
107
107
108 def __init__(self, x, y=1):
108 def __init__(self, x, y=1):
109 """This is the constructor docstring."""
109 """This is the constructor docstring."""
110
110
111 def __call__(self, *a, **kw):
111 def __call__(self, *a, **kw):
112 """This is the call docstring."""
112 """This is the call docstring."""
113
113
114 def method(self, x, z=2):
114 def method(self, x, z=2):
115 """Some method's docstring"""
115 """Some method's docstring"""
116
116
117 class HasSignature(object):
117 class HasSignature(object):
118 """This is the class docstring."""
118 """This is the class docstring."""
119 __signature__ = Signature([Parameter('test', Parameter.POSITIONAL_OR_KEYWORD)])
119 __signature__ = Signature([Parameter('test', Parameter.POSITIONAL_OR_KEYWORD)])
120
120
121 def __init__(self, *args):
121 def __init__(self, *args):
122 """This is the init docstring"""
122 """This is the init docstring"""
123
123
124
124
125 class SimpleClass(object):
125 class SimpleClass(object):
126 def method(self, x, z=2):
126 def method(self, x, z=2):
127 """Some method's docstring"""
127 """Some method's docstring"""
128
128
129
129
130 class Awkward(object):
130 class Awkward(object):
131 def __getattr__(self, name):
131 def __getattr__(self, name):
132 raise Exception(name)
132 raise Exception(name)
133
133
134 class NoBoolCall:
134 class NoBoolCall:
135 """
135 """
136 callable with `__bool__` raising should still be inspect-able.
136 callable with `__bool__` raising should still be inspect-able.
137 """
137 """
138
138
139 def __call__(self):
139 def __call__(self):
140 """does nothing"""
140 """does nothing"""
141 pass
141 pass
142
142
143 def __bool__(self):
143 def __bool__(self):
144 """just raise NotImplemented"""
144 """just raise NotImplemented"""
145 raise NotImplementedError('Must be implemented')
145 raise NotImplementedError('Must be implemented')
146
146
147
147
148 class SerialLiar(object):
148 class SerialLiar(object):
149 """Attribute accesses always get another copy of the same class.
149 """Attribute accesses always get another copy of the same class.
150
150
151 unittest.mock.call does something similar, but it's not ideal for testing
151 unittest.mock.call does something similar, but it's not ideal for testing
152 as the failure mode is to eat all your RAM. This gives up after 10k levels.
152 as the failure mode is to eat all your RAM. This gives up after 10k levels.
153 """
153 """
154 def __init__(self, max_fibbing_twig, lies_told=0):
154 def __init__(self, max_fibbing_twig, lies_told=0):
155 if lies_told > 10000:
155 if lies_told > 10000:
156 raise RuntimeError('Nose too long, honesty is the best policy')
156 raise RuntimeError('Nose too long, honesty is the best policy')
157 self.max_fibbing_twig = max_fibbing_twig
157 self.max_fibbing_twig = max_fibbing_twig
158 self.lies_told = lies_told
158 self.lies_told = lies_told
159 max_fibbing_twig[0] = max(max_fibbing_twig[0], lies_told)
159 max_fibbing_twig[0] = max(max_fibbing_twig[0], lies_told)
160
160
161 def __getattr__(self, item):
161 def __getattr__(self, item):
162 return SerialLiar(self.max_fibbing_twig, self.lies_told + 1)
162 return SerialLiar(self.max_fibbing_twig, self.lies_told + 1)
163
163
164 #-----------------------------------------------------------------------------
164 #-----------------------------------------------------------------------------
165 # Tests
165 # Tests
166 #-----------------------------------------------------------------------------
166 #-----------------------------------------------------------------------------
167
167
168 def test_info():
168 def test_info():
169 "Check that Inspector.info fills out various fields as expected."
169 "Check that Inspector.info fills out various fields as expected."
170 i = inspector.info(Call, oname='Call')
170 i = inspector.info(Call, oname="Call")
171 nt.assert_equal(i['type_name'], 'type')
171 assert i["type_name"] == "type"
172 expted_class = str(type(type)) # <class 'type'> (Python 3) or <type 'type'>
172 expted_class = str(type(type)) # <class 'type'> (Python 3) or <type 'type'>
173 nt.assert_equal(i['base_class'], expted_class)
173 assert i["base_class"] == expted_class
174 nt.assert_regex(i['string_form'], "<class 'IPython.core.tests.test_oinspect.Call'( at 0x[0-9a-f]{1,9})?>")
174 nt.assert_regex(
175 i["string_form"],
176 "<class 'IPython.core.tests.test_oinspect.Call'( at 0x[0-9a-f]{1,9})?>",
177 )
175 fname = __file__
178 fname = __file__
176 if fname.endswith(".pyc"):
179 if fname.endswith(".pyc"):
177 fname = fname[:-1]
180 fname = fname[:-1]
178 # case-insensitive comparison needed on some filesystems
181 # case-insensitive comparison needed on some filesystems
179 # e.g. Windows:
182 # e.g. Windows:
180 nt.assert_equal(i['file'].lower(), compress_user(fname).lower())
183 assert i["file"].lower() == compress_user(fname).lower()
181 nt.assert_equal(i['definition'], None)
184 assert i["definition"] == None
182 nt.assert_equal(i['docstring'], Call.__doc__)
185 assert i["docstring"] == Call.__doc__
183 nt.assert_equal(i['source'], None)
186 assert i["source"] == None
184 nt.assert_true(i['isclass'])
187 nt.assert_true(i["isclass"])
185 nt.assert_equal(i['init_definition'], "Call(x, y=1)")
188 assert i["init_definition"] == "Call(x, y=1)"
186 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
189 assert i["init_docstring"] == Call.__init__.__doc__
187
190
188 i = inspector.info(Call, detail_level=1)
191 i = inspector.info(Call, detail_level=1)
189 nt.assert_not_equal(i['source'], None)
192 nt.assert_not_equal(i["source"], None)
190 nt.assert_equal(i['docstring'], None)
193 assert i["docstring"] == None
191
194
192 c = Call(1)
195 c = Call(1)
193 c.__doc__ = "Modified instance docstring"
196 c.__doc__ = "Modified instance docstring"
194 i = inspector.info(c)
197 i = inspector.info(c)
195 nt.assert_equal(i['type_name'], 'Call')
198 assert i["type_name"] == "Call"
196 nt.assert_equal(i['docstring'], "Modified instance docstring")
199 assert i["docstring"] == "Modified instance docstring"
197 nt.assert_equal(i['class_docstring'], Call.__doc__)
200 assert i["class_docstring"] == Call.__doc__
198 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
201 assert i["init_docstring"] == Call.__init__.__doc__
199 nt.assert_equal(i['call_docstring'], Call.__call__.__doc__)
202 assert i["call_docstring"] == Call.__call__.__doc__
203
200
204
201 def test_class_signature():
205 def test_class_signature():
202 info = inspector.info(HasSignature, 'HasSignature')
206 info = inspector.info(HasSignature, "HasSignature")
203 nt.assert_equal(info['init_definition'], "HasSignature(test)")
207 assert info["init_definition"] == "HasSignature(test)"
204 nt.assert_equal(info['init_docstring'], HasSignature.__init__.__doc__)
208 assert info["init_docstring"] == HasSignature.__init__.__doc__
209
205
210
206 def test_info_awkward():
211 def test_info_awkward():
207 # Just test that this doesn't throw an error.
212 # Just test that this doesn't throw an error.
208 inspector.info(Awkward())
213 inspector.info(Awkward())
209
214
210 def test_bool_raise():
215 def test_bool_raise():
211 inspector.info(NoBoolCall())
216 inspector.info(NoBoolCall())
212
217
213 def test_info_serialliar():
218 def test_info_serialliar():
214 fib_tracker = [0]
219 fib_tracker = [0]
215 inspector.info(SerialLiar(fib_tracker))
220 inspector.info(SerialLiar(fib_tracker))
216
221
217 # Nested attribute access should be cut off at 100 levels deep to avoid
222 # Nested attribute access should be cut off at 100 levels deep to avoid
218 # infinite loops: https://github.com/ipython/ipython/issues/9122
223 # infinite loops: https://github.com/ipython/ipython/issues/9122
219 nt.assert_less(fib_tracker[0], 9000)
224 nt.assert_less(fib_tracker[0], 9000)
220
225
221 def support_function_one(x, y=2, *a, **kw):
226 def support_function_one(x, y=2, *a, **kw):
222 """A simple function."""
227 """A simple function."""
223
228
224 def test_calldef_none():
229 def test_calldef_none():
225 # We should ignore __call__ for all of these.
230 # We should ignore __call__ for all of these.
226 for obj in [support_function_one, SimpleClass().method, any, str.upper]:
231 for obj in [support_function_one, SimpleClass().method, any, str.upper]:
227 i = inspector.info(obj)
232 i = inspector.info(obj)
228 nt.assert_is(i['call_def'], None)
233 nt.assert_is(i['call_def'], None)
229
234
230 def f_kwarg(pos, *, kwonly):
235 def f_kwarg(pos, *, kwonly):
231 pass
236 pass
232
237
233 def test_definition_kwonlyargs():
238 def test_definition_kwonlyargs():
234 i = inspector.info(f_kwarg, oname='f_kwarg') # analysis:ignore
239 i = inspector.info(f_kwarg, oname="f_kwarg") # analysis:ignore
235 nt.assert_equal(i['definition'], "f_kwarg(pos, *, kwonly)")
240 assert i["definition"] == "f_kwarg(pos, *, kwonly)"
241
236
242
237 def test_getdoc():
243 def test_getdoc():
238 class A(object):
244 class A(object):
239 """standard docstring"""
245 """standard docstring"""
240 pass
246 pass
241
247
242 class B(object):
248 class B(object):
243 """standard docstring"""
249 """standard docstring"""
244 def getdoc(self):
250 def getdoc(self):
245 return "custom docstring"
251 return "custom docstring"
246
252
247 class C(object):
253 class C(object):
248 """standard docstring"""
254 """standard docstring"""
249 def getdoc(self):
255 def getdoc(self):
250 return None
256 return None
251
257
252 a = A()
258 a = A()
253 b = B()
259 b = B()
254 c = C()
260 c = C()
255
261
256 nt.assert_equal(oinspect.getdoc(a), "standard docstring")
262 assert oinspect.getdoc(a) == "standard docstring"
257 nt.assert_equal(oinspect.getdoc(b), "custom docstring")
263 assert oinspect.getdoc(b) == "custom docstring"
258 nt.assert_equal(oinspect.getdoc(c), "standard docstring")
264 assert oinspect.getdoc(c) == "standard docstring"
259
265
260
266
261 def test_empty_property_has_no_source():
267 def test_empty_property_has_no_source():
262 i = inspector.info(property(), detail_level=1)
268 i = inspector.info(property(), detail_level=1)
263 nt.assert_is(i['source'], None)
269 nt.assert_is(i['source'], None)
264
270
265
271
266 def test_property_sources():
272 def test_property_sources():
267 import posixpath
273 import posixpath
268 # A simple adder whose source and signature stays
274 # A simple adder whose source and signature stays
269 # the same across Python distributions
275 # the same across Python distributions
270 def simple_add(a, b):
276 def simple_add(a, b):
271 "Adds two numbers"
277 "Adds two numbers"
272 return a + b
278 return a + b
273
279
274 class A(object):
280 class A(object):
275 @property
281 @property
276 def foo(self):
282 def foo(self):
277 return 'bar'
283 return 'bar'
278
284
279 foo = foo.setter(lambda self, v: setattr(self, 'bar', v))
285 foo = foo.setter(lambda self, v: setattr(self, 'bar', v))
280
286
281 dname = property(posixpath.dirname)
287 dname = property(posixpath.dirname)
282 adder = property(simple_add)
288 adder = property(simple_add)
283
289
284 i = inspector.info(A.foo, detail_level=1)
290 i = inspector.info(A.foo, detail_level=1)
285 nt.assert_in('def foo(self):', i['source'])
291 nt.assert_in('def foo(self):', i['source'])
286 nt.assert_in('lambda self, v:', i['source'])
292 nt.assert_in('lambda self, v:', i['source'])
287
293
288 i = inspector.info(A.dname, detail_level=1)
294 i = inspector.info(A.dname, detail_level=1)
289 nt.assert_in('def dirname(p)', i['source'])
295 nt.assert_in('def dirname(p)', i['source'])
290
296
291 i = inspector.info(A.adder, detail_level=1)
297 i = inspector.info(A.adder, detail_level=1)
292 nt.assert_in('def simple_add(a, b)', i['source'])
298 nt.assert_in('def simple_add(a, b)', i['source'])
293
299
294
300
295 def test_property_docstring_is_in_info_for_detail_level_0():
301 def test_property_docstring_is_in_info_for_detail_level_0():
296 class A(object):
302 class A(object):
297 @property
303 @property
298 def foobar(self):
304 def foobar(self):
299 """This is `foobar` property."""
305 """This is `foobar` property."""
300 pass
306 pass
301
307
302 ip.user_ns['a_obj'] = A()
308 ip.user_ns["a_obj"] = A()
303 nt.assert_equal(
309 assert (
304 'This is `foobar` property.',
310 "This is `foobar` property."
305 ip.object_inspect('a_obj.foobar', detail_level=0)['docstring'])
311 == ip.object_inspect("a_obj.foobar", detail_level=0)["docstring"]
312 )
306
313
307 ip.user_ns['a_cls'] = A
314 ip.user_ns["a_cls"] = A
308 nt.assert_equal(
315 assert (
309 'This is `foobar` property.',
316 "This is `foobar` property."
310 ip.object_inspect('a_cls.foobar', detail_level=0)['docstring'])
317 == ip.object_inspect("a_cls.foobar", detail_level=0)["docstring"]
318 )
311
319
312
320
313 def test_pdef():
321 def test_pdef():
314 # See gh-1914
322 # See gh-1914
315 def foo(): pass
323 def foo(): pass
316 inspector.pdef(foo, 'foo')
324 inspector.pdef(foo, 'foo')
317
325
318
326
319 def test_pinfo_nonascii():
327 def test_pinfo_nonascii():
320 # See gh-1177
328 # See gh-1177
321 from . import nonascii2
329 from . import nonascii2
322 ip.user_ns['nonascii2'] = nonascii2
330 ip.user_ns['nonascii2'] = nonascii2
323 ip._inspect('pinfo', 'nonascii2', detail_level=1)
331 ip._inspect('pinfo', 'nonascii2', detail_level=1)
324
332
325 def test_pinfo_type():
333 def test_pinfo_type():
326 """
334 """
327 type can fail in various edge case, for example `type.__subclass__()`
335 type can fail in various edge case, for example `type.__subclass__()`
328 """
336 """
329 ip._inspect('pinfo', 'type')
337 ip._inspect('pinfo', 'type')
330
338
331
339
332 def test_pinfo_docstring_no_source():
340 def test_pinfo_docstring_no_source():
333 """Docstring should be included with detail_level=1 if there is no source"""
341 """Docstring should be included with detail_level=1 if there is no source"""
334 with AssertPrints('Docstring:'):
342 with AssertPrints('Docstring:'):
335 ip._inspect('pinfo', 'str.format', detail_level=0)
343 ip._inspect('pinfo', 'str.format', detail_level=0)
336 with AssertPrints('Docstring:'):
344 with AssertPrints('Docstring:'):
337 ip._inspect('pinfo', 'str.format', detail_level=1)
345 ip._inspect('pinfo', 'str.format', detail_level=1)
338
346
339
347
340 def test_pinfo_no_docstring_if_source():
348 def test_pinfo_no_docstring_if_source():
341 """Docstring should not be included with detail_level=1 if source is found"""
349 """Docstring should not be included with detail_level=1 if source is found"""
342 def foo():
350 def foo():
343 """foo has a docstring"""
351 """foo has a docstring"""
344
352
345 ip.user_ns['foo'] = foo
353 ip.user_ns['foo'] = foo
346
354
347 with AssertPrints('Docstring:'):
355 with AssertPrints('Docstring:'):
348 ip._inspect('pinfo', 'foo', detail_level=0)
356 ip._inspect('pinfo', 'foo', detail_level=0)
349 with AssertPrints('Source:'):
357 with AssertPrints('Source:'):
350 ip._inspect('pinfo', 'foo', detail_level=1)
358 ip._inspect('pinfo', 'foo', detail_level=1)
351 with AssertNotPrints('Docstring:'):
359 with AssertNotPrints('Docstring:'):
352 ip._inspect('pinfo', 'foo', detail_level=1)
360 ip._inspect('pinfo', 'foo', detail_level=1)
353
361
354
362
355 def test_pinfo_docstring_if_detail_and_no_source():
363 def test_pinfo_docstring_if_detail_and_no_source():
356 """ Docstring should be displayed if source info not available """
364 """ Docstring should be displayed if source info not available """
357 obj_def = '''class Foo(object):
365 obj_def = '''class Foo(object):
358 """ This is a docstring for Foo """
366 """ This is a docstring for Foo """
359 def bar(self):
367 def bar(self):
360 """ This is a docstring for Foo.bar """
368 """ This is a docstring for Foo.bar """
361 pass
369 pass
362 '''
370 '''
363
371
364 ip.run_cell(obj_def)
372 ip.run_cell(obj_def)
365 ip.run_cell('foo = Foo()')
373 ip.run_cell('foo = Foo()')
366
374
367 with AssertNotPrints("Source:"):
375 with AssertNotPrints("Source:"):
368 with AssertPrints('Docstring:'):
376 with AssertPrints('Docstring:'):
369 ip._inspect('pinfo', 'foo', detail_level=0)
377 ip._inspect('pinfo', 'foo', detail_level=0)
370 with AssertPrints('Docstring:'):
378 with AssertPrints('Docstring:'):
371 ip._inspect('pinfo', 'foo', detail_level=1)
379 ip._inspect('pinfo', 'foo', detail_level=1)
372 with AssertPrints('Docstring:'):
380 with AssertPrints('Docstring:'):
373 ip._inspect('pinfo', 'foo.bar', detail_level=0)
381 ip._inspect('pinfo', 'foo.bar', detail_level=0)
374
382
375 with AssertNotPrints('Docstring:'):
383 with AssertNotPrints('Docstring:'):
376 with AssertPrints('Source:'):
384 with AssertPrints('Source:'):
377 ip._inspect('pinfo', 'foo.bar', detail_level=1)
385 ip._inspect('pinfo', 'foo.bar', detail_level=1)
378
386
379
387
380 def test_pinfo_magic():
388 def test_pinfo_magic():
381 with AssertPrints('Docstring:'):
389 with AssertPrints('Docstring:'):
382 ip._inspect('pinfo', 'lsmagic', detail_level=0)
390 ip._inspect('pinfo', 'lsmagic', detail_level=0)
383
391
384 with AssertPrints('Source:'):
392 with AssertPrints('Source:'):
385 ip._inspect('pinfo', 'lsmagic', detail_level=1)
393 ip._inspect('pinfo', 'lsmagic', detail_level=1)
386
394
387
395
388 def test_init_colors():
396 def test_init_colors():
389 # ensure colors are not present in signature info
397 # ensure colors are not present in signature info
390 info = inspector.info(HasSignature)
398 info = inspector.info(HasSignature)
391 init_def = info['init_definition']
399 init_def = info['init_definition']
392 nt.assert_not_in('[0m', init_def)
400 nt.assert_not_in('[0m', init_def)
393
401
394
402
395 def test_builtin_init():
403 def test_builtin_init():
396 info = inspector.info(list)
404 info = inspector.info(list)
397 init_def = info['init_definition']
405 init_def = info['init_definition']
398 nt.assert_is_not_none(init_def)
406 nt.assert_is_not_none(init_def)
399
407
400
408
401 def test_render_signature_short():
409 def test_render_signature_short():
402 def short_fun(a=1): pass
410 def short_fun(a=1): pass
403 sig = oinspect._render_signature(
411 sig = oinspect._render_signature(
404 signature(short_fun),
412 signature(short_fun),
405 short_fun.__name__,
413 short_fun.__name__,
406 )
414 )
407 nt.assert_equal(sig, 'short_fun(a=1)')
415 assert sig == "short_fun(a=1)"
408
416
409
417
410 def test_render_signature_long():
418 def test_render_signature_long():
411 from typing import Optional
419 from typing import Optional
412
420
413 def long_function(
421 def long_function(
414 a_really_long_parameter: int,
422 a_really_long_parameter: int,
415 and_another_long_one: bool = False,
423 and_another_long_one: bool = False,
416 let_us_make_sure_this_is_looong: Optional[str] = None,
424 let_us_make_sure_this_is_looong: Optional[str] = None,
417 ) -> bool: pass
425 ) -> bool: pass
418
426
419 sig = oinspect._render_signature(
427 sig = oinspect._render_signature(
420 signature(long_function),
428 signature(long_function),
421 long_function.__name__,
429 long_function.__name__,
422 )
430 )
423 nt.assert_in(sig, [
431 nt.assert_in(sig, [
424 # Python >=3.9
432 # Python >=3.9
425 '''\
433 '''\
426 long_function(
434 long_function(
427 a_really_long_parameter: int,
435 a_really_long_parameter: int,
428 and_another_long_one: bool = False,
436 and_another_long_one: bool = False,
429 let_us_make_sure_this_is_looong: Optional[str] = None,
437 let_us_make_sure_this_is_looong: Optional[str] = None,
430 ) -> bool\
438 ) -> bool\
431 ''',
439 ''',
432 # Python >=3.7
440 # Python >=3.7
433 '''\
441 '''\
434 long_function(
442 long_function(
435 a_really_long_parameter: int,
443 a_really_long_parameter: int,
436 and_another_long_one: bool = False,
444 and_another_long_one: bool = False,
437 let_us_make_sure_this_is_looong: Union[str, NoneType] = None,
445 let_us_make_sure_this_is_looong: Union[str, NoneType] = None,
438 ) -> bool\
446 ) -> bool\
439 ''', # Python <=3.6
447 ''', # Python <=3.6
440 '''\
448 '''\
441 long_function(
449 long_function(
442 a_really_long_parameter:int,
450 a_really_long_parameter:int,
443 and_another_long_one:bool=False,
451 and_another_long_one:bool=False,
444 let_us_make_sure_this_is_looong:Union[str, NoneType]=None,
452 let_us_make_sure_this_is_looong:Union[str, NoneType]=None,
445 ) -> bool\
453 ) -> bool\
446 ''',
454 ''',
447 ])
455 ])
General Comments 0
You need to be logged in to leave comments. Login now