The problem is that yourfuncme()
function is assuming it has been called directly rather indirectly through something else — such as a decorator. This could be fixed by changing its calling sequence and adding an additionaldepth
keyword argument with a default value which will be passed on to _sys._getframe()
. With this scaffolding in place, the decorator can then override the default value. The following will print the same thing whether or not the decorator has been applied:
1 import sys
2 import Errors
3 def argcheck(in_=(), out=(type(None),)):
4 def _argcheck(function):
5 # do something here
6 def __argcheck(*args, **kw):
7 print '+++++++++ checking types before calling the func'
8 # do something here
9 res = function(*args, depth=2, **kw) # override default depth
10 return res
11 return __argcheck
12 return _argcheck
13
14 @argcheck((str))
15 def funcme(name, depth=1): # added keyword arg with default value
16 try:
17 f = sys._getframe(depth) # explicitly pass stack depth wanted
18 except ValueError, err:
19 raise Errors.UserError(err) # stack too deep
20
21 filename, lineno = f.f_globals['__name__'], f.f_lineno
22 print filename, lineno