##// END OF EJS Templates
cleanup
Srinivas Reddy Thatiparthy -
Show More
@@ -1,74 +1,74 b''
1 # coding: utf-8
1 # coding: utf-8
2 """Tests for the compilerop module.
2 """Tests for the compilerop module.
3 """
3 """
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2010-2011 The IPython Development Team.
5 # Copyright (C) 2010-2011 The IPython Development Team.
6 #
6 #
7 # Distributed under the terms of the BSD License.
7 # Distributed under the terms of the BSD License.
8 #
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 # Stdlib imports
16 # Stdlib imports
17 import linecache
17 import linecache
18 import sys
18 import sys
19
19
20 # Third-party imports
20 # Third-party imports
21 import nose.tools as nt
21 import nose.tools as nt
22
22
23 # Our own imports
23 # Our own imports
24 from IPython.core import compilerop
24 from IPython.core import compilerop
25 from IPython.utils import py3compat
25 from IPython.utils import py3compat
26
26
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28 # Test functions
28 # Test functions
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30
30
31 def test_code_name():
31 def test_code_name():
32 code = 'x=1'
32 code = 'x=1'
33 name = compilerop.code_name(code)
33 name = compilerop.code_name(code)
34 nt.assert_true(name.startswith('<ipython-input-0'))
34 nt.assert_true(name.startswith('<ipython-input-0'))
35
35
36
36
37 def test_code_name2():
37 def test_code_name2():
38 code = 'x=1'
38 code = 'x=1'
39 name = compilerop.code_name(code, 9)
39 name = compilerop.code_name(code, 9)
40 nt.assert_true(name.startswith('<ipython-input-9'))
40 nt.assert_true(name.startswith('<ipython-input-9'))
41
41
42
42
43 def test_cache():
43 def test_cache():
44 """Test the compiler correctly compiles and caches inputs
44 """Test the compiler correctly compiles and caches inputs
45 """
45 """
46 cp = compilerop.CachingCompiler()
46 cp = compilerop.CachingCompiler()
47 ncache = len(linecache.cache)
47 ncache = len(linecache.cache)
48 cp.cache('x=1')
48 cp.cache('x=1')
49 nt.assert_true(len(linecache.cache) > ncache)
49 nt.assert_true(len(linecache.cache) > ncache)
50
50
51 def setUp():
51 def setUp():
52 # Check we're in a proper Python 2 environment (some imports, such
52 # Check we're in a proper Python 2 environment (some imports, such
53 # as GTK, can change the default encoding, which can hide bugs.)
53 # as GTK, can change the default encoding, which can hide bugs.)
54 nt.assert_equal(sys.getdefaultencoding(), "utf-8" if py3compat.PY3 else "ascii")
54 nt.assert_equal(sys.getdefaultencoding(), "utf-8")
55
55
56 def test_cache_unicode():
56 def test_cache_unicode():
57 cp = compilerop.CachingCompiler()
57 cp = compilerop.CachingCompiler()
58 ncache = len(linecache.cache)
58 ncache = len(linecache.cache)
59 cp.cache(u"t = 'žćčőđ'")
59 cp.cache(u"t = 'žćčőđ'")
60 nt.assert_true(len(linecache.cache) > ncache)
60 nt.assert_true(len(linecache.cache) > ncache)
61
61
62 def test_compiler_check_cache():
62 def test_compiler_check_cache():
63 """Test the compiler properly manages the cache.
63 """Test the compiler properly manages the cache.
64 """
64 """
65 # Rather simple-minded tests that just exercise the API
65 # Rather simple-minded tests that just exercise the API
66 cp = compilerop.CachingCompiler()
66 cp = compilerop.CachingCompiler()
67 cp.cache('x=1', 99)
67 cp.cache('x=1', 99)
68 # Ensure now that after clearing the cache, our entries survive
68 # Ensure now that after clearing the cache, our entries survive
69 linecache.checkcache()
69 linecache.checkcache()
70 for k in linecache.cache:
70 for k in linecache.cache:
71 if k.startswith('<ipython-input-99'):
71 if k.startswith('<ipython-input-99'):
72 break
72 break
73 else:
73 else:
74 raise AssertionError('Entry for input-99 missing from linecache')
74 raise AssertionError('Entry for input-99 missing from linecache')
@@ -1,419 +1,418 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, Parameter
8 from inspect import Signature, Parameter
9 import os
9 import os
10 import re
10 import re
11 import sys
11 import sys
12
12
13 import nose.tools as nt
13 import nose.tools as nt
14
14
15 from .. import oinspect
15 from .. import oinspect
16 from IPython.core.magic import (Magics, magics_class, line_magic,
16 from IPython.core.magic import (Magics, magics_class, line_magic,
17 cell_magic, line_cell_magic,
17 cell_magic, line_cell_magic,
18 register_line_magic, register_cell_magic,
18 register_line_magic, register_cell_magic,
19 register_line_cell_magic)
19 register_line_cell_magic)
20 from decorator import decorator
20 from decorator import decorator
21 from IPython import get_ipython
21 from IPython import get_ipython
22 from IPython.testing.decorators import skipif
22 from IPython.testing.decorators import skipif
23 from IPython.testing.tools import AssertPrints, AssertNotPrints
23 from IPython.testing.tools import AssertPrints, AssertNotPrints
24 from IPython.utils.path import compress_user
24 from IPython.utils.path import compress_user
25 from IPython.utils import py3compat
25 from IPython.utils import py3compat
26
26
27
27
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29 # Globals and constants
29 # Globals and constants
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31
31
32 inspector = oinspect.Inspector()
32 inspector = oinspect.Inspector()
33 ip = get_ipython()
33 ip = get_ipython()
34
34
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36 # Local utilities
36 # Local utilities
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38
38
39 # WARNING: since this test checks the line number where a function is
39 # WARNING: since this test checks the line number where a function is
40 # defined, if any code is inserted above, the following line will need to be
40 # defined, if any code is inserted above, the following line will need to be
41 # updated. Do NOT insert any whitespace between the next line and the function
41 # updated. Do NOT insert any whitespace between the next line and the function
42 # definition below.
42 # definition below.
43 THIS_LINE_NUMBER = 43 # Put here the actual number of this line
43 THIS_LINE_NUMBER = 43 # Put here the actual number of this line
44
44
45 from unittest import TestCase
45 from unittest import TestCase
46
46
47 class Test(TestCase):
47 class Test(TestCase):
48
48
49 def test_find_source_lines(self):
49 def test_find_source_lines(self):
50 self.assertEqual(oinspect.find_source_lines(Test.test_find_source_lines),
50 self.assertEqual(oinspect.find_source_lines(Test.test_find_source_lines),
51 THIS_LINE_NUMBER+6)
51 THIS_LINE_NUMBER+6)
52
52
53
53
54 # A couple of utilities to ensure these tests work the same from a source or a
54 # A couple of utilities to ensure these tests work the same from a source or a
55 # binary install
55 # binary install
56 def pyfile(fname):
56 def pyfile(fname):
57 return os.path.normcase(re.sub('.py[co]$', '.py', fname))
57 return os.path.normcase(re.sub('.py[co]$', '.py', fname))
58
58
59
59
60 def match_pyfiles(f1, f2):
60 def match_pyfiles(f1, f2):
61 nt.assert_equal(pyfile(f1), pyfile(f2))
61 nt.assert_equal(pyfile(f1), pyfile(f2))
62
62
63
63
64 def test_find_file():
64 def test_find_file():
65 match_pyfiles(oinspect.find_file(test_find_file), os.path.abspath(__file__))
65 match_pyfiles(oinspect.find_file(test_find_file), os.path.abspath(__file__))
66
66
67
67
68 def test_find_file_decorated1():
68 def test_find_file_decorated1():
69
69
70 @decorator
70 @decorator
71 def noop1(f):
71 def noop1(f):
72 def wrapper(*a, **kw):
72 def wrapper(*a, **kw):
73 return f(*a, **kw)
73 return f(*a, **kw)
74 return wrapper
74 return wrapper
75
75
76 @noop1
76 @noop1
77 def f(x):
77 def f(x):
78 "My docstring"
78 "My docstring"
79
79
80 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
80 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
81 nt.assert_equal(f.__doc__, "My docstring")
81 nt.assert_equal(f.__doc__, "My docstring")
82
82
83
83
84 def test_find_file_decorated2():
84 def test_find_file_decorated2():
85
85
86 @decorator
86 @decorator
87 def noop2(f, *a, **kw):
87 def noop2(f, *a, **kw):
88 return f(*a, **kw)
88 return f(*a, **kw)
89
89
90 @noop2
90 @noop2
91 @noop2
91 @noop2
92 @noop2
92 @noop2
93 def f(x):
93 def f(x):
94 "My docstring 2"
94 "My docstring 2"
95
95
96 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
96 match_pyfiles(oinspect.find_file(f), os.path.abspath(__file__))
97 nt.assert_equal(f.__doc__, "My docstring 2")
97 nt.assert_equal(f.__doc__, "My docstring 2")
98
98
99
99
100 def test_find_file_magic():
100 def test_find_file_magic():
101 run = ip.find_line_magic('run')
101 run = ip.find_line_magic('run')
102 nt.assert_not_equal(oinspect.find_file(run), None)
102 nt.assert_not_equal(oinspect.find_file(run), None)
103
103
104
104
105 # A few generic objects we can then inspect in the tests below
105 # A few generic objects we can then inspect in the tests below
106
106
107 class Call(object):
107 class Call(object):
108 """This is the class docstring."""
108 """This is the class docstring."""
109
109
110 def __init__(self, x, y=1):
110 def __init__(self, x, y=1):
111 """This is the constructor docstring."""
111 """This is the constructor docstring."""
112
112
113 def __call__(self, *a, **kw):
113 def __call__(self, *a, **kw):
114 """This is the call docstring."""
114 """This is the call docstring."""
115
115
116 def method(self, x, z=2):
116 def method(self, x, z=2):
117 """Some method's docstring"""
117 """Some method's docstring"""
118
118
119 class HasSignature(object):
119 class HasSignature(object):
120 """This is the class docstring."""
120 """This is the class docstring."""
121 __signature__ = Signature([Parameter('test', Parameter.POSITIONAL_OR_KEYWORD)])
121 __signature__ = Signature([Parameter('test', Parameter.POSITIONAL_OR_KEYWORD)])
122
122
123 def __init__(self, *args):
123 def __init__(self, *args):
124 """This is the init docstring"""
124 """This is the init docstring"""
125
125
126
126
127 class SimpleClass(object):
127 class SimpleClass(object):
128 def method(self, x, z=2):
128 def method(self, x, z=2):
129 """Some method's docstring"""
129 """Some method's docstring"""
130
130
131
131
132 class OldStyle:
132 class OldStyle:
133 """An old-style class for testing."""
133 """An old-style class for testing."""
134 pass
134 pass
135
135
136
136
137 def f(x, y=2, *a, **kw):
137 def f(x, y=2, *a, **kw):
138 """A simple function."""
138 """A simple function."""
139
139
140
140
141 def g(y, z=3, *a, **kw):
141 def g(y, z=3, *a, **kw):
142 pass # no docstring
142 pass # no docstring
143
143
144
144
145 @register_line_magic
145 @register_line_magic
146 def lmagic(line):
146 def lmagic(line):
147 "A line magic"
147 "A line magic"
148
148
149
149
150 @register_cell_magic
150 @register_cell_magic
151 def cmagic(line, cell):
151 def cmagic(line, cell):
152 "A cell magic"
152 "A cell magic"
153
153
154
154
155 @register_line_cell_magic
155 @register_line_cell_magic
156 def lcmagic(line, cell=None):
156 def lcmagic(line, cell=None):
157 "A line/cell magic"
157 "A line/cell magic"
158
158
159
159
160 @magics_class
160 @magics_class
161 class SimpleMagics(Magics):
161 class SimpleMagics(Magics):
162 @line_magic
162 @line_magic
163 def Clmagic(self, cline):
163 def Clmagic(self, cline):
164 "A class-based line magic"
164 "A class-based line magic"
165
165
166 @cell_magic
166 @cell_magic
167 def Ccmagic(self, cline, ccell):
167 def Ccmagic(self, cline, ccell):
168 "A class-based cell magic"
168 "A class-based cell magic"
169
169
170 @line_cell_magic
170 @line_cell_magic
171 def Clcmagic(self, cline, ccell=None):
171 def Clcmagic(self, cline, ccell=None):
172 "A class-based line/cell magic"
172 "A class-based line/cell magic"
173
173
174
174
175 class Awkward(object):
175 class Awkward(object):
176 def __getattr__(self, name):
176 def __getattr__(self, name):
177 raise Exception(name)
177 raise Exception(name)
178
178
179 class NoBoolCall:
179 class NoBoolCall:
180 """
180 """
181 callable with `__bool__` raising should still be inspect-able.
181 callable with `__bool__` raising should still be inspect-able.
182 """
182 """
183
183
184 def __call__(self):
184 def __call__(self):
185 """does nothing"""
185 """does nothing"""
186 pass
186 pass
187
187
188 def __bool__(self):
188 def __bool__(self):
189 """just raise NotImplemented"""
189 """just raise NotImplemented"""
190 raise NotImplementedError('Must be implemented')
190 raise NotImplementedError('Must be implemented')
191
191
192
192
193 class SerialLiar(object):
193 class SerialLiar(object):
194 """Attribute accesses always get another copy of the same class.
194 """Attribute accesses always get another copy of the same class.
195
195
196 unittest.mock.call does something similar, but it's not ideal for testing
196 unittest.mock.call does something similar, but it's not ideal for testing
197 as the failure mode is to eat all your RAM. This gives up after 10k levels.
197 as the failure mode is to eat all your RAM. This gives up after 10k levels.
198 """
198 """
199 def __init__(self, max_fibbing_twig, lies_told=0):
199 def __init__(self, max_fibbing_twig, lies_told=0):
200 if lies_told > 10000:
200 if lies_told > 10000:
201 raise RuntimeError('Nose too long, honesty is the best policy')
201 raise RuntimeError('Nose too long, honesty is the best policy')
202 self.max_fibbing_twig = max_fibbing_twig
202 self.max_fibbing_twig = max_fibbing_twig
203 self.lies_told = lies_told
203 self.lies_told = lies_told
204 max_fibbing_twig[0] = max(max_fibbing_twig[0], lies_told)
204 max_fibbing_twig[0] = max(max_fibbing_twig[0], lies_told)
205
205
206 def __getattr__(self, item):
206 def __getattr__(self, item):
207 return SerialLiar(self.max_fibbing_twig, self.lies_told + 1)
207 return SerialLiar(self.max_fibbing_twig, self.lies_told + 1)
208
208
209 #-----------------------------------------------------------------------------
209 #-----------------------------------------------------------------------------
210 # Tests
210 # Tests
211 #-----------------------------------------------------------------------------
211 #-----------------------------------------------------------------------------
212
212
213 def test_info():
213 def test_info():
214 "Check that Inspector.info fills out various fields as expected."
214 "Check that Inspector.info fills out various fields as expected."
215 i = inspector.info(Call, oname='Call')
215 i = inspector.info(Call, oname='Call')
216 nt.assert_equal(i['type_name'], 'type')
216 nt.assert_equal(i['type_name'], 'type')
217 expted_class = str(type(type)) # <class 'type'> (Python 3) or <type 'type'>
217 expted_class = str(type(type)) # <class 'type'> (Python 3) or <type 'type'>
218 nt.assert_equal(i['base_class'], expted_class)
218 nt.assert_equal(i['base_class'], expted_class)
219 nt.assert_regex(i['string_form'], "<class 'IPython.core.tests.test_oinspect.Call'( at 0x[0-9a-f]{1,9})?>")
219 nt.assert_regex(i['string_form'], "<class 'IPython.core.tests.test_oinspect.Call'( at 0x[0-9a-f]{1,9})?>")
220 fname = __file__
220 fname = __file__
221 if fname.endswith(".pyc"):
221 if fname.endswith(".pyc"):
222 fname = fname[:-1]
222 fname = fname[:-1]
223 # case-insensitive comparison needed on some filesystems
223 # case-insensitive comparison needed on some filesystems
224 # e.g. Windows:
224 # e.g. Windows:
225 nt.assert_equal(i['file'].lower(), compress_user(fname).lower())
225 nt.assert_equal(i['file'].lower(), compress_user(fname).lower())
226 nt.assert_equal(i['definition'], None)
226 nt.assert_equal(i['definition'], None)
227 nt.assert_equal(i['docstring'], Call.__doc__)
227 nt.assert_equal(i['docstring'], Call.__doc__)
228 nt.assert_equal(i['source'], None)
228 nt.assert_equal(i['source'], None)
229 nt.assert_true(i['isclass'])
229 nt.assert_true(i['isclass'])
230 _self_py2 = '' if py3compat.PY3 else 'self, '
230 nt.assert_equal(i['init_definition'], "Call(x, y=1)")
231 nt.assert_equal(i['init_definition'], "Call(%sx, y=1)" % _self_py2)
232 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
231 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
233
232
234 i = inspector.info(Call, detail_level=1)
233 i = inspector.info(Call, detail_level=1)
235 nt.assert_not_equal(i['source'], None)
234 nt.assert_not_equal(i['source'], None)
236 nt.assert_equal(i['docstring'], None)
235 nt.assert_equal(i['docstring'], None)
237
236
238 c = Call(1)
237 c = Call(1)
239 c.__doc__ = "Modified instance docstring"
238 c.__doc__ = "Modified instance docstring"
240 i = inspector.info(c)
239 i = inspector.info(c)
241 nt.assert_equal(i['type_name'], 'Call')
240 nt.assert_equal(i['type_name'], 'Call')
242 nt.assert_equal(i['docstring'], "Modified instance docstring")
241 nt.assert_equal(i['docstring'], "Modified instance docstring")
243 nt.assert_equal(i['class_docstring'], Call.__doc__)
242 nt.assert_equal(i['class_docstring'], Call.__doc__)
244 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
243 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
245 nt.assert_equal(i['call_docstring'], Call.__call__.__doc__)
244 nt.assert_equal(i['call_docstring'], Call.__call__.__doc__)
246
245
247 # Test old-style classes, which for example may not have an __init__ method.
246 # Test old-style classes, which for example may not have an __init__ method.
248 if not py3compat.PY3:
247 if not py3compat.PY3:
249 i = inspector.info(OldStyle)
248 i = inspector.info(OldStyle)
250 nt.assert_equal(i['type_name'], 'classobj')
249 nt.assert_equal(i['type_name'], 'classobj')
251
250
252 i = inspector.info(OldStyle())
251 i = inspector.info(OldStyle())
253 nt.assert_equal(i['type_name'], 'instance')
252 nt.assert_equal(i['type_name'], 'instance')
254 nt.assert_equal(i['docstring'], OldStyle.__doc__)
253 nt.assert_equal(i['docstring'], OldStyle.__doc__)
255
254
256 def test_class_signature():
255 def test_class_signature():
257 info = inspector.info(HasSignature, 'HasSignature')
256 info = inspector.info(HasSignature, 'HasSignature')
258 nt.assert_equal(info['init_definition'], "HasSignature(test)")
257 nt.assert_equal(info['init_definition'], "HasSignature(test)")
259 nt.assert_equal(info['init_docstring'], HasSignature.__init__.__doc__)
258 nt.assert_equal(info['init_docstring'], HasSignature.__init__.__doc__)
260
259
261 def test_info_awkward():
260 def test_info_awkward():
262 # Just test that this doesn't throw an error.
261 # Just test that this doesn't throw an error.
263 inspector.info(Awkward())
262 inspector.info(Awkward())
264
263
265 def test_bool_raise():
264 def test_bool_raise():
266 inspector.info(NoBoolCall())
265 inspector.info(NoBoolCall())
267
266
268 def test_info_serialliar():
267 def test_info_serialliar():
269 fib_tracker = [0]
268 fib_tracker = [0]
270 inspector.info(SerialLiar(fib_tracker))
269 inspector.info(SerialLiar(fib_tracker))
271
270
272 # Nested attribute access should be cut off at 100 levels deep to avoid
271 # Nested attribute access should be cut off at 100 levels deep to avoid
273 # infinite loops: https://github.com/ipython/ipython/issues/9122
272 # infinite loops: https://github.com/ipython/ipython/issues/9122
274 nt.assert_less(fib_tracker[0], 9000)
273 nt.assert_less(fib_tracker[0], 9000)
275
274
276 def test_calldef_none():
275 def test_calldef_none():
277 # We should ignore __call__ for all of these.
276 # We should ignore __call__ for all of these.
278 for obj in [f, SimpleClass().method, any, str.upper]:
277 for obj in [f, SimpleClass().method, any, str.upper]:
279 print(obj)
278 print(obj)
280 i = inspector.info(obj)
279 i = inspector.info(obj)
281 nt.assert_is(i['call_def'], None)
280 nt.assert_is(i['call_def'], None)
282
281
283 def f_kwarg(pos, *, kwonly):
282 def f_kwarg(pos, *, kwonly):
284 pass
283 pass
285
284
286 def test_definition_kwonlyargs():
285 def test_definition_kwonlyargs():
287 i = inspector.info(f_kwarg, oname='f_kwarg') # analysis:ignore
286 i = inspector.info(f_kwarg, oname='f_kwarg') # analysis:ignore
288 nt.assert_equal(i['definition'], "f_kwarg(pos, *, kwonly)")
287 nt.assert_equal(i['definition'], "f_kwarg(pos, *, kwonly)")
289
288
290 def test_getdoc():
289 def test_getdoc():
291 class A(object):
290 class A(object):
292 """standard docstring"""
291 """standard docstring"""
293 pass
292 pass
294
293
295 class B(object):
294 class B(object):
296 """standard docstring"""
295 """standard docstring"""
297 def getdoc(self):
296 def getdoc(self):
298 return "custom docstring"
297 return "custom docstring"
299
298
300 class C(object):
299 class C(object):
301 """standard docstring"""
300 """standard docstring"""
302 def getdoc(self):
301 def getdoc(self):
303 return None
302 return None
304
303
305 a = A()
304 a = A()
306 b = B()
305 b = B()
307 c = C()
306 c = C()
308
307
309 nt.assert_equal(oinspect.getdoc(a), "standard docstring")
308 nt.assert_equal(oinspect.getdoc(a), "standard docstring")
310 nt.assert_equal(oinspect.getdoc(b), "custom docstring")
309 nt.assert_equal(oinspect.getdoc(b), "custom docstring")
311 nt.assert_equal(oinspect.getdoc(c), "standard docstring")
310 nt.assert_equal(oinspect.getdoc(c), "standard docstring")
312
311
313
312
314 def test_empty_property_has_no_source():
313 def test_empty_property_has_no_source():
315 i = inspector.info(property(), detail_level=1)
314 i = inspector.info(property(), detail_level=1)
316 nt.assert_is(i['source'], None)
315 nt.assert_is(i['source'], None)
317
316
318
317
319 def test_property_sources():
318 def test_property_sources():
320 import zlib
319 import zlib
321
320
322 class A(object):
321 class A(object):
323 @property
322 @property
324 def foo(self):
323 def foo(self):
325 return 'bar'
324 return 'bar'
326
325
327 foo = foo.setter(lambda self, v: setattr(self, 'bar', v))
326 foo = foo.setter(lambda self, v: setattr(self, 'bar', v))
328
327
329 id = property(id)
328 id = property(id)
330 compress = property(zlib.compress)
329 compress = property(zlib.compress)
331
330
332 i = inspector.info(A.foo, detail_level=1)
331 i = inspector.info(A.foo, detail_level=1)
333 nt.assert_in('def foo(self):', i['source'])
332 nt.assert_in('def foo(self):', i['source'])
334 nt.assert_in('lambda self, v:', i['source'])
333 nt.assert_in('lambda self, v:', i['source'])
335
334
336 i = inspector.info(A.id, detail_level=1)
335 i = inspector.info(A.id, detail_level=1)
337 nt.assert_in('fget = <function id>', i['source'])
336 nt.assert_in('fget = <function id>', i['source'])
338
337
339 i = inspector.info(A.compress, detail_level=1)
338 i = inspector.info(A.compress, detail_level=1)
340 nt.assert_in('fget = <function zlib.compress>', i['source'])
339 nt.assert_in('fget = <function zlib.compress>', i['source'])
341
340
342
341
343 def test_property_docstring_is_in_info_for_detail_level_0():
342 def test_property_docstring_is_in_info_for_detail_level_0():
344 class A(object):
343 class A(object):
345 @property
344 @property
346 def foobar(self):
345 def foobar(self):
347 """This is `foobar` property."""
346 """This is `foobar` property."""
348 pass
347 pass
349
348
350 ip.user_ns['a_obj'] = A()
349 ip.user_ns['a_obj'] = A()
351 nt.assert_equal(
350 nt.assert_equal(
352 'This is `foobar` property.',
351 'This is `foobar` property.',
353 ip.object_inspect('a_obj.foobar', detail_level=0)['docstring'])
352 ip.object_inspect('a_obj.foobar', detail_level=0)['docstring'])
354
353
355 ip.user_ns['a_cls'] = A
354 ip.user_ns['a_cls'] = A
356 nt.assert_equal(
355 nt.assert_equal(
357 'This is `foobar` property.',
356 'This is `foobar` property.',
358 ip.object_inspect('a_cls.foobar', detail_level=0)['docstring'])
357 ip.object_inspect('a_cls.foobar', detail_level=0)['docstring'])
359
358
360
359
361 def test_pdef():
360 def test_pdef():
362 # See gh-1914
361 # See gh-1914
363 def foo(): pass
362 def foo(): pass
364 inspector.pdef(foo, 'foo')
363 inspector.pdef(foo, 'foo')
365
364
366
365
367 def test_pinfo_nonascii():
366 def test_pinfo_nonascii():
368 # See gh-1177
367 # See gh-1177
369 from . import nonascii2
368 from . import nonascii2
370 ip.user_ns['nonascii2'] = nonascii2
369 ip.user_ns['nonascii2'] = nonascii2
371 ip._inspect('pinfo', 'nonascii2', detail_level=1)
370 ip._inspect('pinfo', 'nonascii2', detail_level=1)
372
371
373
372
374 def test_pinfo_docstring_no_source():
373 def test_pinfo_docstring_no_source():
375 """Docstring should be included with detail_level=1 if there is no source"""
374 """Docstring should be included with detail_level=1 if there is no source"""
376 with AssertPrints('Docstring:'):
375 with AssertPrints('Docstring:'):
377 ip._inspect('pinfo', 'str.format', detail_level=0)
376 ip._inspect('pinfo', 'str.format', detail_level=0)
378 with AssertPrints('Docstring:'):
377 with AssertPrints('Docstring:'):
379 ip._inspect('pinfo', 'str.format', detail_level=1)
378 ip._inspect('pinfo', 'str.format', detail_level=1)
380
379
381
380
382 def test_pinfo_no_docstring_if_source():
381 def test_pinfo_no_docstring_if_source():
383 """Docstring should not be included with detail_level=1 if source is found"""
382 """Docstring should not be included with detail_level=1 if source is found"""
384 def foo():
383 def foo():
385 """foo has a docstring"""
384 """foo has a docstring"""
386
385
387 ip.user_ns['foo'] = foo
386 ip.user_ns['foo'] = foo
388
387
389 with AssertPrints('Docstring:'):
388 with AssertPrints('Docstring:'):
390 ip._inspect('pinfo', 'foo', detail_level=0)
389 ip._inspect('pinfo', 'foo', detail_level=0)
391 with AssertPrints('Source:'):
390 with AssertPrints('Source:'):
392 ip._inspect('pinfo', 'foo', detail_level=1)
391 ip._inspect('pinfo', 'foo', detail_level=1)
393 with AssertNotPrints('Docstring:'):
392 with AssertNotPrints('Docstring:'):
394 ip._inspect('pinfo', 'foo', detail_level=1)
393 ip._inspect('pinfo', 'foo', detail_level=1)
395
394
396
395
397 def test_pinfo_magic():
396 def test_pinfo_magic():
398 with AssertPrints('Docstring:'):
397 with AssertPrints('Docstring:'):
399 ip._inspect('pinfo', 'lsmagic', detail_level=0)
398 ip._inspect('pinfo', 'lsmagic', detail_level=0)
400
399
401 with AssertPrints('Source:'):
400 with AssertPrints('Source:'):
402 ip._inspect('pinfo', 'lsmagic', detail_level=1)
401 ip._inspect('pinfo', 'lsmagic', detail_level=1)
403
402
404
403
405 def test_init_colors():
404 def test_init_colors():
406 # ensure colors are not present in signature info
405 # ensure colors are not present in signature info
407 info = inspector.info(HasSignature)
406 info = inspector.info(HasSignature)
408 init_def = info['init_definition']
407 init_def = info['init_definition']
409 nt.assert_not_in('[0m', init_def)
408 nt.assert_not_in('[0m', init_def)
410
409
411
410
412 def test_builtin_init():
411 def test_builtin_init():
413 info = inspector.info(list)
412 info = inspector.info(list)
414 init_def = info['init_definition']
413 init_def = info['init_definition']
415 # Python < 3.4 can't get init definition from builtins,
414 # Python < 3.4 can't get init definition from builtins,
416 # but still exercise the inspection in case of error-raising bugs.
415 # but still exercise the inspection in case of error-raising bugs.
417 if sys.version_info >= (3,4):
416 if sys.version_info >= (3,4):
418 nt.assert_is_not_none(init_def)
417 nt.assert_is_not_none(init_def)
419
418
General Comments 0
You need to be logged in to leave comments. Login now