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