Created
April 12, 2024 14:55
-
-
Save kamahen/cc466d546f5cfef9b25f1201810a8b26 to your computer and use it in GitHub Desktop.
WIP context manager for swipy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ git diff stash@{1} | |
diff --git a/janus.doc b/janus.doc | |
index fafbae8..dc1836d 100644 | |
--- a/janus.doc | |
+++ b/janus.doc | |
@@ -431,7 +431,7 @@ Loading janus into Python is realized using the Python package | |
\const{janus-swi}, which defines the module \const{janus_swi}. We do | |
not call this simply \const{janus} to allow coexistence of Janus for | |
multiple Prolog implementations. Unless you plan to interact with | |
-multiple Prolog systems in the same session, we advise importing janus | |
+multiple Prolog systems in the same session, we advice to import janus | |
for SWI-Prolog as below. | |
\begin{code} | |
@@ -564,8 +564,8 @@ though and thus is either \const{True} or an instance of the class | |
\begin{code} | |
import janus_swi as janus | |
-def printRange(fr, to): | |
- for d in janus.query("between(F,T,X)", {"F":fr, "T":to}): | |
+def printRange(from, to): | |
+ for d in janus.query("between(F,T,X)", {"F":from, "T":to}) | |
print(d["X"]) | |
\end{code} | |
diff --git a/janus/janus.py b/janus/janus.py | |
index 9eb72d3..a276290 100644 | |
--- a/janus/janus.py | |
+++ b/janus/janus.py | |
@@ -202,23 +202,21 @@ class query: | |
return self | |
def __next__(self): | |
"""Implement iter protocol. Returns a dict as janus.query_once()""" | |
- rc = self.next() | |
- if rc is None: | |
+ rc = _swipl.next_solution(self.state) | |
+ if rc == False or rc["truth"] == False: | |
raise StopIteration() | |
- return rc | |
- def __enter__(self): | |
- """Implement context manager protocol""" | |
- return self | |
- def __exit__(self, type, value, tb): | |
- """Implement context manager protocol""" | |
- self.close() | |
+ else: | |
+ return rc | |
def __del__(self): | |
"""Close the Prolog query""" | |
- self.close() | |
+ _swipl.close_query(self.state) | |
def next(self): | |
"""Allow for explicit enumeration, Returns None or a dict""" | |
rc = _swipl.next_solution(self.state) | |
- return None if rc == False or rc["truth"] == False else rc | |
+ if rc == False or rc["truth"] == False: | |
+ return None | |
+ else: | |
+ return rc | |
def close(self): | |
"""Explicitly close the query.""" | |
_swipl.close_query(self.state) | |
@@ -466,7 +464,7 @@ class Term: | |
in Python. Instances are created if data is passed to Python as | |
`prolog(Term)`. Upon transforming the data back to Prolog, the | |
interface recovers a copy of the original Prolog terms. | |
- | |
+ | |
The user should never create instances of this explicitly. | |
""" | |
diff --git a/test_janus.pl b/test_janus.pl | |
index 4897efe..aa1fd69 100644 | |
--- a/test_janus.pl | |
+++ b/test_janus.pl | |
@@ -347,10 +347,8 @@ test(py_double, Tuples == [1-1,2-1,3-1, | |
1-3,2-3,3-3, | |
1-4,2-4,3-4]) :- | |
py_call(demo:double_iter(3,4), Tuples). | |
-% test(invalid_nesting, X == @true) :- | |
-% py_call(demo:test_invalid_nesting(), X). | |
test(invalid_nesting, X == @true) :- | |
- py_call(demo:test_invalid_nesting2(), X). | |
+ py_call(demo:test_invalid_nesting(), X). | |
:- if((py_call(sys:hexversion, V), V >= 0x03080000)). | |
test(while, X == [1,2,3]) :- | |
py_call(while:test_while(), X). | |
diff --git a/tests/demo.py b/tests/demo.py | |
index 153b07d..587ee04 100644 | |
--- a/tests/demo.py | |
+++ b/tests/demo.py | |
@@ -73,48 +73,30 @@ def kwd_all(a=1, b=2, c=3): | |
def abort_iter(n): | |
sum=0 | |
- with query("between(1,M,X)", {"M":n}) as q: | |
- for d in q: | |
- sum += d["X"] | |
- if sum > 10000: | |
- break; | |
+ for d in query("between(1,M,X)", {"M":n}): | |
+ sum += d["X"] | |
+ if sum > 10000: | |
+ break; | |
return sum; | |
def double_iter(w,h): | |
tuples=[] | |
- with query("between(1,M,Y)", {"M":h}) as q1: | |
- for yd in q1: | |
- with query("between(1,M,X)", {"M":w}) as q2: | |
- tuples += [(xd['X'],yd['Y']) for xd in q2] | |
+ for yd in query("between(1,M,Y)", {"M":h}): | |
+ for xd in query("between(1,M,X)", {"M":w}): | |
+ tuples.append((xd['X'],yd['Y'])) | |
return tuples | |
def test_invalid_nesting(): | |
- rc = False | |
q1 = query("between(1,3,X)") | |
q2 = query("between(1,3,Y)") | |
q2.next() | |
try: | |
q1.next() | |
- except PrologError: | |
+ except: | |
q2.close() | |
- rc = True | |
q1.next() | |
q1.close() | |
- return False | |
- | |
-def test_invalid_nesting2(): | |
- with (query("between(1,3,X)") as q1, | |
- query("between(1,3,Y)") as q2): | |
- q2.next() | |
- try: | |
- q1.next() | |
- except PrologError as exc_p: | |
- print('*** IN PROLOG_ERROR\n') | |
- return '***' + str(type(exc_p)) | |
- except Exception as exc: | |
- print('*** IN EXCEPTION\n') | |
- return repr(exc) | |
- return False | |
+ return True | |
# Test using generators as custom iterators. | |
diff --git a/tests/threads.py b/tests/threads.py | |
index ecee2d3..2eb7bea 100644 | |
--- a/tests/threads.py | |
+++ b/tests/threads.py | |
@@ -7,7 +7,7 @@ def one(): | |
print("Starting one") | |
plone() | |
-def plone(): | |
+def plone(): | |
x = janus.query_once(""" | |
thread_self(_Me), | |
thread_property(_Me, id(Me)), | |
diff --git a/tests/while.py b/tests/while.py | |
index 930b9b4..870e79c 100644 | |
--- a/tests/while.py | |
+++ b/tests/while.py | |
@@ -4,7 +4,8 @@ from janus import * | |
def test_while(): | |
list=[] | |
- with query("between(1,3,X)") as q: | |
- while ( s := q.next() ): | |
- list.append(s['X']) | |
+ q = query("between(1,3,X)") | |
+ while ( s := q.next() ): | |
+ list.append(s['X']) | |
+ q.close() | |
return list | |
[peter@penguin swipy (context-manager)]$ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment