txl-kernel 0.1.24__tar.gz → 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- txl_kernel-0.2.1/.gitignore +3 -0
- {txl_kernel-0.1.24 → txl_kernel-0.2.1}/PKG-INFO +3 -2
- {txl_kernel-0.1.24 → txl_kernel-0.2.1}/pyproject.toml +2 -1
- txl_kernel-0.2.1/txl_kernel/__init__.py +1 -0
- {txl_kernel-0.1.24 → txl_kernel-0.2.1}/txl_kernel/driver.py +77 -80
- txl_kernel-0.1.24/.gitignore +0 -1
- txl_kernel-0.1.24/txl_kernel/__init__.py +0 -1
- {txl_kernel-0.1.24 → txl_kernel-0.2.1}/LICENSE.txt +0 -0
- {txl_kernel-0.1.24 → txl_kernel-0.2.1}/README.md +0 -0
- {txl_kernel-0.1.24 → txl_kernel-0.2.1}/txl_kernel/message.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: txl_kernel
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: TXL plugin for a kernel driver
|
|
5
5
|
Project-URL: Source, https://github.com/davidbrochart/jpterm/plugins/kernel
|
|
6
6
|
Author-email: David Brochart <david.brochart@gmail.com>
|
|
@@ -10,12 +10,13 @@ Classifier: Development Status :: 4 - Beta
|
|
|
10
10
|
Classifier: Programming Language :: Python
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
14
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
14
15
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
15
16
|
Requires-Python: >=3.10
|
|
17
|
+
Requires-Dist: pycrdt<0.8.0,>=0.7.2
|
|
16
18
|
Requires-Dist: python-dateutil>=2.8.2
|
|
17
19
|
Requires-Dist: txl
|
|
18
|
-
Requires-Dist: y-py<1,>=0.6.0
|
|
19
20
|
Description-Content-Type: text/markdown
|
|
20
21
|
|
|
21
22
|
# TXL plugin for a kernel driver
|
|
@@ -17,13 +17,14 @@ classifiers = [
|
|
|
17
17
|
"Programming Language :: Python",
|
|
18
18
|
"Programming Language :: Python :: 3.10",
|
|
19
19
|
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
20
21
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
21
22
|
"Programming Language :: Python :: Implementation :: PyPy",
|
|
22
23
|
]
|
|
23
24
|
dependencies = [
|
|
24
25
|
"txl",
|
|
25
26
|
"python-dateutil >=2.8.2",
|
|
26
|
-
"
|
|
27
|
+
"pycrdt >=0.7.2,<0.8.0",
|
|
27
28
|
]
|
|
28
29
|
dynamic = ["version"]
|
|
29
30
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.1"
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import time
|
|
3
|
-
from typing import Dict
|
|
3
|
+
from typing import Dict
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
from pycrdt import Array, Map
|
|
6
6
|
|
|
7
7
|
from .message import create_message
|
|
8
8
|
|
|
@@ -34,7 +34,7 @@ class Comm:
|
|
|
34
34
|
class KernelMixin:
|
|
35
35
|
def __init__(self):
|
|
36
36
|
self.msg_cnt = 0
|
|
37
|
-
self.execute_requests: Dict[str, Dict[str,
|
|
37
|
+
self.execute_requests: Dict[str, Dict[str, asyncio.Queue]] = {}
|
|
38
38
|
self.recv_queue = asyncio.Queue()
|
|
39
39
|
self.started = asyncio.Event()
|
|
40
40
|
asyncio.create_task(self.recv())
|
|
@@ -55,18 +55,20 @@ class KernelMixin:
|
|
|
55
55
|
await self.send_message(msg, self.shell_channel, change_date_to_str=True)
|
|
56
56
|
msg_id = msg["header"]["msg_id"]
|
|
57
57
|
self.execute_requests[msg_id] = {
|
|
58
|
-
"iopub":
|
|
59
|
-
"shell":
|
|
58
|
+
"iopub": asyncio.Queue(),
|
|
59
|
+
"shell": asyncio.Queue(),
|
|
60
60
|
}
|
|
61
61
|
try:
|
|
62
|
-
msg = await asyncio.wait_for(
|
|
62
|
+
msg = await asyncio.wait_for(
|
|
63
|
+
self.execute_requests[msg_id]["shell"].get(), new_timeout
|
|
64
|
+
)
|
|
63
65
|
except asyncio.TimeoutError:
|
|
64
66
|
del self.execute_requests[msg_id]
|
|
65
67
|
error_message = f"Kernel didn't respond in {timeout} seconds"
|
|
66
68
|
raise RuntimeError(error_message)
|
|
67
69
|
if msg["header"]["msg_type"] == "kernel_info_reply":
|
|
68
70
|
try:
|
|
69
|
-
msg = await asyncio.wait_for(self.execute_requests[msg_id]["iopub"]
|
|
71
|
+
msg = await asyncio.wait_for(self.execute_requests[msg_id]["iopub"].get(), 0.2)
|
|
70
72
|
except asyncio.TimeoutError:
|
|
71
73
|
pass
|
|
72
74
|
else:
|
|
@@ -91,21 +93,11 @@ class KernelMixin:
|
|
|
91
93
|
if msg_id in self.execute_requests:
|
|
92
94
|
# msg["header"] = str_to_date(msg["header"])
|
|
93
95
|
# msg["parent_header"] = str_to_date(msg["parent_header"])
|
|
94
|
-
|
|
95
|
-
if future_msgs:
|
|
96
|
-
fut = future_msgs[-1]
|
|
97
|
-
if fut.done():
|
|
98
|
-
fut = asyncio.Future()
|
|
99
|
-
future_msgs.append(fut)
|
|
100
|
-
else:
|
|
101
|
-
fut = asyncio.Future()
|
|
102
|
-
future_msgs.append(fut)
|
|
103
|
-
fut.set_result(msg)
|
|
96
|
+
self.execute_requests[msg_id][channel].put_nowait(msg)
|
|
104
97
|
|
|
105
98
|
async def execute(
|
|
106
99
|
self,
|
|
107
|
-
|
|
108
|
-
ycell: Y.YMap,
|
|
100
|
+
ycell: Map,
|
|
109
101
|
timeout: float = float("inf"),
|
|
110
102
|
msg_id: str = "",
|
|
111
103
|
wait_for_executed: bool = True,
|
|
@@ -113,6 +105,7 @@ class KernelMixin:
|
|
|
113
105
|
await self.started.wait()
|
|
114
106
|
if ycell["cell_type"] != "code":
|
|
115
107
|
return
|
|
108
|
+
ycell["outputs"].clear()
|
|
116
109
|
code = str(ycell["source"])
|
|
117
110
|
content = {"code": code, "silent": False}
|
|
118
111
|
msg = create_message(
|
|
@@ -127,77 +120,81 @@ class KernelMixin:
|
|
|
127
120
|
msg_id = msg["header"]["msg_id"]
|
|
128
121
|
self.msg_cnt += 1
|
|
129
122
|
self.execute_requests[msg_id] = {
|
|
130
|
-
"iopub":
|
|
131
|
-
"shell":
|
|
123
|
+
"iopub": asyncio.Queue(),
|
|
124
|
+
"shell": asyncio.Queue(),
|
|
132
125
|
}
|
|
133
126
|
await self.send_message(msg, self.shell_channel, change_date_to_str=True)
|
|
134
127
|
if wait_for_executed:
|
|
135
128
|
deadline = time.monotonic() + timeout
|
|
129
|
+
while True:
|
|
130
|
+
try:
|
|
131
|
+
msg = await asyncio.wait_for(
|
|
132
|
+
self.execute_requests[msg_id]["iopub"].get(),
|
|
133
|
+
deadline_to_timeout(deadline),
|
|
134
|
+
)
|
|
135
|
+
except asyncio.TimeoutError:
|
|
136
|
+
del self.execute_requests[msg_id]
|
|
137
|
+
error_message = f"Kernel didn't respond in {timeout} seconds"
|
|
138
|
+
raise RuntimeError(error_message)
|
|
139
|
+
await self._handle_outputs(ycell["outputs"], msg)
|
|
140
|
+
if (
|
|
141
|
+
(msg["header"]["msg_type"] == "status"
|
|
142
|
+
and msg["content"]["execution_state"] == "idle")
|
|
143
|
+
):
|
|
144
|
+
break
|
|
136
145
|
try:
|
|
137
|
-
await asyncio.wait_for(
|
|
138
|
-
self.execute_requests[msg_id]["
|
|
139
|
-
deadline_to_timeout(deadline),
|
|
140
|
-
)
|
|
141
|
-
except asyncio.TimeoutError:
|
|
142
|
-
del self.execute_requests[msg_id]
|
|
143
|
-
error_message = f"Kernel didn't respond in {timeout} seconds"
|
|
144
|
-
raise RuntimeError(error_message)
|
|
145
|
-
await self._handle_outputs(ydoc, ycell, self.execute_requests[msg_id]["iopub"])
|
|
146
|
-
try:
|
|
147
|
-
await asyncio.wait_for(
|
|
148
|
-
self.execute_requests[msg_id]["shell"][0],
|
|
146
|
+
msg = await asyncio.wait_for(
|
|
147
|
+
self.execute_requests[msg_id]["shell"].get(),
|
|
149
148
|
deadline_to_timeout(deadline),
|
|
150
149
|
)
|
|
151
150
|
except asyncio.TimeoutError:
|
|
152
151
|
del self.execute_requests[msg_id]
|
|
153
152
|
error_message = f"Kernel didn't respond in {timeout} seconds"
|
|
154
153
|
raise RuntimeError(error_message)
|
|
155
|
-
|
|
156
|
-
with ydoc.begin_transaction() as txn:
|
|
157
|
-
ycell.set(txn, "execution_count", msg["content"]["execution_count"])
|
|
154
|
+
ycell["execution_count"] = msg["content"]["execution_count"]
|
|
158
155
|
del self.execute_requests[msg_id]
|
|
159
156
|
|
|
160
|
-
async def _handle_outputs(
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
157
|
+
async def _handle_outputs(self, outputs: Array, msg):
|
|
158
|
+
msg_type = msg["header"]["msg_type"]
|
|
159
|
+
content = msg["content"]
|
|
160
|
+
if msg_type == "stream":
|
|
161
|
+
with outputs.doc.transaction():
|
|
162
|
+
# TODO: uncomment when changes are made in jupyter-ydoc
|
|
163
|
+
if (not outputs) or (outputs[-1]["name"] != content["name"]): # type: ignore
|
|
164
|
+
outputs.append(
|
|
165
|
+
#Map(
|
|
166
|
+
# {
|
|
167
|
+
# "name": content["name"],
|
|
168
|
+
# "output_type": msg_type,
|
|
169
|
+
# "text": Array([content["text"]]),
|
|
170
|
+
# }
|
|
171
|
+
#)
|
|
172
|
+
{
|
|
173
|
+
"name": content["name"],
|
|
174
|
+
"output_type": msg_type,
|
|
175
|
+
"text": [content["text"]],
|
|
176
|
+
}
|
|
177
|
+
)
|
|
178
|
+
else:
|
|
179
|
+
#outputs[-1]["text"].append(content["text"]) # type: ignore
|
|
180
|
+
last_output = outputs[-1]
|
|
181
|
+
last_output["text"].append(content["text"]) # type: ignore
|
|
182
|
+
outputs[-1] = last_output
|
|
183
|
+
elif msg_type in ("display_data", "execute_result"):
|
|
184
|
+
outputs.append(
|
|
185
|
+
{
|
|
186
|
+
"data": content["data"],
|
|
187
|
+
"execution_count": content["execution_count"],
|
|
188
|
+
"metadata": {},
|
|
189
|
+
"output_type": msg_type,
|
|
190
|
+
}
|
|
191
|
+
)
|
|
192
|
+
elif msg_type == "error":
|
|
193
|
+
outputs.append(
|
|
194
|
+
{
|
|
195
|
+
"ename": content["ename"],
|
|
196
|
+
"evalue": content["evalue"],
|
|
197
|
+
"output_type": "error",
|
|
198
|
+
"traceback": content["traceback"],
|
|
199
|
+
}
|
|
200
|
+
)
|
txl_kernel-0.1.24/.gitignore
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__pycache__
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.1.24"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|