diff --git a/pymatbridge/matlab/matlabserver.m b/pymatbridge/matlab/matlabserver.m index 8fa7507..3337b1e 100644 --- a/pymatbridge/matlab/matlabserver.m +++ b/pymatbridge/matlab/matlabserver.m @@ -19,18 +19,10 @@ function matlabserver(socket_address) clear mex; break; - case {'run_function'} - resp = pymat_feval(req); - messenger('respond', resp); - - case {'run_code'} + case {'eval'} resp = pymat_eval(req); messenger('respond', resp); - case {'get_var'} - resp = pymat_get_variable(req); - messenger('respond', resp); - otherwise messenger('respond', 'i dont know what you want'); end diff --git a/pymatbridge/matlab/util/pymat_eval.m b/pymatbridge/matlab/util/pymat_eval.m index 64d081b..60912b2 100644 --- a/pymatbridge/matlab/util/pymat_eval.m +++ b/pymatbridge/matlab/util/pymat_eval.m @@ -11,31 +11,32 @@ % % Based on Max Jaderberg's web_feval -response.success = 'false'; -field_names = fieldnames(req); - +response.success = true; response.content = ''; - -code_check = false; -if size(field_names) - if isfield(req, 'code') - code_check = true; - end -end - -if ~code_check - response.message = 'No code provided as POST parameter'; - json_response = json_dump(response); - return; -end - -code = req.code; +response.result = ''; try % tempname is less likely to get bonked by another process. diary_file = [tempname() '_diary.txt']; diary(diary_file); - evalin('base', code); + + % Add function path to current path + if req.dname + addpath(req.dname); + end + + if iscell(req.func_args) + [resp{1:req.nargout}] = feval(req.func_name, req.func_args{:}); + else + [resp{1:req.nargout}] = feval(req.func_name, req.func_args); + end + + if req.nargout == 1 + response.result = resp{1}; + else + response.result = resp; + end + diary('off'); datadir = fullfile(tempdir(),'MatlabData'); @@ -45,8 +46,6 @@ end fig_files = make_figs(datadir); - - response.success = 'true'; response.content.figures = fig_files; % this will not work on Windows: @@ -58,18 +57,16 @@ fclose(FID); response.content.stdout = stdout; else - response.success = 'false'; + response.success = false; response.content.stdout = sprintf('could not open %s for read',diary_file); end delete(diary_file) catch ME diary('off'); - response.success = 'false'; + response.success = false; response.content.stdout = ME.message; end -response.content.code = code; - json_response = json_dump(response); end %function diff --git a/pymatbridge/matlab/util/pymat_feval.m b/pymatbridge/matlab/util/pymat_feval.m deleted file mode 100644 index 8aef44b..0000000 --- a/pymatbridge/matlab/util/pymat_feval.m +++ /dev/null @@ -1,54 +0,0 @@ -% Max Jaderberg 2011 - -function json_response = pymat_feval(req) - - response.success = 'false'; - field_names = fieldnames(req); - - response.result = ''; - - func_path_check = false; - arguments_check = false; - if size(field_names) - if isfield(req, 'func_path') - func_path_check = true; - end - if isfield(req, 'func_args') - arguments_check = true; - end - end - - if ~func_path_check - response.message = 'No function given as func_path POST parameter'; - json_response = json_dump(response); - return - end - - func_path = req.func_path; - if arguments_check - arguments = req.func_args; - else - arguments = ''; - end - - try - [resp{1:req.nargout}] = run_dot_m(func_path, arguments, req.nargout); - catch ME - response.message = ME.message; - json_response = json_dump(response); - return - end - - if req.nargout == 1 - response.result = resp{1}; - else - response.result = resp; - end - response.success = 'true'; - response.message = 'Successfully completed request'; - - json_response = json_dump(response); - - return - -end diff --git a/pymatbridge/matlab/util/pymat_get_variable.m b/pymatbridge/matlab/util/pymat_get_variable.m deleted file mode 100644 index 1b22952..0000000 --- a/pymatbridge/matlab/util/pymat_get_variable.m +++ /dev/null @@ -1,43 +0,0 @@ -function json_response = pymat_get_variable(req) -% Reach into the current namespace get a variable in json format that can -% be returned as part of a response - -response.success = 'false'; - -field_names = fieldnames(req); - -response.content = ''; - -varname_check = false; -if size(field_names) - if isfield(req, 'varname') - varname_check = true; - end -end - -if ~varname_check - response.message = 'No variable name provided as input argument'; - json_response = json_dump(response); - return -end - - -varname = req.varname; - - -% if the var doesn't exist in the workspace, inform adequately -expr = strcat('exist(''', varname, ''',''var'')'); -var_exists = evalin('base', expr); -if ~var_exists - response.exists = false; - response.var = ''; -else - response.exists = true; - response.var = evalin('base', varname); - response.success = 'true'; -end - -json_response = json_dump(response); - -return -end diff --git a/pymatbridge/matlab/util/pymat_set_variable.m b/pymatbridge/matlab/util/pymat_set_variable.m deleted file mode 100644 index e3936f4..0000000 --- a/pymatbridge/matlab/util/pymat_set_variable.m +++ /dev/null @@ -1,7 +0,0 @@ -function res = pymat_set_variable(args) -% Setup a variable in Matlab workspace - - assignin('base', args.name, args.value); - res = 1; - -end %function diff --git a/pymatbridge/matlab/util/run_dot_m.m b/pymatbridge/matlab/util/run_dot_m.m deleted file mode 100644 index e60aeac..0000000 --- a/pymatbridge/matlab/util/run_dot_m.m +++ /dev/null @@ -1,30 +0,0 @@ -% Max Jaderberg 2011 - -function varargout = run_dot_m( func_to_run, arguments, nout ) -%RUN_DOT_M Runs the given function or .m file with the arguments given -% and the nout selected -% For exmaple run_dot_m('/path/to/function.m', args, 1); -% arguments can be a scalar, as cell, or struct containing the arguments. -% If it is a struct, func_to_run must take only one parameter, the argument structure - - [dname, func_name, ext] = fileparts(func_to_run); - - if size(ext) - if ~strcmp(ext, '.m') - varargout = 'Error: Need to give path to .m file'; - return - end - end - - % Add function path to current path - if size(dname) - addpath(dname); - end - - if iscell(arguments) - [varargout{1:nout}] = feval(func_name, arguments{:}); - else - [varargout{1:nout}] = feval(func_name, arguments); - end - -end diff --git a/pymatbridge/matlab_magic.py b/pymatbridge/matlab_magic.py index f8b441e..17debc8 100644 --- a/pymatbridge/matlab_magic.py +++ b/pymatbridge/matlab_magic.py @@ -93,7 +93,7 @@ def eval(self, line): """ run_dict = self.Matlab.run_code(line) - if run_dict['success'] == 'false': + if not run_dict['success']: raise MatlabInterperterError(line, run_dict['content']['stdout']) # This is the matlab stdout: @@ -105,7 +105,7 @@ def set_matlab_var(self, name, value): """ run_dict = self.Matlab.set_variable(name, value) - if run_dict['success'] == 'false': + if not run_dict['success']: raise MatlabInterperterError(line, run_dict['content']['stdout']) diff --git a/pymatbridge/pymatbridge.py b/pymatbridge/pymatbridge.py index c69120e..ea2da87 100644 --- a/pymatbridge/pymatbridge.py +++ b/pymatbridge/pymatbridge.py @@ -15,7 +15,7 @@ .MATLAB started and connected! True >>> m.run_code('a=1;') -{'content': {'stdout': '', 'datadir': '/private/tmp/MatlabData/', 'code': 'a=1;', 'figures': []}, 'success': 'true'} +{'content': {'stdout': '', 'datadir': '/private/tmp/MatlabData/', 'code': 'a=1;', 'figures': []}, 'success': True} >>> m.get_variable('a') 1 @@ -260,7 +260,7 @@ def is_connected(self): def is_function_processor_working(self): result = self.run_func('%s/usrprog/test_sum.m' % MATLAB_FOLDER, {'echo': '%s: Function processor is working!' % self._program_name()}) - return result['success'] == 'true' + return result['success'] def _json_response(self, **kwargs): return json.loads(self._response(**kwargs), object_hook=decode_pymat) @@ -288,9 +288,15 @@ def run_func(self, func_path, *func_args, **kwargs): nargout = kwargs.pop('nargout', 1) func_args += tuple(item for pair in zip(kwargs.keys(), kwargs.values()) for item in pair) - return self._json_response(cmd='run_function', - func_path=func_path, - func_args=func_args, + dname = os.path.dirname(func_path) + fname = os.path.basename(func_path) + func_name, ext = os.path.splitext(fname) + if ext and not ext == '.m': + raise TypeError('Need to give path to .m file') + return self._json_response(cmd='eval', + func_name=func_name, + func_args=func_args or '', + dname=dname, nargout=nargout) def run_code(self, code): @@ -301,17 +307,16 @@ def run_code(self, code): code : str Code to send for evaluation. """ - return self._json_response(cmd='run_code', code=code) + return self.run_func('evalin', 'base', code, nargout=0) def get_variable(self, varname, default=None): - response = self._json_response(cmd='get_var', varname=varname) - return response['var'] if response['exists'] else default + resp = self.run_func('evalin', 'base', varname) + return resp['result'] if resp['success'] else default def set_variable(self, varname, value): if isinstance(value, spmatrix): return self._set_sparse_variable(varname, value) - return self.run_func('pymat_set_variable.m', - {'name': varname, 'value': value}) + return self.run_func('assignin', 'base', varname, value, nargout=0) def set_default_plot_size(self, width=512, height=384): code = "set(0, 'defaultfigurepaperunits', 'inches');\n" diff --git a/pymatbridge/tests/test_functions.py b/pymatbridge/tests/test_functions.py index 4fed51c..e0367fc 100644 --- a/pymatbridge/tests/test_functions.py +++ b/pymatbridge/tests/test_functions.py @@ -52,6 +52,8 @@ def test_create_func(self): def test_pass_kwargs(self): resp = self.mlab.run_func('plot', [1, 2, 3], Linewidth=3) - assert resp['success'] == 'true' + assert resp['success'] + assert len(resp['content']['figures']) resp = self.mlab.plot([1, 2, 3], Linewidth=3) assert resp['result'] is not None + assert len(resp['content']['figures']) diff --git a/pymatbridge/tests/test_run_code.py b/pymatbridge/tests/test_run_code.py index abd903e..816f3b2 100644 --- a/pymatbridge/tests/test_run_code.py +++ b/pymatbridge/tests/test_run_code.py @@ -59,7 +59,7 @@ def test_undefined_code(self): success = self.mlab.run_code("this_is_nonsense")['success'] message = self.mlab.run_code("this_is_nonsense")['content']['stdout'] - npt.assert_equal(success, "false") + assert not success if tu.on_octave(): npt.assert_equal(message, "'this_is_nonsense' undefined near line 1 column 1") else: