kafka-python 2.1.5__tar.gz → 2.1.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 (157) hide show
  1. {kafka_python-2.1.5 → kafka_python-2.1.6}/CHANGES.md +5 -0
  2. {kafka_python-2.1.5 → kafka_python-2.1.6}/PKG-INFO +1 -1
  3. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/consumer/fetcher.py +38 -27
  4. kafka_python-2.1.6/kafka/version.py +1 -0
  5. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka_python.egg-info/PKG-INFO +1 -1
  6. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_fetcher.py +1 -0
  7. kafka_python-2.1.5/kafka/version.py +0 -1
  8. {kafka_python-2.1.5 → kafka_python-2.1.6}/AUTHORS.md +0 -0
  9. {kafka_python-2.1.5 → kafka_python-2.1.6}/LICENSE +0 -0
  10. {kafka_python-2.1.5 → kafka_python-2.1.6}/MANIFEST.in +0 -0
  11. {kafka_python-2.1.5 → kafka_python-2.1.6}/README.rst +0 -0
  12. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/__init__.py +0 -0
  13. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/admin/__init__.py +0 -0
  14. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/admin/acl_resource.py +0 -0
  15. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/admin/client.py +0 -0
  16. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/admin/config_resource.py +0 -0
  17. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/admin/new_partitions.py +0 -0
  18. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/admin/new_topic.py +0 -0
  19. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/benchmarks/__init__.py +0 -0
  20. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/benchmarks/consumer_performance.py +0 -0
  21. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/benchmarks/load_example.py +0 -0
  22. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/benchmarks/producer_performance.py +0 -0
  23. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/benchmarks/record_batch_compose.py +0 -0
  24. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/benchmarks/record_batch_read.py +0 -0
  25. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/benchmarks/varint_speed.py +0 -0
  26. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/client_async.py +0 -0
  27. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/cluster.py +0 -0
  28. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/codec.py +0 -0
  29. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/conn.py +0 -0
  30. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/consumer/__init__.py +0 -0
  31. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/consumer/group.py +0 -0
  32. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/consumer/subscription_state.py +0 -0
  33. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/coordinator/__init__.py +0 -0
  34. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/coordinator/assignors/__init__.py +0 -0
  35. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/coordinator/assignors/abstract.py +0 -0
  36. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/coordinator/assignors/range.py +0 -0
  37. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/coordinator/assignors/roundrobin.py +0 -0
  38. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/coordinator/assignors/sticky/__init__.py +0 -0
  39. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/coordinator/assignors/sticky/partition_movements.py +0 -0
  40. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/coordinator/assignors/sticky/sorted_set.py +0 -0
  41. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/coordinator/assignors/sticky/sticky_assignor.py +0 -0
  42. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/coordinator/base.py +0 -0
  43. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/coordinator/consumer.py +0 -0
  44. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/coordinator/heartbeat.py +0 -0
  45. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/coordinator/protocol.py +0 -0
  46. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/errors.py +0 -0
  47. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/future.py +0 -0
  48. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/__init__.py +0 -0
  49. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/compound_stat.py +0 -0
  50. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/dict_reporter.py +0 -0
  51. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/kafka_metric.py +0 -0
  52. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/measurable.py +0 -0
  53. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/measurable_stat.py +0 -0
  54. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/metric_config.py +0 -0
  55. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/metric_name.py +0 -0
  56. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/metrics.py +0 -0
  57. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/metrics_reporter.py +0 -0
  58. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/quota.py +0 -0
  59. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/stat.py +0 -0
  60. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/stats/__init__.py +0 -0
  61. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/stats/avg.py +0 -0
  62. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/stats/count.py +0 -0
  63. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/stats/histogram.py +0 -0
  64. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/stats/max_stat.py +0 -0
  65. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/stats/min_stat.py +0 -0
  66. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/stats/percentile.py +0 -0
  67. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/stats/percentiles.py +0 -0
  68. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/stats/rate.py +0 -0
  69. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/stats/sampled_stat.py +0 -0
  70. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/stats/sensor.py +0 -0
  71. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/metrics/stats/total.py +0 -0
  72. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/partitioner/__init__.py +0 -0
  73. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/partitioner/default.py +0 -0
  74. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/producer/__init__.py +0 -0
  75. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/producer/future.py +0 -0
  76. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/producer/kafka.py +0 -0
  77. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/producer/record_accumulator.py +0 -0
  78. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/producer/sender.py +0 -0
  79. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/__init__.py +0 -0
  80. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/abstract.py +0 -0
  81. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/admin.py +0 -0
  82. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/api.py +0 -0
  83. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/api_versions.py +0 -0
  84. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/broker_api_versions.py +0 -0
  85. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/commit.py +0 -0
  86. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/fetch.py +0 -0
  87. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/find_coordinator.py +0 -0
  88. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/frame.py +0 -0
  89. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/group.py +0 -0
  90. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/list_offsets.py +0 -0
  91. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/message.py +0 -0
  92. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/metadata.py +0 -0
  93. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/offset_for_leader_epoch.py +0 -0
  94. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/parser.py +0 -0
  95. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/pickle.py +0 -0
  96. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/produce.py +0 -0
  97. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/sasl_authenticate.py +0 -0
  98. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/sasl_handshake.py +0 -0
  99. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/struct.py +0 -0
  100. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/protocol/types.py +0 -0
  101. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/record/__init__.py +0 -0
  102. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/record/_crc32c.py +0 -0
  103. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/record/abc.py +0 -0
  104. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/record/default_records.py +0 -0
  105. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/record/legacy_records.py +0 -0
  106. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/record/memory_records.py +0 -0
  107. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/record/util.py +0 -0
  108. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/sasl/__init__.py +0 -0
  109. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/sasl/abc.py +0 -0
  110. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/sasl/gssapi.py +0 -0
  111. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/sasl/msk.py +0 -0
  112. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/sasl/oauth.py +0 -0
  113. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/sasl/plain.py +0 -0
  114. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/sasl/scram.py +0 -0
  115. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/sasl/sspi.py +0 -0
  116. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/serializer/__init__.py +0 -0
  117. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/serializer/abstract.py +0 -0
  118. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/socks5_wrapper.py +0 -0
  119. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/structs.py +0 -0
  120. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/util.py +0 -0
  121. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/vendor/__init__.py +0 -0
  122. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/vendor/enum34.py +0 -0
  123. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/vendor/selectors34.py +0 -0
  124. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/vendor/six.py +0 -0
  125. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka/vendor/socketpair.py +0 -0
  126. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka_python.egg-info/SOURCES.txt +0 -0
  127. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka_python.egg-info/dependency_links.txt +0 -0
  128. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka_python.egg-info/requires.txt +0 -0
  129. {kafka_python-2.1.5 → kafka_python-2.1.6}/kafka_python.egg-info/top_level.txt +0 -0
  130. {kafka_python-2.1.5 → kafka_python-2.1.6}/pyproject.toml +0 -0
  131. {kafka_python-2.1.5 → kafka_python-2.1.6}/setup.cfg +0 -0
  132. {kafka_python-2.1.5 → kafka_python-2.1.6}/setup.py +0 -0
  133. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_acl_comparisons.py +0 -0
  134. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_admin.py +0 -0
  135. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_admin_integration.py +0 -0
  136. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_api_object_implementation.py +0 -0
  137. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_assignors.py +0 -0
  138. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_client_async.py +0 -0
  139. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_cluster.py +0 -0
  140. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_codec.py +0 -0
  141. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_conn.py +0 -0
  142. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_consumer.py +0 -0
  143. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_consumer_group.py +0 -0
  144. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_consumer_integration.py +0 -0
  145. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_coordinator.py +0 -0
  146. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_metrics.py +0 -0
  147. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_object_conversion.py +0 -0
  148. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_package.py +0 -0
  149. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_partition_movements.py +0 -0
  150. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_partitioner.py +0 -0
  151. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_producer.py +0 -0
  152. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_protocol.py +0 -0
  153. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_sasl_integration.py +0 -0
  154. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_sender.py +0 -0
  155. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_subscription_state.py +0 -0
  156. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/test_util.py +0 -0
  157. {kafka_python-2.1.5 → kafka_python-2.1.6}/test/testutil.py +0 -0
@@ -1,3 +1,8 @@
1
+ # 2.1.6 (May 2, 2025)
2
+
3
+ Fixes
4
+ * Only create fetch requests for ready nodes (#2607)
5
+
1
6
  # 2.1.5 (Apr 4, 2025)
2
7
 
3
8
  Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kafka-python
3
- Version: 2.1.5
3
+ Version: 2.1.6
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
@@ -134,6 +134,7 @@ class Fetcher(six.Iterator):
134
134
  future = self._client.send(node_id, request, wakeup=False)
135
135
  future.add_callback(self._handle_fetch_response, node_id, fetch_offsets, time.time())
136
136
  future.add_errback(self._handle_fetch_error, node_id)
137
+ future.add_both(self._clear_pending_fetch_request, node_id)
137
138
  futures.append(future)
138
139
  self._fetch_futures.extend(futures)
139
140
  self._clean_done_fetch_futures()
@@ -610,36 +611,42 @@ class Fetcher(six.Iterator):
610
611
  log.log(0, "Skipping fetch for partition %s because node %s is throttled",
611
612
  partition, node_id)
612
613
 
614
+ elif not self._client.ready(node_id):
615
+ # Until we support send request queues, any attempt to send to a not-ready node will be
616
+ # immediately failed with NodeNotReadyError.
617
+ log.debug("Skipping fetch for partition %s because connection to leader node is not ready yet")
618
+
613
619
  elif node_id in self._nodes_with_pending_fetch_requests:
614
620
  log.log(0, "Skipping fetch for partition %s because there is a pending fetch request to node %s",
615
621
  partition, node_id)
616
- continue
617
622
 
618
- if version < 5:
619
- partition_info = (
620
- partition.partition,
621
- position.offset,
622
- self.config['max_partition_fetch_bytes']
623
- )
624
- elif version <= 8:
625
- partition_info = (
626
- partition.partition,
627
- position.offset,
628
- -1, # log_start_offset is used internally by brokers / replicas only
629
- self.config['max_partition_fetch_bytes'],
630
- )
631
623
  else:
632
- partition_info = (
633
- partition.partition,
634
- position.leader_epoch,
635
- position.offset,
636
- -1, # log_start_offset is used internally by brokers / replicas only
637
- self.config['max_partition_fetch_bytes'],
638
- )
639
-
640
- fetchable[node_id][partition] = partition_info
641
- log.debug("Adding fetch request for partition %s at offset %d",
642
- partition, position.offset)
624
+ # Leader is connected and does not have a pending fetch request
625
+ if version < 5:
626
+ partition_info = (
627
+ partition.partition,
628
+ position.offset,
629
+ self.config['max_partition_fetch_bytes']
630
+ )
631
+ elif version <= 8:
632
+ partition_info = (
633
+ partition.partition,
634
+ position.offset,
635
+ -1, # log_start_offset is used internally by brokers / replicas only
636
+ self.config['max_partition_fetch_bytes'],
637
+ )
638
+ else:
639
+ partition_info = (
640
+ partition.partition,
641
+ position.leader_epoch,
642
+ position.offset,
643
+ -1, # log_start_offset is used internally by brokers / replicas only
644
+ self.config['max_partition_fetch_bytes'],
645
+ )
646
+
647
+ fetchable[node_id][partition] = partition_info
648
+ log.debug("Adding fetch request for partition %s at offset %d",
649
+ partition, position.offset)
643
650
 
644
651
  requests = {}
645
652
  for node_id, next_partitions in six.iteritems(fetchable):
@@ -728,14 +735,18 @@ class Fetcher(six.Iterator):
728
735
 
729
736
  if self._sensors:
730
737
  self._sensors.fetch_latency.record((time.time() - send_time) * 1000)
731
- self._nodes_with_pending_fetch_requests.remove(node_id)
732
738
 
733
739
  def _handle_fetch_error(self, node_id, exception):
734
740
  level = logging.INFO if isinstance(exception, Errors.Cancelled) else logging.ERROR
735
741
  log.log(level, 'Fetch to node %s failed: %s', node_id, exception)
736
742
  if node_id in self._session_handlers:
737
743
  self._session_handlers[node_id].handle_error(exception)
738
- self._nodes_with_pending_fetch_requests.remove(node_id)
744
+
745
+ def _clear_pending_fetch_request(self, node_id, _):
746
+ try:
747
+ self._nodes_with_pending_fetch_requests.remove(node_id)
748
+ except KeyError:
749
+ pass
739
750
 
740
751
  def _parse_fetched_data(self, completed_fetch):
741
752
  tp = completed_fetch.topic_partition
@@ -0,0 +1 @@
1
+ __version__ = '2.1.6'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kafka-python
3
- Version: 2.1.5
3
+ Version: 2.1.6
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
@@ -108,6 +108,7 @@ def test_create_fetch_requests(fetcher, mocker, api_version, fetch_version):
108
108
  fetcher._client._api_versions = BROKER_API_VERSIONS[api_version]
109
109
  mocker.patch.object(fetcher._client.cluster, "leader_for_partition", return_value=0)
110
110
  mocker.patch.object(fetcher._client.cluster, "leader_epoch_for_partition", return_value=0)
111
+ mocker.patch.object(fetcher._client, "ready", return_value=True)
111
112
  by_node = fetcher._create_fetch_requests()
112
113
  requests_and_offsets = by_node.values()
113
114
  assert set([r.API_VERSION for (r, _offsets) in requests_and_offsets]) == set([fetch_version])
@@ -1 +0,0 @@
1
- __version__ = '2.1.5'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes