Show More
@@ -261,6 +261,16 b' def call_tip(oinfo, format_call=True):' | |||
|
261 | 261 | |
|
262 | 262 | return call_line, doc |
|
263 | 263 | |
|
264 | def safe_hasattr(obj, attr): | |
|
265 | """In recent versions of Python, hasattr() only catches AttributeError. | |
|
266 | This catches all errors. | |
|
267 | """ | |
|
268 | try: | |
|
269 | getattr(obj, attr) | |
|
270 | return True | |
|
271 | except: | |
|
272 | return False | |
|
273 | ||
|
264 | 274 | |
|
265 | 275 | def find_file(obj): |
|
266 | 276 | """Find the absolute path to the file where an object was defined. |
@@ -279,7 +289,7 b' def find_file(obj):' | |||
|
279 | 289 | The absolute path to the file where the object was defined. |
|
280 | 290 | """ |
|
281 | 291 | # get source if obj was decorated with @decorator |
|
282 | if hasattr(obj, '__wrapped__'): | |
|
292 | if safe_hasattr(obj, '__wrapped__'): | |
|
283 | 293 | obj = obj.__wrapped__ |
|
284 | 294 | |
|
285 | 295 | fname = None |
@@ -316,7 +326,7 b' def find_source_lines(obj):' | |||
|
316 | 326 | The line number where the object definition starts. |
|
317 | 327 | """ |
|
318 | 328 | # get source if obj was decorated with @decorator |
|
319 | if hasattr(obj, '__wrapped__'): | |
|
329 | if safe_hasattr(obj, '__wrapped__'): | |
|
320 | 330 | obj = obj.__wrapped__ |
|
321 | 331 | |
|
322 | 332 | try: |
@@ -779,7 +789,7 b' class Inspector:' | |||
|
779 | 789 | out['init_docstring'] = init_ds |
|
780 | 790 | |
|
781 | 791 | # Call form docstring for callable instances |
|
782 | if hasattr(obj, '__call__'): | |
|
792 | if safe_hasattr(obj, '__call__'): | |
|
783 | 793 | call_def = self._getdef(obj.__call__, oname) |
|
784 | 794 | if call_def is not None: |
|
785 | 795 | out['call_def'] = self.format(call_def) |
@@ -158,6 +158,11 b' class SimpleMagics(Magics):' | |||
|
158 | 158 | "A class-based line/cell magic" |
|
159 | 159 | |
|
160 | 160 | |
|
161 | class Awkward(object): | |
|
162 | def __getattr__(self, name): | |
|
163 | raise Exception(name) | |
|
164 | ||
|
165 | ||
|
161 | 166 | def check_calltip(obj, name, call, docstring): |
|
162 | 167 | """Generic check pattern all calltip tests will use""" |
|
163 | 168 | info = inspector.info(obj, name) |
@@ -261,6 +266,10 b' def test_info():' | |||
|
261 | 266 | nt.assert_equal(i['type_name'], 'instance') |
|
262 | 267 | nt.assert_equal(i['docstring'], OldStyle.__doc__) |
|
263 | 268 | |
|
269 | def test_info_awkward(): | |
|
270 | # Just test that this doesn't throw an error. | |
|
271 | i = inspector.info(Awkward()) | |
|
272 | ||
|
264 | 273 | def test_getdoc(): |
|
265 | 274 | class A(object): |
|
266 | 275 | """standard docstring""" |
General Comments 0
You need to be logged in to leave comments.
Login now