1
# -*- coding: utf-8 -*-
3
# Copyright © 2009 Pierre Raybaut
4
# Licensed under the terms of the MIT License
5
# (see spyderlib/__init__.py for details)
8
Python class/function parser
10
Derived from "Demo/parser/example.py" from Python distribution
12
******************************** WARNING ***************************************
13
This module is not used anymore in Spyder since v1.1.0.
14
However, it will still be part of spyderlib module for a little while -
15
we never know, it could be useful...
16
********************************************************************************
22
from types import ListType, TupleType
25
def get_info(fileName):
26
source = open(fileName, "U").read() + "\n"
27
basename = os.path.basename(os.path.splitext(fileName)[0])
28
ast = parser.suite(source)
29
return ModuleInfo(ast.totuple(line_info=True), basename)
31
def get_classes(filename):
33
Return classes (with methods) and functions of module *filename*:
34
[ (class1_lineno, class1_name, [ (method1_lineno, method1_name), ]),
35
(func1_lineno, func1_name, None),]
37
moduleinfo = get_info(filename)
39
for classname in moduleinfo.get_class_names():
40
clinfo = moduleinfo.get_class_info(classname)
42
for methodname in clinfo.get_method_names():
43
minfo = clinfo.get_method_info(methodname)
44
methods.append( (minfo.get_lineno(), methodname) )
46
classes.append( (clinfo.get_lineno(), classname, methods) )
47
for funcname in moduleinfo.get_function_names():
48
finfo = moduleinfo.get_function_info(funcname)
49
classes.append( (finfo.get_lineno(), funcname, None) )
57
# This pattern identifies compound statements, allowing them to be readily
58
# differentiated from simple statements.
60
COMPOUND_STMT_PATTERN = (
62
(symbol.compound_stmt, ['compound'])
65
def __init__(self, tree = None):
67
self._function_info = {}
69
self._extract_info(tree)
71
def _extract_info(self, tree):
73
# discover inner definitions
75
found, vars = match(self.COMPOUND_STMT_PATTERN, node)
77
cstmt = vars['compound']
78
if cstmt[0] == symbol.funcdef:
79
func_info = FunctionInfo(cstmt)
80
self._function_info[func_info._name] = func_info
81
elif cstmt[0] == symbol.classdef:
82
class_info = ClassInfo(cstmt)
83
self._class_info[class_info._name] = class_info
91
def get_class_names(self):
92
return self._class_info.keys()
94
def get_class_info(self, name):
95
return self._class_info[name]
97
def __getitem__(self, name):
99
return self._class_info[name]
101
return self._function_info[name]
105
# Mixin class providing access to function names and info.
107
def get_function_names(self):
108
return self._function_info.keys()
110
def get_function_info(self, name):
111
return self._function_info[name]
114
class FunctionInfo(SuiteInfoBase, SuiteFuncInfo):
115
def __init__(self, tree = None):
118
if tree[1][0] == symbol.decorators:
121
self._name = prefix + tree[index][1]
122
self._lineno = tree[index][2]
123
SuiteInfoBase.__init__(self, tree and tree[-1] or None)
126
class ClassInfo(SuiteInfoBase):
127
def __init__(self, tree = None):
128
self._name = tree[2][1]
129
self._lineno = tree[2][2]
130
SuiteInfoBase.__init__(self, tree and tree[-1] or None)
132
def get_method_names(self):
133
return self._function_info.keys()
135
def get_method_info(self, name):
136
return self._function_info[name]
139
class ModuleInfo(SuiteInfoBase, SuiteFuncInfo):
140
def __init__(self, tree = None, name = "<string>"):
143
if tree[0] == symbol.encoding_decl:
144
self._encoding = tree[2]
147
self._encoding = 'ascii'
148
SuiteInfoBase.__init__(self, tree)
151
def match(pattern, data, vars=None):
152
"""Match `data' to `pattern', with variable extraction.
155
Pattern to match against, possibly containing variables.
158
Data to be checked and against which variables are extracted.
161
Dictionary of variables which have already been found. If not
162
provided, an empty dictionary is created.
164
The `pattern' value may contain variables of the form ['varname'] which
165
are allowed to match anything. The value that is matched is returned as
166
part of a dictionary which maps 'varname' to the matched value. 'varname'
167
is not required to be a string object, but using strings makes patterns
168
and the code which uses them more readable.
170
This function returns two values: a boolean indicating whether a match
171
was found and a dictionary mapping variable names to their associated
176
if type(pattern) is ListType: # 'variables' are ['varname']
177
vars[pattern[0]] = data
179
if type(pattern) is not TupleType:
180
return (pattern == data), vars
181
if len(data) != len(pattern):
183
for pattern, data in map(None, pattern, data):
184
same, vars = match(pattern, data, vars)
190
if __name__ == '__main__':
193
classes = get_classes(sys.argv[1])
194
print "Elapsed time: %s ms" % round((time.time()-t0)*1000)
195
# from pprint import pprint
1
# -*- coding: utf-8 -*-
3
# Copyright © 2009 Pierre Raybaut
4
# Licensed under the terms of the MIT License
5
# (see spyderlib/__init__.py for details)
8
Python class/function parser
10
Derived from "Demo/parser/example.py" from Python distribution
12
******************************** WARNING ***************************************
13
This module is not used anymore in Spyder since v1.1.0.
14
However, it will still be part of spyderlib module for a little while -
15
we never know, it could be useful...
16
********************************************************************************
22
from types import ListType, TupleType
25
def get_info(fileName):
26
source = open(fileName, "U").read() + "\n"
27
basename = os.path.basename(os.path.splitext(fileName)[0])
28
ast = parser.suite(source)
29
return ModuleInfo(ast.totuple(line_info=True), basename)
31
def get_classes(filename):
33
Return classes (with methods) and functions of module *filename*:
34
[ (class1_lineno, class1_name, [ (method1_lineno, method1_name), ]),
35
(func1_lineno, func1_name, None),]
37
moduleinfo = get_info(filename)
39
for classname in moduleinfo.get_class_names():
40
clinfo = moduleinfo.get_class_info(classname)
42
for methodname in clinfo.get_method_names():
43
minfo = clinfo.get_method_info(methodname)
44
methods.append( (minfo.get_lineno(), methodname) )
46
classes.append( (clinfo.get_lineno(), classname, methods) )
47
for funcname in moduleinfo.get_function_names():
48
finfo = moduleinfo.get_function_info(funcname)
49
classes.append( (finfo.get_lineno(), funcname, None) )
57
# This pattern identifies compound statements, allowing them to be readily
58
# differentiated from simple statements.
60
COMPOUND_STMT_PATTERN = (
62
(symbol.compound_stmt, ['compound'])
65
def __init__(self, tree = None):
67
self._function_info = {}
69
self._extract_info(tree)
71
def _extract_info(self, tree):
73
# discover inner definitions
75
found, vars = match(self.COMPOUND_STMT_PATTERN, node)
77
cstmt = vars['compound']
78
if cstmt[0] == symbol.funcdef:
79
func_info = FunctionInfo(cstmt)
80
self._function_info[func_info._name] = func_info
81
elif cstmt[0] == symbol.classdef:
82
class_info = ClassInfo(cstmt)
83
self._class_info[class_info._name] = class_info
91
def get_class_names(self):
92
return self._class_info.keys()
94
def get_class_info(self, name):
95
return self._class_info[name]
97
def __getitem__(self, name):
99
return self._class_info[name]
101
return self._function_info[name]
105
# Mixin class providing access to function names and info.
107
def get_function_names(self):
108
return self._function_info.keys()
110
def get_function_info(self, name):
111
return self._function_info[name]
114
class FunctionInfo(SuiteInfoBase, SuiteFuncInfo):
115
def __init__(self, tree = None):
118
if tree[1][0] == symbol.decorators:
121
self._name = prefix + tree[index][1]
122
self._lineno = tree[index][2]
123
SuiteInfoBase.__init__(self, tree and tree[-1] or None)
126
class ClassInfo(SuiteInfoBase):
127
def __init__(self, tree = None):
128
self._name = tree[2][1]
129
self._lineno = tree[2][2]
130
SuiteInfoBase.__init__(self, tree and tree[-1] or None)
132
def get_method_names(self):
133
return self._function_info.keys()
135
def get_method_info(self, name):
136
return self._function_info[name]
139
class ModuleInfo(SuiteInfoBase, SuiteFuncInfo):
140
def __init__(self, tree = None, name = "<string>"):
143
if tree[0] == symbol.encoding_decl:
144
self._encoding = tree[2]
147
self._encoding = 'ascii'
148
SuiteInfoBase.__init__(self, tree)
151
def match(pattern, data, vars=None):
152
"""Match `data' to `pattern', with variable extraction.
155
Pattern to match against, possibly containing variables.
158
Data to be checked and against which variables are extracted.
161
Dictionary of variables which have already been found. If not
162
provided, an empty dictionary is created.
164
The `pattern' value may contain variables of the form ['varname'] which
165
are allowed to match anything. The value that is matched is returned as
166
part of a dictionary which maps 'varname' to the matched value. 'varname'
167
is not required to be a string object, but using strings makes patterns
168
and the code which uses them more readable.
170
This function returns two values: a boolean indicating whether a match
171
was found and a dictionary mapping variable names to their associated
176
if type(pattern) is ListType: # 'variables' are ['varname']
177
vars[pattern[0]] = data
179
if type(pattern) is not TupleType:
180
return (pattern == data), vars
181
if len(data) != len(pattern):
183
for pattern, data in map(None, pattern, data):
184
same, vars = match(pattern, data, vars)
190
if __name__ == '__main__':
193
classes = get_classes(sys.argv[1])
194
print "Elapsed time: %s ms" % round((time.time()-t0)*1000)
195
# from pprint import pprint