kafka-python 3.0.4__tar.gz → 3.0.6__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 (409) hide show
  1. {kafka_python-3.0.4 → kafka_python-3.0.6}/CHANGES.md +23 -0
  2. {kafka_python-3.0.4 → kafka_python-3.0.6}/PKG-INFO +1 -1
  3. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/consumer/subscription_state.py +39 -5
  4. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/net/manager.py +5 -0
  5. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/fields/array.py +19 -4
  6. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/fields/codecs/encode_buffer.py +40 -1
  7. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/fields/codecs/tagged_fields.py +1 -0
  8. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/fields/codecs/types.py +31 -12
  9. kafka_python-3.0.6/kafka/protocol/schemas/fields/codegen.py +71 -0
  10. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/fields/struct.py +10 -0
  11. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/fields/struct_array.py +6 -1
  12. kafka_python-3.0.6/kafka/version.py +1 -0
  13. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka_python.egg-info/PKG-INFO +1 -1
  14. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/integration/fixtures.py +20 -12
  15. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/net/test_manager.py +50 -2
  16. kafka_python-3.0.4/kafka/protocol/schemas/fields/codegen.py +0 -40
  17. kafka_python-3.0.4/kafka/version.py +0 -1
  18. {kafka_python-3.0.4 → kafka_python-3.0.6}/AUTHORS.md +0 -0
  19. {kafka_python-3.0.4 → kafka_python-3.0.6}/LICENSE +0 -0
  20. {kafka_python-3.0.4 → kafka_python-3.0.6}/MANIFEST.in +0 -0
  21. {kafka_python-3.0.4 → kafka_python-3.0.6}/README.rst +0 -0
  22. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/__init__.py +0 -0
  23. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/__main__.py +0 -0
  24. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/admin/__init__.py +0 -0
  25. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/admin/__main__.py +0 -0
  26. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/admin/_acls.py +0 -0
  27. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/admin/_cluster.py +0 -0
  28. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/admin/_configs.py +0 -0
  29. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/admin/_groups.py +0 -0
  30. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/admin/_partitions.py +0 -0
  31. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/admin/_topics.py +0 -0
  32. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/admin/_transactions.py +0 -0
  33. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/admin/_users.py +0 -0
  34. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/admin/client.py +0 -0
  35. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/benchmarks/__init__.py +0 -0
  36. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/benchmarks/consumer_performance.py +0 -0
  37. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/benchmarks/load_example.py +0 -0
  38. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/benchmarks/producer_encode_path.py +0 -0
  39. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/benchmarks/producer_performance.py +0 -0
  40. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/benchmarks/profile_protocol.py +0 -0
  41. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/benchmarks/protocol_old_vs_new.py +0 -0
  42. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/benchmarks/record_batch_compose.py +0 -0
  43. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/benchmarks/record_batch_read.py +0 -0
  44. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/benchmarks/varint_speed.py +0 -0
  45. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/__init__.py +0 -0
  46. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/__init__.py +0 -0
  47. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/acls/__init__.py +0 -0
  48. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/acls/common.py +0 -0
  49. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/acls/create.py +0 -0
  50. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/acls/delete.py +0 -0
  51. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/acls/describe.py +0 -0
  52. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/cluster/__init__.py +0 -0
  53. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/cluster/describe.py +0 -0
  54. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/cluster/describe_quorum.py +0 -0
  55. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/cluster/features.py +0 -0
  56. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/cluster/log_dirs.py +0 -0
  57. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/cluster/versions.py +0 -0
  58. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/configs/__init__.py +0 -0
  59. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/configs/alter.py +0 -0
  60. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/configs/common.py +0 -0
  61. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/configs/describe.py +0 -0
  62. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/configs/list.py +0 -0
  63. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/configs/reset.py +0 -0
  64. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/groups/__init__.py +0 -0
  65. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/groups/alter_offsets.py +0 -0
  66. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/groups/delete.py +0 -0
  67. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/groups/delete_offsets.py +0 -0
  68. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/groups/describe.py +0 -0
  69. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/groups/list.py +0 -0
  70. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/groups/list_offsets.py +0 -0
  71. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/groups/remove_members.py +0 -0
  72. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/groups/reset_offsets.py +0 -0
  73. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/partitions/__init__.py +0 -0
  74. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/partitions/alter_reassignments.py +0 -0
  75. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/partitions/create.py +0 -0
  76. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/partitions/delete_records.py +0 -0
  77. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/partitions/describe.py +0 -0
  78. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/partitions/elect_leaders.py +0 -0
  79. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/partitions/list_offsets.py +0 -0
  80. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/partitions/list_reassignments.py +0 -0
  81. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/topics/__init__.py +0 -0
  82. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/topics/create.py +0 -0
  83. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/topics/delete.py +0 -0
  84. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/topics/describe.py +0 -0
  85. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/topics/list.py +0 -0
  86. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/transactions/__init__.py +0 -0
  87. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/transactions/abort.py +0 -0
  88. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/transactions/describe.py +0 -0
  89. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/transactions/describe_producers.py +0 -0
  90. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/transactions/find_hanging.py +0 -0
  91. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/transactions/list.py +0 -0
  92. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/users/__init__.py +0 -0
  93. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/users/alter_user_scram_credentials.py +0 -0
  94. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/admin/users/describe_user_scram_credentials.py +0 -0
  95. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/common.py +0 -0
  96. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/consumer/__init__.py +0 -0
  97. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cli/producer/__init__.py +0 -0
  98. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/cluster.py +0 -0
  99. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/codec.py +0 -0
  100. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/consumer/__init__.py +0 -0
  101. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/consumer/__main__.py +0 -0
  102. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/consumer/fetcher.py +0 -0
  103. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/consumer/group.py +0 -0
  104. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/coordinator/__init__.py +0 -0
  105. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/coordinator/assignors/__init__.py +0 -0
  106. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/coordinator/assignors/abstract.py +0 -0
  107. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/coordinator/assignors/cooperative_sticky.py +0 -0
  108. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/coordinator/assignors/range.py +0 -0
  109. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/coordinator/assignors/roundrobin.py +0 -0
  110. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/coordinator/assignors/sticky/StickyAssignorUserData.json +0 -0
  111. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/coordinator/assignors/sticky/__init__.py +0 -0
  112. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/coordinator/assignors/sticky/partition_movements.py +0 -0
  113. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/coordinator/assignors/sticky/sorted_set.py +0 -0
  114. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/coordinator/assignors/sticky/sticky_assignor.py +0 -0
  115. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/coordinator/assignors/sticky/user_data.py +0 -0
  116. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/coordinator/base.py +0 -0
  117. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/coordinator/consumer.py +0 -0
  118. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/coordinator/heartbeat.py +0 -0
  119. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/coordinator/subscription.py +0 -0
  120. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/errors.py +0 -0
  121. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/future.py +0 -0
  122. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/__init__.py +0 -0
  123. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/compound_stat.py +0 -0
  124. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/dict_reporter.py +0 -0
  125. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/kafka_metric.py +0 -0
  126. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/measurable.py +0 -0
  127. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/measurable_stat.py +0 -0
  128. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/metric_config.py +0 -0
  129. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/metric_name.py +0 -0
  130. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/metrics.py +0 -0
  131. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/metrics_reporter.py +0 -0
  132. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/quota.py +0 -0
  133. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/stat.py +0 -0
  134. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/stats/__init__.py +0 -0
  135. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/stats/avg.py +0 -0
  136. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/stats/count.py +0 -0
  137. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/stats/histogram.py +0 -0
  138. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/stats/max_stat.py +0 -0
  139. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/stats/min_stat.py +0 -0
  140. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/stats/percentile.py +0 -0
  141. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/stats/percentiles.py +0 -0
  142. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/stats/rate.py +0 -0
  143. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/stats/sampled_stat.py +0 -0
  144. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/stats/sensor.py +0 -0
  145. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/metrics/stats/total.py +0 -0
  146. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/net/__init__.py +0 -0
  147. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/net/compat.py +0 -0
  148. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/net/connection.py +0 -0
  149. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/net/http_connect.py +0 -0
  150. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/net/inet.py +0 -0
  151. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/net/metrics.py +0 -0
  152. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/net/sasl/__init__.py +0 -0
  153. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/net/sasl/abc.py +0 -0
  154. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/net/sasl/gssapi.py +0 -0
  155. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/net/sasl/msk.py +0 -0
  156. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/net/sasl/oauth.py +0 -0
  157. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/net/sasl/plain.py +0 -0
  158. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/net/sasl/scram.py +0 -0
  159. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/net/sasl/sspi.py +0 -0
  160. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/net/selector.py +0 -0
  161. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/net/socks5.py +0 -0
  162. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/net/transport.py +0 -0
  163. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/net/wakeup_notifier.py +0 -0
  164. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/partitioner/__init__.py +0 -0
  165. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/partitioner/abc.py +0 -0
  166. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/partitioner/default.py +0 -0
  167. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/partitioner/sticky.py +0 -0
  168. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/producer/__init__.py +0 -0
  169. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/producer/__main__.py +0 -0
  170. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/producer/future.py +0 -0
  171. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/producer/kafka.py +0 -0
  172. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/producer/producer_batch.py +0 -0
  173. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/producer/record_accumulator.py +0 -0
  174. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/producer/sender.py +0 -0
  175. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/producer/transaction_manager.py +0 -0
  176. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/__init__.py +0 -0
  177. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/admin/__init__.py +0 -0
  178. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/admin/acl.py +0 -0
  179. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/admin/acl.pyi +0 -0
  180. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/admin/client_quotas.py +0 -0
  181. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/admin/client_quotas.pyi +0 -0
  182. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/admin/cluster.py +0 -0
  183. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/admin/cluster.pyi +0 -0
  184. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/admin/configs.py +0 -0
  185. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/admin/configs.pyi +0 -0
  186. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/admin/groups.py +0 -0
  187. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/admin/groups.pyi +0 -0
  188. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/admin/topics.py +0 -0
  189. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/admin/topics.pyi +0 -0
  190. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/admin/transactions.py +0 -0
  191. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/admin/transactions.pyi +0 -0
  192. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/admin/users.py +0 -0
  193. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/admin/users.pyi +0 -0
  194. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/api_data.py +0 -0
  195. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/api_header.py +0 -0
  196. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/api_key.py +0 -0
  197. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/api_message.py +0 -0
  198. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/broker_version_data.py +0 -0
  199. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/consumer/__init__.py +0 -0
  200. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/consumer/fetch.py +0 -0
  201. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/consumer/fetch.pyi +0 -0
  202. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/consumer/group.py +0 -0
  203. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/consumer/group.pyi +0 -0
  204. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/consumer/metadata.py +0 -0
  205. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/consumer/metadata.pyi +0 -0
  206. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/consumer/offsets.py +0 -0
  207. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/consumer/offsets.pyi +0 -0
  208. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/data_container.py +0 -0
  209. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/frame.py +0 -0
  210. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/generate_stubs.py +0 -0
  211. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/metadata/__init__.py +0 -0
  212. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/metadata/api_versions.py +0 -0
  213. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/metadata/api_versions.pyi +0 -0
  214. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/metadata/find_coordinator.py +0 -0
  215. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/metadata/find_coordinator.pyi +0 -0
  216. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/metadata/metadata.py +0 -0
  217. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/metadata/metadata.pyi +0 -0
  218. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/__init__.py +0 -0
  219. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/abstract.py +0 -0
  220. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/add_offsets_to_txn.py +0 -0
  221. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/add_partitions_to_txn.py +0 -0
  222. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/admin.py +0 -0
  223. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/api.py +0 -0
  224. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/api_versions.py +0 -0
  225. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/commit.py +0 -0
  226. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/consumer_protocol.py +0 -0
  227. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/end_txn.py +0 -0
  228. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/fetch.py +0 -0
  229. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/find_coordinator.py +0 -0
  230. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/group.py +0 -0
  231. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/init_producer_id.py +0 -0
  232. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/list_offsets.py +0 -0
  233. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/metadata.py +0 -0
  234. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/offset_for_leader_epoch.py +0 -0
  235. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/produce.py +0 -0
  236. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/sasl_authenticate.py +0 -0
  237. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/sasl_handshake.py +0 -0
  238. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/struct.py +0 -0
  239. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/txn_offset_commit.py +0 -0
  240. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/old/types.py +0 -0
  241. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/parser.py +0 -0
  242. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/producer/__init__.py +0 -0
  243. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/producer/produce.py +0 -0
  244. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/producer/produce.pyi +0 -0
  245. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/producer/transaction.py +0 -0
  246. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/producer/transaction.pyi +0 -0
  247. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/sasl.py +0 -0
  248. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/sasl.pyi +0 -0
  249. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/__init__.py +0 -0
  250. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/fields/__init__.py +0 -0
  251. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/fields/base.py +0 -0
  252. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/fields/codecs/__init__.py +0 -0
  253. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/fields/simple.py +0 -0
  254. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/load_json.py +0 -0
  255. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/AddOffsetsToTxnRequest.json +0 -0
  256. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/AddOffsetsToTxnResponse.json +0 -0
  257. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/AddPartitionsToTxnRequest.json +0 -0
  258. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/AddPartitionsToTxnResponse.json +0 -0
  259. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/AlterClientQuotasRequest.json +0 -0
  260. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/AlterClientQuotasResponse.json +0 -0
  261. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/AlterConfigsRequest.json +0 -0
  262. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/AlterConfigsResponse.json +0 -0
  263. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/AlterPartitionReassignmentsRequest.json +0 -0
  264. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/AlterPartitionReassignmentsResponse.json +0 -0
  265. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/AlterReplicaLogDirsRequest.json +0 -0
  266. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/AlterReplicaLogDirsResponse.json +0 -0
  267. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/AlterUserScramCredentialsRequest.json +0 -0
  268. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/AlterUserScramCredentialsResponse.json +0 -0
  269. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/ApiVersionsRequest.json +0 -0
  270. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/ApiVersionsResponse.json +0 -0
  271. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/ConsumerProtocolAssignment.json +0 -0
  272. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/ConsumerProtocolSubscription.json +0 -0
  273. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/CreateAclsRequest.json +0 -0
  274. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/CreateAclsResponse.json +0 -0
  275. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/CreatePartitionsRequest.json +0 -0
  276. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/CreatePartitionsResponse.json +0 -0
  277. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/CreateTopicsRequest.json +0 -0
  278. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/CreateTopicsResponse.json +0 -0
  279. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DeleteAclsRequest.json +0 -0
  280. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DeleteAclsResponse.json +0 -0
  281. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DeleteGroupsRequest.json +0 -0
  282. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DeleteGroupsResponse.json +0 -0
  283. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DeleteRecordsRequest.json +0 -0
  284. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DeleteRecordsResponse.json +0 -0
  285. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DeleteTopicsRequest.json +0 -0
  286. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DeleteTopicsResponse.json +0 -0
  287. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeAclsRequest.json +0 -0
  288. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeAclsResponse.json +0 -0
  289. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeClientQuotasRequest.json +0 -0
  290. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeClientQuotasResponse.json +0 -0
  291. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeClusterRequest.json +0 -0
  292. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeClusterResponse.json +0 -0
  293. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeConfigsRequest.json +0 -0
  294. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeConfigsResponse.json +0 -0
  295. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeGroupsRequest.json +0 -0
  296. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeGroupsResponse.json +0 -0
  297. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeLogDirsRequest.json +0 -0
  298. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeLogDirsResponse.json +0 -0
  299. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeProducersRequest.json +0 -0
  300. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeProducersResponse.json +0 -0
  301. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeQuorumRequest.json +0 -0
  302. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeQuorumResponse.json +0 -0
  303. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeTopicPartitionsRequest.json +0 -0
  304. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeTopicPartitionsResponse.json +0 -0
  305. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeTransactionsRequest.json +0 -0
  306. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeTransactionsResponse.json +0 -0
  307. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeUserScramCredentialsRequest.json +0 -0
  308. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/DescribeUserScramCredentialsResponse.json +0 -0
  309. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/ElectLeadersRequest.json +0 -0
  310. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/ElectLeadersResponse.json +0 -0
  311. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/EndTxnRequest.json +0 -0
  312. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/EndTxnResponse.json +0 -0
  313. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/FetchRequest.json +0 -0
  314. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/FetchResponse.json +0 -0
  315. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/FindCoordinatorRequest.json +0 -0
  316. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/FindCoordinatorResponse.json +0 -0
  317. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/HeartbeatRequest.json +0 -0
  318. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/HeartbeatResponse.json +0 -0
  319. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/IncrementalAlterConfigsRequest.json +0 -0
  320. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/IncrementalAlterConfigsResponse.json +0 -0
  321. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/InitProducerIdRequest.json +0 -0
  322. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/InitProducerIdResponse.json +0 -0
  323. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/JoinGroupRequest.json +0 -0
  324. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/JoinGroupResponse.json +0 -0
  325. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/LeaveGroupRequest.json +0 -0
  326. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/LeaveGroupResponse.json +0 -0
  327. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/ListConfigResourcesRequest.json +0 -0
  328. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/ListConfigResourcesResponse.json +0 -0
  329. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/ListGroupsRequest.json +0 -0
  330. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/ListGroupsResponse.json +0 -0
  331. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/ListOffsetsRequest.json +0 -0
  332. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/ListOffsetsResponse.json +0 -0
  333. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/ListPartitionReassignmentsRequest.json +0 -0
  334. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/ListPartitionReassignmentsResponse.json +0 -0
  335. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/ListTransactionsRequest.json +0 -0
  336. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/ListTransactionsResponse.json +0 -0
  337. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/MetadataRequest.json +0 -0
  338. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/MetadataResponse.json +0 -0
  339. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/OffsetCommitRequest.json +0 -0
  340. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/OffsetCommitResponse.json +0 -0
  341. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/OffsetDeleteRequest.json +0 -0
  342. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/OffsetDeleteResponse.json +0 -0
  343. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/OffsetFetchRequest.json +0 -0
  344. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/OffsetFetchResponse.json +0 -0
  345. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/OffsetForLeaderEpochRequest.json +0 -0
  346. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/OffsetForLeaderEpochResponse.json +0 -0
  347. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/ProduceRequest.json +0 -0
  348. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/ProduceResponse.json +0 -0
  349. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/RequestHeader.json +0 -0
  350. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/ResponseHeader.json +0 -0
  351. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/SaslAuthenticateRequest.json +0 -0
  352. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/SaslAuthenticateResponse.json +0 -0
  353. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/SaslHandshakeRequest.json +0 -0
  354. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/SaslHandshakeResponse.json +0 -0
  355. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/SyncGroupRequest.json +0 -0
  356. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/SyncGroupResponse.json +0 -0
  357. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/TxnOffsetCommitRequest.json +0 -0
  358. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/TxnOffsetCommitResponse.json +0 -0
  359. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/UpdateFeaturesRequest.json +0 -0
  360. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/UpdateFeaturesResponse.json +0 -0
  361. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/WriteTxnMarkersRequest.json +0 -0
  362. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/WriteTxnMarkersResponse.json +0 -0
  363. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/protocol/schemas/resources/__init__.py +0 -0
  364. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/record/__init__.py +0 -0
  365. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/record/_crc32c.py +0 -0
  366. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/record/abc.py +0 -0
  367. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/record/default_records.py +0 -0
  368. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/record/legacy_records.py +0 -0
  369. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/record/memory_records.py +0 -0
  370. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/record/util.py +0 -0
  371. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/serializer/__init__.py +0 -0
  372. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/serializer/abstract.py +0 -0
  373. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/serializer/default.py +0 -0
  374. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/serializer/json.py +0 -0
  375. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/serializer/wrapper.py +0 -0
  376. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/structs.py +0 -0
  377. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/util.py +0 -0
  378. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka/vendor/__init__.py +0 -0
  379. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka_python.egg-info/SOURCES.txt +0 -0
  380. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka_python.egg-info/dependency_links.txt +0 -0
  381. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka_python.egg-info/entry_points.txt +0 -0
  382. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka_python.egg-info/requires.txt +0 -0
  383. {kafka_python-3.0.4 → kafka_python-3.0.6}/kafka_python.egg-info/top_level.txt +0 -0
  384. {kafka_python-3.0.4 → kafka_python-3.0.6}/pyproject.toml +0 -0
  385. {kafka_python-3.0.4 → kafka_python-3.0.6}/setup.cfg +0 -0
  386. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/integration/__init__.py +0 -0
  387. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/integration/conftest.py +0 -0
  388. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/integration/test_admin_integration.py +0 -0
  389. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/integration/test_consumer_integration.py +0 -0
  390. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/integration/test_producer_integration.py +0 -0
  391. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/integration/test_sasl_integration.py +0 -0
  392. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/integration/test_ssl_integration.py +0 -0
  393. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/net/__init__.py +0 -0
  394. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/net/test_compat.py +0 -0
  395. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/net/test_connection.py +0 -0
  396. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/net/test_http_connect.py +0 -0
  397. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/net/test_inet.py +0 -0
  398. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/net/test_sasl_reauthentication.py +0 -0
  399. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/net/test_selector.py +0 -0
  400. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/net/test_transport.py +0 -0
  401. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/net/test_wakeup_notifier.py +0 -0
  402. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/test_cluster.py +0 -0
  403. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/test_codec.py +0 -0
  404. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/test_future.py +0 -0
  405. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/test_metrics.py +0 -0
  406. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/test_mock_broker.py +0 -0
  407. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/test_package.py +0 -0
  408. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/test_util.py +0 -0
  409. {kafka_python-3.0.4 → kafka_python-3.0.6}/test/testutil.py +0 -0
@@ -1,3 +1,26 @@
1
+ # 3.0.6 (Jun 25, 2026)
2
+
3
+ ### Fixes
4
+ * consumer: track current leader epoch in addition to record epoch (#3107)
5
+
6
+
7
+ ### CI
8
+ * Also `wait_for_topics` on <0.10 test fixtures (#3105)
9
+
10
+ # 3.0.5 (Jun 24, 2026)
11
+
12
+ ### Fixes
13
+ * Reserve buffer capacity before every encode_into write (#3103)
14
+ * Fix backoff on bootstrap init failure after connection_made (#3098)
15
+
16
+ ### CI
17
+ * Bump actions/cache from 5 to 6 (#3099)
18
+ * only save kafka dist cache on master (#3100)
19
+ * Fix flakey test: test_send_during_backoff
20
+
21
+ ### Documentation
22
+ * Add new extended logging args to docs/cli
23
+
1
24
  # 3.0.4 (Jun 23, 2026)
2
25
 
3
26
  ### Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kafka-python
3
- Version: 3.0.4
3
+ Version: 3.0.6
4
4
  Summary: Pure Python client for Apache Kafka
5
5
  Author-email: Dana Powers <dana.powers@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -564,6 +564,18 @@ class TopicPartitionState:
564
564
  # until OffsetForLeaderEpoch confirms the position is consistent with
565
565
  # the current leader's log; mutually exclusive with awaiting_reset.
566
566
  self._awaiting_validation = False
567
+ # Highest cluster leader epoch this position has already been reconciled
568
+ # against (a completed validation, or adoption of a position whose
569
+ # record epoch is unknown). This is deliberately distinct from the
570
+ # position's *record* epoch (``OffsetAndMetadata.leader_epoch``, which
571
+ # is sent as last_fetched_epoch for KIP-595 divergence detection): a
572
+ # leader election bumps the cluster epoch without changing the epoch of
573
+ # the record we're positioned on, and OffsetForLeaderEpoch reports the
574
+ # epoch of the requested (older) point, so the record epoch alone can't
575
+ # tell us whether we've validated against the current leader. Tracking
576
+ # it separately is what stops poll() from re-validating forever and
577
+ # stalling the consumer. See #3106.
578
+ self._current_leader_epoch = -1
567
579
  # KIP-392: preferred read replica chosen by the broker (rack-aware).
568
580
  # ``_preferred_read_replica_expiration`` is a monotonic deadline; after
569
581
  # it passes we fall back to the leader and re-learn. Cleared on
@@ -597,6 +609,7 @@ class TopicPartitionState:
597
609
  self._position = None
598
610
  self.next_allowed_retry_time = None
599
611
  self._awaiting_validation = False
612
+ self._current_leader_epoch = -1
600
613
  self.clear_preferred_read_replica()
601
614
 
602
615
  def is_reset_allowed(self):
@@ -625,6 +638,11 @@ class TopicPartitionState:
625
638
  self.drop_pending_record_batch = True
626
639
  self.next_allowed_retry_time = None
627
640
  self._awaiting_validation = False
641
+ # A freshly-seeked position has not been reconciled against any leader;
642
+ # force the next maybe_validate_position to validate it against the
643
+ # current leader (the prior position's validation says nothing about
644
+ # this offset).
645
+ self._current_leader_epoch = -1
628
646
  self.clear_preferred_read_replica()
629
647
 
630
648
  def pause(self):
@@ -686,7 +704,8 @@ class TopicPartitionState:
686
704
  return self._awaiting_validation
687
705
 
688
706
  def maybe_validate_position(self, current_leader_epoch):
689
- """Mark for validation if current leader has advanced beyond our position's epoch.
707
+ """Mark for validation if the current leader has advanced beyond the
708
+ leader epoch this position was last reconciled against.
690
709
 
691
710
  Returns True if the partition is now awaiting validation.
692
711
  """
@@ -696,11 +715,26 @@ class TopicPartitionState:
696
715
  return False
697
716
  if current_leader_epoch is None or current_leader_epoch < 0:
698
717
  return False
699
- # Positions without a known epoch (legacy data, post-seek to bare offset)
700
- # can't be validated; treat as already-fetchable.
701
- if self._position.leader_epoch < 0:
718
+ # Have we already reconciled this position against this leader epoch (or
719
+ # a newer one)? The floor is the max of:
720
+ # - the record epoch of the position itself: a record we actually
721
+ # fetched at this offset proves the position is valid through its
722
+ # epoch (so a position fetched under the current leader needs no
723
+ # validation), and
724
+ # - the leader epoch a completed validation reconciled us against,
725
+ # which can exceed the record epoch because OffsetForLeaderEpoch
726
+ # reports the epoch of the requested (older) point, not the current
727
+ # leader's. Without this second term the position is re-marked every
728
+ # poll and the partition never becomes fetchable again (#3106).
729
+ reconciled_epoch = max(self._current_leader_epoch, self._position.leader_epoch)
730
+ if current_leader_epoch <= reconciled_epoch:
702
731
  return False
703
- if self._position.leader_epoch >= current_leader_epoch:
732
+ # We are now tracking this leader epoch regardless of whether the
733
+ # position itself carries a record epoch we can validate against.
734
+ self._current_leader_epoch = current_leader_epoch
735
+ # Positions without a known record epoch (legacy data, post-seek to bare
736
+ # offset) can't be validated; treat as already-fetchable.
737
+ if self._position.leader_epoch < 0:
704
738
  return False
705
739
  self.clear_preferred_read_replica()
706
740
  self._awaiting_validation = True
@@ -142,6 +142,9 @@ class KafkaConnectionManager:
142
142
  raise
143
143
  except Exception as exc:
144
144
  self._conns.pop(bootstrap_broker.node_id, conn).close(exc)
145
+ backoff_ms = self.update_backoff(bootstrap_broker.node_id)
146
+ log.warning('Bootstrap connection to %s failed: %s (backoff %.2f secs)',
147
+ bootstrap_broker.node_id, exc, backoff_ms / 1000)
145
148
  continue
146
149
 
147
150
  try:
@@ -258,6 +261,8 @@ class KafkaConnectionManager:
258
261
  return
259
262
  conn.connection_made(transport)
260
263
  transport = None # conn owns cleanup now; skip finally: transport.close()
264
+ # Note: conn.initialize does not currently raise on error;
265
+ # errors are pushed to conn.init_future and raised on await conn
261
266
  await conn.initialize(timeout_at=timeout_at)
262
267
  except Exception as exc:
263
268
  log.error('Connection failed: %s', exc)
@@ -72,9 +72,10 @@ class ArrayField(BaseField):
72
72
  if compact:
73
73
  an = ctx.next_var('an')
74
74
  ctx.emit(indent, '%s = len(%s) + 1 if %s is not None else 0' % (an, val_expr, val_expr))
75
- UnsignedVarInt32.emit_encode_into(ctx, an, indent)
75
+ UnsignedVarInt32.emit_encode_into(ctx, an, indent) # reserves the length varint
76
76
  ctx.emit(indent, 'if %s is not None:' % val_expr)
77
77
  else:
78
+ ctx.emit_reserve(indent, 4)
78
79
  ctx.emit(indent, 'if %s is None:' % val_expr)
79
80
  ctx.emit(indent, " pack_into('>i', buf, pos, -1)")
80
81
  ctx.emit(indent, ' pos += 4')
@@ -83,9 +84,23 @@ class ArrayField(BaseField):
83
84
  ctx.emit(indent, ' pos += 4')
84
85
  guard = indent + ' '
85
86
  item_var = ctx.next_var('ai')
86
- ctx.emit(guard, 'for %s in %s:' % (item_var, val_expr))
87
- self.array_of.emit_encode_into(ctx, item_var, guard + ' ',
88
- version=version, compact=compact, tagged=tagged)
87
+ elem = self.array_of
88
+ if isinstance(elem, SimpleField) and elem.is_batchable():
89
+ # Fast path: array of fixed-size primitives (e.g. []int32). Reserve
90
+ # the whole run with a single ensure, then write each element inline
91
+ # without a per-element capacity check. The reserve sits inside the
92
+ # `is not None` branch (compact) / `else` branch (non-compact), so
93
+ # len() is always safe here.
94
+ be_fmt = elem._type._be_fmt
95
+ size = elem._type.size
96
+ ctx.emit_reserve(guard, '%d * len(%s)' % (size, val_expr))
97
+ ctx.emit(guard, 'for %s in %s:' % (item_var, val_expr))
98
+ ctx.emit(guard, " pack_into('%s', buf, pos, %s)" % (be_fmt, item_var))
99
+ ctx.emit(guard, ' pos += %d' % size)
100
+ else:
101
+ ctx.emit(guard, 'for %s in %s:' % (item_var, val_expr))
102
+ elem.emit_encode_into(ctx, item_var, guard + ' ',
103
+ version=version, compact=compact, tagged=tagged)
89
104
 
90
105
  def emit_decode_from(self, ctx, var_name, indent, version=None, compact=False, tagged=False):
91
106
  n = ctx.next_var('n')
@@ -2,7 +2,35 @@ import threading
2
2
 
3
3
 
4
4
  class EncodeBuffer:
5
- """Growable buffer for encode_into operations."""
5
+ """Growable byte buffer for the ``encode_into`` fast path.
6
+
7
+ The encoders write primitives directly into ``buf`` at offset ``pos``
8
+ rather than building and joining intermediate ``bytes`` objects. The
9
+ buffer starts at a fixed size and grows on demand via :meth:`ensure`.
10
+
11
+ Capacity contract
12
+ -----------------
13
+ Writing past the end of ``buf`` does not grow it automatically:
14
+
15
+ * single-byte index writes (``buf[pos] = x``) raise ``IndexError``,
16
+ * ``pack_into`` raises ``struct.error``,
17
+ * slice assignment (``buf[pos:pos+n] = data``) silently *resizes* the
18
+ bytearray, defeating the preallocation.
19
+
20
+ Therefore **every writer must call** ``ensure(n)`` to reserve ``n`` bytes
21
+ before writing ``n`` bytes at ``pos`` (where ``n`` is the maximum the write
22
+ can consume - e.g. ``5`` for a varint32, a fixed field's ``size``, or
23
+ ``len(payload)`` for variable data). See the codecs in ``types.py`` for the
24
+ pattern, and ``CodegenContext.emit_reserve`` for the compiled equivalent.
25
+
26
+ Reallocation note
27
+ -----------------
28
+ ``ensure`` may replace ``buf`` with a larger bytearray. Any caller (or
29
+ generated code) that caches ``buf`` in a local **must re-read** ``self.buf``
30
+ after a call that can grow it - including indirect growth through a nested
31
+ ``encode_into`` / ``ensure``. Forgetting to re-read leaves writes targeting
32
+ the old, discarded buffer (silent data loss) or raises out of range.
33
+ """
6
34
  __slots__ = ('buf', 'pos')
7
35
 
8
36
  def __init__(self, size=65536):
@@ -14,6 +42,16 @@ class EncodeBuffer:
14
42
  self.pos = 0
15
43
 
16
44
  def ensure(self, needed):
45
+ """Guarantee at least ``needed`` writable bytes remain at ``pos``.
46
+
47
+ Call this *before* writing ``needed`` bytes at ``self.pos``. If the
48
+ current buffer cannot hold them it is grown (at least doubled) and the
49
+ existing ``[:pos]`` content is preserved.
50
+
51
+ WARNING: this may rebind ``self.buf`` to a new bytearray, so re-read
52
+ ``self.buf`` afterwards if you hold a local reference to it (see the
53
+ class docstring).
54
+ """
17
55
  if self.pos + needed > len(self.buf):
18
56
  new_size = max(len(self.buf) * 2, self.pos + needed)
19
57
  new_buf = bytearray(new_size)
@@ -21,6 +59,7 @@ class EncodeBuffer:
21
59
  self.buf = new_buf
22
60
 
23
61
  def result(self):
62
+ """Return the encoded bytes written so far (``buf[:pos]``)."""
24
63
  # Return a bytearray slice (one copy) rather than bytes(self.buf[:pos])
25
64
  # (two copies - the slice creates a bytearray, then bytes() copies
26
65
  # again). Downstream consumers (protocol codec slice assignment,
@@ -60,6 +60,7 @@ class TaggedFields:
60
60
  # Encode value into buffer after reserving space for size prefix.
61
61
  # Strategy: assume size fits in 1 byte (< 128), encode value,
62
62
  # then fix up if the size varint is larger.
63
+ out.ensure(1) # reserve the assumed 1-byte size prefix
63
64
  size_pos = out.pos
64
65
  out.pos += 1 # reserve 1 byte for size
65
66
  val_start = out.pos
@@ -26,6 +26,7 @@ class FixedCodec:
26
26
 
27
27
  @classmethod
28
28
  def encode_into(cls, out, value, compact=False):
29
+ out.ensure(cls.size)
29
30
  pack_into(cls._be_fmt, out.buf, out.pos, value)
30
31
  out.pos += cls.size
31
32
 
@@ -40,6 +41,7 @@ class FixedCodec:
40
41
 
41
42
  @classmethod
42
43
  def emit_encode_into(cls, ctx, val_expr, indent, compact=False):
44
+ ctx.emit_reserve(indent, cls.size)
43
45
  ctx.emit(indent, "pack_into('%s', buf, pos, %s)" % (cls._be_fmt, val_expr))
44
46
  ctx.emit(indent, 'pos += %d' % cls.size)
45
47
 
@@ -101,6 +103,7 @@ class UUID:
101
103
  b = value.bytes
102
104
  else:
103
105
  b = uuid.UUID(value).bytes
106
+ out.ensure(16)
104
107
  pos = out.pos
105
108
  out.buf[pos:pos+16] = b
106
109
  out.pos = pos + 16
@@ -111,6 +114,7 @@ class UUID:
111
114
  v = ctx.next_var('uv')
112
115
  ctx.emit(indent, '%s = %s' % (v, val_expr))
113
116
  ctx.emit(indent, 'if %s is None: %s = _ZERO_UUID' % (v, v))
117
+ ctx.emit_reserve(indent, 16)
114
118
  ctx.emit(indent, 'buf[pos:pos+16] = %s.bytes if hasattr(%s, "bytes") else __import__("uuid").UUID(%s).bytes' % (v, v, v))
115
119
  ctx.emit(indent, 'pos += 16')
116
120
 
@@ -151,43 +155,52 @@ class String:
151
155
  def encode_into(self, out, value, compact=False):
152
156
  if compact:
153
157
  if value is None:
154
- UnsignedVarInt32.encode_into(out,0)
158
+ UnsignedVarInt32.encode_into(out, 0) # ensures internally
155
159
  return
156
160
  value = str(value).encode(self.encoding)
157
- UnsignedVarInt32.encode_into(out,len(value) + 1)
161
+ UnsignedVarInt32.encode_into(out, len(value) + 1) # ensures internally
158
162
  else:
159
163
  if value is None:
164
+ out.ensure(2)
160
165
  pack_into('>h', out.buf, out.pos, -1)
161
166
  out.pos += 2
162
167
  return
163
168
  value = str(value).encode(self.encoding)
169
+ out.ensure(2)
164
170
  pack_into('>h', out.buf, out.pos, len(value))
165
171
  out.pos += 2
166
172
  n = len(value)
173
+ out.ensure(n)
167
174
  pos = out.pos
168
175
  out.buf[pos:pos+n] = value
169
176
  out.pos = pos + n
170
177
 
171
178
  def emit_encode_into(self, ctx, val_expr, indent, compact=False):
172
179
  sv = ctx.next_var('sv')
180
+ body = indent + ' '
173
181
  ctx.emit(indent, 'if %s is None:' % val_expr)
174
182
  if compact:
183
+ ctx.emit_reserve(body, 1)
175
184
  ctx.emit(indent, ' buf[pos] = 0')
176
185
  ctx.emit(indent, ' pos += 1')
177
186
  ctx.emit(indent, 'else:')
178
187
  sn = ctx.next_var('sn')
179
188
  ctx.emit(indent, ' %s = str(%s).encode("utf-8")' % (sv, val_expr))
180
189
  ctx.emit(indent, ' %s = len(%s) + 1' % (sn, sv))
181
- UnsignedVarInt32.emit_encode_into(ctx, sn, indent + ' ')
190
+ UnsignedVarInt32.emit_encode_into(ctx, sn, body) # reserves the length varint
191
+ ctx.emit_reserve(body, 'len(%s)' % sv)
182
192
  ctx.emit(indent, ' buf[pos:pos+len(%s)] = %s' % (sv, sv))
183
193
  ctx.emit(indent, ' pos += len(%s)' % sv)
184
194
  else:
195
+ ctx.emit_reserve(body, 2)
185
196
  ctx.emit(indent, " pack_into('>h', buf, pos, -1)")
186
197
  ctx.emit(indent, ' pos += 2')
187
198
  ctx.emit(indent, 'else:')
188
199
  ctx.emit(indent, ' %s = str(%s).encode("utf-8")' % (sv, val_expr))
200
+ ctx.emit_reserve(body, 2)
189
201
  ctx.emit(indent, " pack_into('>h', buf, pos, len(%s))" % sv)
190
202
  ctx.emit(indent, ' pos += 2')
203
+ ctx.emit_reserve(body, 'len(%s)' % sv)
191
204
  ctx.emit(indent, ' buf[pos:pos+len(%s)] = %s' % (sv, sv))
192
205
  ctx.emit(indent, ' pos += len(%s)' % sv)
193
206
 
@@ -240,14 +253,16 @@ class Bytes:
240
253
  value = value.encode()
241
254
  if compact:
242
255
  if value is None:
243
- UnsignedVarInt32.encode_into(out, 0)
256
+ UnsignedVarInt32.encode_into(out, 0) # ensures internally
244
257
  return
245
- UnsignedVarInt32.encode_into(out, len(value) + 1)
258
+ UnsignedVarInt32.encode_into(out, len(value) + 1) # ensures internally
246
259
  else:
247
260
  if value is None:
261
+ out.ensure(4)
248
262
  pack_into('>i', out.buf, out.pos, -1)
249
263
  out.pos += 4
250
264
  return
265
+ out.ensure(4)
251
266
  pack_into('>i', out.buf, out.pos, len(value))
252
267
  out.pos += 4
253
268
  n = len(value)
@@ -260,35 +275,35 @@ class Bytes:
260
275
  def emit_encode_into(cls, ctx, val_expr, indent, compact=False):
261
276
  bv = ctx.next_var('bv')
262
277
  bn = ctx.next_var('bn')
278
+ body = indent + ' '
263
279
  if compact:
264
280
  ctx.emit(indent, '%s = %s' % (bv, val_expr))
265
281
  ctx.emit(indent, 'if %s is not None and not isinstance(%s, (bytes, bytearray, memoryview)): %s = %s.encode()' % (bv, bv, bv, bv))
266
282
  ctx.emit(indent, 'if %s is None:' % bv)
283
+ ctx.emit_reserve(body, 1)
267
284
  ctx.emit(indent, ' buf[pos] = 0')
268
285
  ctx.emit(indent, ' pos += 1')
269
286
  ctx.emit(indent, 'else:')
270
287
  ctx.emit(indent, ' %s = len(%s)' % (bn, bv))
271
288
  sn = ctx.next_var('sn')
272
289
  ctx.emit(indent, ' %s = %s + 1' % (sn, bn))
273
- UnsignedVarInt32.emit_encode_into(ctx, sn, indent + ' ')
274
- ctx.emit(indent, ' out.pos = pos')
275
- ctx.emit(indent, ' out.ensure(%s)' % bn)
276
- ctx.emit(indent, ' buf = out.buf')
290
+ UnsignedVarInt32.emit_encode_into(ctx, sn, body) # reserves the length varint
291
+ ctx.emit_reserve(body, bn)
277
292
  ctx.emit(indent, ' buf[pos:pos+%s] = %s' % (bn, bv))
278
293
  ctx.emit(indent, ' pos += %s' % bn)
279
294
  else:
280
295
  ctx.emit(indent, '%s = %s' % (bv, val_expr))
281
296
  ctx.emit(indent, 'if %s is not None and not isinstance(%s, (bytes, bytearray, memoryview)): %s = %s.encode()' % (bv, bv, bv, bv))
282
297
  ctx.emit(indent, 'if %s is None:' % bv)
298
+ ctx.emit_reserve(body, 4)
283
299
  ctx.emit(indent, " pack_into('>i', buf, pos, -1)")
284
300
  ctx.emit(indent, ' pos += 4')
285
301
  ctx.emit(indent, 'else:')
286
302
  ctx.emit(indent, ' %s = len(%s)' % (bn, bv))
303
+ ctx.emit_reserve(body, 4)
287
304
  ctx.emit(indent, " pack_into('>i', buf, pos, %s)" % bn)
288
305
  ctx.emit(indent, ' pos += 4')
289
- ctx.emit(indent, ' out.pos = pos')
290
- ctx.emit(indent, ' out.ensure(%s)' % bn)
291
- ctx.emit(indent, ' buf = out.buf')
306
+ ctx.emit_reserve(body, bn)
292
307
  ctx.emit(indent, ' buf[pos:pos+%s] = %s' % (bn, bv))
293
308
  ctx.emit(indent, ' pos += %s' % bn)
294
309
 
@@ -341,6 +356,7 @@ class UnsignedVarInt32:
341
356
 
342
357
  @classmethod
343
358
  def encode_into(cls, out, value):
359
+ out.ensure(5) # a varint32 is at most 5 bytes
344
360
  buf = out.buf
345
361
  pos = out.pos
346
362
  while (value & 0xffffff80) != 0:
@@ -352,6 +368,7 @@ class UnsignedVarInt32:
352
368
 
353
369
  @classmethod
354
370
  def emit_encode_into(cls, ctx, val_expr, indent, compact=False):
371
+ ctx.emit_reserve(indent, 5) # a varint32 is at most 5 bytes
355
372
  ctx.emit(indent, 'while (%s & 0xffffff80) != 0:' % val_expr)
356
373
  ctx.emit(indent, ' buf[pos] = (%s & 0x7f) | 0x80' % val_expr)
357
374
  ctx.emit(indent, ' %s >>= 7' % val_expr)
@@ -462,6 +479,7 @@ class BitField:
462
479
  def encode_into(cls, out, vals, compact=False):
463
480
  if vals is None:
464
481
  vals = {31}
482
+ out.ensure(4)
465
483
  pack_into('>I', out.buf, out.pos, cls.to_32_bit_field(vals))
466
484
  out.pos += 4
467
485
 
@@ -473,6 +491,7 @@ class BitField:
473
491
  ctx.emit(indent, 'if %s is None: %s = {31}' % (bf, bf))
474
492
  ctx.emit(indent, '%s = 0' % bfi)
475
493
  ctx.emit(indent, 'for _b in %s: %s |= 1 << _b' % (bf, bfi))
494
+ ctx.emit_reserve(indent, 4)
476
495
  ctx.emit(indent, "pack_into('>I', buf, pos, %s)" % bfi)
477
496
  ctx.emit(indent, 'pos += 4')
478
497
 
@@ -0,0 +1,71 @@
1
+ """Generate flat encode/decode functions for a StructField + version.
2
+
3
+ Given a StructField and a protocol version, generates Python functions
4
+ that encode/decode directly with zero dispatch overhead - no intermediate
5
+ SimpleField/ArrayField/StructField method calls.
6
+
7
+ Usage:
8
+ from kafka.protocol.schemas.fields.codegen import CodegenContext
9
+ # Encode: see StructField.compiled_encode_into()
10
+ # Decode: see StructField.compiled_decode_from()
11
+ """
12
+
13
+ from struct import pack_into, unpack_from
14
+
15
+
16
+ class CodegenContext:
17
+ """Shared state for code generation."""
18
+
19
+ def __init__(self):
20
+ self.lines = []
21
+ self.globs = {'pack_into': pack_into, 'unpack_from': unpack_from}
22
+ self._var_counter = 0
23
+
24
+ def next_var(self, prefix='v'):
25
+ self._var_counter += 1
26
+ return f'_{prefix}{self._var_counter}'
27
+
28
+ def emit(self, indent, line):
29
+ self.lines.append(f'{indent}{line}')
30
+
31
+ def emit_reserve(self, indent, nbytes):
32
+ """Emit an inline capacity check before a write of up to ``nbytes`` bytes.
33
+
34
+ Generated encode functions keep three locals in sync:
35
+
36
+ * ``buf`` - the destination bytearray (``out.buf``),
37
+ * ``pos`` - the current write offset,
38
+ * ``_cap`` - ``len(buf)``, the cached capacity.
39
+
40
+ These are not set up per fragment: they are declared once by the
41
+ ``def _encode(item, out):`` preamble in
42
+ ``StructField.encode_into__optimized_context`` (the sole generator of
43
+ the compiled encode function), and every emitted fragment - including
44
+ this one - is spliced into that function body. Emit fragments are
45
+ therefore only valid inside that body; they cannot stand alone.
46
+
47
+ ``nbytes`` is the MAXIMUM number of bytes the following write can
48
+ consume (an ``int`` for fixed/varint fields, or a string expression
49
+ such as ``'len(_bv1)'`` for a variable payload). The fast path is a
50
+ single comparison; only on overflow do we sync ``out.pos``, grow via
51
+ :meth:`EncodeBuffer.ensure`, and re-read the (possibly reallocated)
52
+ buffer back into ``buf``/``_cap``.
53
+
54
+ Because :meth:`EncodeBuffer.ensure` may rebind ``out.buf``, code that
55
+ instead delegates to a runtime ``encode_into`` (e.g. tagged fields)
56
+ must re-bind ``buf``/``_cap`` itself afterwards - ``emit_reserve`` only
57
+ covers writes emitted inline.
58
+ """
59
+ self.emit(indent, 'if pos + %s > _cap:' % nbytes)
60
+ self.emit(indent, ' out.pos = pos; out.ensure(%s); buf = out.buf; _cap = len(buf)' % nbytes)
61
+
62
+ def source(self):
63
+ return '\n'.join(self.lines)
64
+
65
+ def print(self):
66
+ print('GLOBALS:')
67
+ for var in self.globs:
68
+ print(f' {var}={self.globs[var]}')
69
+ print('\nSOURCE:')
70
+ for i, line in enumerate(self.lines):
71
+ print(f'{i+1:<4} {line}')
@@ -116,6 +116,7 @@ class StructField(BaseField):
116
116
  and not tuple_access
117
117
  )
118
118
  if inline_nullable:
119
+ ctx.emit_reserve(indent, 1)
119
120
  ctx.emit(indent, 'if %s is None:' % item_expr)
120
121
  ctx.emit(indent, ' buf[pos] = 0xff')
121
122
  ctx.emit(indent, ' pos += 1')
@@ -136,8 +137,13 @@ class StructField(BaseField):
136
137
  ctx.globs[tf_var] = self.tagged_fields(version)
137
138
  ctx.emit(indent, 'out.pos = pos')
138
139
  ctx.emit(indent, '%s.encode_into(%s, out, version=%d)' % (tf_var, item_expr, version))
140
+ # TaggedFields.encode_into may grow (reallocate) out.buf, so re-bind
141
+ # the cached buf/_cap locals before any further inline writes.
139
142
  ctx.emit(indent, 'pos = out.pos')
143
+ ctx.emit(indent, 'buf = out.buf')
144
+ ctx.emit(indent, '_cap = len(buf)')
140
145
  elif tagged is None:
146
+ ctx.emit_reserve(indent, 1)
141
147
  ctx.emit(indent, 'buf[pos] = 0')
142
148
  ctx.emit(indent, 'pos += 1')
143
149
 
@@ -170,9 +176,13 @@ class StructField(BaseField):
170
176
  def encode_into__optimized_context(self, version, compact=False, tagged=False):
171
177
  ctx = CodegenContext()
172
178
  indent = ' '
179
+ # Preamble: declare the buf/pos/_cap locals that every emitted fragment
180
+ # relies on (see CodegenContext.emit_reserve). Fragments are spliced
181
+ # into this function body and are not valid outside it.
173
182
  ctx.lines.append('def _encode(item, out):')
174
183
  ctx.emit(indent, 'buf = out.buf')
175
184
  ctx.emit(indent, 'pos = out.pos')
185
+ ctx.emit(indent, '_cap = len(buf) # cached len(buf); kept in sync by emit_reserve')
176
186
  self.emit_encode_into(ctx, 'item', indent, version=version, compact=compact, tagged=tagged)
177
187
  ctx.emit(indent, 'out.pos = pos')
178
188
  return ctx
@@ -92,9 +92,10 @@ class StructArrayField(ArrayField):
92
92
  if compact:
93
93
  an = ctx.next_var('an')
94
94
  ctx.emit(indent, '%s = len(%s) + 1 if %s is not None else 0' % (an, val_expr, val_expr))
95
- UnsignedVarInt32.emit_encode_into(ctx, an, indent)
95
+ UnsignedVarInt32.emit_encode_into(ctx, an, indent) # reserves the length varint
96
96
  ctx.emit(indent, 'if %s is not None:' % val_expr)
97
97
  else:
98
+ ctx.emit_reserve(indent, 4)
98
99
  ctx.emit(indent, 'if %s is None:' % val_expr)
99
100
  ctx.emit(indent, " pack_into('>i', buf, pos, -1)")
100
101
  ctx.emit(indent, ' pos += 4')
@@ -118,8 +119,12 @@ class StructArrayField(ArrayField):
118
119
  ctx.emit(scalar_indent, 'out.pos = pos')
119
120
  ctx.emit(scalar_indent, '# tagged fields for single-field struct')
120
121
  ctx.emit(scalar_indent, '%s.encode_into(%s, out, version=%d)' % (tf_var, item_var, version))
122
+ # encode_into may reallocate out.buf - re-bind cached locals.
121
123
  ctx.emit(scalar_indent, 'pos = out.pos')
124
+ ctx.emit(scalar_indent, 'buf = out.buf')
125
+ ctx.emit(scalar_indent, '_cap = len(buf)')
122
126
  elif tagged is None:
127
+ ctx.emit_reserve(scalar_indent, 1)
123
128
  ctx.emit(scalar_indent, 'buf[pos] = 0')
124
129
  ctx.emit(scalar_indent, 'pos += 1')
125
130
  else:
@@ -0,0 +1 @@
1
+ __version__ = '3.0.6'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kafka-python
3
- Version: 3.0.4
3
+ Version: 3.0.6
4
4
  Summary: Pure Python client for Apache Kafka
5
5
  Author-email: Dana Powers <dana.powers@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -34,21 +34,29 @@ def create_topics(broker, topic_names, num_partitions=None, replication_factor=N
34
34
  for topic_name in topic_names:
35
35
  # TODO: verify kafka-topics.sh support for early 0.8 brokers
36
36
  broker._create_topic_via_cli(topic_name, num_partitions, replication_factor)
37
+ _wait_for_topics(broker, topic_names)
37
38
 
38
39
 
39
40
  def _create_topics_via_admin(broker, topic_names, num_partitions, replication_factor):
40
- from kafka.admin import NewTopic
41
- params = broker._enrich_client_params({}, client_id='topic_creator')
42
- admin = KafkaAdminClient(**params)
43
- try:
44
- topics = [NewTopic(name, num_partitions, replication_factor) for name in topic_names]
45
- admin.create_topics(topics, wait_for_metadata=True)
46
- except InvalidReplicationFactorError:
47
- time.sleep(0.5)
48
- topics = [NewTopic(name, num_partitions, replication_factor) for name in topic_names]
49
- admin.create_topics(topics, wait_for_metadata=True)
50
- finally:
51
- admin.close()
41
+ params = broker._enrich_client_params({'api_version': env_kafka_version(), 'client_id': 'topic_creator'})
42
+ with KafkaAdminClient(**params) as admin:
43
+ try:
44
+ topics = {name: {'num_partitions': num_partitions, 'replication_factor': replication_factor}
45
+ for name in topic_names}
46
+ admin.create_topics(topics, wait_for_metadata=True)
47
+ except InvalidReplicationFactorError:
48
+ # wait and try again
49
+ # in CI the brokers sometimes take a while to find themselves
50
+ time.sleep(0.5)
51
+ topics = {name: {'num_partitions': num_partitions, 'replication_factor': replication_factor}
52
+ for name in topic_names}
53
+ admin.create_topics(topics, wait_for_metadata=True)
54
+
55
+
56
+ def _wait_for_topics(broker, topics):
57
+ params = broker._enrich_client_params({'api_version': env_kafka_version(), 'client_id': 'topic_creator'})
58
+ with KafkaAdminClient(**params) as admin:
59
+ admin.wait_for_topics(topics)
52
60
 
53
61
 
54
62
  def client_params(broker, client_id='client', **overrides):