kafka-python 2.2.15__tar.gz → 2.2.16__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 (168) hide show
  1. {kafka_python-2.2.15 → kafka_python-2.2.16}/CHANGES.md +6 -0
  2. {kafka_python-2.2.15 → kafka_python-2.2.16}/PKG-INFO +1 -1
  3. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/conn.py +7 -0
  4. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/consumer/group.py +1 -1
  5. kafka_python-2.2.16/kafka/version.py +1 -0
  6. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka_python.egg-info/PKG-INFO +1 -1
  7. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_conn.py +55 -2
  8. kafka_python-2.2.15/kafka/version.py +0 -1
  9. {kafka_python-2.2.15 → kafka_python-2.2.16}/AUTHORS.md +0 -0
  10. {kafka_python-2.2.15 → kafka_python-2.2.16}/LICENSE +0 -0
  11. {kafka_python-2.2.15 → kafka_python-2.2.16}/MANIFEST.in +0 -0
  12. {kafka_python-2.2.15 → kafka_python-2.2.16}/README.rst +0 -0
  13. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/__init__.py +0 -0
  14. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/admin/__init__.py +0 -0
  15. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/admin/acl_resource.py +0 -0
  16. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/admin/client.py +0 -0
  17. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/admin/config_resource.py +0 -0
  18. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/admin/new_partitions.py +0 -0
  19. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/admin/new_topic.py +0 -0
  20. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/benchmarks/__init__.py +0 -0
  21. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/benchmarks/consumer_performance.py +0 -0
  22. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/benchmarks/load_example.py +0 -0
  23. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/benchmarks/producer_performance.py +0 -0
  24. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/benchmarks/record_batch_compose.py +0 -0
  25. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/benchmarks/record_batch_read.py +0 -0
  26. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/benchmarks/varint_speed.py +0 -0
  27. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/client_async.py +0 -0
  28. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/cluster.py +0 -0
  29. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/codec.py +0 -0
  30. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/consumer/__init__.py +0 -0
  31. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/consumer/fetcher.py +0 -0
  32. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/consumer/subscription_state.py +0 -0
  33. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/coordinator/__init__.py +0 -0
  34. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/coordinator/assignors/__init__.py +0 -0
  35. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/coordinator/assignors/abstract.py +0 -0
  36. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/coordinator/assignors/range.py +0 -0
  37. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/coordinator/assignors/roundrobin.py +0 -0
  38. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/coordinator/assignors/sticky/__init__.py +0 -0
  39. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/coordinator/assignors/sticky/partition_movements.py +0 -0
  40. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/coordinator/assignors/sticky/sorted_set.py +0 -0
  41. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/coordinator/assignors/sticky/sticky_assignor.py +0 -0
  42. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/coordinator/base.py +0 -0
  43. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/coordinator/consumer.py +0 -0
  44. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/coordinator/heartbeat.py +0 -0
  45. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/coordinator/protocol.py +0 -0
  46. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/errors.py +0 -0
  47. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/future.py +0 -0
  48. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/__init__.py +0 -0
  49. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/compound_stat.py +0 -0
  50. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/dict_reporter.py +0 -0
  51. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/kafka_metric.py +0 -0
  52. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/measurable.py +0 -0
  53. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/measurable_stat.py +0 -0
  54. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/metric_config.py +0 -0
  55. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/metric_name.py +0 -0
  56. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/metrics.py +0 -0
  57. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/metrics_reporter.py +0 -0
  58. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/quota.py +0 -0
  59. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/stat.py +0 -0
  60. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/stats/__init__.py +0 -0
  61. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/stats/avg.py +0 -0
  62. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/stats/count.py +0 -0
  63. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/stats/histogram.py +0 -0
  64. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/stats/max_stat.py +0 -0
  65. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/stats/min_stat.py +0 -0
  66. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/stats/percentile.py +0 -0
  67. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/stats/percentiles.py +0 -0
  68. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/stats/rate.py +0 -0
  69. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/stats/sampled_stat.py +0 -0
  70. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/stats/sensor.py +0 -0
  71. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/metrics/stats/total.py +0 -0
  72. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/partitioner/__init__.py +0 -0
  73. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/partitioner/default.py +0 -0
  74. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/producer/__init__.py +0 -0
  75. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/producer/future.py +0 -0
  76. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/producer/kafka.py +0 -0
  77. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/producer/record_accumulator.py +0 -0
  78. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/producer/sender.py +0 -0
  79. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/producer/transaction_manager.py +0 -0
  80. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/__init__.py +0 -0
  81. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/abstract.py +0 -0
  82. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/add_offsets_to_txn.py +0 -0
  83. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/add_partitions_to_txn.py +0 -0
  84. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/admin.py +0 -0
  85. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/api.py +0 -0
  86. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/api_versions.py +0 -0
  87. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/broker_api_versions.py +0 -0
  88. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/commit.py +0 -0
  89. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/end_txn.py +0 -0
  90. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/fetch.py +0 -0
  91. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/find_coordinator.py +0 -0
  92. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/frame.py +0 -0
  93. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/group.py +0 -0
  94. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/init_producer_id.py +0 -0
  95. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/list_offsets.py +0 -0
  96. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/message.py +0 -0
  97. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/metadata.py +0 -0
  98. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/offset_for_leader_epoch.py +0 -0
  99. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/parser.py +0 -0
  100. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/pickle.py +0 -0
  101. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/produce.py +0 -0
  102. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/sasl_authenticate.py +0 -0
  103. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/sasl_handshake.py +0 -0
  104. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/struct.py +0 -0
  105. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/txn_offset_commit.py +0 -0
  106. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/protocol/types.py +0 -0
  107. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/record/__init__.py +0 -0
  108. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/record/_crc32c.py +0 -0
  109. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/record/abc.py +0 -0
  110. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/record/default_records.py +0 -0
  111. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/record/legacy_records.py +0 -0
  112. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/record/memory_records.py +0 -0
  113. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/record/util.py +0 -0
  114. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/sasl/__init__.py +0 -0
  115. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/sasl/abc.py +0 -0
  116. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/sasl/gssapi.py +0 -0
  117. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/sasl/msk.py +0 -0
  118. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/sasl/oauth.py +0 -0
  119. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/sasl/plain.py +0 -0
  120. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/sasl/scram.py +0 -0
  121. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/sasl/sspi.py +0 -0
  122. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/serializer/__init__.py +0 -0
  123. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/serializer/abstract.py +0 -0
  124. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/socks5_wrapper.py +0 -0
  125. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/structs.py +0 -0
  126. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/util.py +0 -0
  127. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/vendor/__init__.py +0 -0
  128. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/vendor/enum34.py +0 -0
  129. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/vendor/selectors34.py +0 -0
  130. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/vendor/six.py +0 -0
  131. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka/vendor/socketpair.py +0 -0
  132. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka_python.egg-info/SOURCES.txt +0 -0
  133. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka_python.egg-info/dependency_links.txt +0 -0
  134. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka_python.egg-info/requires.txt +0 -0
  135. {kafka_python-2.2.15 → kafka_python-2.2.16}/kafka_python.egg-info/top_level.txt +0 -0
  136. {kafka_python-2.2.15 → kafka_python-2.2.16}/pyproject.toml +0 -0
  137. {kafka_python-2.2.15 → kafka_python-2.2.16}/setup.cfg +0 -0
  138. {kafka_python-2.2.15 → kafka_python-2.2.16}/setup.py +0 -0
  139. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/integration/__init__.py +0 -0
  140. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/integration/conftest.py +0 -0
  141. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/integration/fixtures.py +0 -0
  142. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/integration/test_admin_integration.py +0 -0
  143. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/integration/test_consumer_group.py +0 -0
  144. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/integration/test_consumer_integration.py +0 -0
  145. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/integration/test_producer_integration.py +0 -0
  146. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/integration/test_sasl_integration.py +0 -0
  147. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_acl_comparisons.py +0 -0
  148. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_admin.py +0 -0
  149. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_api_object_implementation.py +0 -0
  150. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_assignors.py +0 -0
  151. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_client_async.py +0 -0
  152. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_cluster.py +0 -0
  153. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_codec.py +0 -0
  154. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_consumer.py +0 -0
  155. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_coordinator.py +0 -0
  156. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_fetcher.py +0 -0
  157. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_metrics.py +0 -0
  158. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_object_conversion.py +0 -0
  159. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_package.py +0 -0
  160. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_partition_movements.py +0 -0
  161. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_partitioner.py +0 -0
  162. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_producer.py +0 -0
  163. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_protocol.py +0 -0
  164. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_record_accumulator.py +0 -0
  165. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_sender.py +0 -0
  166. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_subscription_state.py +0 -0
  167. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/test_util.py +0 -0
  168. {kafka_python-2.2.15 → kafka_python-2.2.16}/test/testutil.py +0 -0
@@ -1,3 +1,9 @@
1
+ # 2.2.16 (Nov 18, 2025)
2
+
3
+ Fixes
4
+ * Fix thread not waking up when there is still data to be sent (gqmelo / #2670)
5
+ * Ensure timeout is checked after each fetch position update in `Consumer.position()` (k61n / #2668)
6
+
1
7
  # 2.2.15 (July 1, 2025)
2
8
 
3
9
  Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kafka-python
3
- Version: 2.2.15
3
+ Version: 2.2.16
4
4
  Summary: Pure Python client for Apache Kafka
5
5
  Author-email: Dana Powers <dana.powers@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/dpkp/kafka-python
@@ -1075,6 +1075,13 @@ class BrokerConnection(object):
1075
1075
  total_bytes = self._send_bytes(self._send_buffer)
1076
1076
  self._send_buffer = self._send_buffer[total_bytes:]
1077
1077
 
1078
+ # If all data was sent, we need to get the new data from the protocol now, otherwise
1079
+ # this function would return True, indicating that there are no more pending
1080
+ # requests. This could cause the calling thread to wait indefinitely as it won't
1081
+ # know that there is still buffered data to send.
1082
+ if not self._send_buffer:
1083
+ self._send_buffer = self._protocol.send_bytes()
1084
+
1078
1085
  if self._sensors:
1079
1086
  self._sensors.bytes_sent.record(total_bytes)
1080
1087
  # Return True iff send buffer is empty
@@ -757,7 +757,7 @@ class KafkaConsumer(six.Iterator):
757
757
  # batch update fetch positions for any partitions without a valid position
758
758
  if self._update_fetch_positions(timeout_ms=timer.timeout_ms):
759
759
  position = self._subscription.assignment[partition].position
760
- elif timer.expired:
760
+ if timer.expired:
761
761
  return None
762
762
  else:
763
763
  return position.offset
@@ -0,0 +1 @@
1
+ __version__ = '2.2.16'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kafka-python
3
- Version: 2.2.15
3
+ Version: 2.2.16
4
4
  Summary: Pure Python client for Apache Kafka
5
5
  Author-email: Dana Powers <dana.powers@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/dpkp/kafka-python
@@ -12,6 +12,9 @@ import pytest
12
12
 
13
13
  from kafka.conn import BrokerConnection, ConnectionStates
14
14
  from kafka.future import Future
15
+ from kafka.conn import BrokerConnection, ConnectionStates, SSLWantWriteError
16
+ from kafka.metrics.metrics import Metrics
17
+ from kafka.metrics.stats.sensor import Sensor
15
18
  from kafka.protocol.api import RequestHeader
16
19
  from kafka.protocol.group import HeartbeatResponse
17
20
  from kafka.protocol.metadata import MetadataRequest
@@ -43,10 +46,20 @@ def _socket(mocker):
43
46
  mocker.patch('socket.socket', return_value=socket)
44
47
  return socket
45
48
 
49
+ @pytest.fixture
50
+ def metrics(mocker):
51
+ metrics = mocker.MagicMock(Metrics)
52
+ metrics.mocked_sensors = {}
53
+ def sensor(name, **kwargs):
54
+ if name not in metrics.mocked_sensors:
55
+ metrics.mocked_sensors[name] = mocker.MagicMock(Sensor)
56
+ return metrics.mocked_sensors[name]
57
+ metrics.sensor.side_effect = sensor
58
+ return metrics
46
59
 
47
60
  @pytest.fixture
48
- def conn(_socket, dns_lookup, mocker):
49
- conn = BrokerConnection('localhost', 9092, socket.AF_INET)
61
+ def conn(_socket, dns_lookup, metrics, mocker):
62
+ conn = BrokerConnection('localhost', 9092, socket.AF_INET, metrics=metrics)
50
63
  mocker.patch.object(conn, '_try_api_versions_check', return_value=True)
51
64
  return conn
52
65
 
@@ -228,6 +241,46 @@ def test_send_response(_socket, conn):
228
241
  assert len(conn.in_flight_requests) == 1
229
242
 
230
243
 
244
+ def test_send_async_request_while_other_request_is_already_in_buffer(_socket, conn, metrics):
245
+ conn.connect()
246
+ assert conn.state is ConnectionStates.CONNECTED
247
+ assert 'node-0.bytes-sent' in metrics.mocked_sensors
248
+ bytes_sent_sensor = metrics.mocked_sensors['node-0.bytes-sent']
249
+
250
+ req1 = MetadataRequest[0](topics='foo')
251
+ header1 = RequestHeader(req1, client_id=conn.config['client_id'])
252
+ payload_bytes1 = len(header1.encode()) + len(req1.encode())
253
+ req2 = MetadataRequest[0]([])
254
+ header2 = RequestHeader(req2, client_id=conn.config['client_id'])
255
+ payload_bytes2 = len(header2.encode()) + len(req2.encode())
256
+
257
+ # The first call to the socket will raise a transient SSL exception. This will make the first
258
+ # request to be kept in the internal buffer to be sent in the next call of
259
+ # send_pending_requests_v2.
260
+ _socket.send.side_effect = [SSLWantWriteError, 4 + payload_bytes1, 4 + payload_bytes2]
261
+
262
+ conn.send(req1, blocking=False)
263
+ # This won't send any bytes because of the SSL exception and the request bytes will be kept in
264
+ # the buffer.
265
+ assert conn.send_pending_requests_v2() is False
266
+ assert bytes_sent_sensor.record.call_args_list[0].args == (0,)
267
+
268
+ conn.send(req2, blocking=False)
269
+ # This will send the remaining bytes in the buffer from the first request, but should notice
270
+ # that the second request was queued, therefore it should return False.
271
+ bytes_sent_sensor.record.reset_mock()
272
+ assert conn.send_pending_requests_v2() is False
273
+ bytes_sent_sensor.record.assert_called_once_with(4 + payload_bytes1)
274
+
275
+ bytes_sent_sensor.record.reset_mock()
276
+ assert conn.send_pending_requests_v2() is True
277
+ bytes_sent_sensor.record.assert_called_once_with(4 + payload_bytes2)
278
+
279
+ bytes_sent_sensor.record.reset_mock()
280
+ assert conn.send_pending_requests_v2() is True
281
+ bytes_sent_sensor.record.assert_called_once_with(0)
282
+
283
+
231
284
  def test_send_error(_socket, conn):
232
285
  conn.connect()
233
286
  assert conn.state is ConnectionStates.CONNECTED
@@ -1 +0,0 @@
1
- __version__ = '2.2.15'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes