comparison pyeval.cc @ 307:b4e56f7255f7

Add option to specify namespace when calling pyexec and pyeval (fixes issue #25) * pyeval.cc, pyexec.cc: Use the second parameter (if supplied) as namespace to eval/exec the python code.
author Abhinav Tripathi <genuinelucifer@gmail.com>
date Tue, 09 Aug 2016 11:28:15 -0700
parents 6e83efbcf1bc
children a140160b2319
comparison
equal deleted inserted replaced
306:2ecae5c6eeb6 307:b4e56f7255f7
33 33
34 #define PYTAVE_DO_DECLARE_SYMBOL 34 #define PYTAVE_DO_DECLARE_SYMBOL
35 #include "arrayobjectdefs.h" 35 #include "arrayobjectdefs.h"
36 #include "exceptions.h" 36 #include "exceptions.h"
37 #include "python_to_octave.h" 37 #include "python_to_octave.h"
38 #include "pytave_utils.h"
38 39
39 using namespace boost::python; 40 using namespace boost::python;
40 41
41 DEFUN_DLD (pyeval, args, nargout, 42 DEFUN_DLD (pyeval, args, nargout,
42 "-*- texinfo -*-\n\ 43 "-*- texinfo -*-\n\
43 @deftypefn {} {} pyeval (@var{expr})\n\ 44 @deftypefn {} {} pyeval (@var{expr})\n\
44 @deftypefnx {} {@var{x} =} pyeval (@var{expr})\n\ 45 @deftypefnx {} {@var{x} =} pyeval (@var{expr})\n\
46 @deftypefn {} {} pyeval (@var{expr}, @var{localNS})\n\
47 @deftypefnx {} {@var{x} =} pyeval (@var{expr}, @var{localNS})\n\
45 Evaluate a Python expression and return the result.\n\ 48 Evaluate a Python expression and return the result.\n\
49 You can supply a 'localNS' to enforce all changes in that namespace.\n\
46 \n\ 50 \n\
47 Examples:\n\ 51 Examples:\n\
48 @example\n\ 52 @example\n\
49 @group\n\ 53 @group\n\
50 pyexec (\"import sys\")\n\ 54 pyexec (\"import sys\")\n\
61 { 65 {
62 octave_value_list retval; 66 octave_value_list retval;
63 67
64 int nargin = args.length (); 68 int nargin = args.length ();
65 69
70 if (nargin < 1 || nargin > 2)
71 {
72 print_usage ();
73 return retval;
74 }
75
66 std::string code = args(0).string_value (); 76 std::string code = args(0).string_value ();
67 77
68 std::string id; 78 std::string id;
69 object res; 79 object res;
70 80
71 Py_Initialize (); 81 Py_Initialize ();
72 82
73 object main_module = import ("__main__"); 83 object main_module = import ("__main__");
74 object main_namespace = main_module.attr ("__dict__"); 84 object main_namespace = main_module.attr ("__dict__");
85 object local_namespace;
86 if (nargin > 1)
87 {
88 pytave::get_object_from_python (args(1), local_namespace);
89 if (local_namespace.is_none ())
90 error ("pyeval: NAMESPACE must be a string or a Python reference");
91 }
92 else
93 local_namespace = main_namespace;
75 94
76 try 95 try
77 { 96 {
78 res = eval (code.c_str (), main_namespace, main_namespace); 97 res = eval (code.c_str (), main_namespace, local_namespace);
79 98
80 if (nargout > 0 || ! res.is_none ()) 99 if (nargout > 0 || ! res.is_none ())
81 { 100 {
82 octave_value val; 101 octave_value val;
83 pytave::pyobj_to_octvalue (val, res); 102 pytave::pyobj_to_octvalue (val, res);
152 %! assert (z{4}{2}{2}, 422) 171 %! assert (z{4}{2}{2}, 422)
153 172
154 %!error <NameError> 173 %!error <NameError>
155 %! pyexec ("def raiseException(): raise NameError ('oops')") 174 %! pyexec ("def raiseException(): raise NameError ('oops')")
156 %! pyeval ("raiseException()") 175 %! pyeval ("raiseException()")
176
177 %!test
178 %! % Variable defined in global namespace is available locally
179 %! myNS = pyeval ("{}");
180 %! pyexec ("myvar = 1")
181 %! assert (pyeval ("myvar", myNS), 1);
182
183 %!test
184 %! % Variables with same name can have different values in different namespaces
185 %! myNS1 = pyeval ("{}");
186 %! myNS2 = pyeval ("{}");
187 %! pyexec ("myvar = 1")
188 %! pyexec ("myvar = 2", myNS1)
189 %! pyexec ("myvar = 3", myNS2)
190 %! assert (pyeval ("myvar"), 1)
191 %! assert (pyeval ("myvar", myNS1), 2)
192 %! assert (pyeval ("myvar", myNS2), 3)
193
194 %!test
195 %! pyexec ("if 'myvar' in globals(): del myvar")
196 %! % Namespaces can also be passed as strings
197 %! pyexec ("myNS = {}");
198 %! pyexec ("myvar = 1", "myNS");
199 %! assert (pyeval ("myvar", "myNS"), 1);
200
201 %!error <NameError>
202 %! pyexec ("if 'myvar' in globals(): del myvar")
203 %! % Variable defined in local namespace MUST not be available globally
204 %! myNS = pyeval ("{}");
205 %! pyexec ("myvar = 1", myNS)
206 %! pyeval ("myvar");
207
208 %!error <NameError>
209 %! pyexec ("if 'myvar' in globals(): del myvar")
210 %! % Variable defined in one local namespace MUST not be available in another
211 %! myNS1 = pyeval ("{}");
212 %! myNS2 = pyeval ("{}");
213 %! pyexec ("myvar = 1", myNS1)
214 %! pyeval ("myvar", myNS2);
215
216 %!error <NameError>
217 %! pyexec ("if 'sys' in globals(): del sys")
218 %! % Modules imported in local namespace MUST not be accessible globally
219 %! myNS = pyeval ("{}");
220 %! pyexec ("import sys", myNS);
221 %! pyeval ("sys");
157 */ 222 */