##// END OF EJS Templates
Consolidate code to check for method in IPython.utils.dir2
Thomas Kluyver -
Show More
@@ -71,7 +71,7 b' from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol'
71 71 from IPython.utils import generics
72 72 from IPython.utils import io
73 73 from IPython.utils.decorators import undoc
74 from IPython.utils.dir2 import dir2, safe_hasattr
74 from IPython.utils.dir2 import dir2, get_real_method
75 75 from IPython.utils.process import arg_split
76 76 from IPython.utils.py3compat import builtin_mod, string_types, PY3
77 77 from traitlets import CBool, Enum
@@ -472,19 +472,6 b' def _safe_isinstance(obj, module, class_name):'
472 472 return (module in sys.modules and
473 473 isinstance(obj, getattr(__import__(module), class_name)))
474 474
475 def _safe_really_hasattr(obj, name):
476 """Checks that an object genuinely has a given attribute.
477
478 Some objects claim to have any attribute that's requested, to act as a lazy
479 proxy for something else. We want to catch these cases and ignore their
480 claim to have the attribute we're interested in.
481 """
482 if safe_hasattr(obj, '_ipy_proxy_check_dont_define_this_'):
483 # If it claims this exists, don't trust it
484 return False
485
486 return safe_hasattr(obj, name)
487
488 475
489 476 def back_unicode_name_matches(text):
490 477 u"""Match unicode characters back to unicode name
@@ -937,8 +924,9 b' class IPCompleter(Completer):'
937 924 def get_keys(obj):
938 925 # Objects can define their own completions by defining an
939 926 # _ipy_key_completions_() method.
940 if _safe_really_hasattr(obj, '_ipython_key_completions_'):
941 return obj._ipython_key_completions_()
927 method = get_real_method(obj, '_ipython_key_completions_')
928 if method is not None:
929 return method()
942 930
943 931 # Special case some common in-memory dict-like types
944 932 if isinstance(obj, dict) or\
@@ -13,7 +13,6 b' import sys'
13 13 import io as _io
14 14 import tokenize
15 15
16 from IPython.core.formatters import _safe_get_formatter_method
17 16 from traitlets.config.configurable import Configurable
18 17 from IPython.utils import io
19 18 from IPython.utils.py3compat import builtin_mod, cast_unicode_py2
@@ -22,6 +22,7 b' from decorator import decorator'
22 22 from traitlets.config.configurable import Configurable
23 23 from IPython.core.getipython import get_ipython
24 24 from IPython.utils.sentinel import Sentinel
25 from IPython.utils.dir2 import get_real_method
25 26 from IPython.lib import pretty
26 27 from traitlets import (
27 28 Bool, Dict, Integer, Unicode, CUnicode, ObjectName, List,
@@ -32,29 +33,6 b' from IPython.utils.py3compat import ('
32 33 )
33 34
34 35
35 #-----------------------------------------------------------------------------
36 # The main DisplayFormatter class
37 #-----------------------------------------------------------------------------
38
39
40 def _safe_get_formatter_method(obj, name):
41 """Safely get a formatter method
42
43 - Classes cannot have formatter methods, only instance
44 - protect against proxy objects that claim to have everything
45 """
46 if inspect.isclass(obj):
47 # repr methods only make sense on instances, not classes
48 return None
49 method = pretty._safe_getattr(obj, name, None)
50 if callable(method):
51 # obj claims to have repr method...
52 if callable(pretty._safe_getattr(obj, '_ipython_canary_method_should_not_exist_', None)):
53 # ...but don't trust proxy objects that claim to have everything
54 return None
55 return method
56
57
58 36 class DisplayFormatter(Configurable):
59 37
60 38 # When set to true only the default plain text formatter will be used.
@@ -338,7 +316,7 b' class BaseFormatter(Configurable):'
338 316 else:
339 317 return printer(obj)
340 318 # Finally look for special method names
341 method = _safe_get_formatter_method(obj, self.print_method)
319 method = get_real_method(obj, self.print_method)
342 320 if method is not None:
343 321 return method()
344 322 return None
@@ -904,7 +882,7 b' class IPythonDisplayFormatter(BaseFormatter):'
904 882 printer(obj)
905 883 return True
906 884 # Finally look for special method names
907 method = _safe_get_formatter_method(obj, self.print_method)
885 method = get_real_method(obj, self.print_method)
908 886 if method is not None:
909 887 method()
910 888 return True
@@ -2,21 +2,11 b''
2 2 """A fancy version of Python's builtin :func:`dir` function.
3 3 """
4 4
5 #-----------------------------------------------------------------------------
6 # Copyright (C) 2008-2011 The IPython Development Team
7 #
8 # Distributed under the terms of the BSD License. The full license is in
9 # the file COPYING, distributed as part of this software.
10 #-----------------------------------------------------------------------------
11
12 #-----------------------------------------------------------------------------
13 # Imports
14 #-----------------------------------------------------------------------------
15 from .py3compat import string_types
5 # Copyright (c) IPython Development Team.
6 # Distributed under the terms of the Modified BSD License.
16 7
17 #-----------------------------------------------------------------------------
18 # Code
19 #-----------------------------------------------------------------------------
8 import inspect
9 from .py3compat import string_types
20 10
21 11
22 12 def safe_hasattr(obj, attr):
@@ -56,3 +46,36 b' def dir2(obj):'
56 46
57 47 words = [w for w in words if isinstance(w, string_types)]
58 48 return sorted(words)
49
50
51 def get_real_method(obj, name):
52 """Like getattr, but with a few extra sanity checks:
53
54 - If obj is a class, ignore its methods
55 - Check if obj is a proxy that claims to have all attributes
56 - Catch attribute access failing with any exception
57 - Check that the attribute is a callable object
58
59 Returns the method or None.
60 """
61 if inspect.isclass(obj):
62 return None
63
64 try:
65 canary = getattr(obj, '_ipython_canary_method_should_not_exist_', None)
66 except Exception:
67 return None
68
69 if canary is not None:
70 # It claimed to have an attribute it should never have
71 return None
72
73 try:
74 m = getattr(obj, name, None)
75 except Exception:
76 return None
77
78 if callable(m):
79 return m
80
81 return None
General Comments 0
You need to be logged in to leave comments. Login now