From 693af6ca3ebac55aa1afb07d411145b7334b628a Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Sat, 14 Mar 2015 17:15:12 +0100 Subject: prolog.engine: use .get() to access reply In case SWI engine goes insane and returns a malformed reply (has happened). Also fix the test case in this file to use the new, classless methods. --- prolog/engine.py | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'prolog') diff --git a/prolog/engine.py b/prolog/engine.py index af79535..e64f728 100644 --- a/prolog/engine.py +++ b/prolog/engine.py @@ -6,22 +6,24 @@ import json import re import urllib -# Create a new pengine. If query is given: run it, destroy the engine and -# return the reply. Otherwise, return the ID of the new pengine. +# Create a new pengine, initialize it with [code] and return its ID. The engine +# will be destroyed after completing one query. def create(code=''): opts = {'format': 'json-s', 'destroy': True, 'src_text': code} reply, messages = request('POST', '/pengine/create', body=json.dumps(opts)) - if reply['event'] != 'create' or 'error' in messages: + if reply.get('event') != 'create' or 'error' in messages: raise Exception('\n'.join(messages['error'])) return reply['id'] +# Create a new pengine with [code], run [query] and destroy the engine. Return +# the reply from engine. def create_and_ask(code, query): opts = {'format': 'json-s', 'destroy': True, 'src_text': code, 'ask': query} reply, messages = request('POST', '/pengine/create', body=json.dumps(opts)) - if reply['event'] != 'create' or 'error' in messages: + if reply.get('event') != 'create' or 'error' in messages: raise Exception('\n'.join(messages['error'])) return reply['answer']['data'] @@ -60,7 +62,7 @@ def request(method, path, body=None): raise Exception('server returned {}'.format(response.status)) reply = json.loads(response.read().decode('utf-8')) - if reply['event'] == 'output': + if reply.get('event') == 'output': msg_type, msg_data = get_message(reply) messages[msg_type].append(msg_data) @@ -90,15 +92,14 @@ def get_message(reply): if reply.get('code') == 'syntax_error': match = re.match(r'^.*Syntax error: (.*)$', data, flags=re.DOTALL) - message += match.group(1) + data = match.group(1) elif reply.get('code') == 'permission_error': match = re.match(r'^.*(No permission [^\n]*)', data, flags=re.DOTALL) - message += match.group(1) + data = match.group(1) elif reply.get('code') == 'type_error': match = re.match(r'^.*(Type error: [^\n]*)', data, flags=re.DOTALL) - message += match.group(1) - else: - message += data + data = match.group(1) + message += data # Replace anonymous variable names with _. message = re.sub(r'_G[0-9]*', '_', message) @@ -109,7 +110,7 @@ def get_message(reply): def test_all(name, code): reply = create_and_ask(code=code, query="run_tests({}, Results)".format(name)) - if reply['event'] != 'success': + if reply.get('event') != 'success': raise Exception('testing procedure failed') results = re.findall(r'(?:success|failure)\([^)]*\)', reply['data'][0]['Results']) @@ -122,13 +123,13 @@ def test_all(name, code): def test(name, code): try: reply = create_and_ask(code=code, query='run_tests({})'.format(name)) - return reply['event'] == 'success' + return reply.get('event') == 'success' except Exception as ex: return False # Basic sanity check. if __name__ == '__main__': - engine = PrologEngine(code='dup([],[]). dup([H|T],[H,H|TT]) :- dup(T,TT).') - print('engine id is ' + engine.id) - print(engine.ask("run_tests({}, Result)".format('dup/2'))) - engine.destroy() + engine = create(code='dup([],[]). dup([H|T],[H,H|TT]) :- dup(T,TT).') + print('engine id is ' + engine) + print(ask(engine, "run_tests({}, Result)".format('dup/2'))) + destroy(engine) -- cgit v1.2.1