Skip to content

Commit 06de3ac

Browse files
committed
core: added get_all_class_method_bodies for getting class method bodies just like functions
1 parent fcd4494 commit 06de3ac

File tree

4 files changed

+82
-5
lines changed

4 files changed

+82
-5
lines changed

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"Programming Language :: Python :: 3",
2424
"Programming Language :: Python :: 3.6",
2525
],
26-
version="0.9.2",
26+
version="0.10.0",
2727
packages=find_packages(exclude=("tests",)),
2828
install_requires=["tree-sitter", "pygit2", "pytest", "PyYAML"],
2929
entry_points = {

tests/assets/file_with_different_functions.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,6 @@ class AnotherClass(BaseClass):
9191
def __init__(self):
9292
super(AnotherClass, self).__init__(12)
9393
self.name = "AnotherClass"
94+
95+
def get_class_name(self):
96+
return self.name

tests/test_python_parser.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ def test_parser_get_all_class_method_names(python_parser):
6666
'scan'
6767
],
6868
'AnotherClass': [
69-
'__init__'
69+
'__init__',
70+
'get_class_name'
7071
]
7172
}
7273

@@ -86,6 +87,22 @@ def test_parser_get_all_function_bodies(python_parser):
8687
)
8788
assert python_parser.get_all_function_bodies()["function_different_args"] == \
8889
'def function_different_args(foo, bar, no, pi, opt_typed):\n return 0'
90+
91+
def test_parser_get_all_method_bodies(python_parser):
92+
assert python_parser.get_all_class_method_bodies()['BaseClass']["get_name"] == \
93+
"def get_name(self):\n '''Get the name parameter\n '''\n return self.name"
94+
assert python_parser.get_all_class_method_bodies(get_index=True)['BaseClass']["get_name"] ==(
95+
"def get_name(self):\n '''Get the name parameter\n '''\n return self.name",
96+
(75, 8),
97+
(77, 24)
98+
)
99+
assert python_parser.get_all_class_method_bodies(get_index=True, strip_docstr=True)['BaseClass']["get_name"] == (
100+
('def get_name(self):\n return self.name',
101+
"'''Get the name parameter\n '''"),
102+
(75, 8),
103+
(77, 24)
104+
)
105+
89106

90107
def test_parser_get_all_function_documentations(python_parser):
91108
assert python_parser.get_all_function_documentations() == {
@@ -98,11 +115,11 @@ def test_parser_get_all_function_documentations(python_parser):
98115
def test_parser_walk(python_parser):
99116
l = []
100117
python_parser.walk(lambda node: l.append(1) if node.type == "function_definition" else l.append(0))
101-
assert sum(l) == 12
118+
assert sum(l) == 13
102119

103120
def test_parser_reduction(python_parser):
104121
assert python_parser.reduction(
105122
lambda node,acc: acc+1 if node.type == "function_definition" else acc, 0
106-
) == 12
123+
) == 13
107124

108125

tree_hugger/core/parser/python/python_parser.py

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def _outer_indent(self, code):
6464
return min(spaces_arr) if spaces_arr else 4
6565

6666

67-
def get_all_class_method_names(self) -> List:
67+
def get_all_class_method_names(self) -> Dict:
6868
"""
6969
Gets all the method names from a file.
7070
@@ -164,6 +164,63 @@ def get_all_method_documentations(self, strip_quotes: bool=False) -> Dict:
164164
def _get_var_names_as_string_from_param_list(self, param_list):
165165
return "(" + ", ".join([var_name for var_name, _, _ in param_list]) + ")"
166166

167+
def get_all_class_method_bodies(self, strip_docstr: bool=False, get_index: bool=False) -> Dict:
168+
class_method_names = self.get_all_class_method_names()
169+
methods_and_params = self.get_all_function_names_with_params()
170+
method_and_docstr = self.get_all_method_docstrings()
171+
172+
captures = self._run_query_and_get_captures('all_function_bodies', self.root_node)
173+
174+
ret_struct = {}
175+
pp = {}
176+
177+
for i in range(0, len(captures), 2):
178+
func_name = match_from_span(captures[i][0], self.splitted_code)
179+
for class_name, method_name_list in class_method_names.items():
180+
if func_name in method_name_list and (func_name != "__init__" and func_name != "__new__"):
181+
if pp.get(class_name) is None:
182+
pp[class_name] = {}
183+
pp[class_name] = {func_name:
184+
(match_from_span(captures[i+1][0], self.splitted_code), captures[i+1][0].start_point, captures[i+1][0].end_point)
185+
}
186+
else:
187+
if func_name != "__init__" and func_name != "__new__":
188+
pp[class_name][func_name] = (match_from_span(captures[i+1][0], self.splitted_code), captures[i+1][0].start_point, captures[i+1][0].end_point)
189+
190+
if strip_docstr:
191+
for class_name, func_data_struct in pp.items():
192+
ret_struct[class_name] = {}
193+
for k, (v,sp,ep) in func_data_struct.items():
194+
if method_and_docstr[class_name].get(k) is not None and method_and_docstr[class_name].get(k) is not '':
195+
code = v.replace(method_and_docstr[class_name][k], "")
196+
outer_indent = self._outer_indent(code)
197+
spaces = " ".join([''] * (outer_indent + 1))
198+
if code.startswith("\n"):
199+
ret_struct[class_name][k] = (f"def {k}{self._get_var_names_as_string_from_param_list(methods_and_params[k])}:{code}",
200+
method_and_docstr[class_name][k])
201+
else:
202+
ret_struct[class_name][k] = (f"def {k}{self._get_var_names_as_string_from_param_list(methods_and_params[k])}:\n{spaces}{code}",
203+
method_and_docstr[class_name][k])
204+
else:
205+
outer_indent = self._outer_indent(v)
206+
spaces = " ".join([''] * (outer_indent + 1))
207+
ret_struct[class_name][k] = (f"def {k}{self._get_var_names_as_string_from_param_list(methods_and_params[k])}:\n{spaces}{v}", "")
208+
if get_index:
209+
ret_struct[class_name][k] = ret_struct[class_name][k],sp,ep
210+
else:
211+
for class_name, func_data_struct in pp.items():
212+
for k, (v,sp,ep) in func_data_struct.items():
213+
outer_indent = self._outer_indent(v)
214+
spaces = " ".join([''] * (outer_indent + 1))
215+
if ret_struct.get(class_name) is None:
216+
ret_struct[class_name] = {}
217+
ret_struct[class_name][k] = f"def {k}{self._get_var_names_as_string_from_param_list(methods_and_params[k])}:\n{spaces}{v}"
218+
else:
219+
ret_struct[class_name][k] = f"def {k}{self._get_var_names_as_string_from_param_list(methods_and_params[k])}:\n{spaces}{v}"
220+
if get_index:
221+
ret_struct[class_name][k] = (ret_struct[class_name][k], sp, ep)
222+
return ret_struct
223+
167224
def get_all_function_bodies(self, strip_docstr: bool=False, get_index: bool=False) -> Dict:
168225
"""
169226
Returns a dict where function names are the key and the whole function code are the values

0 commit comments

Comments
 (0)