codegrapher 0.2.1__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- codegrapher-0.3.0/.gitattributes +1 -0
- codegrapher-0.3.0/.github/workflows/main.yaml +39 -0
- codegrapher-0.3.0/.github/workflows/publish.yaml +21 -0
- codegrapher-0.3.0/.gitignore +13 -0
- codegrapher-0.3.0/.readthedocs.yaml +22 -0
- codegrapher-0.3.0/LICENSE +16 -0
- codegrapher-0.3.0/Makefile +16 -0
- codegrapher-0.3.0/PKG-INFO +150 -0
- {codegrapher-0.2.1 → codegrapher-0.3.0}/README.rst +5 -5
- codegrapher-0.3.0/codegrapher/__init__.py +1 -0
- {codegrapher-0.2.1 → codegrapher-0.3.0}/codegrapher/parser.py +37 -40
- codegrapher-0.3.0/docs/Makefile +177 -0
- codegrapher-0.3.0/docs/codegrapher.rst +29 -0
- codegrapher-0.3.0/docs/conf.py +261 -0
- codegrapher-0.3.0/docs/docs-requirements.txt +3 -0
- codegrapher-0.3.0/docs/index.rst +25 -0
- codegrapher-0.3.0/docs/make.bat +242 -0
- codegrapher-0.3.0/docs/modules.rst +7 -0
- codegrapher-0.3.0/docs/readme_link.rst +3 -0
- codegrapher-0.3.0/pyproject.toml +53 -0
- codegrapher-0.3.0/setup.md +38 -0
- {codegrapher-0.2.1 → codegrapher-0.3.0}/tests/test_graph.py +0 -3
- {codegrapher-0.2.1 → codegrapher-0.3.0}/tests/test_parser.py +26 -15
- codegrapher-0.3.0/uv.lock +691 -0
- codegrapher-0.2.1/PKG-INFO +0 -16
- codegrapher-0.2.1/codegrapher/__init__.py +0 -1
- codegrapher-0.2.1/codegrapher.egg-info/PKG-INFO +0 -16
- codegrapher-0.2.1/codegrapher.egg-info/SOURCES.txt +0 -17
- codegrapher-0.2.1/codegrapher.egg-info/dependency_links.txt +0 -1
- codegrapher-0.2.1/codegrapher.egg-info/entry_points.txt +0 -4
- codegrapher-0.2.1/codegrapher.egg-info/pbr.json +0 -1
- codegrapher-0.2.1/codegrapher.egg-info/requires.txt +0 -2
- codegrapher-0.2.1/codegrapher.egg-info/top_level.txt +0 -3
- codegrapher-0.2.1/setup.cfg +0 -5
- codegrapher-0.2.1/setup.py +0 -32
- {codegrapher-0.2.1 → codegrapher-0.3.0}/cli/__init__.py +0 -0
- {codegrapher-0.2.1 → codegrapher-0.3.0}/cli/script.py +0 -0
- {codegrapher-0.2.1 → codegrapher-0.3.0}/codegrapher/graph.py +0 -0
- {codegrapher-0.2.1 → codegrapher-0.3.0}/tests/__init__.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* text=auto eol=lf
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Codegrapher unit tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
|
|
14
|
+
fail-fast: false
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
19
|
+
uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: ${{ matrix.python-version }}
|
|
22
|
+
- name: Install uv
|
|
23
|
+
uses: astral-sh/setup-uv@v5
|
|
24
|
+
- name: Install project and dev dependencies
|
|
25
|
+
run: uv sync --locked --extra dev
|
|
26
|
+
- name: Test with pytest
|
|
27
|
+
run: uv run pytest tests --doctest-modules --junitxml=junit/test-results-${{ matrix.python-version }}.xml --cov --cov-report=xml --cov-report=html
|
|
28
|
+
- name: Upload test results
|
|
29
|
+
uses: actions/upload-artifact@v4
|
|
30
|
+
if: always()
|
|
31
|
+
with:
|
|
32
|
+
name: test-results-${{ matrix.python-version }}
|
|
33
|
+
path: junit/test-results-${{ matrix.python-version }}.xml
|
|
34
|
+
- name: Upload coverage report
|
|
35
|
+
uses: actions/upload-artifact@v4
|
|
36
|
+
if: always()
|
|
37
|
+
with:
|
|
38
|
+
name: coverage-report-${{ matrix.python-version }}
|
|
39
|
+
path: htmlcov/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
publish:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
environment: release
|
|
11
|
+
permissions:
|
|
12
|
+
id-token: write # required for OIDC trusted publishing
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- name: Install uv
|
|
17
|
+
uses: astral-sh/setup-uv@v5
|
|
18
|
+
- name: Build distribution
|
|
19
|
+
run: uv build
|
|
20
|
+
- name: Publish to PyPI
|
|
21
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# .readthedocs.yaml
|
|
2
|
+
# Read the Docs configuration file
|
|
3
|
+
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
|
4
|
+
|
|
5
|
+
# Required
|
|
6
|
+
version: 2
|
|
7
|
+
|
|
8
|
+
# Set the version of Python and other tools you might need
|
|
9
|
+
build:
|
|
10
|
+
os: ubuntu-22.04
|
|
11
|
+
tools:
|
|
12
|
+
python: "3.11"
|
|
13
|
+
|
|
14
|
+
# Build documentation in the docs/ directory with Sphinx
|
|
15
|
+
sphinx:
|
|
16
|
+
configuration: docs/conf.py
|
|
17
|
+
|
|
18
|
+
# We recommend specifying your dependencies to enable reproducible builds:
|
|
19
|
+
# https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
|
|
20
|
+
# python:
|
|
21
|
+
# install:
|
|
22
|
+
# - requirements: docs/requirements.txt
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Laura Rupprecht
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
|
6
|
+
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
|
7
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
8
|
+
persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
|
11
|
+
Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
|
14
|
+
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
15
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
16
|
+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: codegrapher
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Code that graphs code
|
|
5
|
+
Project-URL: Homepage, https://github.com/LaurEars/codegrapher
|
|
6
|
+
Project-URL: Repository, https://github.com/LaurEars/codegrapher
|
|
7
|
+
Project-URL: Issues, https://github.com/LaurEars/codegrapher/issues
|
|
8
|
+
Author: Laura Rupprecht
|
|
9
|
+
License: The MIT License (MIT)
|
|
10
|
+
|
|
11
|
+
Copyright (c) 2026 Laura Rupprecht
|
|
12
|
+
|
|
13
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
|
14
|
+
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
|
15
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
16
|
+
persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
17
|
+
|
|
18
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
|
19
|
+
Software.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
|
22
|
+
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
23
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
24
|
+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Keywords: ast,call-graph,code,documentation,graph,graphviz
|
|
27
|
+
Classifier: Development Status :: 4 - Beta
|
|
28
|
+
Classifier: Intended Audience :: Developers
|
|
29
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
30
|
+
Classifier: Programming Language :: Python :: 3
|
|
31
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
32
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
33
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
37
|
+
Classifier: Topic :: Software Development :: Documentation
|
|
38
|
+
Requires-Python: >=3.8
|
|
39
|
+
Requires-Dist: click>=7.0
|
|
40
|
+
Requires-Dist: graphviz>=0.4.2
|
|
41
|
+
Provides-Extra: dev
|
|
42
|
+
Requires-Dist: coverage>=5.0; extra == 'dev'
|
|
43
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
|
|
44
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
45
|
+
Description-Content-Type: text/x-rst
|
|
46
|
+
|
|
47
|
+
codegrapher
|
|
48
|
+
===========
|
|
49
|
+
|
|
50
|
+
.. image:: https://github.com/LaurEars/codegrapher/actions/workflows/main.yaml/badge.svg
|
|
51
|
+
:target: https://github.com/LaurEars/codegrapher/actions/workflows/main.yaml
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
Code that graphs code
|
|
55
|
+
---------------------
|
|
56
|
+
Uses the python `AST <https://docs.python.org/3/library/ast.html>`_ to parse Python source code and build a call graph.
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
Output
|
|
60
|
+
------
|
|
61
|
+
An example of the current output of the parser parsing itself.
|
|
62
|
+
|
|
63
|
+
.. image:: docs/codegrapher.png
|
|
64
|
+
:target: docs/codegrapher.png
|
|
65
|
+
:align: center
|
|
66
|
+
:width: 100 %
|
|
67
|
+
:alt: parser.py
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
Installation
|
|
71
|
+
------------
|
|
72
|
+
|
|
73
|
+
.. code:: bash
|
|
74
|
+
|
|
75
|
+
pip install codegrapher
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
To generate graphs, `graphviz <http://www.graphviz.org/Download.php>`_ must be installed.
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
Usage
|
|
82
|
+
-----
|
|
83
|
+
|
|
84
|
+
At the command line
|
|
85
|
+
~~~~~~~~~~~~~~~~~~~
|
|
86
|
+
To parse a file and output results to the console:
|
|
87
|
+
|
|
88
|
+
.. code:: bash
|
|
89
|
+
|
|
90
|
+
codegrapher path/to/file.py --printed
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
To parse a file and output results to a file:
|
|
94
|
+
|
|
95
|
+
.. code:: bash
|
|
96
|
+
|
|
97
|
+
codegrapher path/to/file.py --output output_file_name --output-type png
|
|
98
|
+
|
|
99
|
+
To analyze a directory of files, along with all files it contains:
|
|
100
|
+
|
|
101
|
+
.. code:: bash
|
|
102
|
+
|
|
103
|
+
codegrapher -r path/to/directory --output multiple_file_analysis
|
|
104
|
+
|
|
105
|
+
And if you have a list of functions that aren't useful in your graph, add it to a `.cg_ignore` file:
|
|
106
|
+
|
|
107
|
+
::
|
|
108
|
+
|
|
109
|
+
# cg_ignore file
|
|
110
|
+
# all lines beginning with '#' are ignored
|
|
111
|
+
|
|
112
|
+
# every function calls this, so it's not helpful in my graph:
|
|
113
|
+
log_error
|
|
114
|
+
|
|
115
|
+
# I don't want to see this in my graph:
|
|
116
|
+
parse
|
|
117
|
+
lower
|
|
118
|
+
|
|
119
|
+
Then add the `--ignore` flag to your command. Using the flag `--remove-builtins` provides the same functionality
|
|
120
|
+
for ignoring items found in `__builtins__`.
|
|
121
|
+
|
|
122
|
+
As a Python module
|
|
123
|
+
~~~~~~~~~~~~~~~~~~
|
|
124
|
+
|
|
125
|
+
To easily parse code in Python :
|
|
126
|
+
|
|
127
|
+
.. code:: python
|
|
128
|
+
|
|
129
|
+
from codegrapher.parser import FileObject
|
|
130
|
+
|
|
131
|
+
file_object = FileObject('path/to/file.py')
|
|
132
|
+
file_object.visit()
|
|
133
|
+
|
|
134
|
+
And then to add that code to a graph and render it (using graphviz):
|
|
135
|
+
|
|
136
|
+
.. code:: python
|
|
137
|
+
|
|
138
|
+
from codegrapher.graph import FunctionGrapher
|
|
139
|
+
|
|
140
|
+
graph = FunctionGrapher()
|
|
141
|
+
graph.add_file_to_graph(file_object)
|
|
142
|
+
graph.name = 'name.gv'
|
|
143
|
+
graph.format = 'png'
|
|
144
|
+
graph.render()
|
|
145
|
+
|
|
146
|
+
Which will produce your code as a png file, `name.gv.png`, along with a
|
|
147
|
+
`dot file <http://en.wikipedia.org/wiki/DOT_%28graph_description_language%29>`_ `name.gv`
|
|
148
|
+
|
|
149
|
+
More documentation for the Python module can be found at
|
|
150
|
+
`Read the Docs <http://codegrapher.readthedocs.org/en/latest/>`_.
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
codegrapher
|
|
2
2
|
===========
|
|
3
3
|
|
|
4
|
-
.. image:: https://
|
|
5
|
-
:target: https://
|
|
4
|
+
.. image:: https://github.com/LaurEars/codegrapher/actions/workflows/main.yaml/badge.svg
|
|
5
|
+
:target: https://github.com/LaurEars/codegrapher/actions/workflows/main.yaml
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
Code that graphs code
|
|
9
9
|
---------------------
|
|
10
|
-
Uses the python `AST <https://docs.python.org/
|
|
10
|
+
Uses the python `AST <https://docs.python.org/3/library/ast.html>`_ to parse Python source code and build a call graph.
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
Output
|
|
14
14
|
------
|
|
15
15
|
An example of the current output of the parser parsing itself.
|
|
16
16
|
|
|
17
|
-
.. image::
|
|
18
|
-
:target:
|
|
17
|
+
.. image:: docs/codegrapher.png
|
|
18
|
+
:target: docs/codegrapher.png
|
|
19
19
|
:align: center
|
|
20
20
|
:width: 100 %
|
|
21
21
|
:alt: parser.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.3.0'
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import os
|
|
2
1
|
import ast
|
|
3
2
|
import copy
|
|
3
|
+
import os
|
|
4
4
|
from pprint import pformat
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
class FileObject
|
|
8
|
-
"""
|
|
7
|
+
class FileObject:
|
|
8
|
+
"""Class for keeping track of files.
|
|
9
9
|
|
|
10
10
|
Attributes:
|
|
11
11
|
modules (dict): dict of current modules with `alias: module_name`, `key:value pairs`.
|
|
@@ -29,7 +29,7 @@ class FileObject(object):
|
|
|
29
29
|
self.ignore = set()
|
|
30
30
|
|
|
31
31
|
def visit(self):
|
|
32
|
-
"""
|
|
32
|
+
"""Visits all the nodes within the current file AST node.
|
|
33
33
|
|
|
34
34
|
Updates `self.classes` for the current instance.
|
|
35
35
|
"""
|
|
@@ -41,13 +41,12 @@ class FileObject(object):
|
|
|
41
41
|
self.namespace()
|
|
42
42
|
|
|
43
43
|
def remove_builtins(self):
|
|
44
|
-
"""
|
|
45
|
-
"""
|
|
44
|
+
"""Removes builtins from each class in a `FileObject` instance."""
|
|
46
45
|
for class_object in self.classes:
|
|
47
46
|
class_object.remove_builtins()
|
|
48
47
|
|
|
49
48
|
def add_ignore_file(self):
|
|
50
|
-
"""
|
|
49
|
+
"""Use a file `.cg_ignore` to ignore a list of functions from the call graph
|
|
51
50
|
"""
|
|
52
51
|
if os.path.isfile('.cg_ignore'):
|
|
53
52
|
with open('.cg_ignore', 'r') as ignore_file:
|
|
@@ -56,21 +55,21 @@ class FileObject(object):
|
|
|
56
55
|
self.ignore.add(line.strip())
|
|
57
56
|
|
|
58
57
|
def ignore_functions(self):
|
|
59
|
-
"""
|
|
58
|
+
"""Ignore all functions in the current class which are present in the instance's `ignore` attribute.
|
|
60
59
|
"""
|
|
61
60
|
for class_object in self.classes:
|
|
62
61
|
class_object.ignore_functions(self.ignore)
|
|
63
62
|
|
|
64
63
|
def namespace(self):
|
|
65
|
-
"""
|
|
64
|
+
"""Programmatically change the name of items in the call tree so they have relative path information
|
|
66
65
|
"""
|
|
67
66
|
|
|
68
67
|
for class_object in self.classes:
|
|
69
68
|
class_object.namespace(self.relative_namespace)
|
|
70
69
|
|
|
71
70
|
|
|
72
|
-
class ClassObject
|
|
73
|
-
"""
|
|
71
|
+
class ClassObject:
|
|
72
|
+
"""Class for keeping track of classes in code.
|
|
74
73
|
|
|
75
74
|
Attributes:
|
|
76
75
|
modules (dict): dict of current modules with `alias: module_name`, `key:value pairs`.
|
|
@@ -90,39 +89,30 @@ class ClassObject(object):
|
|
|
90
89
|
self.call_tree = {}
|
|
91
90
|
|
|
92
91
|
def visit(self):
|
|
93
|
-
"""
|
|
92
|
+
"""Visits all the nodes within the current class AST node.
|
|
94
93
|
|
|
95
94
|
Updates `self.functions` and `self.call_tree` for the current instance.
|
|
96
95
|
"""
|
|
97
96
|
function_visitor = FunctionVisitor(aliases=self.aliases, modules=self.modules)
|
|
98
97
|
function_visitor.visit(self.node)
|
|
99
98
|
self.functions = function_visitor.functions
|
|
100
|
-
self.call_tree = dict(((self.name, k), v) for k, v in function_visitor.calls.
|
|
99
|
+
self.call_tree = dict(((self.name, k), v) for k, v in function_visitor.calls.items())
|
|
101
100
|
|
|
102
101
|
def remove_builtins(self):
|
|
103
|
-
"""
|
|
102
|
+
"""For many classes, we may not want to include builtin functions in the graph.
|
|
104
103
|
Remove builtins from the call tree and from called functions list.
|
|
105
104
|
"""
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
new_call_list = []
|
|
109
|
-
for call in call_list:
|
|
110
|
-
if __builtins__.has_key(call[0]):
|
|
111
|
-
continue
|
|
112
|
-
else:
|
|
113
|
-
new_call_list.append(call)
|
|
114
|
-
new_call_tree[caller] = new_call_list
|
|
115
|
-
|
|
116
|
-
self.call_tree = new_call_tree
|
|
105
|
+
self.call_tree = {caller: [call for call in call_list if not self.is_builtin(call[0])]
|
|
106
|
+
for caller, call_list in self.call_tree.items()}
|
|
117
107
|
|
|
118
108
|
def ignore_functions(self, ignore_set):
|
|
119
|
-
"""
|
|
109
|
+
"""Ignores all functions matching those specified in a pre-defined ignore set.
|
|
120
110
|
|
|
121
111
|
Args:
|
|
122
112
|
ignore_set (set): Functions whose calls should be removed (ignored) in the class call tree.
|
|
123
113
|
"""
|
|
124
114
|
new_call_tree = {}
|
|
125
|
-
for caller, call_list in self.call_tree.
|
|
115
|
+
for caller, call_list in self.call_tree.items():
|
|
126
116
|
new_call_list = []
|
|
127
117
|
for call in call_list:
|
|
128
118
|
if call[-1] not in ignore_set:
|
|
@@ -132,7 +122,7 @@ class ClassObject(object):
|
|
|
132
122
|
self.call_tree = new_call_tree
|
|
133
123
|
|
|
134
124
|
def namespace(self, relative_namespace):
|
|
135
|
-
"""
|
|
125
|
+
"""Take the relative namespace for the class and prepend it to each item defined in the current class.
|
|
136
126
|
|
|
137
127
|
Args:
|
|
138
128
|
relative_namespace (string): Namespace to be prepended to each item in the call tree.
|
|
@@ -143,13 +133,20 @@ class ClassObject(object):
|
|
|
143
133
|
self.call_tree = new_call_tree
|
|
144
134
|
|
|
145
135
|
def pprint(self):
|
|
146
|
-
"""
|
|
136
|
+
"""Pretty print formatter for class object.
|
|
147
137
|
|
|
148
138
|
Returns:
|
|
149
139
|
string
|
|
150
140
|
"""
|
|
151
141
|
return pformat(self.call_tree)
|
|
152
142
|
|
|
143
|
+
@staticmethod
|
|
144
|
+
def is_builtin(fn):
|
|
145
|
+
"""Checks if a """
|
|
146
|
+
if isinstance(fn, str):
|
|
147
|
+
return fn in __builtins__
|
|
148
|
+
return False
|
|
149
|
+
|
|
153
150
|
def __repr__(self):
|
|
154
151
|
return "ClassObject {}".format(self.name)
|
|
155
152
|
|
|
@@ -158,8 +155,8 @@ class ClassObject(object):
|
|
|
158
155
|
return "Class {}\nDefined functions: {}".format(self.name, functions)
|
|
159
156
|
|
|
160
157
|
|
|
161
|
-
class FunctionObject
|
|
162
|
-
"""
|
|
158
|
+
class FunctionObject:
|
|
159
|
+
"""Object that stores information within a single function definition
|
|
163
160
|
|
|
164
161
|
attributes:
|
|
165
162
|
modules: dict of current modules with `alias: module_name`, `key:value pairs`.
|
|
@@ -183,7 +180,7 @@ class FunctionObject(object):
|
|
|
183
180
|
|
|
184
181
|
@classmethod
|
|
185
182
|
def _extract_decorators(cls, node):
|
|
186
|
-
"""
|
|
183
|
+
"""Pulls out strings for each item in a decorator list on a FunctionDef node
|
|
187
184
|
|
|
188
185
|
Args:
|
|
189
186
|
node (:mod:`ast.AST`): Node from which `decorator_list` will be extracted
|
|
@@ -200,7 +197,7 @@ class FunctionObject(object):
|
|
|
200
197
|
return decorator_list
|
|
201
198
|
|
|
202
199
|
def visit(self):
|
|
203
|
-
"""
|
|
200
|
+
"""Visits all the nodes within the current function object's AST node.
|
|
204
201
|
|
|
205
202
|
Updates `self.calls`, `self.modules`, and `self.aliases` for the current instance.
|
|
206
203
|
"""
|
|
@@ -215,7 +212,7 @@ class FunctionObject(object):
|
|
|
215
212
|
|
|
216
213
|
|
|
217
214
|
class CallInspector(ast.NodeVisitor):
|
|
218
|
-
"""
|
|
215
|
+
"""Within a call, a Name or Attribute will provide the function name currently in use.
|
|
219
216
|
|
|
220
217
|
Identifies `Name` nodes, which are called as ``name(args)``, and `Attribute` nodes, which are called as
|
|
221
218
|
``object.attr(args)``
|
|
@@ -240,7 +237,7 @@ class CallInspector(ast.NodeVisitor):
|
|
|
240
237
|
|
|
241
238
|
|
|
242
239
|
class ImportVisitor(ast.NodeVisitor):
|
|
243
|
-
"""
|
|
240
|
+
"""For import related calls, store the source modules and aliases used.
|
|
244
241
|
Designed to be inherited by other classes that need to know about imports in their current scope.
|
|
245
242
|
|
|
246
243
|
Attributes:
|
|
@@ -267,9 +264,9 @@ class ImportVisitor(ast.NodeVisitor):
|
|
|
267
264
|
self.aliases[asname] = item.name
|
|
268
265
|
self.modules[asname] = module
|
|
269
266
|
|
|
270
|
-
|
|
267
|
+
|
|
271
268
|
class CallVisitor(ImportVisitor):
|
|
272
|
-
"""
|
|
269
|
+
"""Finds all calls present in the current scope and inspect them.
|
|
273
270
|
|
|
274
271
|
Attributes:
|
|
275
272
|
call_names (set): set of :class:`CallInspector.identifier` items within current AST node.
|
|
@@ -327,7 +324,7 @@ class CallVisitor(ImportVisitor):
|
|
|
327
324
|
|
|
328
325
|
|
|
329
326
|
class FunctionVisitor(ImportVisitor):
|
|
330
|
-
"""
|
|
327
|
+
"""Function definitions are where the function is defined, and the call is where the ast for that function exists.
|
|
331
328
|
|
|
332
329
|
This only looks for items that are called within the scope of a function, and associates those items
|
|
333
330
|
with the function.
|
|
@@ -355,7 +352,7 @@ class FunctionVisitor(ImportVisitor):
|
|
|
355
352
|
|
|
356
353
|
|
|
357
354
|
class FileVisitor(ImportVisitor):
|
|
358
|
-
"""
|
|
355
|
+
"""First visitor that should be called on the file level.
|
|
359
356
|
|
|
360
357
|
Attributes:
|
|
361
358
|
classes (list): list of :class:`ClassObject` instances defined in the current file.
|
|
@@ -377,7 +374,7 @@ class FileVisitor(ImportVisitor):
|
|
|
377
374
|
self.classes.append(new_class)
|
|
378
375
|
|
|
379
376
|
def remove_builtins(self):
|
|
380
|
-
"""
|
|
377
|
+
"""Removes builtins from each class in a `FileVisitor` instance.
|
|
381
378
|
"""
|
|
382
379
|
for class_object in self.classes:
|
|
383
380
|
class_object.remove_builtins()
|