|
@@
-1,96
+1,95
b''
|
|
1
|
1
|
# encoding: utf-8
|
|
2
|
2
|
"""
|
|
3
|
3
|
Utilities for working with stack frames.
|
|
4
|
4
|
"""
|
|
5
|
5
|
|
|
6
|
6
|
#-----------------------------------------------------------------------------
|
|
7
|
7
|
# Copyright (C) 2008-2011 The IPython Development Team
|
|
8
|
8
|
#
|
|
9
|
9
|
# Distributed under the terms of the BSD License. The full license is in
|
|
10
|
10
|
# the file COPYING, distributed as part of this software.
|
|
11
|
11
|
#-----------------------------------------------------------------------------
|
|
12
|
12
|
|
|
13
|
13
|
#-----------------------------------------------------------------------------
|
|
14
|
14
|
# Imports
|
|
15
|
15
|
#-----------------------------------------------------------------------------
|
|
16
|
16
|
|
|
17
|
17
|
import sys
|
|
18
|
18
|
from IPython.utils import py3compat
|
|
19
|
19
|
|
|
20
|
20
|
#-----------------------------------------------------------------------------
|
|
21
|
21
|
# Code
|
|
22
|
22
|
#-----------------------------------------------------------------------------
|
|
23
|
23
|
|
|
24
|
24
|
def extract_vars(*names,**kw):
|
|
25
|
25
|
"""Extract a set of variables by name from another frame.
|
|
26
|
26
|
|
|
27
|
27
|
Parameters
|
|
28
|
28
|
----------
|
|
29
|
29
|
*names : str
|
|
30
|
30
|
One or more variable names which will be extracted from the caller's
|
|
31
|
31
|
frame.
|
|
32
|
32
|
|
|
33
|
33
|
depth : integer, optional
|
|
34
|
34
|
How many frames in the stack to walk when looking for your variables.
|
|
35
|
35
|
The default is 0, which will use the frame where the call was made.
|
|
36
|
36
|
|
|
37
|
37
|
|
|
38
|
38
|
Examples
|
|
39
|
39
|
--------
|
|
40
|
40
|
::
|
|
41
|
41
|
|
|
42
|
42
|
In [2]: def func(x):
|
|
43
|
43
|
...: y = 1
|
|
44
|
44
|
...: print(sorted(extract_vars('x','y').items()))
|
|
45
|
45
|
...:
|
|
46
|
46
|
|
|
47
|
47
|
In [3]: func('hello')
|
|
48
|
48
|
[('x', 'hello'), ('y', 1)]
|
|
49
|
49
|
"""
|
|
50
|
50
|
|
|
51
|
51
|
depth = kw.get('depth',0)
|
|
52
|
52
|
|
|
53
|
53
|
callerNS = sys._getframe(depth+1).f_locals
|
|
54
|
54
|
return dict((k,callerNS[k]) for k in names)
|
|
55
|
55
|
|
|
56
|
56
|
|
|
57
|
57
|
def extract_vars_above(*names):
|
|
58
|
58
|
"""Extract a set of variables by name from another frame.
|
|
59
|
59
|
|
|
60
|
60
|
Similar to extractVars(), but with a specified depth of 1, so that names
|
|
61
|
|
are exctracted exactly from above the caller.
|
|
|
61
|
are extracted exactly from above the caller.
|
|
62
|
62
|
|
|
63
|
63
|
This is simply a convenience function so that the very common case (for us)
|
|
64
|
64
|
of skipping exactly 1 frame doesn't have to construct a special dict for
|
|
65
|
65
|
keyword passing."""
|
|
66
|
66
|
|
|
67
|
67
|
callerNS = sys._getframe(2).f_locals
|
|
68
|
68
|
return dict((k,callerNS[k]) for k in names)
|
|
69
|
69
|
|
|
70
|
70
|
|
|
71
|
71
|
def debugx(expr,pre_msg=''):
|
|
72
|
72
|
"""Print the value of an expression from the caller's frame.
|
|
73
|
73
|
|
|
74
|
74
|
Takes an expression, evaluates it in the caller's frame and prints both
|
|
75
|
75
|
the given expression and the resulting value (as well as a debug mark
|
|
76
|
76
|
indicating the name of the calling function. The input must be of a form
|
|
77
|
77
|
suitable for eval().
|
|
78
|
78
|
|
|
79
|
79
|
An optional message can be passed, which will be prepended to the printed
|
|
80
|
80
|
expr->value pair."""
|
|
81
|
81
|
|
|
82
|
82
|
cf = sys._getframe(1)
|
|
83
|
83
|
print('[DBG:%s] %s%s -> %r' % (cf.f_code.co_name,pre_msg,expr,
|
|
84
|
84
|
eval(expr,cf.f_globals,cf.f_locals)))
|
|
85
|
85
|
|
|
86
|
86
|
|
|
87
|
87
|
# deactivate it by uncommenting the following line, which makes it a no-op
|
|
88
|
88
|
#def debugx(expr,pre_msg=''): pass
|
|
89
|
89
|
|
|
90
|
90
|
def extract_module_locals(depth=0):
|
|
91
|
91
|
"""Returns (module, locals) of the function `depth` frames away from the caller"""
|
|
92
|
92
|
f = sys._getframe(depth + 1)
|
|
93
|
93
|
global_ns = f.f_globals
|
|
94
|
94
|
module = sys.modules[global_ns['__name__']]
|
|
95
|
95
|
return (module, f.f_locals)
|
|
96
|
|
|