babelqueue 1.21.0__tar.gz → 1.21.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.
Files changed (142) hide show
  1. {babelqueue-1.21.0 → babelqueue-1.21.1}/CHANGELOG.md +9 -0
  2. {babelqueue-1.21.0 → babelqueue-1.21.1}/PKG-INFO +1 -1
  3. {babelqueue-1.21.0 → babelqueue-1.21.1}/pyproject.toml +1 -1
  4. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/__init__.py +1 -1
  5. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/asb_transport.py +34 -1
  6. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_asb_transport.py +13 -0
  7. {babelqueue-1.21.0 → babelqueue-1.21.1}/.github/FUNDING.yml +0 -0
  8. {babelqueue-1.21.0 → babelqueue-1.21.1}/.github/dependabot.yml +0 -0
  9. {babelqueue-1.21.0 → babelqueue-1.21.1}/.github/workflows/ci.yml +0 -0
  10. {babelqueue-1.21.0 → babelqueue-1.21.1}/.github/workflows/release.yml +0 -0
  11. {babelqueue-1.21.0 → babelqueue-1.21.1}/.gitignore +0 -0
  12. {babelqueue-1.21.0 → babelqueue-1.21.1}/LICENSE +0 -0
  13. {babelqueue-1.21.0 → babelqueue-1.21.1}/README.md +0 -0
  14. {babelqueue-1.21.0 → babelqueue-1.21.1}/conformance-known-gaps.json +0 -0
  15. {babelqueue-1.21.0 → babelqueue-1.21.1}/scripts/check_conformance_results.py +0 -0
  16. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/_envelope_shape.py +0 -0
  17. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/app.py +0 -0
  18. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/artemis_transport.py +0 -0
  19. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/celery.py +0 -0
  20. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/codec.py +0 -0
  21. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/contracts.py +0 -0
  22. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/dead_letter.py +0 -0
  23. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/django/__init__.py +0 -0
  24. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/django/apps.py +0 -0
  25. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/django/management/__init__.py +0 -0
  26. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/django/management/commands/__init__.py +0 -0
  27. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/django/management/commands/babelqueue_worker.py +0 -0
  28. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/exceptions.py +0 -0
  29. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/gdpr.py +0 -0
  30. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/headers.py +0 -0
  31. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/idempotency.py +0 -0
  32. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/kafka_transport.py +0 -0
  33. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/otel.py +0 -0
  34. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/outbox.py +0 -0
  35. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/pika_transport.py +0 -0
  36. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/pulsar_transport.py +0 -0
  37. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/py.typed +0 -0
  38. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/redis_transport.py +0 -0
  39. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/redrive.py +0 -0
  40. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/replay.py +0 -0
  41. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/routing.py +0 -0
  42. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/schema.py +0 -0
  43. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/sqs_transport.py +0 -0
  44. {babelqueue-1.21.0 → babelqueue-1.21.1}/src/babelqueue/transport.py +0 -0
  45. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/CONFORMANCE_VERSION +0 -0
  46. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/blank-ascii-job-urn-fallback.json +0 -0
  47. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/data-array-rejected.json +0 -0
  48. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/dead-letter-roundtrip.json +0 -0
  49. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/dead-lettered.json +0 -0
  50. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/duplicate-keys-last-wins.json +0 -0
  51. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/empty-data-roundtrip.json +0 -0
  52. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/forbidden-key-job-and-urn.json +0 -0
  53. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/forbidden-key-job-nonascii-space-and-urn.json +0 -0
  54. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/forbidden-key-meta-attempts.json +0 -0
  55. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/forbidden-key-meta-max-retries.json +0 -0
  56. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/forbidden-key-meta-source.json +0 -0
  57. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/forbidden-key-meta-ts.json +0 -0
  58. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/forbidden-key-timestamp.json +0 -0
  59. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/invalid-missing-urn.json +0 -0
  60. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/invalid-unknown-schema-version.json +0 -0
  61. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/invalid-wrong-case-job.json +0 -0
  62. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/job-type-array-urn-fallback.json +0 -0
  63. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/job-type-bool-urn-fallback.json +0 -0
  64. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/job-type-empty-string-urn-fallback.json +0 -0
  65. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/job-type-missing-job-array-urn.json +0 -0
  66. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/job-type-null-no-urn.json +0 -0
  67. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/job-type-null-urn-fallback.json +0 -0
  68. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/job-type-number-blank-urn.json +0 -0
  69. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/job-type-number-nonstring-urn.json +0 -0
  70. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/job-type-number-urn-fallback.json +0 -0
  71. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/job-type-object-urn-fallback.json +0 -0
  72. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/meta-ext-vendor-roundtrip.json +0 -0
  73. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/order-created.json +0 -0
  74. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-blank-job-cr.json +0 -0
  75. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-blank-job-ff.json +0 -0
  76. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-blank-job-lf.json +0 -0
  77. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-blank-job-space.json +0 -0
  78. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-blank-job-tab.json +0 -0
  79. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-blank-job-vt.json +0 -0
  80. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-blank-trace-id-cr.json +0 -0
  81. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-blank-trace-id-ff.json +0 -0
  82. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-blank-trace-id-lf.json +0 -0
  83. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-blank-trace-id-space.json +0 -0
  84. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-blank-trace-id-tab.json +0 -0
  85. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-blank-trace-id-vt.json +0 -0
  86. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-job-and-urn-both-blank.json +0 -0
  87. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-reemit-job-ascii-padded.json +0 -0
  88. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-reemit-job-unicode-padded.json +0 -0
  89. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-reemit-trace-id-padded.json +0 -0
  90. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-unicode-job-emsp.json +0 -0
  91. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-unicode-job-ideographic.json +0 -0
  92. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-unicode-job-nbsp.json +0 -0
  93. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-urn-only-ascii-blank.json +0 -0
  94. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/trim-urn-only-unicode-space.json +0 -0
  95. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/unicode-and-numbers.json +0 -0
  96. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/unknown-lang.json +0 -0
  97. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/unknown-meta-roundtrip.json +0 -0
  98. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/unknown-toplevel-roundtrip.json +0 -0
  99. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/urn-alias.json +0 -0
  100. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/urn-only-roundtrip.json +0 -0
  101. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/fixtures/wrong-case-keys-roundtrip.json +0 -0
  102. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/manifest.json +0 -0
  103. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/schema/message-envelope.schema.json +0 -0
  104. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/schema/results.example.json +0 -0
  105. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/conformance/schema/results.schema.json +0 -0
  106. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/fakes/confluent_kafka/__init__.py +0 -0
  107. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/fakes/confluent_kafka/admin.py +0 -0
  108. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/fixtures/dead-lettered.json +0 -0
  109. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/fixtures/order-created.json +0 -0
  110. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/poison-trigger-set.json +0 -0
  111. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_app.py +0 -0
  112. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_artemis_conformance.py +0 -0
  113. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_artemis_transport.py +0 -0
  114. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_asb_conformance.py +0 -0
  115. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_behaviour_conformance.py +0 -0
  116. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_celery.py +0 -0
  117. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_codec.py +0 -0
  118. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_conformance.py +0 -0
  119. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_dead_letter.py +0 -0
  120. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_django.py +0 -0
  121. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_gdpr.py +0 -0
  122. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_headers.py +0 -0
  123. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_idempotency.py +0 -0
  124. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_kafka_conformance.py +0 -0
  125. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_kafka_integration.py +0 -0
  126. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_kafka_integration_logic.py +0 -0
  127. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_kafka_transport.py +0 -0
  128. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_otel.py +0 -0
  129. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_outbox.py +0 -0
  130. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_overhead.py +0 -0
  131. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_pika_transport.py +0 -0
  132. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_pulsar_conformance.py +0 -0
  133. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_pulsar_transport.py +0 -0
  134. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_redis_transport.py +0 -0
  135. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_redrive.py +0 -0
  136. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_reencode_regression.py +0 -0
  137. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_replay.py +0 -0
  138. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_schema.py +0 -0
  139. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_schema_conformance.py +0 -0
  140. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_shutdown.py +0 -0
  141. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_sqs_conformance.py +0 -0
  142. {babelqueue-1.21.0 → babelqueue-1.21.1}/tests/test_sqs_transport.py +0 -0
@@ -9,6 +9,15 @@ The envelope wire format is versioned separately by `meta.schema_version`
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [1.21.1] - 2026-10-20
13
+
14
+ ### Fixed
15
+ - **Azure Service Bus: `publish` no longer fails with `Value supplied for int invalid`.** The pure-Python AMQP
16
+ stack in `azure-servicebus` encodes a bare Python int as AMQP int32, so the millisecond `bq-created-at`
17
+ application property (broker-bindings.md §4.3) overflowed at send time. Out-of-int32 integer properties
18
+ are now sent as AMQP `long`, matching the Go, Java, .NET and Node transports. The native projection and
19
+ the envelope body are unchanged.
20
+
12
21
  ## [1.21.0] - 2026-10-19
13
22
 
14
23
  Implements ADR-0032 (conformance packaging, results format, ASCII trim and the non-string `job` rule).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: babelqueue
3
- Version: 1.21.0
3
+ Version: 1.21.1
4
4
  Summary: Polyglot Queues, Simplified — the Python core: the canonical BabelQueue wire-envelope codec, contracts and dead-letter helpers.
5
5
  Project-URL: Homepage, https://babelqueue.com
6
6
  Project-URL: Source, https://github.com/BabelQueue/babelqueue-python
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "babelqueue"
7
- version = "1.21.0"
7
+ version = "1.21.1"
8
8
  description = "Polyglot Queues, Simplified — the Python core: the canonical BabelQueue wire-envelope codec, contracts and dead-letter helpers."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -41,7 +41,7 @@ from .transport import (
41
41
  Transport,
42
42
  )
43
43
 
44
- __version__ = "1.21.0"
44
+ __version__ = "1.21.1"
45
45
 
46
46
  __all__ = [
47
47
  "BabelQueue",
@@ -44,6 +44,36 @@ _BLANK_ASCII_PATTERN = re.compile("[" + re.escape(ASCII_WHITESPACE) + "]*")
44
44
  UNSUPPORTED_SCHEMA_ROUTE_PREFIX = "babelqueue:unsupported-schema-version:"
45
45
 
46
46
 
47
+ _INT32_MIN = -(2**31)
48
+ _INT32_MAX = 2**31 - 1
49
+
50
+
51
+ def _amqp_typed(props: Dict[str, Any]) -> Dict[str, Any]:
52
+ """Pin out-of-int32 ints to AMQP ``long`` (§4.3: ``bq-created-at`` is Unix ms).
53
+
54
+ The pure-Python AMQP stack in ``azure-servicebus`` encodes every bare Python int as an
55
+ AMQP int32, so a millisecond epoch overflows at send time. A value outside the int32 range
56
+ is wrapped in the stack's explicit type descriptor; everything else is left as-is.
57
+ """
58
+ try:
59
+ from azure.servicebus._pyamqp.types import TYPE, VALUE, AMQPTypes
60
+
61
+ long_type: Any = AMQPTypes.long
62
+ except ImportError: # pragma: no cover - older SDK layouts
63
+ TYPE, VALUE, long_type = "TYPE", "VALUE", "LONG"
64
+ out: Dict[str, Any] = {}
65
+ for key, value in props.items():
66
+ if (
67
+ isinstance(value, int)
68
+ and not isinstance(value, bool)
69
+ and not _INT32_MIN <= value <= _INT32_MAX
70
+ ):
71
+ out[key] = {TYPE: long_type, VALUE: value}
72
+ else:
73
+ out[key] = value
74
+ return out
75
+
76
+
47
77
  class AsbTransport(Transport):
48
78
  def __init__(
49
79
  self,
@@ -196,7 +226,10 @@ class AsbTransport(Transport):
196
226
  def publish(self, queue: str, body: str) -> None:
197
227
  from azure.servicebus import ServiceBusMessage
198
228
 
199
- message = ServiceBusMessage(body, **self._projection(body))
229
+ kwargs = self._projection(body)
230
+ if kwargs.get("application_properties"):
231
+ kwargs["application_properties"] = _amqp_typed(kwargs["application_properties"])
232
+ message = ServiceBusMessage(body, **kwargs)
200
233
  self._sender(queue).send_messages(message)
201
234
 
202
235
  def pop(self, queue: str, timeout: float = 1.0) -> Optional[ReceivedMessage]:
@@ -322,6 +322,19 @@ class AsbPublishTest(unittest.TestCase):
322
322
  self.assertEqual(sent.content_type, "application/json")
323
323
  self.assertEqual(EnvelopeCodec.urn(EnvelopeCodec.decode(str(sent))), URN)
324
324
 
325
+ def test_publish_encodes_ms_created_at_as_amqp_long(self):
326
+ from azure.servicebus._pyamqp import _encode
327
+
328
+ sender = FakeSender()
329
+ AsbTransport(client=FakeClient(sender=sender)).publish("orders", body())
330
+
331
+ props = sender.sent[0].application_properties
332
+ out = bytearray()
333
+ # a bare int > int32 raises "Value supplied for int invalid" here
334
+ _encode.encode_value(out, _encode.encode_application_properties(props))
335
+ self.assertIn(b"bq-created-at\x81", bytes(out))
336
+ self.assertIn(b"bq-schema-version\x54\x01", bytes(out))
337
+
325
338
 
326
339
  if __name__ == "__main__":
327
340
  unittest.main()
File without changes
File without changes
File without changes