##// END OF EJS Templates
Defer Traits import in ipy_traits_completer....
Robert Kern -
Show More
@@ -44,13 +44,14 b' Notes'
44 =====
44 =====
45
45
46 - This requires Python 2.4 to work (I use sets). I don't think anyone is
46 - This requires Python 2.4 to work (I use sets). I don't think anyone is
47 using traits with 2.3 anyway, so that's OK.
47 using traits with 2.3 anyway, so that's OK.
48
49 - Imports from enthought.traits are deferred until an object with a class that
50 looks like it subclasses from HasTraits comes along. This test is done by
51 looking at the name of the class and its superclasses.
48 """
52 """
49
53
50 #############################################################################
54 #############################################################################
51 # External imports
52 from enthought.traits import api as T
53
54 # IPython imports
55 # IPython imports
55 from IPython.core.error import TryNext
56 from IPython.core.error import TryNext
56 from IPython.core.ipapi import get as ipget
57 from IPython.core.ipapi import get as ipget
@@ -71,11 +72,37 b' COMPLETE_THRESHOLD = 3'
71
72
72 # Set of names that Traits automatically adds to ANY traits-inheriting object.
73 # Set of names that Traits automatically adds to ANY traits-inheriting object.
73 # These are the names we'll filter out.
74 # These are the names we'll filter out.
74 TRAIT_NAMES = set( dir2(T.HasTraits()) ) - set( dir2(object()) )
75 TRAIT_NAMES = None
76 def get_trait_names():
77 global TRAIT_NAMES
78 from enthought.traits.api import HasTraits
79 if TRAIT_NAMES is None:
80 TRAIT_NAMES = set( dir2(HasTraits()) ) - set( dir2(object()) )
81 else:
82 return TRAIT_NAMES
75
83
76 #############################################################################
84 #############################################################################
77 # Code begins
85 # Code begins
78
86
87 def looks_like_isinstance(obj, classname):
88 """ Return True if the object has a class or superclass with the given class
89 name.
90
91 Ignores old-style classes.
92 """
93 from types import InstanceType
94
95 t = type(obj)
96 if t is InstanceType:
97 # Old-style classes.
98 return False
99 elif t.__name__ == classname:
100 return True
101 for klass in t.__mro__:
102 if klass.__name__ == classname:
103 return True
104 return False
105
79 def trait_completer(self,event):
106 def trait_completer(self,event):
80 """A custom IPython tab-completer that is traits-aware.
107 """A custom IPython tab-completer that is traits-aware.
81
108
@@ -94,7 +121,13 b' def trait_completer(self,event):'
94
121
95 obj = oinfo['obj']
122 obj = oinfo['obj']
96 # OK, we got the object. See if it's traits, else punt
123 # OK, we got the object. See if it's traits, else punt
97 if not isinstance(obj,T.HasTraits):
124 if not looks_like_isinstance(obj, 'HasTraits'):
125 raise TryNext
126
127 # Defer import until here so as not to require Traits until we get something
128 # that looks like it might be a HasTraits instance.
129 from enthought.traits.api import HasTraits
130 if not isinstance(obj, HasTraits):
98 raise TryNext
131 raise TryNext
99
132
100 # it's a traits object, don't show the tr* attributes unless the completion
133 # it's a traits object, don't show the tr* attributes unless the completion
@@ -115,7 +148,7 b' def trait_completer(self,event):'
115 #print '\nastart:<%r>' % attr_start # dbg
148 #print '\nastart:<%r>' % attr_start # dbg
116
149
117 if len(attr_start)<COMPLETE_THRESHOLD:
150 if len(attr_start)<COMPLETE_THRESHOLD:
118 attrs = list(set(attrs) - TRAIT_NAMES)
151 attrs = list(set(attrs) - get_trait_names())
119
152
120 # The base of the completion, so we can form the final results list
153 # The base of the completion, so we can form the final results list
121 bdot = base+'.'
154 bdot = base+'.'
@@ -150,13 +183,14 b' def activate(complete_threshold = COMPLETE_THRESHOLD):'
150 #############################################################################
183 #############################################################################
151 if __name__ == '__main__':
184 if __name__ == '__main__':
152 # Testing/debugging
185 # Testing/debugging
186 from enthought.traits.api import HasTraits
153
187
154 # A sorted list of the names we'll filter out
188 # A sorted list of the names we'll filter out
155 TNL = list(TRAIT_NAMES)
189 TNL = list(get_trait_names())
156 TNL.sort()
190 TNL.sort()
157
191
158 # Make a few objects for testing
192 # Make a few objects for testing
159 class TClean(T.HasTraits): pass
193 class TClean(HasTraits): pass
160 class Bunch(object): pass
194 class Bunch(object): pass
161 # A clean traits object
195 # A clean traits object
162 t = TClean()
196 t = TClean()
General Comments 0
You need to be logged in to leave comments. Login now