Coverage for python/lsst/utils/get_caller_name.py: 10%

Shortcuts on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

20 statements  

1# This file is part of utils. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (https://www.lsst.org). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# Use of this source code is governed by a 3-clause BSD-style 

10# license that can be found in the LICENSE file. 

11 

12__all__ = ["get_caller_name"] 

13 

14import inspect 

15 

16 

17def get_caller_name(skip: int = 2) -> str: 

18 """Get the name of the caller method. 

19 

20 Any item that cannot be determined (or is not relevant, e.g. a free 

21 function has no class) is silently omitted, along with an 

22 associated separator. 

23 

24 Parameters 

25 ---------- 

26 skip : `int` 

27 How many levels of stack to skip while getting caller name; 

28 1 means "who calls me", 2 means "who calls my caller", etc. 

29 

30 Returns 

31 ------- 

32 name : `str` 

33 Name of the caller as a string in the form ``module.class.method``. 

34 An empty string is returned if ``skip`` exceeds the stack height. 

35 

36 Notes 

37 ----- 

38 Adapted from from http://stackoverflow.com/a/9812105 

39 by adding support to get the class from ``parentframe.f_locals['cls']`` 

40 """ 

41 stack = inspect.stack() 

42 start = 0 + skip 

43 if len(stack) < start + 1: 

44 return '' 

45 parentframe = stack[start][0] 

46 

47 name = [] 

48 module = inspect.getmodule(parentframe) 

49 if module: 

50 name.append(module.__name__) 

51 # add class name, if any 

52 if 'self' in parentframe.f_locals: 

53 name.append(type(parentframe.f_locals['self']).__name__) 

54 elif 'cls' in parentframe.f_locals: 

55 name.append(parentframe.f_locals['cls'].__name__) 

56 codename = parentframe.f_code.co_name 

57 if codename != '<module>': # top level usually 

58 name.append(codename) # function or a method 

59 return ".".join(name)