##// END OF EJS Templates
Jorgens patch for ? wildcard (single char globbing)
vivainio -
Show More
@@ -1,138 +1,138 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Support for wildcard pattern matching in object inspection.
2 """Support for wildcard pattern matching in object inspection.
3
3
4 $Id: OInspect.py 608 2005-07-06 17:52:32Z fperez $
4 $Id: OInspect.py 608 2005-07-06 17:52:32Z fperez $
5 """
5 """
6
6
7 #*****************************************************************************
7 #*****************************************************************************
8 # Copyright (C) 2005 JΓΆrgen Stenarson <jorgen.stenarson@bostream.nu>
8 # Copyright (C) 2005 JΓΆrgen Stenarson <jorgen.stenarson@bostream.nu>
9 #
9 #
10 # Distributed under the terms of the BSD License. The full license is in
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
11 # the file COPYING, distributed as part of this software.
12 #*****************************************************************************
12 #*****************************************************************************
13
13
14 from IPython import Release
14 from IPython import Release
15 __author__ = "JΓΆrgen Stenarson <jorgen.stenarson@bostream.nu>"
15 __author__ = "JΓΆrgen Stenarson <jorgen.stenarson@bostream.nu>"
16 __license__ = Release.license
16 __license__ = Release.license
17
17
18 import __builtin__
18 import __builtin__
19 import exceptions
19 import exceptions
20 import pdb
20 import pdb
21 import pprint
21 import pprint
22 import re
22 import re
23 import types
23 import types
24
24
25 def create_typestr2type_dicts(dont_include_in_type2type2str=["lambda"]):
25 def create_typestr2type_dicts(dont_include_in_type2type2str=["lambda"]):
26 """Return dictionaries mapping lower case typename to type objects, from
26 """Return dictionaries mapping lower case typename to type objects, from
27 the types package, and vice versa."""
27 the types package, and vice versa."""
28 typenamelist=[]
28 typenamelist=[]
29 for tname in dir(types):
29 for tname in dir(types):
30 if tname[-4:]=="Type":
30 if tname[-4:]=="Type":
31 typenamelist.append(tname)
31 typenamelist.append(tname)
32 typestr2type={}
32 typestr2type={}
33 type2typestr={}
33 type2typestr={}
34 for tname in typenamelist:
34 for tname in typenamelist:
35 name=tname[:-4].lower()
35 name=tname[:-4].lower()
36 obj=getattr(types,tname)
36 obj=getattr(types,tname)
37 typestr2type[name]=getattr(types,tname)
37 typestr2type[name]=getattr(types,tname)
38 if name in dont_include_in_type2type2str:
38 if name in dont_include_in_type2type2str:
39 type2typestr[obj]=name
39 type2typestr[obj]=name
40 return typestr2type,type2typestr
40 return typestr2type,type2typestr
41
41
42 typestr2type,type2typestr=create_typestr2type_dicts()
42 typestr2type,type2typestr=create_typestr2type_dicts()
43
43
44 def is_type(obj,typestr_or_type):
44 def is_type(obj,typestr_or_type):
45 """is_type(obj,typestr_or_type) verifies if obj is of a certain type or
45 """is_type(obj,typestr_or_type) verifies if obj is of a certain type or
46 group of types takes strings as parameters of the for 'tuple'<->TupleType
46 group of types takes strings as parameters of the for 'tuple'<->TupleType
47 'all' matches all types. TODO: Should be extended for choosing more than
47 'all' matches all types. TODO: Should be extended for choosing more than
48 one type
48 one type
49 """
49 """
50 if typestr_or_type=="all":
50 if typestr_or_type=="all":
51 return True
51 return True
52 if type(typestr_or_type)==types.TypeType:
52 if type(typestr_or_type)==types.TypeType:
53 test_type=typestr_or_type
53 test_type=typestr_or_type
54 else:
54 else:
55 test_type=typestr2type.get(typestr_or_type,False)
55 test_type=typestr2type.get(typestr_or_type,False)
56 if test_type:
56 if test_type:
57 return isinstance(obj,test_type)
57 return isinstance(obj,test_type)
58 else:
58 else:
59 return False
59 return False
60
60
61 def show_hidden(str,show_all=False):
61 def show_hidden(str,show_all=False):
62 """Return true for strings starting with single _ if show_all is true."""
62 """Return true for strings starting with single _ if show_all is true."""
63 return show_all or str.startswith("__") or not str.startswith("_")
63 return show_all or str.startswith("__") or not str.startswith("_")
64
64
65
65
66 class NameSpace(object):
66 class NameSpace(object):
67 """NameSpace holds the dictionary for a namespace and implements filtering
67 """NameSpace holds the dictionary for a namespace and implements filtering
68 on name and types"""
68 on name and types"""
69 def __init__(self,obj,name_pattern="*",type_pattern="all",ignore_case=True,
69 def __init__(self,obj,name_pattern="*",type_pattern="all",ignore_case=True,
70 show_all=True):
70 show_all=True):
71 self.show_all = show_all #Hide names beginning with single _
71 self.show_all = show_all #Hide names beginning with single _
72 self.object = obj
72 self.object = obj
73 self.name_pattern = name_pattern
73 self.name_pattern = name_pattern
74 self.type_pattern = type_pattern
74 self.type_pattern = type_pattern
75 self.ignore_case = ignore_case
75 self.ignore_case = ignore_case
76
76
77 # We should only match EXACT dicts here, so DON'T use isinstance()
77 # We should only match EXACT dicts here, so DON'T use isinstance()
78 if type(obj) == types.DictType:
78 if type(obj) == types.DictType:
79 self._ns = obj
79 self._ns = obj
80 else:
80 else:
81 self._ns = dict([(key,getattr(obj,key)) for key in dir(obj)
81 self._ns = dict([(key,getattr(obj,key)) for key in dir(obj)
82 if isinstance(key, basestring)])
82 if isinstance(key, basestring)])
83
83
84 def get_ns(self):
84 def get_ns(self):
85 """Return name space dictionary with objects matching type and name patterns."""
85 """Return name space dictionary with objects matching type and name patterns."""
86 return self.filter(self.name_pattern,self.type_pattern)
86 return self.filter(self.name_pattern,self.type_pattern)
87 ns=property(get_ns)
87 ns=property(get_ns)
88
88
89 def get_ns_names(self):
89 def get_ns_names(self):
90 """Return list of object names in namespace that match the patterns."""
90 """Return list of object names in namespace that match the patterns."""
91 return self.ns.keys()
91 return self.ns.keys()
92 ns_names=property(get_ns_names,doc="List of objects in name space that "
92 ns_names=property(get_ns_names,doc="List of objects in name space that "
93 "match the type and name patterns.")
93 "match the type and name patterns.")
94
94
95 def filter(self,name_pattern,type_pattern):
95 def filter(self,name_pattern,type_pattern):
96 """Return dictionary of filtered namespace."""
96 """Return dictionary of filtered namespace."""
97 def glob_filter(lista,name_pattern,hidehidden,ignore_case):
97 def glob_filter(lista,name_pattern,hidehidden,ignore_case):
98 """Return list of elements in lista that match pattern."""
98 """Return list of elements in lista that match pattern."""
99 pattern=name_pattern.replace("*",".*")
99 pattern=name_pattern.replace("*",".*").replace("?",".")
100 if ignore_case:
100 if ignore_case:
101 reg=re.compile(pattern+"$",re.I)
101 reg=re.compile(pattern+"$",re.I)
102 else:
102 else:
103 reg=re.compile(pattern+"$")
103 reg=re.compile(pattern+"$")
104 result=[x for x in lista if reg.match(x) and show_hidden(x,hidehidden)]
104 result=[x for x in lista if reg.match(x) and show_hidden(x,hidehidden)]
105 return result
105 return result
106 ns=self._ns
106 ns=self._ns
107 #Filter namespace by the name_pattern
107 #Filter namespace by the name_pattern
108 all=[(x,ns[x]) for x in glob_filter(ns.keys(),name_pattern,
108 all=[(x,ns[x]) for x in glob_filter(ns.keys(),name_pattern,
109 self.show_all,self.ignore_case)]
109 self.show_all,self.ignore_case)]
110 #Filter namespace by type_pattern
110 #Filter namespace by type_pattern
111 all=[(key,obj) for key,obj in all if is_type(obj,type_pattern)]
111 all=[(key,obj) for key,obj in all if is_type(obj,type_pattern)]
112 all=dict(all)
112 all=dict(all)
113 return all
113 return all
114
114
115 #TODO: Implement dictionary like access to filtered name space?
115 #TODO: Implement dictionary like access to filtered name space?
116
116
117 def list_namespace(namespace,type_pattern,filter,ignore_case=False,show_all=False):
117 def list_namespace(namespace,type_pattern,filter,ignore_case=False,show_all=False):
118 """Return dictionary of all objects in namespace that matches type_pattern
118 """Return dictionary of all objects in namespace that matches type_pattern
119 and filter."""
119 and filter."""
120 pattern_list=filter.split(".")
120 pattern_list=filter.split(".")
121 if len(pattern_list)==1:
121 if len(pattern_list)==1:
122 ns=NameSpace(namespace,name_pattern=pattern_list[0],type_pattern=type_pattern,
122 ns=NameSpace(namespace,name_pattern=pattern_list[0],type_pattern=type_pattern,
123 ignore_case=ignore_case,show_all=show_all)
123 ignore_case=ignore_case,show_all=show_all)
124 return ns.ns
124 return ns.ns
125 else:
125 else:
126 # This is where we can change if all objects should be searched or
126 # This is where we can change if all objects should be searched or
127 # only modules. Just change the type_pattern to module to search only
127 # only modules. Just change the type_pattern to module to search only
128 # modules
128 # modules
129 ns=NameSpace(namespace,name_pattern=pattern_list[0],type_pattern="all",
129 ns=NameSpace(namespace,name_pattern=pattern_list[0],type_pattern="all",
130 ignore_case=ignore_case,show_all=show_all)
130 ignore_case=ignore_case,show_all=show_all)
131 res={}
131 res={}
132 nsdict=ns.ns
132 nsdict=ns.ns
133 for name,obj in nsdict.iteritems():
133 for name,obj in nsdict.iteritems():
134 ns=list_namespace(obj,type_pattern,".".join(pattern_list[1:]),
134 ns=list_namespace(obj,type_pattern,".".join(pattern_list[1:]),
135 ignore_case=ignore_case,show_all=show_all)
135 ignore_case=ignore_case,show_all=show_all)
136 for inner_name,inner_obj in ns.iteritems():
136 for inner_name,inner_obj in ns.iteritems():
137 res["%s.%s"%(name,inner_name)]=inner_obj
137 res["%s.%s"%(name,inner_name)]=inner_obj
138 return res
138 return res
General Comments 0
You need to be logged in to leave comments. Login now