This commit is contained in:
Vitor Santos Costa
2018-03-12 15:11:59 +00:00
parent 31fd3eb344
commit 1a8c26b886
32 changed files with 442 additions and 307 deletions

View File

@@ -64,6 +64,8 @@ yap_ipython/frontend.py
yap_ipython/parallel.py
yap_ipython/html.py
yap_ipython/__main__.py
_version.py
yap_ipython/_version.py
yap_ipython/testing/iptest.py
yap_ipython/testing/skipdoctest.py
yap_ipython/testing/tools.py
@@ -387,7 +389,7 @@ set(FILES ${PYTHON_SOURCES} ${PL_SOURCES} ${EXTRAS} ${RESOURCES})
set(SETUP_PY ${CMAKE_CURRENT_BINARY_DIR}/setup.py)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/yap.tgz
COMMAND ${CMAKE_COMMAND} -E tar cf ${CMAKE_CURRENT_BINARY_DIR}/yap.tgz ${FILES}
COMMAND ${CMAKE_COMMAND} -E tar cf ${CMAKE_CURRENT_BINARY_DIR}/yap.tgz ${FILES}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
@@ -421,13 +423,14 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/resources/logo-
add_custom_target(YAP_KERNEL ALL
COMMAND ${CMAKE_COMMAND} -E tar xzf yap.tgz
COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} build sdist bdist
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/resources/logo-32x32.png ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/resources/logo-64x64.png yap.tgz ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/resources/kernel.js ${CMAKE_CURRENT_BINARY_DIR}/yap_kernel/resources/prolog.js
)
install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} -m pip install --ignore-installed --no-deps .
install(CODE "execute_process(
COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} build sdist bdist
COMMAND ${PYTHON_EXECUTABLE} -m pip install --ignore-installed --no-deps .
COMMAND ${PYTHON_EXECUTABLE} -m yap_kernel.kernelspec
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})")

View File

@@ -40,14 +40,15 @@ here = os.path.abspath(os.path.dirname(__file__))
packages = ['yap_kernel','yap_ipython']
# pkg_root = pjoin(here, name)
# for d, _, _ in os.walk(pjoin(here, 'yap_kernel')):
# if os.path.exists(pjoin(d, '__init__.py')):
# packages.append(d[len(here)+1:].replace(os.path.sep, '.'))
# for d, _, _ in os.walk(pjoin(here, 'yap_ipython')):
# if os.path.exists(pjoin(d, '__init__.py')):
# packages.append(d[len(here)+1:].replace(os.path.sep, '.'))
for d, _, _ in os.walk(pjoin(here, 'yap_kernel')):
if os.path.exists(pjoin(d, '__init__.py')):
packages.append(d[len(here)+1:].replace(os.path.sep, '.'))
for d, _, _ in os.walk(pjoin(here, 'yap_ipython')):
if os.path.exists(pjoin(d, '__init__.py')):
packages.append(d[len(here)+1:].replace(os.path.sep, '.'))
sys.path.insert(0, here)
sys.path.insert(0, pjoin(here,'..','swig'))
package_data = {
'yap_ipython': ['prolog/*.*'],
'yap_kernel': ['resources/*.*']

View File

@@ -32,15 +32,15 @@ This is an handy alias to `ipython history trim --keep=0`
class HistoryTrim(BaseYAPApplication):
description = trim_hist_help
backup = Bool(False,
help="Keep the old history file as history.sqlite.<N>"
).tag(config=True)
keep = Int(1000,
help="Number of recent lines to keep in the database."
).tag(config=True)
flags = Dict(dict(
backup = ({'HistoryTrim' : {'backup' : True}},
backup.help
@@ -50,7 +50,7 @@ class HistoryTrim(BaseYAPApplication):
aliases=Dict(dict(
keep = 'HistoryTrim.keep'
))
def start(self):
profile_dir = self.profile_dir.location
hist_file = os.path.join(profile_dir, 'history.sqlite')
@@ -63,9 +63,9 @@ class HistoryTrim(BaseYAPApplication):
print("There are already at most %d entries in the history database." % self.keep)
print("Not doing anything. Use --keep= argument to keep fewer entries")
return
print("Trimming history to the most recent %d entries." % self.keep)
inputs.pop() # Remove the extra element we got to check the length.
inputs.reverse()
if inputs:
@@ -75,7 +75,7 @@ class HistoryTrim(BaseYAPApplication):
sessions = list(con.execute('SELECT session, start, end, num_cmds, remark FROM '
'sessions WHERE session >= ?', (first_session,)))
con.close()
# Create the new history database.
new_hist_file = os.path.join(profile_dir, 'history.sqlite.new')
i = 0
@@ -114,18 +114,18 @@ class HistoryTrim(BaseYAPApplication):
print("Backed up longer history file to", backup_hist_file)
else:
os.remove(hist_file)
os.rename(new_hist_file, hist_file)
class HistoryClear(HistoryTrim):
description = clear_hist_help
keep = Int(0,
help="Number of recent lines to keep in the database.")
force = Bool(False,
help="Don't prompt user for confirmation"
).tag(config=True)
flags = Dict(dict(
force = ({'HistoryClear' : {'force' : True}},
force.help),

View File

@@ -219,9 +219,9 @@ class ExecutionResult(object):
def raise_error(self):
"""Reraises error if `success` is `False`, otherwise does nothing"""
if self.error_before_exec is not None:
if self.error_before_exec:
raise self.error_before_exec
if self.error_in_exec is not None:
if self.error_in_exec:
raise self.error_in_exec
def __repr__(self):
@@ -2598,7 +2598,7 @@ class InteractiveShell(SingletonConfigurable):
with prepended_to_syspath(dname):
try:
for cell in get_cells():
result = self.run_cell(cell, silent=False , shell_futures=shell_futures)
result = self.run_cell(cell, silent=False, shell_futures=shell_futures)
if raise_exceptions:
result.raise_error()
elif not result.success:
@@ -2661,6 +2661,9 @@ class InteractiveShell(SingletonConfigurable):
-------
result : :class:`ExecutionResult`
"""
print("go")
result = None
try:
result = self._yrun_cell(
raw_cell, store_history, silent, shell_futures)
@@ -2668,6 +2671,7 @@ class InteractiveShell(SingletonConfigurable):
self.events.trigger('post_execute')
if not silent:
self.events.trigger('post_run_cell', result)
print("go", result)
return result
def _run_cell(self, raw_cell, store_history, silent, shell_futures):

View File

@@ -11,15 +11,15 @@
* -
*/
%% :- module( jupyter,
%% [jupyter_query/3,
%% errors/2,
%% ready/2,
%% completion/2,
%% ]
%% ).
% :- module( jupyter,
% [jupyter_query/3,
% errors/2,
% ready/2,
% completion/2,
% ]
%% ).
:- [library(hacks)].
:- reexport(library(yapi)).
:- use_module(library(lists)).
@@ -32,26 +32,24 @@ jupyter_query(Caller, Cell, Line ) :-
jupyter_cell(Caller, Cell, Line).
jupyter_cell(_Caller, Cell, _) :-
jupyter_consult(Cell),
jupyter_consult(Cell), %stack_dump,
fail.
jupyter_cell( _Caller, _, Line ) :-
blank( Line ),
!.
jupyter_cell( _Caller, _, [] ) :- !.
jupyter_cell( Caller, _, Line ) :-
gated_call(
enter_cell(call),
python_query( Caller, Line ),
Port,
enter_cell(Port)
).
Self := Caller.query,
python_query( Self, Line ).
jupyter_consult(Text) :-
blank( Text ),
!.
jupyter_consult(Cell) :-
open_mem_read_stream( Cell, Stream),
load_files(user:'jupyter cell',[stream(Stream)]).
% Name = 'Inp',
% stream_property(Stream, file_name(Name) ),
load_files(user:'jupyter cell',[stream(Stream)]), !.
%should load_files close?
blank(Text) :-
@@ -62,31 +60,18 @@ blankc(' ').
blankc('\n').
blankc('\t').
enter_cell(retry) :-
enter_cell(call).
enter_cell(call) :-
into_cell.
enter_cell(fail) :-
enter_cell(exit).
enter_cell(answer) :-
enter_cell(exit).
enter_cell(exception(_)) :-
enter_cell(exit).
enter_cell(external_exception(_)).
enter_cell(!).
enter_cell(exit) :-
nb_setval(jupyter_cell, off),
close( user_output).
into_cell :-
nb_setval(jupyter_cell, on),
open('/python/sys.input', read, _Input, [bom(false)]),
open('/python/sys.stdout', append, _Output, []),
open('/python/sys.stderr', append, _Error, []),
set_prolog_flag(user_input,_Output),
streams(false) :-
% close( user_input),
close( user_error ),
close( user_output ).
streams(true) :-
% open('/python/input', read, _Input, [alias(user_input),bom(false)]),
open('/python/sys.stdout', append, _Output, [alias(user_output)]),
open('/python/sys.stderr', append, _Error, [alias(user_error)]),
% set_prolog_flag(user_input,_Input),
set_prolog_flag(user_output,_Output),
set_prolog_flag(user_error,_Error).
set_prolog_flag(user_error,_Error).
completions(S, Self) :-
@@ -185,7 +170,7 @@ predicate(N,P,A) :-
cont(0, F, P, P0) :-
atom_concat( F, P, P0 ).
cont( _, F, P, PB ):-
atom_concat( [F, P, '('], PB ).
atom_concat( [F, P, '( )'], PB ).
ready(_Self, Line ) :-

View File

@@ -3,15 +3,14 @@ import sys
import abc
import math
import itertools
import trace
from typing import Iterator, List, Tuple, Iterable, Union
from traitlets import Bool, Enum, observe, Int
try:
from yap4py.yapi import Engine, Goal, EngineArgs, PrologTableIter
except:
print("Could not load _yap dll.")
from yap4py.yapi import *
from yap_ipython.core.completer import Completer, Completion
from yap_ipython.utils.strdispatch import StrDispatch
# import yap_ipython.core
@@ -32,12 +31,13 @@ bindvars = namedtuple('bindvars', 'list')
library = namedtuple('library', 'list')
v = namedtuple('_', 'slot')
load_files = namedtuple('load_files', 'file ofile args')
python_query= namedtuple('python_query', 'query_mgr string')
python_query = namedtuple('python_query', 'query_mgr string')
jupyter_query = namedtuple('jupyter_query', 'self text query')
enter_cell = namedtuple('enter_cell', 'self' )
exit_cell = namedtuple('exit_cell', 'self' )
completions = namedtuple('completions', 'txt self' )
errors = namedtuple('errors', 'self text' )
streams = namedtuple('streams', ' text' )
class YAPInputSplitter(InputSplitter):
@@ -100,6 +100,7 @@ class YAPInputSplitter(InputSplitter):
Python line."""
t = self.physical_line_transforms + \
[self.assemble_logical_lines] + self.logical_line_transforms
return t
def engine(self, engine):
self.yapeng = engine
@@ -107,11 +108,11 @@ class YAPInputSplitter(InputSplitter):
def validQuery(self, text, line=None):
"""Return whether a legal query
"""
if text == self.shell.os:
return True
if not line:
(_,line,_) = self.shell.prolog_cell(text)
line = line.strip().rstrip()
if not line:
return False
line = text.rstrip()
(line, _, _, _)=self.shell.clean_end(line)
self.errors = []
self.yapeng.mgoal(errors(self, line),"user")
return self.errors != []
@@ -496,9 +497,11 @@ class YAPCompleter(Completer):
"""
self.matches = []
prolog_res = self.shell.yapeng.mgoal(completions(text, self), "user")
if self.matches:
return text, self.matches
magic_res = self.magic_matches(text)
return text, magic_res
return text, self.matches+magic_res
@@ -509,8 +512,7 @@ class YAPRun:
self.shell = shell
self.yapeng = Engine()
self.yapeng.goal(use_module(library("jupyter")))
self.q = None
self.port = "call"
self.query = None
self.os = None
self.it = None
self.shell.yapeng = self.yapeng
@@ -521,41 +523,58 @@ class YAPRun:
"""
if not text:
return []
if text == self.os:
return self.errors
self.errors=[]
(text,_,_,_) = self.clean_end(text)
self.yapeng.mgoal(errors(self,text),"user")
return self.errors
def jupyter_query(self, s):
#
# construct a self.query from a one-line string
# self.q is opaque to Python
program,query,mx = self.prolog_cell(s)
Found = False
if query != self.os:
self.os = None
self.iterations = 0
pg = jupyter_query( self, program, query)
self.it = Goal( self.yapeng, pg)
else:
mx += self.iterations
self.os = s
for answ in self.it:
found = True
self.bindings += [answ]
self.iterations += 1
if mx == self.iterations:
return True, self.bindings
port = self.it.port
if port == "exit":
self.q = None
self.os = None
return True,self.bindings
if port == "fail":
self.q = none
self.os = None
if self.bindings_message:
return True,self.bindings
# construct a self.queryuery from a one-line string
# self.query is opaque to Python
try:
program,query,stop,howmany = self.prolog_cell(s)
found = False
if s != self.os:
self.os = s
self.iterations = 0
self.bindings = []
pg = jupyter_query( self, program, query)
self.query = self.yapeng.query( pg)
self.query.port = "call"
else:
self.query.port = "retry"
self.os = s
howmany += self.iterations
while self.query.next():
answer = self.query.answer
found = True
self.bindings += [answer]
self.iterations += 1
if stop and howmany == self.iterations:
self.query.close()
self.query = None
self.os = None
return True, self.bindings
if self.query.port == "exit":
self.query.close()
self.query = None
self.os = None
sys.stderr.writeln('Done, with', self.bindings)
return True,self.bindings
self.query.close()
self.query = None
self.os = None
if self.bindings:
sys.stderr.write('Done, with', self.bindings, '\n')
else:
sys.stderr.write('Fail\n')
return True,{}
except Exception as e:
has_raised = True
self.result.result = False
def _yrun_cell(self, raw_cell, store_history=True, silent=False,
@@ -573,7 +592,7 @@ class YAPRun:
IPython's machinery, this
should be set to False.
silent : bool
v If True, avoid side-effects, such as implicit displayhooks and
If True, avoid side-effects, such as implicit displayhooks and
and logging. silent=True forces store_history=False.
shell_futures : bool
If True, the code will share future statements with the interactive
@@ -704,12 +723,31 @@ v If True, avoid side-effects, such as implicit displayhooks and
has_raised = False
try:
state = None
self.shell.bindings = dict = {}
if cell.strip():
state = self.jupyter_query( cell )
self.bindings = dicts = []
if cell.strip('\n \t'):
#create a Trace object, telling it what to ignore, and whether to
# do tracing or line-counting or both.
tracer = trace.Trace(
#ignoredirs=[sys.prefix, sys.exec_prefix],
trace=1,
count=0)
def f(self, cell):
self.jupyter_query( cell )
# run the new command using the given tracer
#
try:
self.yapeng.mgoal(streams(True),"user")
#state = tracer.runfunc(f,self,cell)
state = self.jupyter_query( cell )
self.yapeng.mgoal(streams(False),"user")
except Exception as e:
has_raised = True
self.yapeng.mgoal(streams("off"),"user")
if state:
self.shell.last_execution_succeeded = True
self.result.result = (True, dict)
self.result.result = (True, dicts)
else:
self.shell.last_execution_succeeded = True
self.result.result = (True, {})
@@ -735,50 +773,49 @@ v If True, avoid side-effects, such as implicit displayhooks and
return self.result
def clean_end(self,s):
"""
Look at the query suffix and return
- whatever is left
- how much was taken
- whether to stop
- when to stop
"""
i = -1
try:
its = 0
j = 1
while s[i].isdigit():
ch = s[i]
its += j * (ord(ch) - ord('0'))
i-=1
j *= 10;
if s[i] == ';':
if j > 1 or its != 0:
return s[:i], 0 - i, True, its
return s[:i], 0 - i, False, 0
# one solution, stop
return s, 0, True, 1
except:
return s,0, False, 0
def prolog_cell(self,s):
"""
Trasform a text into program+query. A query is the
last line if the last line is non-empty and does not terminate
on a dot. You can also finish with
- `*`: you request all solutions
- '^': you want to check if there is an answer
- '?'[N]: you want an answer; optionally you want N answers
- `;`: you request all solutions
- ';'[N]: you want an answer; optionally you want N answers
If the line terminates on a `*/` or starts on a `%` we assume the line
is a comment.
"""
s = s.rstrip()
take = 0
its = 0
s0 = ''
for c in s:
if c == '\n' or c.isspace():
s0 += c
break
sf = ''
for c in reversed(s):
if c == '\n' or c.isspace():
sf += c
break
[program,x,query] = s.rpartition('\n')
if query == '':
query = program
while take < len(query):
take += 1
ch = query[-take]
if ch.isdigit():
its = its*10 + ord(ch) - ord('0')
elif ch == '*' and take == 1:
return program, query[:-take], -1
elif ch == '.' and take == 1:
return s, '', 1
elif ch == '/' and query[-2] == '*' and take == 1:
return program, query[:-take], 1
elif ch == '^' and take == 1:
return program, query[:-take], 1
elif ch == '?':
return program, query[:-take], its+1
else:
return program, query, 1
return s, '', 1
s0 = s.rstrip(' \n\t\i')
[program,x,query] = s0.rpartition('\n')
if query[-1] == '.':
return s,'',False,0
(query, _,loop, sols) = self.clean_end(query)
return (program, query, loop, sols)