From f286289c1469ca12a10022650742336f57f80446 2014-02-27 22:59:47 From: Thomas Kluyver Date: 2014-02-27 22:59:47 Subject: [PATCH] Merge pull request #5229 from minrk/safe-get-ipdisplay get _ipython_display_ method safely --- diff --git a/IPython/core/display.py b/IPython/core/display.py index 301e8aa..624f587 100644 --- a/IPython/core/display.py +++ b/IPython/core/display.py @@ -22,6 +22,7 @@ from __future__ import print_function import os import struct +from IPython.core.formatters import _safe_get_formatter_method from IPython.utils.py3compat import (string_types, cast_bytes_py2, cast_unicode, unicode_type) from IPython.testing.skipdoctest import skip_doctest @@ -116,7 +117,7 @@ def display(*objs, **kwargs): for obj in objs: # If _ipython_display_ is defined, use that to display this object. - display_method = getattr(obj, '_ipython_display_', None) + display_method = _safe_get_formatter_method(obj, '_ipython_display_') if display_method is not None: try: display_method(**kwargs) diff --git a/IPython/core/displayhook.py b/IPython/core/displayhook.py index 5fdffba..57ad39d 100644 --- a/IPython/core/displayhook.py +++ b/IPython/core/displayhook.py @@ -25,7 +25,7 @@ from __future__ import print_function import sys - +from IPython.core.formatters import _safe_get_formatter_method from IPython.config.configurable import Configurable from IPython.utils import io from IPython.utils.py3compat import builtin_mod @@ -242,7 +242,7 @@ class DisplayHook(Configurable): self.check_for_underscore() if result is not None and not self.quiet(): # If _ipython_display_ is defined, use that to display this object. - display_method = getattr(result, '_ipython_display_', None) + display_method = _safe_get_formatter_method(result, '_ipython_display_') if display_method is not None: try: return display_method() diff --git a/IPython/core/formatters.py b/IPython/core/formatters.py index 876ae88..33bdc17 100644 --- a/IPython/core/formatters.py +++ b/IPython/core/formatters.py @@ -64,7 +64,9 @@ def _valid_formatter(f): - unbound methods NO - callable with zero args OK """ - if isinstance(f, type(str.find)): + if f is None: + return False + elif isinstance(f, type(str.find)): # unbound methods on compiled classes have type method_descriptor return False elif isinstance(f, types.BuiltinFunctionType): @@ -80,6 +82,14 @@ def _valid_formatter(f): return True return False +def _safe_get_formatter_method(obj, name): + """Safely get a formatter method""" + method = pretty._safe_getattr(obj, name, None) + # formatter methods must be bound + if _valid_formatter(method): + return method + + class DisplayFormatter(Configurable): # When set to true only the default plain text formatter will be used. @@ -339,9 +349,8 @@ class BaseFormatter(Configurable): else: return printer(obj) # Finally look for special method names - method = pretty._safe_getattr(obj, self.print_method, None) - # print_method must be a bound method: - if _valid_formatter(method): + method = _safe_get_formatter_method(obj, self.print_method) + if method is not None: return method() return None else: