inspy-logger 3.0.dev2__tar.gz → 3.0.dev4__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.
- {inspy_logger-3.0.dev2 → inspy_logger-3.0.dev4}/PKG-INFO +4 -4
- {inspy_logger-3.0.dev2 → inspy_logger-3.0.dev4}/inspy_logger/Scripts/main.py +2 -5
- {inspy_logger-3.0.dev2 → inspy_logger-3.0.dev4}/inspy_logger/__about__.py +2 -1
- {inspy_logger-3.0.dev2 → inspy_logger-3.0.dev4}/inspy_logger/__init__.py +122 -109
- inspy_logger-3.0.dev4/inspy_logger/helpers/base_classes.py +136 -0
- {inspy_logger-3.0.dev2 → inspy_logger-3.0.dev4}/inspy_logger/version.py +1 -1
- {inspy_logger-3.0.dev2 → inspy_logger-3.0.dev4}/pyproject.toml +12 -5
- {inspy_logger-3.0.dev2 → inspy_logger-3.0.dev4}/LICENSE.md +0 -0
- {inspy_logger-3.0.dev2 → inspy_logger-3.0.dev4}/README.md +0 -0
- {inspy_logger-3.0.dev2 → inspy_logger-3.0.dev4}/inspy_logger/errors/__init__.py +0 -0
- {inspy_logger-3.0.dev2 → inspy_logger-3.0.dev4}/inspy_logger/helpers/__init__.py +0 -0
- {inspy_logger-3.0.dev2 → inspy_logger-3.0.dev4}/inspy_logger/helpers/cache.py +0 -0
- {inspy_logger-3.0.dev2 → inspy_logger-3.0.dev4}/inspy_logger/helpers/network.py +0 -0
- {inspy_logger-3.0.dev2 → inspy_logger-3.0.dev4}/inspy_logger/manifest.py +0 -0
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: inspy-logger
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.dev4
|
|
4
4
|
Summary: Colorable, scalable logger for CLI
|
|
5
5
|
Home-page: https://github.com/Inspyre-Softworks/inSPy-Logger
|
|
6
6
|
License: MIT
|
|
7
7
|
Keywords: cli,color,logging,log,terminal,console,colorama,colorlog,rich
|
|
8
8
|
Author: Taylor-Jayde Blackstone
|
|
9
9
|
Author-email: tayjaybabee@gmail.com
|
|
10
|
-
Requires-Python: >=3.
|
|
10
|
+
Requires-Python: >=3.9,<4.0
|
|
11
11
|
Classifier: Development Status :: 5 - Production/Stable
|
|
12
12
|
Classifier: Intended Audience :: Developers
|
|
13
13
|
Classifier: License :: OSI Approved :: MIT License
|
|
14
14
|
Classifier: Natural Language :: English
|
|
15
15
|
Classifier: Operating System :: OS Independent
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
19
17
|
Classifier: Programming Language :: Python :: 3.9
|
|
20
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
21
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
22
20
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
23
23
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
24
|
Classifier: Topic :: System :: Logging
|
|
25
25
|
Classifier: Topic :: Utilities
|
|
@@ -68,7 +68,7 @@ def get_version_info():
|
|
|
68
68
|
table.add_row('Full Version Name', get_full_version_name())
|
|
69
69
|
|
|
70
70
|
if pypi_info.update_available:
|
|
71
|
-
table.add_row('Update Available',
|
|
71
|
+
table.add_row('Update Available', '[bold green]Yes[/bold green]')
|
|
72
72
|
table.add_row('Latest Version', f'{pypi_info.new_version_available_num}')
|
|
73
73
|
|
|
74
74
|
table.add_row('Python Executable Path', sys.executable)
|
|
@@ -80,10 +80,7 @@ def get_version_info():
|
|
|
80
80
|
|
|
81
81
|
def main():
|
|
82
82
|
|
|
83
|
-
if parsed_args.subcommand == 'update'
|
|
84
|
-
return update()
|
|
85
|
-
|
|
86
|
-
return get_version_info()
|
|
83
|
+
return update() if parsed_args.subcommand == 'update' else get_version_info()
|
|
87
84
|
|
|
88
85
|
|
|
89
86
|
|
|
@@ -11,9 +11,10 @@ Since:
|
|
|
11
11
|
v2.1.1
|
|
12
12
|
|
|
13
13
|
"""
|
|
14
|
+
from inspy_logger.version import parse_version
|
|
14
15
|
|
|
15
16
|
__prog__ = 'inSPy-Logger'
|
|
16
|
-
__version__ =
|
|
17
|
+
__version__ = parse_version()
|
|
17
18
|
__authors__ = [
|
|
18
19
|
('Inspyre-Softworks', 'https://inspyre.tech'),
|
|
19
20
|
('Taylor-Jayde Blackstone', '<t.blackstone@inspyre.tech')
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
import inspect
|
|
3
|
+
import os
|
|
3
4
|
import logging
|
|
4
5
|
from rich.logging import RichHandler
|
|
5
6
|
from inspy_logger.__about__ import __prog__ as PROG_NAME
|
|
@@ -38,11 +39,17 @@ class Logger:
|
|
|
38
39
|
A Singleton class responsible for managing the logging mechanisms of the application.
|
|
39
40
|
"""
|
|
40
41
|
|
|
41
|
-
instances = {}
|
|
42
|
+
instances = {} # A dictionary to hold instances of the Logger class.
|
|
42
43
|
|
|
43
44
|
def __new__(cls, name, *args, **kwargs):
|
|
44
45
|
"""
|
|
45
46
|
Creates or returns an existing instance of the Logger class for the provided name.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
name (str): The name of the logger instance.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
Logger: An instance of the Logger class.
|
|
46
53
|
"""
|
|
47
54
|
|
|
48
55
|
if name not in cls.instances:
|
|
@@ -52,15 +59,22 @@ class Logger:
|
|
|
52
59
|
return cls.instances[name]
|
|
53
60
|
|
|
54
61
|
def __init__(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
self,
|
|
63
|
+
name,
|
|
64
|
+
console_level=DEFAULT_LOGGING_LEVEL,
|
|
65
|
+
file_level=logging.DEBUG,
|
|
66
|
+
filename="app.log",
|
|
67
|
+
parent=None,
|
|
61
68
|
):
|
|
62
69
|
"""
|
|
63
70
|
Initializes a logger instance.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
name (str): The name of the logger instance.
|
|
74
|
+
console_level (str, optional): The logging level for the console. Defaults to DEFAULT_LOGGING_LEVEL.
|
|
75
|
+
file_level (str, optional): The logging level for the file. Defaults to logging.DEBUG.
|
|
76
|
+
filename (str, optional): The name of the log file. Defaults to "app.log".
|
|
77
|
+
parent (Logger, optional): The parent logger instance. Defaults to None.
|
|
64
78
|
"""
|
|
65
79
|
|
|
66
80
|
if not hasattr(self, "logger"):
|
|
@@ -91,10 +105,22 @@ class Logger:
|
|
|
91
105
|
|
|
92
106
|
@property
|
|
93
107
|
def device(self):
|
|
108
|
+
"""
|
|
109
|
+
Returns the logger instance.
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
Logger: The logger instance.
|
|
113
|
+
"""
|
|
94
114
|
return self.logger
|
|
95
115
|
|
|
96
116
|
@property
|
|
97
117
|
def name(self):
|
|
118
|
+
"""
|
|
119
|
+
Returns the name of the logger instance.
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
str: The name of the logger instance.
|
|
123
|
+
"""
|
|
98
124
|
return self.logger.name
|
|
99
125
|
|
|
100
126
|
def set_up_console(self):
|
|
@@ -144,8 +170,7 @@ class Logger:
|
|
|
144
170
|
child.set_level(file_level=file_level)
|
|
145
171
|
|
|
146
172
|
def get_child(self, name=None, console_level=None, file_level=None):
|
|
147
|
-
self.
|
|
148
|
-
console_level = console_level or DEFAULT_LOGGING_LEVEL
|
|
173
|
+
console_level = console_level or self.__console_level
|
|
149
174
|
caller_frame = inspect.stack()[1]
|
|
150
175
|
|
|
151
176
|
if name is None:
|
|
@@ -159,7 +184,7 @@ class Logger:
|
|
|
159
184
|
if child.logger.name == child_logger_name:
|
|
160
185
|
return child
|
|
161
186
|
|
|
162
|
-
child_logger = Logger(child_logger_name, console_level, file_level, parent=self)
|
|
187
|
+
child_logger = Logger(name=child_logger_name, console_level=console_level, file_level=file_level, parent=self)
|
|
163
188
|
self.children.append(child_logger)
|
|
164
189
|
return child_logger
|
|
165
190
|
|
|
@@ -180,6 +205,18 @@ class Logger:
|
|
|
180
205
|
return self.parent
|
|
181
206
|
|
|
182
207
|
def find_child_by_name(self, name: str, case_sensitive=True, exact_match=False):
|
|
208
|
+
"""
|
|
209
|
+
Searches for a child logger by its name.
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
name (str): The name of the child logger to search for.
|
|
213
|
+
case_sensitive (bool, optional): Whether the search should be case sensitive. Defaults to True.
|
|
214
|
+
exact_match (bool, optional): Whether the search should only return exact matches. Defaults to False.
|
|
215
|
+
|
|
216
|
+
Returns:
|
|
217
|
+
list or Logger: If exact_match is True, returns the Logger instance if found, else returns an empty list.
|
|
218
|
+
If exact_match is False, returns a list of Logger instances whose names contain the search term.
|
|
219
|
+
"""
|
|
183
220
|
self.logger.debug(f'Searching for child with name: {name}')
|
|
184
221
|
results = []
|
|
185
222
|
|
|
@@ -195,6 +232,43 @@ class Logger:
|
|
|
195
232
|
|
|
196
233
|
return results
|
|
197
234
|
|
|
235
|
+
def debug(self, message):
|
|
236
|
+
"""
|
|
237
|
+
Logs a debug message.
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
message (str): The message to log.
|
|
241
|
+
"""
|
|
242
|
+
self._log(logging.DEBUG, message, args=(), stacklevel=2)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def info(self, message):
|
|
246
|
+
"""
|
|
247
|
+
Logs an info message.
|
|
248
|
+
|
|
249
|
+
Args:
|
|
250
|
+
message (str): The message to log.
|
|
251
|
+
"""
|
|
252
|
+
self._log(logging.INFO, message, args=(), stacklevel=2)
|
|
253
|
+
|
|
254
|
+
def warning(self, message):
|
|
255
|
+
"""
|
|
256
|
+
Logs a warning message.
|
|
257
|
+
|
|
258
|
+
Args:
|
|
259
|
+
message (str): The message to log.
|
|
260
|
+
"""
|
|
261
|
+
self._log(logging.WARNING, message, args=(), stacklevel=2)
|
|
262
|
+
|
|
263
|
+
def error(self, message):
|
|
264
|
+
"""
|
|
265
|
+
Logs an error message.
|
|
266
|
+
|
|
267
|
+
Args:
|
|
268
|
+
message (str): The message to log.
|
|
269
|
+
"""
|
|
270
|
+
self._log(logging.ERROR, message, args=(), stacklevel=2)
|
|
271
|
+
|
|
198
272
|
def __repr__(self):
|
|
199
273
|
name = self.name
|
|
200
274
|
hex_id = hex(id(self))
|
|
@@ -208,119 +282,58 @@ class Logger:
|
|
|
208
282
|
if parent_part.endswith('|'):
|
|
209
283
|
parent_part = str(parent_part[:-2])
|
|
210
284
|
|
|
211
|
-
return f'<Logger: {name} at {hex_id}{parent_part}>'
|
|
285
|
+
return f'<Logger: {name} w/ level {self.logger.level} at {hex_id}{parent_part}>'
|
|
212
286
|
|
|
287
|
+
@classmethod
|
|
288
|
+
def create_logger_for_caller(cls):
|
|
289
|
+
"""
|
|
290
|
+
Creates a logger for the module that calls this method.
|
|
213
291
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
MOD_LOGGER.debug(f"Started logger for {__name__}.")
|
|
221
|
-
|
|
222
|
-
add_child = LOG_DEVICE.get_child
|
|
223
|
-
|
|
224
|
-
InspyLogger = Logger
|
|
225
|
-
|
|
226
|
-
def _get_parent_logging_device():
|
|
227
|
-
"""
|
|
228
|
-
Determines the parent logging device by inspecting the caller's log_device or parent_log_device attribute.
|
|
229
|
-
|
|
230
|
-
Returns:
|
|
231
|
-
Logger: The parent logging device.
|
|
232
|
-
"""
|
|
233
|
-
MOD_LOGGER.debug("Determining parent logging device")
|
|
234
|
-
caller_frame = inspect.currentframe().f_back
|
|
235
|
-
caller_locals = caller_frame.f_locals
|
|
236
|
-
|
|
237
|
-
if "logger" in caller_locals:
|
|
238
|
-
return caller_locals["logger"]
|
|
239
|
-
elif "parent_log_device" in caller_locals:
|
|
240
|
-
return caller_locals["parent_log_device"]
|
|
241
|
-
else:
|
|
242
|
-
raise ValueError("Unable to determine the parent logging device.")
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
class Loggable:
|
|
246
|
-
"""
|
|
247
|
-
A metaclass to enhance classes with logging capabilities. Classes that inherit from
|
|
248
|
-
'Loggable' can instantly access a logger without manually setting it up. This logger
|
|
249
|
-
is derived from a parent logger, ensuring consistent logging behavior and hierarchy.
|
|
250
|
-
|
|
251
|
-
Attributes:
|
|
252
|
-
- log_device: The logger device associated with the instance of the class.
|
|
253
|
-
"""
|
|
254
|
-
|
|
255
|
-
def __init__(self, parent_log_device=None, **kwargs):
|
|
256
|
-
self.parent_log_device = parent_log_device
|
|
257
|
-
self.__log_name = self.__class__.__name__
|
|
258
|
-
if self.parent_log_device is not None:
|
|
259
|
-
self.__log_device = self.parent_log_device.get_child(
|
|
260
|
-
self.__class__.__name__
|
|
261
|
-
)
|
|
292
|
+
Returns:
|
|
293
|
+
Logger: An instance of the Logger class for the calling module.
|
|
294
|
+
"""
|
|
295
|
+
frame = inspect.currentframe().f_back
|
|
296
|
+
if module_path := cls._determine_module_path(frame):
|
|
297
|
+
return cls(module_path)
|
|
262
298
|
else:
|
|
263
|
-
|
|
264
|
-
self.__class__.__name__
|
|
265
|
-
)
|
|
266
|
-
|
|
267
|
-
@property
|
|
268
|
-
def log_device(self):
|
|
269
|
-
return self.__log_device
|
|
270
|
-
|
|
271
|
-
@log_device.setter
|
|
272
|
-
def log_device(self, new):
|
|
273
|
-
if not isinstance(new, Logger):
|
|
274
|
-
raise TypeError('log_device must be of type "Logger"')
|
|
275
|
-
|
|
276
|
-
self.__log_device = new
|
|
299
|
+
raise ValueError("Unable to determine module path for logger creation.")
|
|
277
300
|
|
|
278
|
-
|
|
301
|
+
@staticmethod
|
|
302
|
+
def _determine_module_path(frame):
|
|
279
303
|
"""
|
|
280
|
-
|
|
304
|
+
Determines the in-project path of the module from the call frame.
|
|
281
305
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
override (bool, optional): A flag to override the membership check. Defaults to False.
|
|
306
|
+
Args:
|
|
307
|
+
frame:
|
|
308
|
+
The frame from which to determine the module path.
|
|
286
309
|
|
|
287
310
|
Returns:
|
|
288
|
-
|
|
311
|
+
str:
|
|
312
|
+
The in-project path of the module.
|
|
289
313
|
"""
|
|
290
|
-
if
|
|
291
|
-
|
|
314
|
+
if module := inspect.getmodule(frame):
|
|
315
|
+
base_path = os.path.dirname(os.path.abspath(module.__file__))
|
|
316
|
+
relative_path = os.path.relpath(frame.f_code.co_filename, base_path)
|
|
317
|
+
return relative_path.replace(os.path.sep, '.').rstrip('.py')
|
|
318
|
+
return None
|
|
292
319
|
|
|
293
|
-
|
|
294
|
-
name = inspect.stack()[1][
|
|
295
|
-
3
|
|
296
|
-
] # Get the name of the calling function if no name is provided
|
|
297
|
-
|
|
298
|
-
return self.log_device.get_child(name)
|
|
299
|
-
|
|
300
|
-
def __is_member__(self):
|
|
320
|
+
def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False, stacklevel=1):
|
|
301
321
|
"""
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
Raises:
|
|
305
|
-
PermissionError: If the caller of this method is not a member of the same class.
|
|
322
|
+
Low-level logging implementation, passing stacklevel to findCaller.
|
|
306
323
|
"""
|
|
307
|
-
|
|
308
|
-
|
|
324
|
+
if self.logger.isEnabledFor(level):
|
|
325
|
+
self.logger._log(level, msg, args, exc_info, extra, stack_info, stacklevel + 1)
|
|
309
326
|
|
|
310
|
-
current_frame = inspect.currentframe()
|
|
311
|
-
log.debug(f"Current frame: {current_frame}")
|
|
312
327
|
|
|
313
|
-
|
|
314
|
-
|
|
328
|
+
found_level = find_variable_in_call_stack('INSPY_LOG_LEVEL', DEFAULT_LOGGING_LEVEL)
|
|
329
|
+
|
|
330
|
+
LOG_DEVICE = Logger(PROG_NAME, found_level)
|
|
331
|
+
MOD_LOG_DEVICE = LOG_DEVICE.get_child("log_engine", found_level)
|
|
332
|
+
MOD_LOGGER = MOD_LOG_DEVICE.logger
|
|
333
|
+
MOD_LOGGER.debug(f"Started logger for {__name__}.")
|
|
315
334
|
|
|
316
|
-
|
|
317
|
-
log.debug(f"Caller self: {caller_self}")
|
|
335
|
+
add_child = LOG_DEVICE.get_child
|
|
318
336
|
|
|
319
|
-
|
|
320
|
-
if not isinstance(caller_self, self.__class__):
|
|
321
|
-
raise PermissionError(
|
|
322
|
-
"Access denied.\n"
|
|
323
|
-
f"Method can only be accessed by members of the same class. {caller_self.__class__.__name__} is not such a member"
|
|
324
|
-
)
|
|
337
|
+
InspyLogger = Logger
|
|
325
338
|
|
|
326
|
-
|
|
339
|
+
from inspy_logger.helpers.base_classes import Loggable
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
from inspy_logger import MOD_LOGGER, MOD_LOG_DEVICE, Logger
|
|
3
|
+
|
|
4
|
+
import inspect
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class LoggableDescriptor:
|
|
8
|
+
"""
|
|
9
|
+
Descriptor for accessing a logger specific to a class method.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
def __get__(self, instance, owner):
|
|
13
|
+
if instance is None:
|
|
14
|
+
# Accessing through the class, not an instance
|
|
15
|
+
return owner.class_logger
|
|
16
|
+
|
|
17
|
+
# Determine the calling method's name
|
|
18
|
+
stack = inspect.stack()
|
|
19
|
+
# Start from 1 to skip the current __get__ frame
|
|
20
|
+
for frame_record in stack[1:]:
|
|
21
|
+
if 'self' in frame_record.frame.f_locals:
|
|
22
|
+
if frame_record.frame.f_locals['self'] is instance:
|
|
23
|
+
method_name = frame_record.function
|
|
24
|
+
break
|
|
25
|
+
else:
|
|
26
|
+
raise Exception("Could not determine the calling method's name.")
|
|
27
|
+
|
|
28
|
+
# Get a child logger named after the class and method
|
|
29
|
+
return instance.log_device.get_child()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _get_parent_logging_device():
|
|
33
|
+
"""
|
|
34
|
+
Determines the parent logging device by inspecting the caller's log_device or parent_log_device attribute.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
Logger: The parent logging device.
|
|
38
|
+
"""
|
|
39
|
+
MOD_LOGGER.debug("Determining parent logging device")
|
|
40
|
+
caller_frame = inspect.currentframe().f_back
|
|
41
|
+
caller_locals = caller_frame.f_locals
|
|
42
|
+
|
|
43
|
+
if "logger" in caller_locals:
|
|
44
|
+
return caller_locals["logger"]
|
|
45
|
+
elif "parent_log_device" in caller_locals:
|
|
46
|
+
return caller_locals["parent_log_device"]
|
|
47
|
+
else:
|
|
48
|
+
raise ValueError("Unable to determine the parent logging device.")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class Loggable:
|
|
52
|
+
"""
|
|
53
|
+
A metaclass to enhance classes with logging capabilities. Classes that inherit from
|
|
54
|
+
'Loggable' can instantly access a logger without manually setting it up. This logger
|
|
55
|
+
is derived from a parent logger, ensuring consistent logging behavior and hierarchy.
|
|
56
|
+
|
|
57
|
+
Attributes:
|
|
58
|
+
- log_device: The logger device associated with the instance of the class.
|
|
59
|
+
"""
|
|
60
|
+
method_logger = LoggableDescriptor()
|
|
61
|
+
class_logger = None
|
|
62
|
+
|
|
63
|
+
def __init__(self, parent_log_device=None, **kwargs):
|
|
64
|
+
self.parent_log_device = parent_log_device
|
|
65
|
+
self.__log_name = self.__class__.__name__
|
|
66
|
+
if self.parent_log_device is not None:
|
|
67
|
+
self.__log_device = self.parent_log_device.get_child(self.__log_name)
|
|
68
|
+
else:
|
|
69
|
+
self.__log_device = _get_parent_logging_device().get_child()
|
|
70
|
+
|
|
71
|
+
# Set up class-level logger if it's not already set
|
|
72
|
+
if self.__class__.class_logger is None:
|
|
73
|
+
self.__class__.class_logger = self.__log_device
|
|
74
|
+
|
|
75
|
+
self.method_logger = self.__class__.method_logger.logger
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def log_device(self):
|
|
79
|
+
return self.__log_device
|
|
80
|
+
|
|
81
|
+
@log_device.setter
|
|
82
|
+
def log_device(self, new):
|
|
83
|
+
if not isinstance(new, Logger):
|
|
84
|
+
raise TypeError('log_device must be of type "Logger"')
|
|
85
|
+
|
|
86
|
+
self.__log_device = new
|
|
87
|
+
|
|
88
|
+
def create_child_logger(self, name=None, override=False):
|
|
89
|
+
"""
|
|
90
|
+
Creates and returns a child logger of this object's logger.
|
|
91
|
+
|
|
92
|
+
Parameters:
|
|
93
|
+
name (str, optional): The name of the child logger.
|
|
94
|
+
If not provided, the name of the calling function is used.
|
|
95
|
+
override (bool, optional): A flag to override the membership check. Defaults to False.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
Logger: An instance of the Logger class that represents the child logger.
|
|
99
|
+
"""
|
|
100
|
+
if not override:
|
|
101
|
+
self.__is_member__()
|
|
102
|
+
|
|
103
|
+
if name is None:
|
|
104
|
+
name = inspect.stack()[1][
|
|
105
|
+
3
|
|
106
|
+
] # Get the name of the calling function if no name is provided
|
|
107
|
+
#print(inspect.stack()[1])
|
|
108
|
+
return self.log_device.get_child(name)
|
|
109
|
+
|
|
110
|
+
def __is_member__(self):
|
|
111
|
+
"""
|
|
112
|
+
Checks whether the caller of this method is a member of the same class.
|
|
113
|
+
|
|
114
|
+
Raises:
|
|
115
|
+
PermissionError: If the caller of this method is not a member of the same class.
|
|
116
|
+
"""
|
|
117
|
+
log_device = self.log_device.get_child("__is_member__")
|
|
118
|
+
log = log_device.logger
|
|
119
|
+
|
|
120
|
+
current_frame = inspect.currentframe()
|
|
121
|
+
log.debug(f"Current frame: {current_frame}")
|
|
122
|
+
|
|
123
|
+
caller_frame = current_frame.f_back
|
|
124
|
+
log.debug(f"Caller frame: {caller_frame}")
|
|
125
|
+
|
|
126
|
+
caller_self = caller_frame.f_locals.get("self", None)
|
|
127
|
+
log.debug(f"Caller self: {caller_self}")
|
|
128
|
+
|
|
129
|
+
log.debug("Checking if caller is a member of this class...")
|
|
130
|
+
if not isinstance(caller_self, self.__class__):
|
|
131
|
+
raise PermissionError(
|
|
132
|
+
"Access denied.\n"
|
|
133
|
+
f"Method can only be accessed by members of the same class. {caller_self.__class__.__name__} is not such a member"
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
log.debug(f"Access granted to {caller_self.__class__.__name__}")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "inspy-logger"
|
|
3
|
-
version = "3.0-dev.
|
|
3
|
+
version = "3.0-dev.4"
|
|
4
4
|
description = "Colorable, scalable logger for CLI"
|
|
5
5
|
authors = ["Taylor-Jayde Blackstone <tayjaybabee@gmail.com>"]
|
|
6
6
|
homepage = 'https://github.com/Inspyre-Softworks/inSPy-Logger'
|
|
@@ -28,7 +28,7 @@ classifiers = [
|
|
|
28
28
|
]
|
|
29
29
|
|
|
30
30
|
[tool.poetry.dependencies]
|
|
31
|
-
python = "
|
|
31
|
+
python = ">=3.9,<4.0"
|
|
32
32
|
colorlog = "^6.7"
|
|
33
33
|
setuptools-autover = "^1.0.2"
|
|
34
34
|
luddite = "^1.0.1"
|
|
@@ -42,15 +42,22 @@ rich = "^13.5.2"
|
|
|
42
42
|
|
|
43
43
|
[tool.poetry.dev-dependencies]
|
|
44
44
|
ptipython = "^1.0.1"
|
|
45
|
-
Sphinx = "^5.3.0"
|
|
46
|
-
sphinxcontrib-napoleon = "^0.7"
|
|
47
|
-
sphinx-rtd-theme = "^1.0.0"
|
|
48
45
|
asciinema = "^2.2.0"
|
|
49
46
|
bpython = "^0.23"
|
|
50
47
|
|
|
51
48
|
[tool.poetry.scripts]
|
|
52
49
|
inspy-logger-tool = "inspy_logger.Scripts.main:main"
|
|
53
50
|
|
|
51
|
+
[tool.poetry.group.docs.dependencies]
|
|
52
|
+
sphinx = "^7.2.6"
|
|
53
|
+
sphinx-autodoc-typehints = "^1.25.2"
|
|
54
|
+
sphinxcontrib-napoleon = "^0.7"
|
|
55
|
+
sphinx-rtd-theme = "^2.0.0"
|
|
56
|
+
sphinxcontrib-argdoc = "^0.1.3"
|
|
57
|
+
autoclasstoc = "^1.6.0"
|
|
58
|
+
sphinx-autodoc-annotation = "^1.0.post1"
|
|
59
|
+
sphinxcontrib-autoprogram = "^0.1.8"
|
|
60
|
+
|
|
54
61
|
[build-system]
|
|
55
62
|
requires = ["poetry-core>=1.0.0"]
|
|
56
63
|
build-backend = "poetry.core.masonry.api"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|