jsonrpcserver 5.1.0__tar.gz → 5.2.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.
Files changed (110) hide show
  1. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/CHANGELOG.md +18 -0
  2. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/PKG-INFO +1 -1
  3. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/jsonrpcserver/__init__.py +1 -1
  4. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/jsonrpcserver/async_dispatcher.py +2 -0
  5. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/jsonrpcserver/dispatcher.py +13 -0
  6. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/jsonrpcserver/main.py +39 -2
  7. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/jsonrpcserver/server.py +17 -5
  8. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tests/test_batch_limit.py +3 -1
  9. jsonrpcserver-5.2.0/tests/test_future_warnings.py +81 -0
  10. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tests/test_robustness.py +4 -1
  11. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tests/test_server.py +3 -2
  12. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/CODE_OF_CONDUCT.md +0 -0
  13. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/CONTRIBUTING.md +0 -0
  14. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/LICENSE +0 -0
  15. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/README.md +0 -0
  16. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/RELEASING.md +0 -0
  17. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/SECURITY.md +0 -0
  18. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/assets/a11y.js +0 -0
  19. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/assets/apple-touch-icon.png +0 -0
  20. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/assets/copy-without-prompts.js +0 -0
  21. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/assets/extra.css +0 -0
  22. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/assets/favicon.png +0 -0
  23. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/assets/logo.png +0 -0
  24. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/assets/social-card.png +0 -0
  25. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/async.md +0 -0
  26. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/batches.md +0 -0
  27. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/changelog.md +0 -0
  28. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/context.md +0 -0
  29. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/contributing.md +0 -0
  30. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/dispatch.md +0 -0
  31. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/errors.md +0 -0
  32. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/examples/aiohttp_server.py +0 -0
  33. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/examples/check_examples.py +0 -0
  34. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/examples/django_server.py +0 -0
  35. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/examples/fastapi_server.py +0 -0
  36. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/examples/flask_server.py +0 -0
  37. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/examples/http_server.py +0 -0
  38. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/examples/quickstart.py +0 -0
  39. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/examples/sanic_server.py +0 -0
  40. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/examples/socketio_server.py +0 -0
  41. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/examples/tornado_server.py +0 -0
  42. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/examples/websockets_server.py +0 -0
  43. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/examples/werkzeug_server.py +0 -0
  44. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/examples/zeromq_async_server.py +0 -0
  45. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/examples/zeromq_server.py +0 -0
  46. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/examples.md +0 -0
  47. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/faq.md +0 -0
  48. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/frameworks/aiohttp.md +0 -0
  49. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/frameworks/django.md +0 -0
  50. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/frameworks/fastapi.md +0 -0
  51. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/frameworks/flask.md +0 -0
  52. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/frameworks/http-server.md +0 -0
  53. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/frameworks/sanic.md +0 -0
  54. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/frameworks/socketio.md +0 -0
  55. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/frameworks/tornado.md +0 -0
  56. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/frameworks/websockets.md +0 -0
  57. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/frameworks/werkzeug.md +0 -0
  58. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/frameworks/zeromq.md +0 -0
  59. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/index.md +0 -0
  60. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/license.md +0 -0
  61. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/methods.md +0 -0
  62. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/migration.md +0 -0
  63. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/reference.md +0 -0
  64. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/roadmap.md +0 -0
  65. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/security-policy.md +0 -0
  66. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/security.md +0 -0
  67. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/testing.md +0 -0
  68. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/threads.md +0 -0
  69. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/typing.md +0 -0
  70. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/docs/validation.md +0 -0
  71. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/jsonrpcserver/async_main.py +0 -0
  72. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/jsonrpcserver/codes.py +0 -0
  73. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/jsonrpcserver/exceptions.py +0 -0
  74. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/jsonrpcserver/methods.py +0 -0
  75. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/jsonrpcserver/py.typed +0 -0
  76. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/jsonrpcserver/request-schema.json +0 -0
  77. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/jsonrpcserver/request.py +0 -0
  78. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/jsonrpcserver/response.py +0 -0
  79. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/jsonrpcserver/result.py +0 -0
  80. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/jsonrpcserver/sentinels.py +0 -0
  81. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/jsonrpcserver/utils.py +0 -0
  82. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/mkdocs.yml +0 -0
  83. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/overrides/404.html +0 -0
  84. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/overrides/main.html +0 -0
  85. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/pyproject.toml +0 -0
  86. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/requirements/build.txt +0 -0
  87. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/requirements/docs-constraints.txt +0 -0
  88. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/requirements/docs.txt +0 -0
  89. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/requirements/examples.txt +0 -0
  90. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/requirements/lint.txt +0 -0
  91. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/requirements/site.txt +0 -0
  92. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/requirements/test.txt +0 -0
  93. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tests/__init__.py +0 -0
  94. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tests/doc_examples.py +0 -0
  95. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tests/test_async_dispatcher.py +0 -0
  96. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tests/test_async_main.py +0 -0
  97. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tests/test_dispatcher.py +0 -0
  98. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tests/test_docs.py +0 -0
  99. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tests/test_docstrings.py +0 -0
  100. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tests/test_main.py +0 -0
  101. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tests/test_methods.py +0 -0
  102. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tests/test_request.py +0 -0
  103. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tests/test_response.py +0 -0
  104. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tests/test_result.py +0 -0
  105. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tests/test_sentinels.py +0 -0
  106. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tests/test_threading.py +0 -0
  107. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tests/test_typing.py +0 -0
  108. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tests/test_version.py +0 -0
  109. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tests/test_warnings.py +0 -0
  110. {jsonrpcserver-5.1.0 → jsonrpcserver-5.2.0}/tox.ini +0 -0
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.2.0 (2026-11-06)
4
+
5
+ Warnings about what 6.0 changes, so an upgrade doesn't surprise you. Nothing
6
+ else changes. Each is a `FutureWarning`, which Python shows by default.
7
+
8
+ - `serve()` without a host warns. From 6.0 it listens on localhost only.
9
+ `serve("", port)` keeps every network interface, quietly.
10
+ - A request with `NaN`, `Infinity`, `-Infinity` or a number too big for a float
11
+ warns. 6.0 rejects them with a Parse error. `deserializer=json.loads` accepts
12
+ them quietly. `dispatch_to_response` now uses the same default deserializer
13
+ as the other dispatch functions.
14
+ - A batch of more than 100 requests without `max_batch_size` warns. 6.0 limits
15
+ batches to 100 by default. Passing `max_batch_size` turns the warning off.
16
+
17
+ The [6.0 plan](https://github.com/bensynapse/jsonrpcserver/blob/main/plans/6.0.md)
18
+ lists everything else that changes, such as results and responses without
19
+ oslash.
20
+
3
21
  ## 5.1.0 (2026-11-06)
4
22
 
5
23
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: jsonrpcserver
3
- Version: 5.1.0
3
+ Version: 5.2.0
4
4
  Summary: Process incoming JSON-RPC 2.0 requests in Python
5
5
  Keywords: json-rpc,jsonrpc,json-rpc-2.0,rpc,server
6
6
  Author-email: Beau Barker <beau@explodinglabs.com>
@@ -38,5 +38,5 @@ from .methods import method
38
38
  from .result import Error, InvalidParams, Result, Success
39
39
  from .server import serve
40
40
 
41
- __version__ = "5.1.0"
41
+ __version__ = "5.2.0"
42
42
  """The version of jsonrpcserver, as a string. Added in 5.0.10."""
@@ -28,6 +28,7 @@ from .dispatcher import (
28
28
  to_result,
29
29
  validate_args,
30
30
  validate_request,
31
+ warn_if_over_6_0_batch_limit,
31
32
  )
32
33
  from .exceptions import JsonRpcError
33
34
  from .methods import AnyMethod, MethodsArgument
@@ -161,6 +162,7 @@ async def dispatch_to_response_pure(
161
162
  return post_process(Left(parsed._error))
162
163
  deserialized = unwrap(parsed)
163
164
  if isinstance(deserialized, list) and deserialized:
165
+ warn_if_over_6_0_batch_limit(len(deserialized), max_batch_size)
164
166
  if max_batch_size is not None and len(deserialized) > max_batch_size:
165
167
  return post_process(
166
168
  Left(BatchTooLargeResponse(len(deserialized), max_batch_size))
@@ -4,6 +4,7 @@ requests, providing responses.
4
4
 
5
5
  import logging
6
6
  import reprlib
7
+ import warnings
7
8
  from functools import partial
8
9
  from inspect import iscoroutine, signature
9
10
  from itertools import starmap
@@ -387,6 +388,17 @@ def check_max_batch_size(max_batch_size: object) -> None:
387
388
  )
388
389
 
389
390
 
391
+ def warn_if_over_6_0_batch_limit(size: int, max_batch_size: Optional[int]) -> None:
392
+ """Warn when a batch would get an error under 6.0's default limit of 100."""
393
+ if max_batch_size is None and size > 100:
394
+ warnings.warn(
395
+ f"This batch has {size} requests. 6.0 limits batches to 100 by default. "
396
+ "Pass max_batch_size=None to keep no limit, or set the limit you want.",
397
+ FutureWarning,
398
+ stacklevel=2,
399
+ )
400
+
401
+
390
402
  def member_id(member: Any) -> Any:
391
403
  """The id of a batch member, or None if it has none we can use.
392
404
 
@@ -453,6 +465,7 @@ def dispatch_to_response_pure(
453
465
  return post_process(Left(parsed._error))
454
466
  deserialized = unwrap(parsed)
455
467
  if isinstance(deserialized, list) and deserialized:
468
+ warn_if_over_6_0_batch_limit(len(deserialized), max_batch_size)
456
469
  if max_batch_size is not None and len(deserialized) > max_batch_size:
457
470
  return post_process(
458
471
  Left(BatchTooLargeResponse(len(deserialized), max_batch_size))
@@ -12,7 +12,9 @@ They differ only in the form of the response:
12
12
 
13
13
  import json
14
14
  import logging
15
+ import math
15
16
  import pkgutil
17
+ import warnings
16
18
  from typing import Any, Callable, Dict, List, Optional, Union, cast
17
19
 
18
20
  from jsonschema.validators import validator_for
@@ -41,7 +43,42 @@ from .utils import identity
41
43
 
42
44
  logger = logging.getLogger(__name__)
43
45
 
44
- default_deserializer = json.loads
46
+ _CONSTANTS = {"NaN": math.nan, "Infinity": math.inf, "-Infinity": -math.inf}
47
+
48
+
49
+ def _future_constant(constant: str) -> float:
50
+ warnings.warn(
51
+ f"{constant} in a request isn't valid JSON. 5.x accepts it, but 6.0 will "
52
+ "reject it with a Parse error.",
53
+ FutureWarning,
54
+ stacklevel=2,
55
+ )
56
+ return _CONSTANTS[constant]
57
+
58
+
59
+ def _future_float(text: str) -> float:
60
+ number = float(text)
61
+ if math.isinf(number):
62
+ warnings.warn(
63
+ f"{text} in a request is too big for a float. 5.x reads it as infinity, "
64
+ "but 6.0 will reject it with a Parse error.",
65
+ FutureWarning,
66
+ stacklevel=2,
67
+ )
68
+ return number
69
+
70
+
71
+ def default_deserializer(request: str) -> Any:
72
+ """json.loads, which warns about input 6.0 will reject.
73
+
74
+ `NaN`, `Infinity`, `-Infinity` and numbers too big for a float are accepted, as
75
+ in every 5.x release, with a `FutureWarning`: 6.0's default rejects them with a
76
+ Parse error. Pass `deserializer=json.loads` to accept them without a warning.
77
+ New in 5.2.0.
78
+ """
79
+ return json.loads(
80
+ request, parse_constant=_future_constant, parse_float=_future_float
81
+ )
45
82
 
46
83
 
47
84
  def default_serializer(response: Any) -> str:
@@ -121,7 +158,7 @@ def dispatch_to_response(
121
158
  methods: Optional[MethodsArgument] = None,
122
159
  *,
123
160
  context: Any = NOCONTEXT,
124
- deserializer: Callable[[str], Deserialized] = json.loads,
161
+ deserializer: Callable[[str], Deserialized] = default_deserializer,
125
162
  validator: Callable[[Deserialized], object] = default_validator,
126
163
  post_process: Callable[[Response], Any] = identity,
127
164
  debug: bool = False,
@@ -7,8 +7,9 @@ server or framework.
7
7
  import json
8
8
  import logging
9
9
  import sys
10
+ import warnings
10
11
  from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
11
- from typing import Any
12
+ from typing import Any, Optional
12
13
 
13
14
  from .main import dispatch
14
15
  from .response import ParseErrorResponse, to_error_dict
@@ -71,7 +72,7 @@ def listening_message(name: str, port: int) -> str:
71
72
  return f" * Listening on http://{name}:{port}/. This is a development server."
72
73
 
73
74
 
74
- def serve(name: str = "", port: int = 5000) -> None:
75
+ def serve(name: Optional[str] = None, port: int = 5000) -> None:
75
76
  """Serve the methods registered with `@method` over HTTP. For development only.
76
77
 
77
78
  It answers POST requests on any path with `dispatch`, sends 204 No Content for a
@@ -87,9 +88,11 @@ def serve(name: str = "", port: int = 5000) -> None:
87
88
  production.
88
89
 
89
90
  Args:
90
- name: The host name or address to listen on. The default, "", listens on
91
- every network interface, so other machines can connect. Pass "localhost"
92
- to accept only local connections.
91
+ name: The host name or address to listen on. Without one, it listens on
92
+ every network interface, so other machines can connect, and gives a
93
+ `FutureWarning` (5.2.0): 6.0 listens on localhost by default. Pass ""
94
+ to keep every interface, or "localhost" to accept only local
95
+ connections.
93
96
  port: The port to listen on.
94
97
 
95
98
  Example:
@@ -103,6 +106,15 @@ def serve(name: str = "", port: int = 5000) -> None:
103
106
  serve("localhost", 8000)
104
107
  ```
105
108
  """
109
+ if name is None:
110
+ warnings.warn(
111
+ "serve() without a host listens on every network interface. From 6.0 it "
112
+ 'will listen on localhost only. Pass serve("", port) to keep listening '
113
+ 'on every interface, or serve("localhost", port).',
114
+ FutureWarning,
115
+ stacklevel=2,
116
+ )
117
+ name = ""
106
118
  httpd = ThreadingHTTPServer((name, port), RequestHandler)
107
119
  try:
108
120
  message = listening_message(name, port)
@@ -47,7 +47,9 @@ def reset_calls() -> None:
47
47
 
48
48
 
49
49
  def test_no_limit_by_default() -> None:
50
- assert len(json.loads(dispatch(batch(500), {"ping": ping}))) == 500
50
+ """5.x has no limit. From 5.2.0 a batch over 6.0's default of 100 warns."""
51
+ with pytest.warns(FutureWarning, match="6.0 limits batches to 100 by default"):
52
+ assert len(json.loads(dispatch(batch(500), {"ping": ping}))) == 500
51
53
 
52
54
 
53
55
  def test_at_the_limit() -> None:
@@ -0,0 +1,81 @@
1
+ """5.2.0 warns about the 5.x behaviour that 6.0 changes (plans/6.0.md, D12)."""
2
+
3
+ import json
4
+ import warnings
5
+ from unittest.mock import Mock, patch
6
+
7
+ import pytest
8
+
9
+ from jsonrpcserver import Result, Success, dispatch, serve
10
+
11
+ METHODS = {"ping": lambda: Success("pong")}
12
+
13
+
14
+ def take_one(x: float) -> Result:
15
+ return Success()
16
+
17
+
18
+ def take_two(a: float, b: float) -> Result:
19
+ return Success()
20
+
21
+
22
+ def batch(size: int) -> str:
23
+ return json.dumps(
24
+ [{"jsonrpc": "2.0", "method": "ping", "id": n} for n in range(size)]
25
+ )
26
+
27
+
28
+ @pytest.mark.parametrize("constant", ["NaN", "Infinity", "-Infinity"])
29
+ def test_non_json_constants_warn(constant: str) -> None:
30
+ request = (
31
+ '{"jsonrpc": "2.0", "method": "ping", "params": [' + constant + '], "id": 1}'
32
+ )
33
+ with pytest.warns(FutureWarning, match=f"{constant} in a request isn't valid JSON"):
34
+ dispatch(request, {"ping": take_one})
35
+
36
+
37
+ def test_json_loads_accepts_them_quietly() -> None:
38
+ request = '{"jsonrpc": "2.0", "method": "ping", "params": [NaN], "id": 1}'
39
+ with warnings.catch_warnings():
40
+ warnings.simplefilter("error")
41
+ dispatch(request, {"ping": take_one}, deserializer=json.loads)
42
+
43
+
44
+ def test_ordinary_numbers_dont_warn() -> None:
45
+ request = '{"jsonrpc": "2.0", "method": "ping", "params": [1.5, 1e300], "id": 1}'
46
+ with warnings.catch_warnings():
47
+ warnings.simplefilter("error")
48
+ dispatch(request, {"ping": take_two})
49
+
50
+
51
+ def test_batch_of_100_doesnt_warn() -> None:
52
+ with warnings.catch_warnings():
53
+ warnings.simplefilter("error")
54
+ dispatch(batch(100), METHODS)
55
+
56
+
57
+ def test_batch_of_101_warns() -> None:
58
+ with pytest.warns(FutureWarning, match="This batch has 101 requests"):
59
+ dispatch(batch(101), METHODS)
60
+
61
+
62
+ @pytest.mark.asyncio
63
+ async def test_async_batch_of_101_warns() -> None:
64
+ from jsonrpcserver import async_dispatch
65
+
66
+ with pytest.warns(FutureWarning, match="This batch has 101 requests"):
67
+ await async_dispatch(batch(101), METHODS)
68
+
69
+
70
+ def test_explicit_limit_doesnt_warn() -> None:
71
+ with warnings.catch_warnings():
72
+ warnings.simplefilter("error")
73
+ dispatch(batch(101), METHODS, max_batch_size=200)
74
+
75
+
76
+ @patch("jsonrpcserver.server.ThreadingHTTPServer")
77
+ def test_serve_with_a_host_doesnt_warn(server: Mock) -> None:
78
+ with warnings.catch_warnings():
79
+ warnings.simplefilter("error")
80
+ serve("", 5000)
81
+ serve("localhost", 5000)
@@ -134,7 +134,10 @@ def test_nan_allowed_with_plain_json_dumps() -> None:
134
134
 
135
135
 
136
136
  def test_infinite_id_gets_null_id() -> None:
137
- response = dispatch('{"jsonrpc": "2.0", "method": "ping", "id": 1e400}', METHODS)
137
+ with pytest.warns(FutureWarning, match="too big for a float"):
138
+ response = dispatch(
139
+ '{"jsonrpc": "2.0", "method": "ping", "id": 1e400}', METHODS
140
+ )
138
141
  assert json.loads(response) == {
139
142
  "jsonrpc": "2.0",
140
143
  "error": INTERNAL_ERROR,
@@ -18,7 +18,8 @@ from jsonrpcserver.server import RequestHandler, listening_message, serve
18
18
 
19
19
  @patch("jsonrpcserver.server.ThreadingHTTPServer")
20
20
  def test_serve(server: Mock) -> None:
21
- serve()
21
+ with pytest.warns(FutureWarning, match="From 6.0 it will listen on localhost"):
22
+ serve()
22
23
  server.assert_called_once_with(("", 5000), RequestHandler)
23
24
  server.return_value.serve_forever.assert_called_once_with()
24
25
  server.return_value.server_close.assert_called_once_with()
@@ -34,7 +35,7 @@ def test_serve_name_and_port(server: Mock) -> None:
34
35
  def test_serve_closes_on_interrupt(server: Mock) -> None:
35
36
  server.return_value.serve_forever.side_effect = KeyboardInterrupt
36
37
  with pytest.raises(KeyboardInterrupt):
37
- serve()
38
+ serve("", 5000)
38
39
  server.return_value.server_close.assert_called_once_with()
39
40
 
40
41
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes