##// END OF EJS Templates
Merge pull request #4996 from minrk/safe-formatter-check...
Thomas Kluyver -
r15321:9abdf62f merge
parent child Browse files
Show More
@@ -246,11 +246,13 class Config(dict):
246 c = Config()
246 c = Config()
247 dict.__setitem__(self, key, c)
247 dict.__setitem__(self, key, c)
248 return c
248 return c
249 else:
249 elif not key.startswith('_'):
250 # undefined, create lazy value, used for container methods
250 # undefined, create lazy value, used for container methods
251 v = LazyConfigValue()
251 v = LazyConfigValue()
252 dict.__setitem__(self, key, v)
252 dict.__setitem__(self, key, v)
253 return v
253 return v
254 else:
255 raise KeyError
254
256
255 def __setitem__(self, key, value):
257 def __setitem__(self, key, value):
256 if _is_section_key(key):
258 if _is_section_key(key):
@@ -369,6 +369,14 class TestConfig(TestCase):
369 assert isinstance(foo, LazyConfigValue)
369 assert isinstance(foo, LazyConfigValue)
370 self.assertIn('foo', cfg)
370 self.assertIn('foo', cfg)
371
371
372 def test_getattr_private_missing(self):
373 cfg = Config()
374 self.assertNotIn('_repr_html_', cfg)
375 with self.assertRaises(AttributeError):
376 _ = cfg._repr_html_
377 self.assertNotIn('_repr_html_', cfg)
378 self.assertEqual(len(cfg), 0)
379
372 def test_getitem_not_section(self):
380 def test_getitem_not_section(self):
373 cfg = Config()
381 cfg = Config()
374 self.assertNotIn('foo', cfg)
382 self.assertNotIn('foo', cfg)
@@ -25,7 +25,9 Authors:
25
25
26 # Stdlib imports
26 # Stdlib imports
27 import abc
27 import abc
28 import inspect
28 import sys
29 import sys
30 import types
29 import warnings
31 import warnings
30
32
31 from IPython.external.decorator import decorator
33 from IPython.external.decorator import decorator
@@ -52,6 +54,32 else:
52 # The main DisplayFormatter class
54 # The main DisplayFormatter class
53 #-----------------------------------------------------------------------------
55 #-----------------------------------------------------------------------------
54
56
57
58 def _valid_formatter(f):
59 """Return whether an object is a valid formatter
60
61 Cases checked:
62
63 - bound methods OK
64 - unbound methods NO
65 - callable with zero args OK
66 """
67 if isinstance(f, type(str.find)):
68 # unbound methods on compiled classes have type method_descriptor
69 return False
70 elif isinstance(f, types.BuiltinFunctionType):
71 # bound methods on compiled classes have type builtin_function
72 return True
73 elif callable(f):
74 # anything that works with zero args should be okay
75 try:
76 inspect.getcallargs(f)
77 except TypeError:
78 return False
79 else:
80 return True
81 return False
82
55 class DisplayFormatter(Configurable):
83 class DisplayFormatter(Configurable):
56
84
57 # When set to true only the default plain text formatter will be used.
85 # When set to true only the default plain text formatter will be used.
@@ -312,7 +340,8 class BaseFormatter(Configurable):
312 return printer(obj)
340 return printer(obj)
313 # Finally look for special method names
341 # Finally look for special method names
314 method = pretty._safe_getattr(obj, self.print_method, None)
342 method = pretty._safe_getattr(obj, self.print_method, None)
315 if method is not None:
343 # print_method must be a bound method:
344 if _valid_formatter(method):
316 return method()
345 return method()
317 return None
346 return None
318 else:
347 else:
@@ -8,6 +8,7 except:
8 numpy = None
8 numpy = None
9 import nose.tools as nt
9 import nose.tools as nt
10
10
11 from IPython.config import Config
11 from IPython.core.formatters import (
12 from IPython.core.formatters import (
12 PlainTextFormatter, HTMLFormatter, PDFFormatter, _mod_name_key
13 PlainTextFormatter, HTMLFormatter, PDFFormatter, _mod_name_key
13 )
14 )
@@ -289,3 +290,33 def test_pdf_formatter():
289 pdf = MakePDF()
290 pdf = MakePDF()
290 f = PDFFormatter()
291 f = PDFFormatter()
291 nt.assert_equal(f(pdf), 'PDF')
292 nt.assert_equal(f(pdf), 'PDF')
293
294 def test_print_method_bound():
295 f = HTMLFormatter()
296 class MyHTML(object):
297 def _repr_html_(self):
298 return "hello"
299
300 with capture_output() as captured:
301 result = f(MyHTML)
302 nt.assert_is(result, None)
303 nt.assert_not_in("FormatterWarning", captured.stderr)
304
305 with capture_output() as captured:
306 result = f(MyHTML())
307 nt.assert_equal(result, "hello")
308 nt.assert_equal(captured.stderr, "")
309
310 def test_format_config():
311 """config objects don't pretend to support fancy reprs with lazy attrs"""
312 f = HTMLFormatter()
313 cfg = Config()
314 with capture_output() as captured:
315 result = f(cfg)
316 nt.assert_is(result, None)
317 nt.assert_equal(captured.stderr, "")
318
319 with capture_output() as captured:
320 result = f(Config)
321 nt.assert_is(result, None)
322 nt.assert_equal(captured.stderr, "")
General Comments 0
You need to be logged in to leave comments. Login now