##// END OF EJS Templates
Simplify and tidy up IPython.utils.wildcard.
Thomas Kluyver -
Show More
@@ -13,68 +13,56 b' Authors'
13 # the file COPYING, distributed as part of this software.
13 # the file COPYING, distributed as part of this software.
14 #*****************************************************************************
14 #*****************************************************************************
15
15
16 import __builtin__
17 import re
16 import re
18 import types
17 import types
19
18
20 from IPython.utils.dir2 import dir2
19 from IPython.utils.dir2 import dir2
21
20
22 def create_typestr2type_dicts(dont_include_in_type2type2str=["lambda"]):
21 def create_typestr2type_dicts(dont_include_in_type2typestr=["lambda"]):
23 """Return dictionaries mapping lower case typename to type objects, from
22 """Return dictionaries mapping lower case typename (e.g. 'tuple) to type
24 the types package, and vice versa."""
23 objects from the types package, and vice versa."""
25 typenamelist=[]
24 typenamelist = [tname for tname in dir(types) if tname.endswith("Type")]
26 for tname in dir(types):
25 typestr2type, type2typestr = {}, {}
27 if tname[-4:]=="Type":
26
28 typenamelist.append(tname)
29 typestr2type={}
30 type2typestr={}
31 for tname in typenamelist:
27 for tname in typenamelist:
32 name=tname[:-4].lower()
28 name = tname[:-4].lower() # Cut 'Type' off the end of the name
33 obj=getattr(types,tname)
29 obj = getattr(types, tname)
34 typestr2type[name]=getattr(types,tname)
30 typestr2type[name] = obj
35 if name in dont_include_in_type2type2str:
31 if name not in dont_include_in_type2typestr:
36 type2typestr[obj]=name
32 type2typestr[obj] = name
37 return typestr2type,type2typestr
33 return typestr2type, type2typestr
38
34
39 typestr2type,type2typestr=create_typestr2type_dicts()
35 typestr2type, type2typestr = create_typestr2type_dicts()
40
36
41 def is_type(obj,typestr_or_type):
37 def is_type(obj, typestr_or_type):
42 """is_type(obj,typestr_or_type) verifies if obj is of a certain type or
38 """is_type(obj, typestr_or_type) verifies if obj is of a certain type. It
43 group of types takes strings as parameters of the for 'tuple'<->TupleType
39 can take strings or actual python types for the second argument, i.e.
44 'all' matches all types. TODO: Should be extended for choosing more than
40 'tuple'<->TupleType. 'all' matches all types.
45 one type
41
46 """
42 TODO: Should be extended for choosing more than one type."""
47 if typestr_or_type=="all":
43 if typestr_or_type=="all":
48 return True
44 return True
49 if type(typestr_or_type)==types.TypeType:
45 if type(typestr_or_type) == types.TypeType:
50 test_type=typestr_or_type
46 test_type = typestr_or_type
51 else:
47 else:
52 test_type=typestr2type.get(typestr_or_type,False)
48 test_type = typestr2type.get(typestr_or_type, False)
53 if test_type:
49 if test_type:
54 return isinstance(obj,test_type)
50 return isinstance(obj, test_type)
55 else:
51 return False
56 return False
57
52
58 def show_hidden(str,show_all=False):
53 def show_hidden(str,show_all=False):
59 """Return true for strings starting with single _ if show_all is true."""
54 """Return true for strings starting with single _ if show_all is true."""
60 return show_all or str.startswith("__") or not str.startswith("_")
55 return show_all or str.startswith("__") or not str.startswith("_")
61
56
62 class NameSpace(object):
57 class NameSpace(dict):
63 """NameSpace holds the dictionary for a namespace and implements filtering
58 """NameSpace holds the dictionary for a namespace and implements filtering
64 on name and types"""
59 on name and types"""
65 def __init__(self, ns_dict, name_pattern="*", type_pattern="all",
60
66 ignore_case=True, show_all=True):
67 self.show_all = show_all #Hide names beginning with single _
68 self.name_pattern = name_pattern
69 self.type_pattern = type_pattern
70 self.ignore_case = ignore_case
71 self._ns = ns_dict
72
73 @classmethod
61 @classmethod
74 def from_object(cls, obj, *args, **kwargs):
62 def from_object(cls, obj, *args, **kwargs):
75 """Instantiate a namespace by constructing a dictionary of an object's
63 """Instantiate a namespace by constructing a dictionary of an object's
76 attributes. A class method, returns a new NameSpace instance."""
64 attributes. A class method, returns a new NameSpace instance."""
77 attrs = {}
65 ns = cls()
78 for key in dir2(obj):
66 for key in dir2(obj):
79 if isinstance(key, basestring):
67 if isinstance(key, basestring):
80 # This seemingly unnecessary try/except is actually needed
68 # This seemingly unnecessary try/except is actually needed
@@ -84,81 +72,63 b' class NameSpace(object):'
84 # object's dictionary. Properties can actually do the same
72 # object's dictionary. Properties can actually do the same
85 # thing. In particular, Traits use this pattern
73 # thing. In particular, Traits use this pattern
86 try:
74 try:
87 attrs[key] = getattr(obj,key)
75 ns[key] = getattr(obj,key)
88 except AttributeError:
76 except AttributeError:
89 pass
77 pass
90 return cls(attrs, *args, **kwargs)
78 return ns
91
92 def get_ns(self):
93 """Return name space dictionary with objects matching type and name patterns."""
94 return self.filter(self.name_pattern,self.type_pattern)
95 ns=property(get_ns)
96
97 def get_ns_names(self):
98 """Return list of object names in namespace that match the patterns."""
99 return self.ns.keys()
100 ns_names=property(get_ns_names,doc="List of objects in name space that "
101 "match the type and name patterns.")
102
79
103 def filter(self,name_pattern,type_pattern):
80 def filter(self, name_pattern="*", type_pattern="all", ignore_case=True,
104 """Return dictionary of filtered namespace."""
81 show_all=True):
105 def glob_filter(lista,name_pattern,hidehidden,ignore_case):
82 """Return a dictionary of the namespace filtered by regex pattern and
106 """Return list of elements in lista that match pattern."""
83 item type."""
107 pattern=name_pattern.replace("*",".*").replace("?",".")
84 pattern=name_pattern.replace("*",".*").replace("?",".")
108 if ignore_case:
85 if ignore_case:
109 reg=re.compile(pattern+"$",re.I)
86 reg=re.compile(pattern+"$",re.I)
110 else:
87 else:
111 reg=re.compile(pattern+"$")
88 reg=re.compile(pattern+"$")
112 result=[x for x in lista if reg.match(x) and show_hidden(x,hidehidden)]
89
113 return result
90 return dict((key,obj) for key,obj in self.iteritems() if all((\
114 ns=self._ns
91 reg.match(key), # Matches pattern
115 #Filter namespace by the name_pattern
92 show_hidden(key, show_all), # Not _hidden
116 all=[(x,ns[x]) for x in glob_filter(ns.keys(),name_pattern,
93 is_type(obj, type_pattern) )) ) # Correct type
117 self.show_all,self.ignore_case)]
118 #Filter namespace by type_pattern
119 all=[(key,obj) for key,obj in all if is_type(obj,type_pattern)]
120 all=dict(all)
121 return all
122
123 #TODO: Implement dictionary like access to filtered name space?
124
94
125 def list_namespace(namespace,type_pattern,filter,ignore_case=False,show_all=False):
95 def list_namespace(namespace,type_pattern,filter,ignore_case=False,show_all=False):
126 """Return dictionary of all objects in a namespace dictionary that match
96 """Return dictionary of all objects in a namespace dictionary that match
127 type_pattern and filter."""
97 type_pattern and filter."""
128 pattern_list=filter.split(".")
98 pattern_list=filter.split(".")
129 if len(pattern_list)==1:
99 ns = NameSpace(namespace)
130 ns=NameSpace(namespace,name_pattern=pattern_list[0],type_pattern=type_pattern,
100 if len(pattern_list) == 1:
131 ignore_case=ignore_case,show_all=show_all)
101 return ns.filter(name_pattern=pattern_list[0], type_pattern=type_pattern,
132 return ns.ns
102 ignore_case=ignore_case, show_all=show_all)
133 else:
103 else:
134 # This is where we can change if all objects should be searched or
104 # This is where we can change if all objects should be searched or
135 # only modules. Just change the type_pattern to module to search only
105 # only modules. Just change the type_pattern to module to search only
136 # modules
106 # modules
137 ns=NameSpace(namespace,name_pattern=pattern_list[0],type_pattern="all",
107 filtered = ns.filter(name_pattern=pattern_list[0], type_pattern="all",
138 ignore_case=ignore_case,show_all=show_all)
108 ignore_case=ignore_case, show_all=show_all)
139 res={}
109 results = {}
140 for name,obj in ns.ns.iteritems():
110 for name, obj in filtered.iteritems():
141 ns = list_object_namespace(obj, type_pattern, pattern_list[1:],
111 ns = list_object_namespace(obj, type_pattern, pattern_list[1:],
142 ignore_case=ignore_case, show_all=show_all)
112 ignore_case=ignore_case, show_all=show_all)
143 for inner_name, inner_obj in ns.iteritems():
113 for inner_name, inner_obj in ns.iteritems():
144 res["%s.%s"%(name,inner_name)]=inner_obj
114 results["%s.%s"%(name,inner_name)] = inner_obj
145 return res
115 return results
146
116
147 def list_object_namespace(ns_obj, type_pattern, pattern_list, ignore_case=False,
117 def list_object_namespace(ns_obj, type_pattern, pattern_list, ignore_case=False,
148 show_all=False):
118 show_all=False):
149 """Return dictionary of all attributes of an object which match type_pattern
119 """Return dictionary of all attributes of an object which match type_pattern
150 and filter."""
120 and filter (pattern_list)."""
151 if len(pattern_list)==1:
121 ns = NameSpace.from_object(ns_obj)
152 ns=NameSpace.from_object(ns_obj, name_pattern=pattern_list[0],
122 if len(pattern_list) == 1:
153 type_pattern=type_pattern, ignore_case=ignore_case, show_all=show_all)
123 return ns.filter(name_pattern=pattern_list[0], type_pattern=type_pattern,
154 return ns.ns
124 ignore_case=ignore_case, show_all=show_all)
155 else:
125 else:
156 ns=NameSpace.from_object(ns_obj, name_pattern=pattern_list[0],
126 filtered = ns.filter(name_pattern=pattern_list[0], type_pattern="all",
157 type_pattern="all", ignore_case=ignore_case, show_all=show_all)
127 ignore_case=ignore_case, show_all=show_all)
158 res={}
128 results = {}
159 for name,obj in ns.ns.iteritems():
129 for name, obj in filtered.iteritems():
160 ns=list_object_namespace(obj, type_pattern, pattern_list[1:],
130 ns = list_object_namespace(obj, type_pattern, pattern_list[1:],
161 ignore_case=ignore_case, show_all=show_all)
131 ignore_case=ignore_case, show_all=show_all)
162 for inner_name,inner_obj in ns.iteritems():
132 for inner_name,inner_obj in ns.iteritems():
163 res["%s.%s"%(name,inner_name)]=inner_obj
133 results["%s.%s"%(name,inner_name)] = inner_obj
164 return res
134 return results
General Comments 0
You need to be logged in to leave comments. Login now