Mercurial > pytave
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 */ |