hereisyou 0.1.2__py3-none-any.whl
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.
- hereisyou/You/__init__.py +9 -0
- hereisyou/You/classifier.py +138 -0
- hereisyou/You/introspection.py +307 -0
- hereisyou/You/parser.py +145 -0
- hereisyou/__init__.py +3 -0
- hereisyou-0.1.2.dist-info/METADATA +105 -0
- hereisyou-0.1.2.dist-info/RECORD +10 -0
- hereisyou-0.1.2.dist-info/WHEEL +5 -0
- hereisyou-0.1.2.dist-info/licenses/LICENSE +674 -0
- hereisyou-0.1.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from .introspection import You
|
|
2
|
+
"""
|
|
3
|
+
BInspected: A recursive Python object introspection engine.
|
|
4
|
+
This module provides the BInspected class, which classifies Python
|
|
5
|
+
objects, extracts metadata, groups children, and recursively builds
|
|
6
|
+
a structured introspection dictionary.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
__all__ = ['You']
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# This file is part of HereIsYou
|
|
2
|
+
# Copyright (C) 2026 Donald Raymond Reilly Jr.
|
|
3
|
+
#
|
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
7
|
+
# (at your option) any later version.
|
|
8
|
+
#
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU General Public License for more details.
|
|
13
|
+
#
|
|
14
|
+
# You should have received a copy of the GNU General Public License
|
|
15
|
+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
|
|
17
|
+
from types import (
|
|
18
|
+
ModuleType,
|
|
19
|
+
MethodType,
|
|
20
|
+
FunctionType,
|
|
21
|
+
BuiltinFunctionType,
|
|
22
|
+
BuiltinMethodType,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class Classifier:
|
|
27
|
+
# TODO: For now i'm going to keep this too expanded class. Just incase I want to expand on this later. Gonna seem like a waste for now.
|
|
28
|
+
# TODO: Need to figure out the whole instance thing and how to actaully handle the __dict__ of some objects. it's a problem that i just passed over for now.
|
|
29
|
+
def __init__(self):
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
def __call__(self, object_to_classify) -> str:
|
|
33
|
+
"""
|
|
34
|
+
Calls the classifier on an object and returns a string representation of the classification.
|
|
35
|
+
|
|
36
|
+
params:
|
|
37
|
+
object_to_classify: Object to be classified.
|
|
38
|
+
return:
|
|
39
|
+
string representation of the classification of the provided object.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
return self.classify_initial_object(object_to_classify)
|
|
43
|
+
|
|
44
|
+
def classify_initial_object(self, object_to_classify) -> str:
|
|
45
|
+
"""
|
|
46
|
+
Classifies objects and all of it's attributes and returns a dictionary representation of the classification.
|
|
47
|
+
|
|
48
|
+
params:
|
|
49
|
+
object_to_classify: Object to be classified.
|
|
50
|
+
return:
|
|
51
|
+
dictionary representation of the classification of the provided object and all of it's attributes.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
if isinstance(object_to_classify, ModuleType):
|
|
55
|
+
return "module"
|
|
56
|
+
if isinstance(object_to_classify, type):
|
|
57
|
+
return "class"
|
|
58
|
+
if isinstance(object_to_classify, MethodType):
|
|
59
|
+
return "method"
|
|
60
|
+
if isinstance(object_to_classify, FunctionType):
|
|
61
|
+
return "function"
|
|
62
|
+
if isinstance(object_to_classify, property):
|
|
63
|
+
return "property"
|
|
64
|
+
if object_to_classify.__class__.__module__ == "builtins":
|
|
65
|
+
return "built-in"
|
|
66
|
+
return "instance"
|
|
67
|
+
|
|
68
|
+
def classify_module(self, module_to_classify: ModuleType) -> str:
|
|
69
|
+
"""
|
|
70
|
+
Classifies modules and all of it's attributes and returns a dictionary representation of the classification.
|
|
71
|
+
|
|
72
|
+
params:
|
|
73
|
+
module_to_classify: Module to be classified.
|
|
74
|
+
return:
|
|
75
|
+
dictionary representation of the classification of the provided module and all of it's attributes.
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
return "module"
|
|
79
|
+
|
|
80
|
+
def classify_instance_of_user_defined_class(self, instance_to_classify: object) -> str:
|
|
81
|
+
"""
|
|
82
|
+
Classifies instances of user-defined classes and all of it's attributes and returns a dictionary representation of the classification.
|
|
83
|
+
|
|
84
|
+
params:
|
|
85
|
+
instance_to_classify: Instance of a user-defined class to be classified.
|
|
86
|
+
return:
|
|
87
|
+
dictionary representation of the classification of the provided instance of a user-defined class and all of it's attributes.
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
return "instance of user-defined class"
|
|
91
|
+
|
|
92
|
+
def classify_class(self, class_to_classify: type) -> str:
|
|
93
|
+
"""
|
|
94
|
+
Classifies classes and all of it's attributes and returns a dictionary representation of the classification.
|
|
95
|
+
|
|
96
|
+
params:
|
|
97
|
+
class_to_classify: Class to be classified.
|
|
98
|
+
return:
|
|
99
|
+
dictionary representation of the classification of the provided class and all of it's attributes.
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
return "class"
|
|
103
|
+
|
|
104
|
+
def classify_method(self, method_to_classify: MethodType) -> str:
|
|
105
|
+
"""
|
|
106
|
+
Classifies methods and all of it's attributes and returns a dictionary representation of the classification.
|
|
107
|
+
|
|
108
|
+
params:
|
|
109
|
+
method_to_classify: Method to be classified.
|
|
110
|
+
return:
|
|
111
|
+
dictionary representation of the classification of the provided method and all of it's attributes.
|
|
112
|
+
"""
|
|
113
|
+
|
|
114
|
+
return "method"
|
|
115
|
+
|
|
116
|
+
def classify_function(self, function_to_classify: FunctionType) -> str:
|
|
117
|
+
"""
|
|
118
|
+
Classifies functions and all of it's attributes and returns a dictionary representation of the classification.
|
|
119
|
+
|
|
120
|
+
params:
|
|
121
|
+
function_to_classify: Function to be classified.
|
|
122
|
+
return:
|
|
123
|
+
dictionary representation of the classification of the provided function and all of it's attributes.
|
|
124
|
+
"""
|
|
125
|
+
|
|
126
|
+
return "function"
|
|
127
|
+
|
|
128
|
+
def classify_property(self, property_to_classify: property) -> str:
|
|
129
|
+
"""
|
|
130
|
+
Classifies properties and all of it's attributes and returns a dictionary representation of the classification.
|
|
131
|
+
|
|
132
|
+
params:
|
|
133
|
+
property_to_classify: Property to be classified.
|
|
134
|
+
return:
|
|
135
|
+
dictionary representation of the classification of the provided property and all of it's attributes.
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
return "property"
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# This file is part of HereIsYou
|
|
2
|
+
# Copyright (C) 2026 Donald Raymond Reilly Jr.
|
|
3
|
+
#
|
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
7
|
+
# (at your option) any later version.
|
|
8
|
+
#
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU General Public License for more details.
|
|
13
|
+
#
|
|
14
|
+
# You should have received a copy of the GNU General Public License
|
|
15
|
+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
|
|
17
|
+
from .classifier import Classifier
|
|
18
|
+
from .parser import Parser
|
|
19
|
+
# BUG Empty fields shouldn't show in json.
|
|
20
|
+
|
|
21
|
+
# WORK CLI needs to be done. Should be able to run and inspect files seperately.
|
|
22
|
+
# DEBT Finish parsing args.
|
|
23
|
+
|
|
24
|
+
# ROADMAP Raw file inspection for self testing and testing of classes.
|
|
25
|
+
class You:
|
|
26
|
+
"""
|
|
27
|
+
You: A look into your modules, class, method, or function for debugging
|
|
28
|
+
purposes.
|
|
29
|
+
|
|
30
|
+
This modusle provides the BInspected class, which classifies Python
|
|
31
|
+
objects, extracts metadata, groups children, and recursively builds
|
|
32
|
+
a structured introspection dictionary.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
def __init__(self):
|
|
36
|
+
"""
|
|
37
|
+
Initializes the BInspected class.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
self.dispatcher = {
|
|
41
|
+
"module": self._inspect_module,
|
|
42
|
+
"class": self._inspect_class,
|
|
43
|
+
"method": self._inspect_method,
|
|
44
|
+
"instance": self._inspect_class_instance,
|
|
45
|
+
"property": self._inspect_property,
|
|
46
|
+
"built-in": self._inspect_built_in,
|
|
47
|
+
"function": self._inspect_function,
|
|
48
|
+
}
|
|
49
|
+
self.classifier = Classifier()
|
|
50
|
+
self.parser = Parser()
|
|
51
|
+
|
|
52
|
+
def __call__(self, object_to_inspect) -> dict:
|
|
53
|
+
"""
|
|
54
|
+
Classify an object and return it's introspection dictionary.
|
|
55
|
+
|
|
56
|
+
Params:
|
|
57
|
+
object_to_inspect: Object to be inspected.
|
|
58
|
+
Returns:
|
|
59
|
+
An introspection dictionary.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
return self._build_inspection(object_to_inspect)
|
|
63
|
+
|
|
64
|
+
def _build_inspection(self, object_to_inspect) -> dict:
|
|
65
|
+
"""
|
|
66
|
+
Complete object inspection and formation of the objects underlying
|
|
67
|
+
structure
|
|
68
|
+
|
|
69
|
+
Params:
|
|
70
|
+
object_to_inspect: Object to inspect
|
|
71
|
+
Returns:
|
|
72
|
+
An introspection dictionary
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
object_type = self.classifier(object_to_inspect)
|
|
76
|
+
parsed_object = self.dispatcher[object_type](object_to_inspect,
|
|
77
|
+
object_type)
|
|
78
|
+
|
|
79
|
+
return parsed_object
|
|
80
|
+
|
|
81
|
+
def _group_children(self, dict_to_group) -> dict:
|
|
82
|
+
"""
|
|
83
|
+
Sort an objects __dict__
|
|
84
|
+
|
|
85
|
+
Params:
|
|
86
|
+
dict_to_group: __dict__ of the object that needs sorting
|
|
87
|
+
Returns:
|
|
88
|
+
A dictionary of the sorted objects. Example structure:
|
|
89
|
+
grouped_dict ={
|
|
90
|
+
"module": {},
|
|
91
|
+
"class": {},
|
|
92
|
+
"method": {},
|
|
93
|
+
"function": {},
|
|
94
|
+
"property": {},
|
|
95
|
+
"instance": {}
|
|
96
|
+
}
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
# System specific children who don't need to be inspected... yet..
|
|
100
|
+
skip_children = [
|
|
101
|
+
"__loader__",
|
|
102
|
+
"__spec__ ",
|
|
103
|
+
"__package__",
|
|
104
|
+
"__builtins__",
|
|
105
|
+
"__cached__",
|
|
106
|
+
"__file__",
|
|
107
|
+
]
|
|
108
|
+
# The layout of the returned dictionary needs to be removed eventually
|
|
109
|
+
# and be formed at creation
|
|
110
|
+
grouped_dict = {
|
|
111
|
+
"module": {},
|
|
112
|
+
"class": {},
|
|
113
|
+
"method": {},
|
|
114
|
+
"function": {},
|
|
115
|
+
"property": {},
|
|
116
|
+
"instance": {},
|
|
117
|
+
}
|
|
118
|
+
# Loop for sorting the __dict__
|
|
119
|
+
for key, value in dict_to_group.items():
|
|
120
|
+
if key in skip_children: # Skips the system entries.
|
|
121
|
+
continue
|
|
122
|
+
# Classifies each child object
|
|
123
|
+
object_type = self.classifier(value)
|
|
124
|
+
if object_type in grouped_dict:
|
|
125
|
+
# Sorts each object in correct dictionary entry.
|
|
126
|
+
grouped_dict[object_type][key] = value
|
|
127
|
+
return grouped_dict
|
|
128
|
+
|
|
129
|
+
def _get_children(self, object_to_get_children) -> dict:
|
|
130
|
+
"""
|
|
131
|
+
Gets the children objects and recursively sorts and produces
|
|
132
|
+
dictionaries.
|
|
133
|
+
|
|
134
|
+
Params:
|
|
135
|
+
object_to_get_children: The object whose children need sorting and
|
|
136
|
+
parsing.
|
|
137
|
+
Returns:
|
|
138
|
+
The parsed dictionary of each child object.
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
# TODO: This needs a little rework. It's ok for now, but it's unclear
|
|
142
|
+
# exactly what it's doing and that could be fixed.
|
|
143
|
+
# TODO: Maybe just a renaming so it's function is clear. This is the
|
|
144
|
+
# problem with recursion, it confuses shit.
|
|
145
|
+
# Get the sorted dictionary of the children objects
|
|
146
|
+
children_dict = self._group_children(object_to_get_children.__dict__)
|
|
147
|
+
# Loop through the sorted dictionary and recursively sort and inspect
|
|
148
|
+
# the children.
|
|
149
|
+
for children_objects in children_dict.values():
|
|
150
|
+
for object_name, object_ref in children_objects.items():
|
|
151
|
+
# call back to inspected to start the loop over again.
|
|
152
|
+
children_objects[object_name] = self(object_ref)
|
|
153
|
+
return children_dict
|
|
154
|
+
|
|
155
|
+
def _inspect_module(self, module_to_inspect, object_type) -> dict:
|
|
156
|
+
"""
|
|
157
|
+
Inspect a modules underlying data structure and provide an
|
|
158
|
+
introspection dictionary.
|
|
159
|
+
|
|
160
|
+
Params:
|
|
161
|
+
module_to_inspect: Module to inspect
|
|
162
|
+
Returns:
|
|
163
|
+
An introspection dictionary
|
|
164
|
+
"""
|
|
165
|
+
|
|
166
|
+
# Gets meta data and build dictionary.
|
|
167
|
+
module_dict = self.parser(module_to_inspect, object_type)
|
|
168
|
+
# Starts recursion.
|
|
169
|
+
module_dict["children"] = self._get_children(module_to_inspect)
|
|
170
|
+
return module_dict
|
|
171
|
+
|
|
172
|
+
def _inspect_class(self, class_to_inspect, object_type) -> dict:
|
|
173
|
+
"""
|
|
174
|
+
Inspect a class' underlying data structure and provide an introspection
|
|
175
|
+
dictionary.
|
|
176
|
+
|
|
177
|
+
Params:
|
|
178
|
+
class_to_inspect: Class to inspect
|
|
179
|
+
Returns:
|
|
180
|
+
An introspection dictionary
|
|
181
|
+
"""
|
|
182
|
+
|
|
183
|
+
# Creates the dictionary representation of the provided class.
|
|
184
|
+
class_dict = self.parser(class_to_inspect, object_type)
|
|
185
|
+
# Pulls out the children of the provided class and sorts them
|
|
186
|
+
# accordingly.
|
|
187
|
+
class_dict["children"] = self._get_children(class_to_inspect)
|
|
188
|
+
return class_dict
|
|
189
|
+
|
|
190
|
+
def _inspect_class_instance(self, instance_to_inspect, object_type) -> dict:
|
|
191
|
+
"""
|
|
192
|
+
Inspect an instances underlying data structure and provide an
|
|
193
|
+
introspection dictionary.
|
|
194
|
+
|
|
195
|
+
Params:
|
|
196
|
+
instance_to_inspect: instance to inspect
|
|
197
|
+
Returns:
|
|
198
|
+
An introspection dictionary
|
|
199
|
+
"""
|
|
200
|
+
|
|
201
|
+
# Creates the dictionary representation of the provided instance of a
|
|
202
|
+
# class.
|
|
203
|
+
instance_dict = self.parser(instance_to_inspect, object_type)
|
|
204
|
+
# Sends the underlying class by through self for classification and
|
|
205
|
+
# parsing.
|
|
206
|
+
class_dict = self(instance_to_inspect.__class__)
|
|
207
|
+
# Merges the two dictionaries.
|
|
208
|
+
instance_dict = instance_dict | class_dict
|
|
209
|
+
return instance_dict
|
|
210
|
+
|
|
211
|
+
def _inspect_method(self, method_to_inspect, object_type) -> dict:
|
|
212
|
+
"""
|
|
213
|
+
Inspect a methods underlying data structure and provide an
|
|
214
|
+
introspection dictionary.
|
|
215
|
+
|
|
216
|
+
Params:
|
|
217
|
+
method_to_inspect: Method to inspect
|
|
218
|
+
Returns:
|
|
219
|
+
An introspection dictionary
|
|
220
|
+
"""
|
|
221
|
+
|
|
222
|
+
# Creates the dicitonary representation of the provided method.
|
|
223
|
+
method_dict = self.parser(method_to_inspect, object_type)
|
|
224
|
+
# Sends the underlying function to the correct inspecetion method.
|
|
225
|
+
function_dict = self(method_to_inspect.__func__)
|
|
226
|
+
# Merges the two introspection dictionaries.
|
|
227
|
+
method_dict |= function_dict
|
|
228
|
+
return method_dict
|
|
229
|
+
|
|
230
|
+
def _inspect_function(self, function_to_inspect, object_type) -> dict:
|
|
231
|
+
"""
|
|
232
|
+
Inspect a functions underlying data structure and provide an
|
|
233
|
+
introspection dictionary.
|
|
234
|
+
|
|
235
|
+
Params:
|
|
236
|
+
function_to_inspect: Function to inspect
|
|
237
|
+
Returns:
|
|
238
|
+
An introspection dictionary
|
|
239
|
+
"""
|
|
240
|
+
|
|
241
|
+
# Create the dictionary representation of the provided function.
|
|
242
|
+
function_dict = self.parser(function_to_inspect, object_type)
|
|
243
|
+
# Sends the functions variables for parsing.
|
|
244
|
+
function_dict["variables"] = self.parser._parse_variables(
|
|
245
|
+
function_to_inspect)
|
|
246
|
+
return function_dict
|
|
247
|
+
|
|
248
|
+
def _inspect_property(self, property_to_inspect, object_type) -> dict:
|
|
249
|
+
"""
|
|
250
|
+
Inspect a property's underlying data structure and provide an
|
|
251
|
+
introspection dictionary.
|
|
252
|
+
|
|
253
|
+
Params:
|
|
254
|
+
property_to_inspect: Property to inspect
|
|
255
|
+
Returns:
|
|
256
|
+
An introspection dictionary
|
|
257
|
+
"""
|
|
258
|
+
|
|
259
|
+
# Creates the dictionary representation of the provided property.
|
|
260
|
+
property_dict = self.parser(property_to_inspect, object_type)
|
|
261
|
+
# Sends the underlying functions to the correct inspection method.
|
|
262
|
+
property_dict["getter"] = (self(property_to_inspect.fget) if
|
|
263
|
+
property_to_inspect.fget else None)
|
|
264
|
+
# Sends the underlying functions to the correct inspection method.
|
|
265
|
+
property_dict["setter"] = (self(property_to_inspect.fset) if property_to_inspect.fset else None)
|
|
266
|
+
# Sends the underlying functions to the correct inspection method.
|
|
267
|
+
property_dict["deleter"] = (self(property_to_inspect.fdel) if property_to_inspect.fdel else None)
|
|
268
|
+
return property_dict
|
|
269
|
+
|
|
270
|
+
def _inspect_built_in(self, instance_to_inspect) -> dict:
|
|
271
|
+
"""
|
|
272
|
+
Inspect the built_in underlying data structure and provide an introspection dictionary.
|
|
273
|
+
|
|
274
|
+
Params:
|
|
275
|
+
built_in_to_inspect: built_in to inspect
|
|
276
|
+
Returns:
|
|
277
|
+
An introspection dictionary
|
|
278
|
+
"""
|
|
279
|
+
|
|
280
|
+
# TODO: Possible feature, and flag. Not sure if built-ins should even be tested. Would make some very heavy duty outputs.
|
|
281
|
+
return {"Not Implemented": "_inspect_built_in"}
|
|
282
|
+
|
|
283
|
+
def _inspect_arguments(self, arguments_to_inspect) -> dict:
|
|
284
|
+
"""
|
|
285
|
+
Inspect an arguments underlying data structure and provide an introspection dictionary.
|
|
286
|
+
|
|
287
|
+
Params:
|
|
288
|
+
argument_to_inspect: Argument to inspect
|
|
289
|
+
Returns:
|
|
290
|
+
An introspection dictionary
|
|
291
|
+
"""
|
|
292
|
+
|
|
293
|
+
# TODO: Decide if this needs to exist or if the code should exist in parser.
|
|
294
|
+
return {"type argument": "argument type"}
|
|
295
|
+
|
|
296
|
+
def _inspect_variables(self, variables_to_inspect, object_type) -> dict:
|
|
297
|
+
"""
|
|
298
|
+
Inspect a variables underlying data structure and provide an introspection dictionary.
|
|
299
|
+
|
|
300
|
+
Params:
|
|
301
|
+
variable_to_inspect: Variable to inspect
|
|
302
|
+
Returns:
|
|
303
|
+
An introspection dictionary
|
|
304
|
+
"""
|
|
305
|
+
|
|
306
|
+
# TODO: Decide if this needs to exist or if the code should exist in parser.
|
|
307
|
+
return {"type variable": "variable type"}
|
hereisyou/You/parser.py
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# This file is part of HereIsYou
|
|
2
|
+
# Copyright (C) 2026 Donald Raymond Reilly Jr.
|
|
3
|
+
#
|
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
7
|
+
# (at your option) any later version.
|
|
8
|
+
#
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU General Public License for more details.
|
|
13
|
+
#
|
|
14
|
+
# You should have received a copy of the GNU General Public License
|
|
15
|
+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
|
|
17
|
+
class Parser:
|
|
18
|
+
"""
|
|
19
|
+
Parser: Extracts meta data from python objects.
|
|
20
|
+
|
|
21
|
+
This class parses python objects to provide clean and readable meta data.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self) -> None:
|
|
25
|
+
"""
|
|
26
|
+
Initializes the Parser class.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
# The method dispatcher, currently not in use, would like to add for easy extension.
|
|
30
|
+
self.dispatcher = {
|
|
31
|
+
# "module": self.parse_module,
|
|
32
|
+
# "class": self.parse_class,
|
|
33
|
+
# "method": self.parse_method,
|
|
34
|
+
"instance": self._parse_class_instance
|
|
35
|
+
# "function": self.parse_function,
|
|
36
|
+
# "property": self.parse_property
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
def __call__(self, object_to_parse, object_type=None) -> dict:
|
|
40
|
+
"""
|
|
41
|
+
Parse an object of a given type and return a dictionary representation.
|
|
42
|
+
|
|
43
|
+
Params:
|
|
44
|
+
object_to_parse: The object to be parsed.
|
|
45
|
+
object_type: The type of the object to be parsed.
|
|
46
|
+
Returns:
|
|
47
|
+
A dictionary representation of the parsed object.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
return self._parse_object(
|
|
51
|
+
object_to_parse=object_to_parse, object_type=object_type
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
def _parse_object(self, object_to_parse, object_type=None) -> dict:
|
|
55
|
+
"""Parse an object of a given type and return a dictionary representation
|
|
56
|
+
|
|
57
|
+
Params:
|
|
58
|
+
object_to_parse: The object to be parsed.
|
|
59
|
+
object_type: The type of the object to be parsed.
|
|
60
|
+
Returns:
|
|
61
|
+
A dicitonary representation of the parsed object.
|
|
62
|
+
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
meta_data_dict = self._extract_meta_data(object_to_parse)
|
|
66
|
+
if object_type in self.dispatcher:
|
|
67
|
+
meta_data_dict |= self.dispatcher[object_type](object_to_parse)
|
|
68
|
+
return meta_data_dict
|
|
69
|
+
|
|
70
|
+
def _extract_meta_data(self, object_to_parse) -> dict:
|
|
71
|
+
"""
|
|
72
|
+
Parse an object, extract meta-data and format it into a dictionary.
|
|
73
|
+
|
|
74
|
+
Params:
|
|
75
|
+
object_to_parse: The object to be parsed.
|
|
76
|
+
object_type: The Name of the object to be parsed.
|
|
77
|
+
Returns:
|
|
78
|
+
A dictionary representation of the meta data.
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
# Calls to meta data to be extracted.
|
|
82
|
+
meta_data_map = {
|
|
83
|
+
"name": lambda: object_to_parse.__name__, # Object name
|
|
84
|
+
"qualified name": lambda: object_to_parse.__qualname__, # Qualified object name
|
|
85
|
+
"module name": lambda: object_to_parse.__module__, # Objects module name
|
|
86
|
+
"bases": lambda: object_to_parse.__bases__, # Base class names
|
|
87
|
+
"doc string": lambda: object_to_parse.__doc__, # Doc String
|
|
88
|
+
"type hints": lambda: object_to_parse.__annotations__, # type hinting of variables
|
|
89
|
+
}
|
|
90
|
+
meta_data_dict = {} # Initializng the meta data dictionary.
|
|
91
|
+
for (meta_data) in (meta_data_map): # For loop that cycles the meta data map and updates the meta_data dict if an expection isn't encountred.
|
|
92
|
+
try:
|
|
93
|
+
meta_data_dict[meta_data] = meta_data_map[meta_data]()
|
|
94
|
+
except:
|
|
95
|
+
continue
|
|
96
|
+
return meta_data_dict
|
|
97
|
+
|
|
98
|
+
def _parse_class_instance(self, instance_to_parse) -> dict:
|
|
99
|
+
"""
|
|
100
|
+
Parse an instance of a class and return a dictionary representation of it.
|
|
101
|
+
|
|
102
|
+
Params:
|
|
103
|
+
instance_to_parse: The instance of a class to be parsed.
|
|
104
|
+
Returns:
|
|
105
|
+
A dictionary representation of the parsed instance of a class.
|
|
106
|
+
"""
|
|
107
|
+
|
|
108
|
+
# Pulls the instance variables.
|
|
109
|
+
instance_dict = {"Instance Variables": instance_to_parse.__dict__}
|
|
110
|
+
return instance_dict
|
|
111
|
+
|
|
112
|
+
def _parse_variables(self, function_to_parse) -> dict[str, ]:
|
|
113
|
+
"""
|
|
114
|
+
Parse the variables of a function.
|
|
115
|
+
|
|
116
|
+
Params:
|
|
117
|
+
function_to_parse: The functions whose variables need parsing.
|
|
118
|
+
Returns:
|
|
119
|
+
A dictionary representation of the parsed variables.
|
|
120
|
+
"""
|
|
121
|
+
|
|
122
|
+
allvars = function_to_parse.__code__.co_varnames
|
|
123
|
+
argsn = function_to_parse.__code__.co_argcount
|
|
124
|
+
anns = function_to_parse.__annotations__ or ()
|
|
125
|
+
defs = function_to_parse.__defaults__ or ()
|
|
126
|
+
ldegs = len(defs)
|
|
127
|
+
localvar = allvars[argsn:]
|
|
128
|
+
args = allvars[:argsn]
|
|
129
|
+
|
|
130
|
+
templst = [None] * (argsn-ldegs)
|
|
131
|
+
templst += defs
|
|
132
|
+
|
|
133
|
+
variables_defaults = list(zip(args,templst))
|
|
134
|
+
dict_laid_out =[]
|
|
135
|
+
|
|
136
|
+
for item in variables_defaults:
|
|
137
|
+
tempd = {
|
|
138
|
+
"name": item[0],
|
|
139
|
+
"default": item[1],
|
|
140
|
+
"type":anns[item[0]] if item[0] in anns else None
|
|
141
|
+
}
|
|
142
|
+
dict_laid_out.append(tempd)
|
|
143
|
+
|
|
144
|
+
return dict_laid_out
|
|
145
|
+
|
hereisyou/__init__.py
ADDED