robotcode-jsonrpc2 2.6.2__tar.gz → 2.8.0__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.
@@ -279,6 +279,9 @@ dist
279
279
  # vuepress build output
280
280
  .vuepress/dist
281
281
 
282
+ # Astro (documentation site)
283
+ docs/.astro/
284
+
282
285
  # Serverless directories
283
286
  .serverless/
284
287
 
@@ -339,7 +342,7 @@ bundled/libs
339
342
  # .agents
340
343
  .agents/
341
344
  skills-lock.json
342
- .claude
345
+ #.claude
343
346
 
344
347
  # sarif files
345
348
  /**/*.sarif.json
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: robotcode-jsonrpc2
3
- Version: 2.6.2
3
+ Version: 2.8.0
4
4
  Summary: JSONRPC Server for RobotCode
5
5
  Project-URL: Homepage, https://robotcode.io
6
6
  Project-URL: Donate, https://opencollective.com/robotcode
@@ -20,12 +20,13 @@ Classifier: Programming Language :: Python :: 3.11
20
20
  Classifier: Programming Language :: Python :: 3.12
21
21
  Classifier: Programming Language :: Python :: 3.13
22
22
  Classifier: Programming Language :: Python :: 3.14
23
+ Classifier: Programming Language :: Python :: 3.15
23
24
  Classifier: Programming Language :: Python :: Implementation :: CPython
24
25
  Classifier: Programming Language :: Python :: Implementation :: PyPy
25
26
  Classifier: Topic :: Utilities
26
27
  Classifier: Typing :: Typed
27
28
  Requires-Python: >=3.10
28
- Requires-Dist: robotcode-core==2.6.2
29
+ Requires-Dist: robotcode-core==2.8.0
29
30
  Description-Content-Type: text/markdown
30
31
 
31
32
  # robotcode-jsonrpc2
@@ -18,6 +18,7 @@ classifiers = [
18
18
  "Programming Language :: Python :: 3.12",
19
19
  "Programming Language :: Python :: 3.13",
20
20
  "Programming Language :: Python :: 3.14",
21
+ "Programming Language :: Python :: 3.15",
21
22
  "Programming Language :: Python :: Implementation :: CPython",
22
23
  "Programming Language :: Python :: Implementation :: PyPy",
23
24
  "Operating System :: OS Independent",
@@ -26,7 +27,7 @@ classifiers = [
26
27
  "Framework :: Robot Framework",
27
28
  "Framework :: Robot Framework :: Tool",
28
29
  ]
29
- dependencies = ["robotcode-core==2.6.2"]
30
+ dependencies = ["robotcode-core==2.8.0"]
30
31
  dynamic = ["version"]
31
32
 
32
33
  [project.urls]
@@ -0,0 +1 @@
1
+ __version__ = "2.8.0"
@@ -1,11 +1,11 @@
1
1
  import abc
2
2
  import asyncio
3
- import io
4
3
  import logging
4
+ import os
5
5
  import sys
6
6
  import threading
7
7
  import weakref
8
- from concurrent.futures import ThreadPoolExecutor
8
+ from concurrent.futures import Future
9
9
  from types import TracebackType
10
10
  from typing import (
11
11
  Any,
@@ -277,8 +277,6 @@ class JsonRPCServer(Generic[TProtocol], abc.ABC):
277
277
  @abc.abstractmethod
278
278
  def create_protocol(self) -> TProtocol: ...
279
279
 
280
- stdio_executor: Optional[ThreadPoolExecutor] = None
281
-
282
280
  @_logger.call
283
281
  def start_stdio(self) -> None:
284
282
  self.mode = ServerMode.STDIO
@@ -293,18 +291,29 @@ class JsonRPCServer(Generic[TProtocol], abc.ABC):
293
291
  async def aio_readline(rfile: BinaryIO, protocol: asyncio.Protocol) -> None:
294
292
  protocol.connection_made(transport)
295
293
 
296
- def run() -> None:
297
- while not stop_event.is_set() and not rfile.closed:
298
- if cast(io.BufferedReader, rfile).peek(1):
299
- data = cast(io.BufferedReader, rfile).read1(10000)
300
-
301
- self.loop.call_soon_threadsafe(protocol.data_received, data)
302
- else:
303
- # no data available, wait a bit if we are not closing
304
- stop_event.wait(0.01)
294
+ done: "Future[None]" = Future()
305
295
 
306
- with ThreadPoolExecutor(max_workers=1, thread_name_prefix="aio_readline") as stdio_executor:
307
- await asyncio.wrap_future(stdio_executor.submit(run))
296
+ def run() -> None:
297
+ # Reads the file descriptor itself: a read that blocks in the buffered
298
+ # reader holds its lock, which the interpreter needs when it shuts down.
299
+ fd = rfile.fileno()
300
+ try:
301
+ while not stop_event.is_set() and not rfile.closed:
302
+ data = os.read(fd, 10000)
303
+ if data:
304
+ self.loop.call_soon_threadsafe(protocol.data_received, data)
305
+ else:
306
+ # end of input, wait a bit if we are not closing
307
+ stop_event.wait(0.01)
308
+ except BaseException as e:
309
+ done.set_exception(e)
310
+ else:
311
+ done.set_result(None)
312
+
313
+ # A daemon thread: a read that blocks on a pipe the client keeps open
314
+ # must not keep the process alive once everything else has ended.
315
+ threading.Thread(target=run, name="aio_readline", daemon=True).start()
316
+ await asyncio.wrap_future(done)
308
317
 
309
318
  self.loop.run_until_complete(aio_readline(transport.rfile, protocol))
310
319
 
@@ -1 +0,0 @@
1
- __version__ = "2.6.2"