diag_msg.py module.
1. diag_msg
With diag_msg you can print messages with the time and caller info added automatically. The default time format is H:M:S.f. The caller info includes the module name, class name (or null), method name (or null), and the line number relative to the start of the module.
- Example:
print a diagnostic message
>>> from scottbrian_utils.diag_msg import diag_msg
>>> diag_msg('this is a diagnostic message')
16:20:05.909260 <input>:1 this is a diagnostic message
Note that the examples are done as if entered in a python session from the console. As such, the module name will show as <input>. When coded in a module, however, you will see the module name instead of <input>.
- class diag_msg.CallerInfo(mod_name: str, cls_name: str, func_name: str, line_num: int)
NamedTuple for the caller info used in diag_msg.
Create new instance of CallerInfo(mod_name, cls_name, func_name, line_num)
-
cls_name:
str Alias for field number 1
-
func_name:
str Alias for field number 2
-
line_num:
int Alias for field number 3
-
mod_name:
str Alias for field number 0
-
cls_name:
- diag_msg.diag_msg(*args, depth=1, dt_format='%H:%M:%S.%f', **kwargs)
Print diagnostic message.
- Parameters:
args (
Any) – the text to print as part of the diagnostic messagedepth (
int) – specifies how many callers to include in the call sequencedt_format (
str) – datetime format to usekwargs (
Any) – keyword args to pass along to the print statement
- Example:
print a diagnostic message from a method with a seq depth of 2
- Return type:
None
>>> from scottbrian_utils.diag_msg import diag_msg >>> class Cls1: ... @classmethod ... def f1(cls, x): ... # limit to two calls ... diag_msg('diagnostic info', x, depth=2) >>> Cls1.f1(42) 16:20:05.909260 <input>:1 -> <input>::Cls1.f1:5 diagnostic info 42
- Example:
print a diagnostic message with different datetime format
>>> from scottbrian_utils.diag_msg import diag_msg >>> class Cls1: ... def f1(self, x): ... # use different datetime format ... diag_msg('diagnostic info', ... x, ... dt_format='%a %b-%d %H:%M:%S') >>> Cls1().f1(24) Tue Feb-16 10:38:32 <input>::Cls1.f1:4 diagnostic info 24
- diag_msg.get_caller_info(frame)
Return caller information from the given stack frame.
- Parameters:
frame (
FrameType) – the frame from which to extract caller info- Return type:
- Returns:
The caller module name, class name (or null), function name (or null), and the line number within the module source
- Example:
get caller info for current frame
>>> from scottbrian_utils.diag_msg import get_caller_info >>> import inspect >>> from os import fspath >>> from pathlib import Path >>> def f1(): ... a_frame = inspect.currentframe() ... caller_info = get_caller_info(a_frame) ... print(f'{caller_info.mod_name=}') ... print(f'{caller_info.cls_name=}') ... print(f'{caller_info.func_name=}') ... print(f'{caller_info.line_num=}') >>> >>> f1() caller_info.mod_name='<input>' caller_info.cls_name='' caller_info.func_name='f1' caller_info.line_num=3
- diag_msg.get_formatted_call_sequence(latest=0, depth=3)
Return a formatted string showing the callers.
- Parameters:
latest (
int) – specifies the stack position of the most recent caller to be included in the call sequencedepth (
int) – specifies how many callers to include in the call sequence
- Return type:
str- Returns:
Formatted string showing for each caller the module name, possibly a function name or a class name/method_name pair, and the source code line number. There are three basic scenarios:
A call from a script will appear as: mod_name:lineno
A call from a function will appear as: mod_name::func_name:lineno
A call from a class method will appear as:: mod_name::cls_name.func_name:lineno
This function is useful if, for example, you want to include the call sequence in a log.
- Example:
get call sequence for three callers
>>> from scottbrian_utils.diag_msg import ( ... get_formatted_call_sequence) >>> def f1(): ... # f1 now on stack ... # call f2 ... f2() >>> def f2(): ... # call f3 ... f3() >>> def f3(): ... # f3 now latest entry in call sequence ... # default is to get three most recent calls ... print(get_formatted_call_sequence()) >>> f1() <input>::f1:4 -> <input>::f2:3 -> <input>::f3:4
Note that when coded in a module, you will get the module name in the sequence instead of <input>, and the line numbers will be relative from the start of the module instead of from each of the function definition sections.
- Example:
get call sequence for last two callers
>>> from scottbrian_utils.diag_msg import ( ... get_formatted_call_sequence) >>> def f1(): ... # f1 now on stack ... # call f2 ... f2() >>> def f2(): ... # call f3 ... f3() >>> def f3(): ... # f3 now latest entry in call sequence ... # specify depth to get two most recent calls ... call_seq = get_formatted_call_sequence(depth=2) ... print(call_seq) >>> f1() <input>::f2:3 -> <input>::f3:4
- Example:
get call sequence for two callers, one caller back
>>> from scottbrian_utils.diag_msg import ( ... get_formatted_call_sequence) >>> def f1(): ... # f1 now on stack ... # call f2 ... f2() >>> def f2(): ... # call f3 ... f3() >>> def f3(): ... # f3 now latest entry in call sequence ... # specify latest to go back 1 and thus ignore f3 ... # specify depth to get two calls from latest going back ... call_seq = get_formatted_call_sequence(latest=1, depth=2) ... print(call_seq) >>> f1() <input>::f1:4 -> <input>::f2:3
- Example:
get sequence for script call to class method
>>> from scottbrian_utils.diag_msg import ( ... get_formatted_call_sequence) >>> class Cls1: ... def f1(self): ... # limit to two calls ... call_seq = get_formatted_call_sequence(depth=2) ... print(call_seq) >>> a_cls1 = Cls1() >>> a_cls1.f1() <input>:1 -> <input>::Cls1.f1:4