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.
@@ -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"}
@@ -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
@@ -0,0 +1,3 @@
1
+ from hereisyou.You import You
2
+
3
+ __all__ = ['You']