##// END OF EJS Templates
Add extra tests for checking decorator logic with __wrapped__.
Fernando Perez -
Show More
@@ -1,243 +1,277 b''
1 """Tests for the object inspection functionality.
1 """Tests for the object inspection functionality.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2010-2011 The IPython Development Team.
4 # Copyright (C) 2010-2011 The IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the BSD License.
6 # Distributed under the terms of the BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 from __future__ import print_function
14 from __future__ import print_function
15
15
16 # Stdlib imports
16 # Stdlib imports
17 import os
17 import os
18
18
19 # Third-party imports
19 # Third-party imports
20 import nose.tools as nt
20 import nose.tools as nt
21
21
22 # Our own imports
22 # Our own imports
23 from .. import oinspect
23 from .. import oinspect
24 from IPython.core.magic import (Magics, magics_class, line_magic,
24 from IPython.core.magic import (Magics, magics_class, line_magic,
25 cell_magic, line_cell_magic,
25 cell_magic, line_cell_magic,
26 register_line_magic, register_cell_magic,
26 register_line_magic, register_cell_magic,
27 register_line_cell_magic)
27 register_line_cell_magic)
28 from IPython.external.decorator import decorator
28 from IPython.utils import py3compat
29 from IPython.utils import py3compat
29
30
31
30 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
31 # Globals and constants
33 # Globals and constants
32 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
33
35
34 inspector = oinspect.Inspector()
36 inspector = oinspect.Inspector()
35 ip = get_ipython()
37 ip = get_ipython()
36
38
37 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
38 # Local utilities
40 # Local utilities
39 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
40
42
41 # WARNING: since this test checks the line number where a function is
43 # WARNING: since this test checks the line number where a function is
42 # defined, if any code is inserted above, the following line will need to be
44 # defined, if any code is inserted above, the following line will need to be
43 # updated. Do NOT insert any whitespace between the next line and the function
45 # updated. Do NOT insert any whitespace between the next line and the function
44 # definition below.
46 # definition below.
45 THIS_LINE_NUMBER = 45 # Put here the actual number of this line
47 THIS_LINE_NUMBER = 47 # Put here the actual number of this line
46 def test_find_source_lines():
48 def test_find_source_lines():
47 nt.assert_equal(oinspect.find_source_lines(test_find_source_lines),
49 nt.assert_equal(oinspect.find_source_lines(test_find_source_lines),
48 THIS_LINE_NUMBER+1)
50 THIS_LINE_NUMBER+1)
49
51
50
52
51 def test_find_file():
53 def test_find_file():
52 nt.assert_equal(oinspect.find_file(test_find_file),
54 nt.assert_equal(oinspect.find_file(test_find_file),
53 os.path.abspath(__file__))
55 os.path.abspath(__file__))
54
56
55
57
58 def test_find_file_decorated1():
59
60 @decorator
61 def noop1(f):
62 def wrapper():
63 return f(*a, **kw)
64 return wrapper
65
66 @noop1
67 def f(x):
68 "My docstring"
69
70 nt.assert_equal(oinspect.find_file(f),
71 os.path.abspath(__file__))
72 nt.assert_equal(f.__doc__, "My docstring")
73
74
75 def test_find_file_decorated2():
76
77 @decorator
78 def noop2(f, *a, **kw):
79 return f(*a, **kw)
80
81 @noop2
82 def f(x):
83 "My docstring 2"
84
85 nt.assert_equal(oinspect.find_file(f),
86 os.path.abspath(__file__))
87 nt.assert_equal(f.__doc__, "My docstring 2")
88
89
56 def test_find_file_magic():
90 def test_find_file_magic():
57 run = ip.find_line_magic('run')
91 run = ip.find_line_magic('run')
58 nt.assert_not_equal(oinspect.find_file(run), None)
92 nt.assert_not_equal(oinspect.find_file(run), None)
59
93
60
94
61 # A few generic objects we can then inspect in the tests below
95 # A few generic objects we can then inspect in the tests below
62
96
63 class Call(object):
97 class Call(object):
64 """This is the class docstring."""
98 """This is the class docstring."""
65
99
66 def __init__(self, x, y=1):
100 def __init__(self, x, y=1):
67 """This is the constructor docstring."""
101 """This is the constructor docstring."""
68
102
69 def __call__(self, *a, **kw):
103 def __call__(self, *a, **kw):
70 """This is the call docstring."""
104 """This is the call docstring."""
71
105
72 def method(self, x, z=2):
106 def method(self, x, z=2):
73 """Some method's docstring"""
107 """Some method's docstring"""
74
108
75
109
76 class OldStyle:
110 class OldStyle:
77 """An old-style class for testing."""
111 """An old-style class for testing."""
78 pass
112 pass
79
113
80
114
81 def f(x, y=2, *a, **kw):
115 def f(x, y=2, *a, **kw):
82 """A simple function."""
116 """A simple function."""
83
117
84
118
85 def g(y, z=3, *a, **kw):
119 def g(y, z=3, *a, **kw):
86 pass # no docstring
120 pass # no docstring
87
121
88
122
89 @register_line_magic
123 @register_line_magic
90 def lmagic(line):
124 def lmagic(line):
91 "A line magic"
125 "A line magic"
92
126
93
127
94 @register_cell_magic
128 @register_cell_magic
95 def cmagic(line, cell):
129 def cmagic(line, cell):
96 "A cell magic"
130 "A cell magic"
97
131
98
132
99 @register_line_cell_magic
133 @register_line_cell_magic
100 def lcmagic(line, cell=None):
134 def lcmagic(line, cell=None):
101 "A line/cell magic"
135 "A line/cell magic"
102
136
103
137
104 @magics_class
138 @magics_class
105 class SimpleMagics(Magics):
139 class SimpleMagics(Magics):
106 @line_magic
140 @line_magic
107 def Clmagic(self, cline):
141 def Clmagic(self, cline):
108 "A class-based line magic"
142 "A class-based line magic"
109
143
110 @cell_magic
144 @cell_magic
111 def Ccmagic(self, cline, ccell):
145 def Ccmagic(self, cline, ccell):
112 "A class-based cell magic"
146 "A class-based cell magic"
113
147
114 @line_cell_magic
148 @line_cell_magic
115 def Clcmagic(self, cline, ccell=None):
149 def Clcmagic(self, cline, ccell=None):
116 "A class-based line/cell magic"
150 "A class-based line/cell magic"
117
151
118
152
119 def check_calltip(obj, name, call, docstring):
153 def check_calltip(obj, name, call, docstring):
120 """Generic check pattern all calltip tests will use"""
154 """Generic check pattern all calltip tests will use"""
121 info = inspector.info(obj, name)
155 info = inspector.info(obj, name)
122 call_line, ds = oinspect.call_tip(info)
156 call_line, ds = oinspect.call_tip(info)
123 nt.assert_equal(call_line, call)
157 nt.assert_equal(call_line, call)
124 nt.assert_equal(ds, docstring)
158 nt.assert_equal(ds, docstring)
125
159
126 #-----------------------------------------------------------------------------
160 #-----------------------------------------------------------------------------
127 # Tests
161 # Tests
128 #-----------------------------------------------------------------------------
162 #-----------------------------------------------------------------------------
129
163
130 def test_calltip_class():
164 def test_calltip_class():
131 check_calltip(Call, 'Call', 'Call(x, y=1)', Call.__init__.__doc__)
165 check_calltip(Call, 'Call', 'Call(x, y=1)', Call.__init__.__doc__)
132
166
133
167
134 def test_calltip_instance():
168 def test_calltip_instance():
135 c = Call(1)
169 c = Call(1)
136 check_calltip(c, 'c', 'c(*a, **kw)', c.__call__.__doc__)
170 check_calltip(c, 'c', 'c(*a, **kw)', c.__call__.__doc__)
137
171
138
172
139 def test_calltip_method():
173 def test_calltip_method():
140 c = Call(1)
174 c = Call(1)
141 check_calltip(c.method, 'c.method', 'c.method(x, z=2)', c.method.__doc__)
175 check_calltip(c.method, 'c.method', 'c.method(x, z=2)', c.method.__doc__)
142
176
143
177
144 def test_calltip_function():
178 def test_calltip_function():
145 check_calltip(f, 'f', 'f(x, y=2, *a, **kw)', f.__doc__)
179 check_calltip(f, 'f', 'f(x, y=2, *a, **kw)', f.__doc__)
146
180
147
181
148 def test_calltip_function2():
182 def test_calltip_function2():
149 check_calltip(g, 'g', 'g(y, z=3, *a, **kw)', '<no docstring>')
183 check_calltip(g, 'g', 'g(y, z=3, *a, **kw)', '<no docstring>')
150
184
151
185
152 def test_calltip_builtin():
186 def test_calltip_builtin():
153 check_calltip(sum, 'sum', None, sum.__doc__)
187 check_calltip(sum, 'sum', None, sum.__doc__)
154
188
155
189
156 def test_calltip_line_magic():
190 def test_calltip_line_magic():
157 check_calltip(lmagic, 'lmagic', 'lmagic(line)', "A line magic")
191 check_calltip(lmagic, 'lmagic', 'lmagic(line)', "A line magic")
158
192
159
193
160 def test_calltip_cell_magic():
194 def test_calltip_cell_magic():
161 check_calltip(cmagic, 'cmagic', 'cmagic(line, cell)', "A cell magic")
195 check_calltip(cmagic, 'cmagic', 'cmagic(line, cell)', "A cell magic")
162
196
163
197
164 def test_calltip_line_magic():
198 def test_calltip_line_magic():
165 check_calltip(lcmagic, 'lcmagic', 'lcmagic(line, cell=None)',
199 check_calltip(lcmagic, 'lcmagic', 'lcmagic(line, cell=None)',
166 "A line/cell magic")
200 "A line/cell magic")
167
201
168
202
169 def test_class_magics():
203 def test_class_magics():
170 cm = SimpleMagics(ip)
204 cm = SimpleMagics(ip)
171 ip.register_magics(cm)
205 ip.register_magics(cm)
172 check_calltip(cm.Clmagic, 'Clmagic', 'Clmagic(cline)',
206 check_calltip(cm.Clmagic, 'Clmagic', 'Clmagic(cline)',
173 "A class-based line magic")
207 "A class-based line magic")
174 check_calltip(cm.Ccmagic, 'Ccmagic', 'Ccmagic(cline, ccell)',
208 check_calltip(cm.Ccmagic, 'Ccmagic', 'Ccmagic(cline, ccell)',
175 "A class-based cell magic")
209 "A class-based cell magic")
176 check_calltip(cm.Clcmagic, 'Clcmagic', 'Clcmagic(cline, ccell=None)',
210 check_calltip(cm.Clcmagic, 'Clcmagic', 'Clcmagic(cline, ccell=None)',
177 "A class-based line/cell magic")
211 "A class-based line/cell magic")
178
212
179
213
180 def test_info():
214 def test_info():
181 "Check that Inspector.info fills out various fields as expected."
215 "Check that Inspector.info fills out various fields as expected."
182 i = inspector.info(Call, oname='Call')
216 i = inspector.info(Call, oname='Call')
183 nt.assert_equal(i['type_name'], 'type')
217 nt.assert_equal(i['type_name'], 'type')
184 expted_class = str(type(type)) # <class 'type'> (Python 3) or <type 'type'>
218 expted_class = str(type(type)) # <class 'type'> (Python 3) or <type 'type'>
185 nt.assert_equal(i['base_class'], expted_class)
219 nt.assert_equal(i['base_class'], expted_class)
186 nt.assert_equal(i['string_form'], "<class 'IPython.core.tests.test_oinspect.Call'>")
220 nt.assert_equal(i['string_form'], "<class 'IPython.core.tests.test_oinspect.Call'>")
187 fname = __file__
221 fname = __file__
188 if fname.endswith(".pyc"):
222 if fname.endswith(".pyc"):
189 fname = fname[:-1]
223 fname = fname[:-1]
190 # case-insensitive comparison needed on some filesystems
224 # case-insensitive comparison needed on some filesystems
191 # e.g. Windows:
225 # e.g. Windows:
192 nt.assert_equal(i['file'].lower(), fname.lower())
226 nt.assert_equal(i['file'].lower(), fname.lower())
193 nt.assert_equal(i['definition'], 'Call(self, *a, **kw)\n')
227 nt.assert_equal(i['definition'], 'Call(self, *a, **kw)\n')
194 nt.assert_equal(i['docstring'], Call.__doc__)
228 nt.assert_equal(i['docstring'], Call.__doc__)
195 nt.assert_equal(i['source'], None)
229 nt.assert_equal(i['source'], None)
196 nt.assert_true(i['isclass'])
230 nt.assert_true(i['isclass'])
197 nt.assert_equal(i['init_definition'], "Call(self, x, y=1)\n")
231 nt.assert_equal(i['init_definition'], "Call(self, x, y=1)\n")
198 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
232 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
199
233
200 i = inspector.info(Call, detail_level=1)
234 i = inspector.info(Call, detail_level=1)
201 nt.assert_not_equal(i['source'], None)
235 nt.assert_not_equal(i['source'], None)
202 nt.assert_equal(i['docstring'], None)
236 nt.assert_equal(i['docstring'], None)
203
237
204 c = Call(1)
238 c = Call(1)
205 c.__doc__ = "Modified instance docstring"
239 c.__doc__ = "Modified instance docstring"
206 i = inspector.info(c)
240 i = inspector.info(c)
207 nt.assert_equal(i['type_name'], 'Call')
241 nt.assert_equal(i['type_name'], 'Call')
208 nt.assert_equal(i['docstring'], "Modified instance docstring")
242 nt.assert_equal(i['docstring'], "Modified instance docstring")
209 nt.assert_equal(i['class_docstring'], Call.__doc__)
243 nt.assert_equal(i['class_docstring'], Call.__doc__)
210 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
244 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
211 nt.assert_equal(i['call_docstring'], c.__call__.__doc__)
245 nt.assert_equal(i['call_docstring'], c.__call__.__doc__)
212
246
213 # Test old-style classes, which for example may not have an __init__ method.
247 # Test old-style classes, which for example may not have an __init__ method.
214 if not py3compat.PY3:
248 if not py3compat.PY3:
215 i = inspector.info(OldStyle)
249 i = inspector.info(OldStyle)
216 nt.assert_equal(i['type_name'], 'classobj')
250 nt.assert_equal(i['type_name'], 'classobj')
217
251
218 i = inspector.info(OldStyle())
252 i = inspector.info(OldStyle())
219 nt.assert_equal(i['type_name'], 'instance')
253 nt.assert_equal(i['type_name'], 'instance')
220 nt.assert_equal(i['docstring'], OldStyle.__doc__)
254 nt.assert_equal(i['docstring'], OldStyle.__doc__)
221
255
222 def test_getdoc():
256 def test_getdoc():
223 class A(object):
257 class A(object):
224 """standard docstring"""
258 """standard docstring"""
225 pass
259 pass
226
260
227 class B(object):
261 class B(object):
228 """standard docstring"""
262 """standard docstring"""
229 def getdoc(self):
263 def getdoc(self):
230 return "custom docstring"
264 return "custom docstring"
231
265
232 class C(object):
266 class C(object):
233 """standard docstring"""
267 """standard docstring"""
234 def getdoc(self):
268 def getdoc(self):
235 return None
269 return None
236
270
237 a = A()
271 a = A()
238 b = B()
272 b = B()
239 c = C()
273 c = C()
240
274
241 nt.assert_equal(oinspect.getdoc(a), "standard docstring")
275 nt.assert_equal(oinspect.getdoc(a), "standard docstring")
242 nt.assert_equal(oinspect.getdoc(b), "custom docstring")
276 nt.assert_equal(oinspect.getdoc(b), "custom docstring")
243 nt.assert_equal(oinspect.getdoc(c), "standard docstring")
277 nt.assert_equal(oinspect.getdoc(c), "standard docstring")
General Comments 0
You need to be logged in to leave comments. Login now