##// END OF EJS Templates
Merge pull request #7006 from minrk/valid_formatter...
Thomas Kluyver -
r19274:f252d2c2 merge
parent child Browse files
Show More
@@ -40,38 +40,21 b' else:'
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41
41
42
42
43 def _valid_formatter(f):
43 def _safe_get_formatter_method(obj, name):
44 """Return whether an object is a valid formatter
44 """Safely get a formatter method
45
46 Cases checked:
47
45
48 - bound methods OK
46 - Classes cannot have formatter methods, only instance
49 - unbound methods NO
47 - protect against proxy objects that claim to have everything
50 - callable with zero args OK
51 """
48 """
52 if f is None:
49 if inspect.isclass(obj):
53 return False
50 # repr methods only make sense on instances, not classes
54 elif isinstance(f, type(str.find)):
51 return None
55 # unbound methods on compiled classes have type method_descriptor
56 return False
57 elif isinstance(f, types.BuiltinFunctionType):
58 # bound methods on compiled classes have type builtin_function
59 return True
60 elif callable(f):
61 # anything that works with zero args should be okay
62 try:
63 inspect.getcallargs(f)
64 except Exception:
65 return False
66 else:
67 return True
68 return False
69
70 def _safe_get_formatter_method(obj, name):
71 """Safely get a formatter method"""
72 method = pretty._safe_getattr(obj, name, None)
52 method = pretty._safe_getattr(obj, name, None)
73 # formatter methods must be bound
53 if callable(method):
74 if _valid_formatter(method):
54 # obj claims to have repr method...
55 if callable(pretty._safe_getattr(obj, '_ipython_canary_method_should_not_exist_', None)):
56 # ...but don't trust proxy objects that claim to have everything
57 return None
75 return method
58 return method
76
59
77
60
@@ -314,7 +314,6 b' def test_print_method_bound():'
314 class MyHTML(object):
314 class MyHTML(object):
315 def _repr_html_(self):
315 def _repr_html_(self):
316 return "hello"
316 return "hello"
317
318 with capture_output() as captured:
317 with capture_output() as captured:
319 result = f(MyHTML)
318 result = f(MyHTML)
320 nt.assert_is(result, None)
319 nt.assert_is(result, None)
@@ -325,6 +324,44 b' def test_print_method_bound():'
325 nt.assert_equal(result, "hello")
324 nt.assert_equal(result, "hello")
326 nt.assert_equal(captured.stderr, "")
325 nt.assert_equal(captured.stderr, "")
327
326
327 def test_print_method_weird():
328
329 class TextMagicHat(object):
330 def __getattr__(self, key):
331 return key
332
333 f = HTMLFormatter()
334
335 text_hat = TextMagicHat()
336 nt.assert_equal(text_hat._repr_html_, '_repr_html_')
337 with capture_output() as captured:
338 result = f(text_hat)
339
340 nt.assert_is(result, None)
341 nt.assert_not_in("FormatterWarning", captured.stderr)
342
343 class CallableMagicHat(object):
344 def __getattr__(self, key):
345 return lambda : key
346
347 call_hat = CallableMagicHat()
348 with capture_output() as captured:
349 result = f(call_hat)
350
351 nt.assert_equal(result, None)
352
353 class BadReprArgs(object):
354 def _repr_html_(self, extra, args):
355 return "html"
356
357 bad = BadReprArgs()
358 with capture_output() as captured:
359 result = f(bad)
360
361 nt.assert_is(result, None)
362 nt.assert_not_in("FormatterWarning", captured.stderr)
363
364
328 def test_format_config():
365 def test_format_config():
329 """config objects don't pretend to support fancy reprs with lazy attrs"""
366 """config objects don't pretend to support fancy reprs with lazy attrs"""
330 f = HTMLFormatter()
367 f = HTMLFormatter()
General Comments 0
You need to be logged in to leave comments. Login now