cengal.code_inspection.line_tracer.versions.v_0.line_tracer
1#!/usr/bin/env python 2# coding=utf-8 3 4# Copyright © 2012-2024 ButenkoMS. All rights reserved. Contacts: <gtalk@butenkoms.space> 5# 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17 18from inspect import getouterframes, currentframe 19from cengal.web_tools.request_cache import RequestCache 20from typing import Optional 21from cengal.introspection.inspect import frame 22import os 23 24""" 25Module Docstring 26Docstrings: http://www.python.org/dev/peps/pep-0257/ 27""" 28 29__author__ = "ButenkoMS <gtalk@butenkoms.space>" 30__copyright__ = "Copyright © 2012-2024 ButenkoMS. All rights reserved. Contacts: <gtalk@butenkoms.space>" 31__credits__ = ["ButenkoMS <gtalk@butenkoms.space>", ] 32__license__ = "Apache License, Version 2.0" 33__version__ = "4.4.1" 34__maintainer__ = "ButenkoMS <gtalk@butenkoms.space>" 35__email__ = "gtalk@butenkoms.space" 36# __status__ = "Prototype" 37__status__ = "Development" 38# __status__ = "Production" 39 40 41class LineTracer: 42 def __init__(self, print_full_file_name=False, trace_allowed=True): 43 self.print_full_file_name = print_full_file_name 44 self.trace_allowed = trace_allowed 45 self._file_cache = RequestCache(999999) 46 pass 47 48 def _get_file_data(self, path): 49 file_data = self._file_cache.try_to_get_data_for_request(path) 50 if not file_data: 51 with open(path) as file: 52 file_data = file.readlines() 53 file_data = [line.rstrip('\n') for line in file_data] 54 self._file_cache.put_new_request(path, file_data) 55 return file_data 56 57 def _get_file_line(self, path, line_num): 58 line_num -= 1 # make line numbers start from 0 - not from 1 59 default_answer = None 60 if line_num < 0: 61 return default_answer 62 63 file_data = self._get_file_data(path) 64 max_line = len(file_data) - 1 65 if line_num > max_line: 66 return default_answer 67 68 return file_data[line_num] 69 70 def _frame_info(self, depth: Optional[int] = 1): 71 fr = frame(depth + 1) 72 filename = fr.f_code.co_filename 73 line_number = fr.f_lineno 74 function_name = fr.f_code.co_name 75 lines = str() 76 index = fr.f_code.co_firstlineno 77 return fr, filename, line_number, function_name, lines, index 78 79 def trace(self, depth: Optional[int] = 1): 80 if not self.trace_allowed: 81 result = (None, None, None, None, None) 82 return result 83 84 frame, filename, line_number, function_name, lines, index = self._frame_info(depth + 1) 85 previous_line_num = line_number - 1 86 lines = self._get_file_line(filename, previous_line_num) 87 if not self.print_full_file_name: 88 filename = os.path.basename(filename) 89 90 result = (filename, function_name, previous_line_num, lines, index) 91 return result 92 93 def trace_self(self, depth: Optional[int] = 1): 94 if not self.trace_allowed: 95 result = (None, None, None, None, None) 96 return result 97 98 frame, filename, line_number, function_name, lines, index = self._frame_info(depth + 1) 99 current_line_num = line_number 100 lines = self._get_file_line(filename, current_line_num) 101 if not self.print_full_file_name: 102 filename = os.path.basename(filename) 103 104 result = (filename, function_name, current_line_num, lines, index) 105 return result 106 107 def trace_next(self, depth: Optional[int] = 1): 108 if not self.trace_allowed: 109 result = (None, None, None, None, None) 110 return result 111 112 frame, filename, line_number, function_name, lines, index = self._frame_info(depth + 1) 113 next_line_num = line_number + 1 114 lines = self._get_file_line(filename, next_line_num) 115 if not self.print_full_file_name: 116 filename = os.path.basename(filename) 117 118 result = (filename, function_name, next_line_num, lines, index) 119 return result 120 121 def trace_exact(self, line_num: int, depth: Optional[int] = 1): 122 if not self.trace_allowed: 123 result = (None, None, None, None, None) 124 return result 125 126 frame, filename, line_number, function_name, lines, index = self._frame_info(depth + 1) 127 exact_line_num = line_num 128 lines = self._get_file_line(filename, exact_line_num) 129 if not self.print_full_file_name: 130 filename = os.path.basename(filename) 131 132 result = (filename, function_name, exact_line_num, lines, index) 133 return result 134 135 def trace_relative(self, line_num_offset: int, depth: Optional[int] = 1): 136 if not self.trace_allowed: 137 result = (None, None, None, None, None) 138 return result 139 140 frame, filename, line_number, function_name, lines, index = self._frame_info(depth + 1) 141 exact_line_num = line_number + line_num_offset 142 lines = self._get_file_line(filename, exact_line_num) 143 if not self.print_full_file_name: 144 filename = os.path.basename(filename) 145 146 result = (filename, function_name, exact_line_num, lines, index) 147 return result 148 149 def __call__(self, depth: Optional[int] = 1): 150 if not self.trace_allowed: 151 return 152 153 print(self.trace(depth=depth)) 154 155 def n(self, name: str = '', depth: Optional[int] = 1): 156 if not self.trace_allowed: 157 return 158 159 if name: 160 print(f'<< {name} >>', self.trace(depth=depth)) 161 else: 162 print(self.trace(depth=depth)) 163 164 165line_tracer = LineTracer() 166line_tracer_full_file_name = LineTracer(print_full_file_name=True) 167 168 169def previous_line_number(depth: Optional[int] = 1) -> int: 170 return line_tracer.trace(depth + 1)[2] 171 172 173def current_line_number(depth: Optional[int] = 1) -> int: 174 return previous_line_number(depth + 1) + 1 175 176 177def next_line_number(depth: Optional[int] = 1) -> int: 178 return previous_line_number(depth + 1) + 2 179 180 181pln = previous_line_number 182cln = current_line_number 183nln = next_line_number
class
LineTracer:
42class LineTracer: 43 def __init__(self, print_full_file_name=False, trace_allowed=True): 44 self.print_full_file_name = print_full_file_name 45 self.trace_allowed = trace_allowed 46 self._file_cache = RequestCache(999999) 47 pass 48 49 def _get_file_data(self, path): 50 file_data = self._file_cache.try_to_get_data_for_request(path) 51 if not file_data: 52 with open(path) as file: 53 file_data = file.readlines() 54 file_data = [line.rstrip('\n') for line in file_data] 55 self._file_cache.put_new_request(path, file_data) 56 return file_data 57 58 def _get_file_line(self, path, line_num): 59 line_num -= 1 # make line numbers start from 0 - not from 1 60 default_answer = None 61 if line_num < 0: 62 return default_answer 63 64 file_data = self._get_file_data(path) 65 max_line = len(file_data) - 1 66 if line_num > max_line: 67 return default_answer 68 69 return file_data[line_num] 70 71 def _frame_info(self, depth: Optional[int] = 1): 72 fr = frame(depth + 1) 73 filename = fr.f_code.co_filename 74 line_number = fr.f_lineno 75 function_name = fr.f_code.co_name 76 lines = str() 77 index = fr.f_code.co_firstlineno 78 return fr, filename, line_number, function_name, lines, index 79 80 def trace(self, depth: Optional[int] = 1): 81 if not self.trace_allowed: 82 result = (None, None, None, None, None) 83 return result 84 85 frame, filename, line_number, function_name, lines, index = self._frame_info(depth + 1) 86 previous_line_num = line_number - 1 87 lines = self._get_file_line(filename, previous_line_num) 88 if not self.print_full_file_name: 89 filename = os.path.basename(filename) 90 91 result = (filename, function_name, previous_line_num, lines, index) 92 return result 93 94 def trace_self(self, depth: Optional[int] = 1): 95 if not self.trace_allowed: 96 result = (None, None, None, None, None) 97 return result 98 99 frame, filename, line_number, function_name, lines, index = self._frame_info(depth + 1) 100 current_line_num = line_number 101 lines = self._get_file_line(filename, current_line_num) 102 if not self.print_full_file_name: 103 filename = os.path.basename(filename) 104 105 result = (filename, function_name, current_line_num, lines, index) 106 return result 107 108 def trace_next(self, depth: Optional[int] = 1): 109 if not self.trace_allowed: 110 result = (None, None, None, None, None) 111 return result 112 113 frame, filename, line_number, function_name, lines, index = self._frame_info(depth + 1) 114 next_line_num = line_number + 1 115 lines = self._get_file_line(filename, next_line_num) 116 if not self.print_full_file_name: 117 filename = os.path.basename(filename) 118 119 result = (filename, function_name, next_line_num, lines, index) 120 return result 121 122 def trace_exact(self, line_num: int, depth: Optional[int] = 1): 123 if not self.trace_allowed: 124 result = (None, None, None, None, None) 125 return result 126 127 frame, filename, line_number, function_name, lines, index = self._frame_info(depth + 1) 128 exact_line_num = line_num 129 lines = self._get_file_line(filename, exact_line_num) 130 if not self.print_full_file_name: 131 filename = os.path.basename(filename) 132 133 result = (filename, function_name, exact_line_num, lines, index) 134 return result 135 136 def trace_relative(self, line_num_offset: int, depth: Optional[int] = 1): 137 if not self.trace_allowed: 138 result = (None, None, None, None, None) 139 return result 140 141 frame, filename, line_number, function_name, lines, index = self._frame_info(depth + 1) 142 exact_line_num = line_number + line_num_offset 143 lines = self._get_file_line(filename, exact_line_num) 144 if not self.print_full_file_name: 145 filename = os.path.basename(filename) 146 147 result = (filename, function_name, exact_line_num, lines, index) 148 return result 149 150 def __call__(self, depth: Optional[int] = 1): 151 if not self.trace_allowed: 152 return 153 154 print(self.trace(depth=depth)) 155 156 def n(self, name: str = '', depth: Optional[int] = 1): 157 if not self.trace_allowed: 158 return 159 160 if name: 161 print(f'<< {name} >>', self.trace(depth=depth)) 162 else: 163 print(self.trace(depth=depth))
def
trace(self, depth: typing.Union[int, NoneType] = 1):
80 def trace(self, depth: Optional[int] = 1): 81 if not self.trace_allowed: 82 result = (None, None, None, None, None) 83 return result 84 85 frame, filename, line_number, function_name, lines, index = self._frame_info(depth + 1) 86 previous_line_num = line_number - 1 87 lines = self._get_file_line(filename, previous_line_num) 88 if not self.print_full_file_name: 89 filename = os.path.basename(filename) 90 91 result = (filename, function_name, previous_line_num, lines, index) 92 return result
def
trace_self(self, depth: typing.Union[int, NoneType] = 1):
94 def trace_self(self, depth: Optional[int] = 1): 95 if not self.trace_allowed: 96 result = (None, None, None, None, None) 97 return result 98 99 frame, filename, line_number, function_name, lines, index = self._frame_info(depth + 1) 100 current_line_num = line_number 101 lines = self._get_file_line(filename, current_line_num) 102 if not self.print_full_file_name: 103 filename = os.path.basename(filename) 104 105 result = (filename, function_name, current_line_num, lines, index) 106 return result
def
trace_next(self, depth: typing.Union[int, NoneType] = 1):
108 def trace_next(self, depth: Optional[int] = 1): 109 if not self.trace_allowed: 110 result = (None, None, None, None, None) 111 return result 112 113 frame, filename, line_number, function_name, lines, index = self._frame_info(depth + 1) 114 next_line_num = line_number + 1 115 lines = self._get_file_line(filename, next_line_num) 116 if not self.print_full_file_name: 117 filename = os.path.basename(filename) 118 119 result = (filename, function_name, next_line_num, lines, index) 120 return result
def
trace_exact(self, line_num: int, depth: typing.Union[int, NoneType] = 1):
122 def trace_exact(self, line_num: int, depth: Optional[int] = 1): 123 if not self.trace_allowed: 124 result = (None, None, None, None, None) 125 return result 126 127 frame, filename, line_number, function_name, lines, index = self._frame_info(depth + 1) 128 exact_line_num = line_num 129 lines = self._get_file_line(filename, exact_line_num) 130 if not self.print_full_file_name: 131 filename = os.path.basename(filename) 132 133 result = (filename, function_name, exact_line_num, lines, index) 134 return result
def
trace_relative(self, line_num_offset: int, depth: typing.Union[int, NoneType] = 1):
136 def trace_relative(self, line_num_offset: int, depth: Optional[int] = 1): 137 if not self.trace_allowed: 138 result = (None, None, None, None, None) 139 return result 140 141 frame, filename, line_number, function_name, lines, index = self._frame_info(depth + 1) 142 exact_line_num = line_number + line_num_offset 143 lines = self._get_file_line(filename, exact_line_num) 144 if not self.print_full_file_name: 145 filename = os.path.basename(filename) 146 147 result = (filename, function_name, exact_line_num, lines, index) 148 return result
line_tracer =
<LineTracer object>
line_tracer_full_file_name =
<LineTracer object>
def
previous_line_number(depth: typing.Union[int, NoneType] = 1) -> int:
def
current_line_number(depth: typing.Union[int, NoneType] = 1) -> int:
def
next_line_number(depth: typing.Union[int, NoneType] = 1) -> int:
def
pln(depth: typing.Union[int, NoneType] = 1) -> int:
def
cln(depth: typing.Union[int, NoneType] = 1) -> int:
def
nln(depth: typing.Union[int, NoneType] = 1) -> int: