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