-
Notifications
You must be signed in to change notification settings - Fork 79
[dev] Parent call tracing
Infernio edited this page Oct 28, 2022
·
7 revisions
It can be really annoying to figure out where some mysterious calls found via profiling come from. Something like this helps:
+ _parent_cache = set()
+ _is_on = False
def isfile(self):
+ if self._is_on:
+ parent_frame = sys._getframe(1)
+ code_obj = parent_frame.f_code
+ calling_loc = f'{code_obj.co_filename}:{parent_frame.f_lineno}' \
+ f'({code_obj.co_name})'
+ if calling_loc not in self._parent_cache:
+ self._parent_cache.add(calling_loc)
+ deprint(f'Called from {calling_loc}')
return os.path.isfile(self._s)
Change _is_on
to True once you want to start monitoring, change it to False once you're done.
Output looks like this:
bolt.py 814 isfile: Called from E:\Infernio\Desktop\Programming\wrye-bash\Mopy\bash\bosh\__init__.py:476(__init__)
bolt.py 814 isfile: Called from E:\Infernio\Desktop\Programming\wrye-bash\Mopy\bash\bosh\__init__.py:640(setGhost)
Copy-pastable version:
_parent_cache = set()
_is_on = False
if self._is_on:
parent_frame = sys._getframe(1)
code_obj = parent_frame.f_code
calling_loc = f'{code_obj.co_filename}:{parent_frame.f_lineno}' \
f'({code_obj.co_name})'
if calling_loc not in self._parent_cache:
self._parent_cache.add(calling_loc)
deprint(f'Called from {calling_loc}')
When you want to know not just where the calls are coming from, but how many are coming from where, this minor variation is useful:
+ _parent_counter = collections.Counter()
+ _is_on = False
def __hash__(self):
+ if self._is_on:
+ parent_frame = sys._getframe(1)
+ code_obj = parent_frame.f_code
+ calling_loc = f'{code_obj.co_filename}:{parent_frame.f_lineno}' \
+ f'({code_obj.co_name})'
+ self._parent_counter[calling_loc] += 1
return hash(self._lower)
Use as before, but once done, pprint
the contents of _parent_counter:
Counter({'E:\\Infernio\\Desktop\\Programming\\wrye-bash\\Mopy\\bash\\load_order.py:104(__init__)': 144537,
'E:\\Infernio\\Desktop\\Programming\\wrye-bash\\Mopy\\bash\\load_order.py:109(<dictcomp>)': 144537,
'E:\\Infernio\\Desktop\\Programming\\wrye-bash\\Mopy\\bash\\bolt.py:633(forward_compat_path_to_fn_list)': 133558,
'E:\\Infernio\\Desktop\\Programming\\wrye-bash\\Mopy\\bash\\load_order.py:112(__init__)': 133558,
'E:\\Infernio\\Desktop\\Programming\\wrye-bash\\Mopy\\bash\\load_order.py:113(<dictcomp>)': 133558})
Copy-pastable version:
_parent_counter = collections.Counter()
_is_on = False
if self._is_on:
parent_frame = sys._getframe(1)
code_obj = parent_frame.f_code
calling_loc = f'{code_obj.co_filename}:{parent_frame.f_lineno}' \
f'({code_obj.co_name})'
self._parent_counter[calling_loc] += 1