Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-azure-cosmos for 
openSUSE:Factory checked in at 2026-01-17 14:56:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-azure-cosmos (Old)
 and      /work/SRC/openSUSE:Factory/.python-azure-cosmos.new.1928 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-azure-cosmos"

Sat Jan 17 14:56:30 2026 rev:21 rq:1327711 version:4.14.5

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-azure-cosmos/python-azure-cosmos.changes  
2026-01-13 21:34:38.908204325 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-azure-cosmos.new.1928/python-azure-cosmos.changes
        2026-01-17 14:57:15.477469762 +0100
@@ -1,0 +2,8 @@
+Fri Jan 16 14:48:08 UTC 2026 - John Paul Adrian Glaubitz 
<[email protected]>
+
+- New upstream release
+  + Version 4.14.5
+  + For detailed information about changes see the
+    CHANGELOG.md file provided with this package
+
+-------------------------------------------------------------------

Old:
----
  azure_cosmos-4.14.4.tar.gz

New:
----
  azure_cosmos-4.14.5.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-azure-cosmos.spec ++++++
--- /var/tmp/diff_new_pack.QcC4sL/_old  2026-01-17 14:57:16.205500344 +0100
+++ /var/tmp/diff_new_pack.QcC4sL/_new  2026-01-17 14:57:16.213500681 +0100
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-azure-cosmos
-Version:        4.14.4
+Version:        4.14.5
 Release:        0
 Summary:        Microsoft Azure Cosmos client library for Python
 License:        MIT

++++++ azure_cosmos-4.14.4.tar.gz -> azure_cosmos-4.14.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_cosmos-4.14.4/CHANGELOG.md 
new/azure_cosmos-4.14.5/CHANGELOG.md
--- old/azure_cosmos-4.14.4/CHANGELOG.md        2026-01-12 02:16:28.000000000 
+0100
+++ new/azure_cosmos-4.14.5/CHANGELOG.md        2026-01-15 23:45:55.000000000 
+0100
@@ -1,5 +1,10 @@
 ## Release History
 
+### 4.14.5 (2026-01-15)
+
+#### Bugs Fixed
+* Fixed bug where sdk was encountering a timeout issue caused by infinite 
recursion during the 410 (Gone) error.See [PR 
44659](https://github.com/Azure/azure-sdk-for-python/pull/44649)
+
 ### 4.14.4 (2026-01-12)
 
 #### Bugs Fixed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_cosmos-4.14.4/PKG-INFO 
new/azure_cosmos-4.14.5/PKG-INFO
--- old/azure_cosmos-4.14.4/PKG-INFO    2026-01-12 02:17:04.133261000 +0100
+++ new/azure_cosmos-4.14.5/PKG-INFO    2026-01-15 23:46:41.777294600 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: azure-cosmos
-Version: 4.14.4
+Version: 4.14.5
 Summary: Microsoft Azure Cosmos Client Library for Python
 Home-page: https://github.com/Azure/azure-sdk-for-python
 Author: Microsoft Corporation
@@ -1177,6 +1177,11 @@
 
 ## Release History
 
+### 4.14.5 (2026-01-15)
+
+#### Bugs Fixed
+* Fixed bug where sdk was encountering a timeout issue caused by infinite 
recursion during the 410 (Gone) error.See [PR 
44659](https://github.com/Azure/azure-sdk-for-python/pull/44649)
+
 ### 4.14.4 (2026-01-12)
 
 #### Bugs Fixed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_cosmos-4.14.4/azure/cosmos/_execution_context/aio/base_execution_context.py
 
new/azure_cosmos-4.14.5/azure/cosmos/_execution_context/aio/base_execution_context.py
--- 
old/azure_cosmos-4.14.4/azure/cosmos/_execution_context/aio/base_execution_context.py
       2026-01-12 02:16:28.000000000 +0100
+++ 
new/azure_cosmos-4.14.5/azure/cosmos/_execution_context/aio/base_execution_context.py
       2026-01-15 23:45:55.000000000 +0100
@@ -25,10 +25,12 @@
 
 from collections import deque
 import copy
+import logging
 
 from ...aio import _retry_utility_async
 from ... import http_constants, exceptions
 
+_LOGGER = logging.getLogger(__name__)
 
 # pylint: disable=protected-access
 
@@ -145,8 +147,19 @@
                 self._client, self._client._global_endpoint_manager, callback, 
**self._options
             )
 
+        # Check if this is an internal partition key range fetch - skip 410 
retry logic to avoid recursion
+        # When we call refresh_routing_map_provider(), it triggers 
_ReadPartitionKeyRanges which would
+        # come through this same code path. If that also gets a 410 and tries 
to refresh, we get infinite recursion.
+        is_pk_range_fetch = self._options.get("_internal_pk_range_fetch", 
False)
+        if is_pk_range_fetch:
+            # For partition key range queries, just execute without 410 
partition split retry
+            # The underlying retry utility will still handle other transient 
errors
+            _LOGGER.debug("Partition split retry (async): Skipping 410 retry 
for internal PK range fetch")
+            return await execute_fetch()
+
         max_retries = 3
         attempt = 0
+
         while attempt <= max_retries:
             try:
                 return await execute_fetch()
@@ -154,14 +167,33 @@
                 if exceptions._partition_range_is_gone(e):
                     attempt += 1
                     if attempt > max_retries:
+                        _LOGGER.error(
+                            "Partition split retry (async): Exhausted all %d 
retries. "
+                            "state: _has_started=%s, _continuation=%s",
+                            max_retries, self._has_started, self._continuation
+                        )
                         raise  # Exhausted retries, propagate error
 
+                    _LOGGER.warning(
+                        "Partition split retry (async): 410 error 
(sub_status=%s). Attempt %d of %d. "
+                        "Refreshing routing map and resetting state.",
+                        getattr(e, 'sub_status', 'N/A'),
+                        attempt,
+                        max_retries
+                    )
+
                     # Refresh routing map to get new partition key ranges
                     self._client.refresh_routing_map_provider()
+                    # Reset execution context state to allow retry from the 
beginning
+                    self._has_started = False
+                    self._continuation = None
                     # Retry immediately (no backoff needed for partition 
splits)
                     continue
                 raise  # Not a partition split error, propagate immediately
 
+        # This should never be reached, but added for safety
+        return []
+
 
 class _DefaultQueryExecutionContext(_QueryExecutionContextBase):
     """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_cosmos-4.14.4/azure/cosmos/_execution_context/base_execution_context.py
 
new/azure_cosmos-4.14.5/azure/cosmos/_execution_context/base_execution_context.py
--- 
old/azure_cosmos-4.14.4/azure/cosmos/_execution_context/base_execution_context.py
   2026-01-12 02:16:28.000000000 +0100
+++ 
new/azure_cosmos-4.14.5/azure/cosmos/_execution_context/base_execution_context.py
   2026-01-15 23:45:55.000000000 +0100
@@ -25,8 +25,10 @@
 
 from collections import deque
 import copy
+import logging
 from .. import _retry_utility, http_constants, exceptions
 
+_LOGGER = logging.getLogger(__name__)
 
 # pylint: disable=protected-access
 
@@ -143,6 +145,16 @@
                 self._client, self._client._global_endpoint_manager, callback, 
**self._options
             )
 
+        # Check if this is an internal partition key range fetch - skip 410 
retry logic to avoid recursion
+        # When we call refresh_routing_map_provider(), it triggers 
_ReadPartitionKeyRanges which would
+        # come through this same code path. If that also gets a 410 and tries 
to refresh, we get infinite recursion.
+        is_pk_range_fetch = self._options.get("_internal_pk_range_fetch", 
False)
+        if is_pk_range_fetch:
+            # For partition key range queries, just execute without 410 
partition split retry
+            # The underlying retry utility will still handle other transient 
errors
+            _LOGGER.debug("Partition split retry: Skipping 410 retry for 
internal PK range fetch")
+            return execute_fetch()
+
         max_retries = 3
         attempt = 0
 
@@ -153,13 +165,32 @@
                 if exceptions._partition_range_is_gone(e):
                     attempt += 1
                     if attempt > max_retries:
+                        _LOGGER.error(
+                            "Partition split retry: Exhausted all %d retries. "
+                            "state: _has_started=%s, _continuation=%s",
+                            max_retries, self._has_started, self._continuation
+                        )
                         raise  # Exhausted retries, propagate error
 
+                    _LOGGER.warning(
+                        "Partition split retry: 410 error (sub_status=%s). 
Attempt %d of %d. "
+                        "Refreshing routing map and resetting state.",
+                        getattr(e, 'sub_status', 'N/A'),
+                        attempt,
+                        max_retries
+                    )
+
                     # Refresh routing map to get new partition key ranges
                     self._client.refresh_routing_map_provider()
+                    # Reset execution context state to allow retry from the 
beginning
+                    self._has_started = False
+                    self._continuation = None
                     # Retry immediately (no backoff needed for partition 
splits)
                     continue
                 raise  # Not a partition split error, propagate immediately
+
+        # This should never be reached, but added for safety
+        return []
     next = __next__  # Python 2 compatibility.
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_cosmos-4.14.4/azure/cosmos/_routing/aio/routing_map_provider.py 
new/azure_cosmos-4.14.5/azure/cosmos/_routing/aio/routing_map_provider.py
--- old/azure_cosmos-4.14.4/azure/cosmos/_routing/aio/routing_map_provider.py   
2026-01-12 02:16:28.000000000 +0100
+++ new/azure_cosmos-4.14.5/azure/cosmos/_routing/aio/routing_map_provider.py   
2026-01-15 23:45:55.000000000 +0100
@@ -22,12 +22,15 @@
 """Internal class for partition key range cache implementation in the Azure
 Cosmos database service.
 """
+import logging
 from typing import Any, Optional
 
 from ... import _base
 from ..collection_routing_map import CollectionRoutingMap
 from .. import routing_range
 
+_LOGGER = logging.getLogger(__name__)
+
 # pylint: disable=protected-access
 
 
@@ -75,18 +78,33 @@
     ):
         collection_routing_map = 
self._collection_routing_map_by_item.get(collection_id)
         if collection_routing_map is None:
+            # Pass _internal_pk_range_fetch flag to prevent recursive 410 
retry logic
+            # When a 410 partition split error occurs, the SDK calls 
refresh_routing_map_provider()
+            # which clears the cache and retries. The retry needs partition 
key ranges, which calls
+            # this method, which triggers _ReadPartitionKeyRanges. If that 
query also goes through
+            # the 410 retry logic and calls refresh again, we get infinite 
recursion.
+            _LOGGER.debug(
+                "PK range cache (async): Initializing routing map for 
collection_id=%s with "
+                "_internal_pk_range_fetch=True to prevent recursive 410 
retry.",
+                collection_id
+            )
+            pk_range_kwargs = {**kwargs, "_internal_pk_range_fetch": True}
             collection_pk_ranges = [pk async for pk in
                                     
self._documentClient._ReadPartitionKeyRanges(collection_link,
                                                                                
  feed_options,
-                                                                               
  **kwargs)]
+                                                                               
  **pk_range_kwargs)]
             # for large collections, a split may complete between the read 
partition key ranges query page responses,
             # causing the partitionKeyRanges to have both the children ranges 
and their parents. Therefore, we need
             # to discard the parent ranges to have a valid routing map.
-            collection_pk_ranges = 
PartitionKeyRangeCache._discard_parent_ranges(collection_pk_ranges)
+            collection_pk_ranges = 
list(PartitionKeyRangeCache._discard_parent_ranges(collection_pk_ranges))
             collection_routing_map = CollectionRoutingMap.CompleteRoutingMap(
                 [(r, True) for r in collection_pk_ranges], collection_id
             )
             self._collection_routing_map_by_item[collection_id] = 
collection_routing_map
+            _LOGGER.debug(
+                "PK range cache (async): Cached routing map for 
collection_id=%s with %d ranges",
+                collection_id, len(collection_pk_ranges)
+            )
 
     async def get_range_by_partition_key_range_id(
             self,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_cosmos-4.14.4/azure/cosmos/_routing/routing_map_provider.py 
new/azure_cosmos-4.14.5/azure/cosmos/_routing/routing_map_provider.py
--- old/azure_cosmos-4.14.4/azure/cosmos/_routing/routing_map_provider.py       
2026-01-12 02:16:28.000000000 +0100
+++ new/azure_cosmos-4.14.5/azure/cosmos/_routing/routing_map_provider.py       
2026-01-15 23:45:55.000000000 +0100
@@ -22,6 +22,7 @@
 """Internal class for partition key range cache implementation in the Azure
 Cosmos database service.
 """
+import logging
 from typing import Any, Optional
 
 from .. import _base
@@ -29,6 +30,8 @@
 from . import routing_range
 from .routing_range import PartitionKeyRange
 
+_LOGGER = logging.getLogger(__name__)
+
 
 # pylint: disable=protected-access
 
@@ -61,17 +64,32 @@
     ):
         collection_routing_map = 
self._collection_routing_map_by_item.get(collection_id)
         if not collection_routing_map:
+            # Pass _internal_pk_range_fetch flag to prevent recursive 410 
retry logic
+            # When a 410 partition split error occurs, the SDK calls 
refresh_routing_map_provider()
+            # which clears the cache and retries. The retry needs partition 
key ranges, which calls
+            # this method, which triggers _ReadPartitionKeyRanges. If that 
query also goes through
+            # the 410 retry logic and calls refresh again, we get infinite 
recursion.
+            _LOGGER.debug(
+                "PK range cache: Initializing routing map for collection_id=%s 
with "
+                "_internal_pk_range_fetch=True to prevent recursive 410 
retry.",
+                collection_id
+            )
+            pk_range_kwargs = {**kwargs, "_internal_pk_range_fetch": True}
             collection_pk_ranges = 
list(self._documentClient._ReadPartitionKeyRanges(collection_link,
                                                                                
      feed_options,
-                                                                               
      **kwargs))
+                                                                               
      **pk_range_kwargs))
             # for large collections, a split may complete between the read 
partition key ranges query page responses,
             # causing the partitionKeyRanges to have both the children ranges 
and their parents. Therefore, we need
             # to discard the parent ranges to have a valid routing map.
-            collection_pk_ranges = 
PartitionKeyRangeCache._discard_parent_ranges(collection_pk_ranges)
+            collection_pk_ranges = 
list(PartitionKeyRangeCache._discard_parent_ranges(collection_pk_ranges))
             collection_routing_map = CollectionRoutingMap.CompleteRoutingMap(
                 [(r, True) for r in collection_pk_ranges], collection_id
             )
             self._collection_routing_map_by_item[collection_id] = 
collection_routing_map
+            _LOGGER.debug(
+                "PK range cache: Cached routing map for collection_id=%s with 
%d ranges",
+                collection_id, len(collection_pk_ranges)
+            )
 
     def get_overlapping_ranges(self, collection_link, partition_key_ranges, 
feed_options, **kwargs):
         """Given a partition key range and a collection, return the list of
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_cosmos-4.14.4/azure/cosmos/_synchronized_request.py 
new/azure_cosmos-4.14.5/azure/cosmos/_synchronized_request.py
--- old/azure_cosmos-4.14.4/azure/cosmos/_synchronized_request.py       
2026-01-12 02:16:28.000000000 +0100
+++ new/azure_cosmos-4.14.5/azure/cosmos/_synchronized_request.py       
2026-01-15 23:45:55.000000000 +0100
@@ -80,6 +80,8 @@
     """
     # pylint: disable=protected-access, too-many-branches
     kwargs.pop(_Constants.OperationStartTime, None)
+    # Pop internal flags that should not be passed to the HTTP layer
+    kwargs.pop("_internal_pk_range_fetch", None)
     connection_timeout = connection_policy.RequestTimeout
     connection_timeout = kwargs.pop("connection_timeout", connection_timeout)
     read_timeout = connection_policy.ReadTimeout
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_cosmos-4.14.4/azure/cosmos/_version.py 
new/azure_cosmos-4.14.5/azure/cosmos/_version.py
--- old/azure_cosmos-4.14.4/azure/cosmos/_version.py    2026-01-12 
02:16:28.000000000 +0100
+++ new/azure_cosmos-4.14.5/azure/cosmos/_version.py    2026-01-15 
23:45:55.000000000 +0100
@@ -19,4 +19,4 @@
 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 # SOFTWARE.
 
-VERSION = "4.14.4"
+VERSION = "4.14.5"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_cosmos-4.14.4/azure/cosmos/aio/_asynchronous_request.py 
new/azure_cosmos-4.14.5/azure/cosmos/aio/_asynchronous_request.py
--- old/azure_cosmos-4.14.4/azure/cosmos/aio/_asynchronous_request.py   
2026-01-12 02:16:28.000000000 +0100
+++ new/azure_cosmos-4.14.5/azure/cosmos/aio/_asynchronous_request.py   
2026-01-15 23:45:55.000000000 +0100
@@ -52,6 +52,8 @@
     """
     # pylint: disable=protected-access, too-many-branches
     kwargs.pop(_Constants.OperationStartTime, None)
+    # Pop internal flags that should not be passed to the HTTP layer
+    kwargs.pop("_internal_pk_range_fetch", None)
     connection_timeout = connection_policy.RequestTimeout
     read_timeout = connection_policy.ReadTimeout
     connection_timeout = kwargs.pop("connection_timeout", connection_timeout)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_cosmos-4.14.4/azure_cosmos.egg-info/PKG-INFO 
new/azure_cosmos-4.14.5/azure_cosmos.egg-info/PKG-INFO
--- old/azure_cosmos-4.14.4/azure_cosmos.egg-info/PKG-INFO      2026-01-12 
02:17:04.000000000 +0100
+++ new/azure_cosmos-4.14.5/azure_cosmos.egg-info/PKG-INFO      2026-01-15 
23:46:41.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: azure-cosmos
-Version: 4.14.4
+Version: 4.14.5
 Summary: Microsoft Azure Cosmos Client Library for Python
 Home-page: https://github.com/Azure/azure-sdk-for-python
 Author: Microsoft Corporation
@@ -1177,6 +1177,11 @@
 
 ## Release History
 
+### 4.14.5 (2026-01-15)
+
+#### Bugs Fixed
+* Fixed bug where sdk was encountering a timeout issue caused by infinite 
recursion during the 410 (Gone) error.See [PR 
44659](https://github.com/Azure/azure-sdk-for-python/pull/44649)
+
 ### 4.14.4 (2026-01-12)
 
 #### Bugs Fixed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_cosmos-4.14.4/azure_cosmos.egg-info/SOURCES.txt 
new/azure_cosmos-4.14.5/azure_cosmos.egg-info/SOURCES.txt
--- old/azure_cosmos-4.14.4/azure_cosmos.egg-info/SOURCES.txt   2026-01-12 
02:17:04.000000000 +0100
+++ new/azure_cosmos-4.14.5/azure_cosmos.egg-info/SOURCES.txt   2026-01-15 
23:46:41.000000000 +0100
@@ -247,6 +247,8 @@
 tests/test_partition_key_async.py
 tests/test_partition_split_query.py
 tests/test_partition_split_query_async.py
+tests/test_partition_split_retry_unit.py
+tests/test_partition_split_retry_unit_async.py
 tests/test_per_partition_circuit_breaker_mm.py
 tests/test_per_partition_circuit_breaker_mm_async.py
 tests/test_per_partition_circuit_breaker_sm_mrr.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_cosmos-4.14.4/tests/routing/test_routing_map_provider.py 
new/azure_cosmos-4.14.5/tests/routing/test_routing_map_provider.py
--- old/azure_cosmos-4.14.4/tests/routing/test_routing_map_provider.py  
2026-01-12 02:16:28.000000000 +0100
+++ new/azure_cosmos-4.14.5/tests/routing/test_routing_map_provider.py  
2026-01-15 23:45:55.000000000 +0100
@@ -18,7 +18,7 @@
         def __init__(self, partition_key_ranges):
             self.partition_key_ranges = partition_key_ranges
 
-        def _ReadPartitionKeyRanges(self, collection_link: str, feed_options: 
Optional[Mapping[str, Any]] = None):
+        def _ReadPartitionKeyRanges(self, collection_link: str, feed_options: 
Optional[Mapping[str, Any]] = None, **kwargs):
             return self.partition_key_ranges
 
     def setUp(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_cosmos-4.14.4/tests/test_partition_split_retry_unit.py 
new/azure_cosmos-4.14.5/tests/test_partition_split_retry_unit.py
--- old/azure_cosmos-4.14.4/tests/test_partition_split_retry_unit.py    
1970-01-01 01:00:00.000000000 +0100
+++ new/azure_cosmos-4.14.5/tests/test_partition_split_retry_unit.py    
2026-01-15 23:45:55.000000000 +0100
@@ -0,0 +1,328 @@
+# The MIT License (MIT)
+# Copyright (c) Microsoft Corporation. All rights reserved.
+
+"""
+Sync unit tests for partition split (410) retry logic.
+"""
+
+import gc
+import time
+import unittest
+from unittest.mock import patch
+
+import pytest
+
+from azure.cosmos import exceptions
+from azure.cosmos._execution_context.base_execution_context import 
_DefaultQueryExecutionContext
+from azure.cosmos.http_constants import StatusCodes, SubStatusCodes
+
+# tracemalloc is not available in PyPy, so we import conditionally
+try:
+    import tracemalloc
+    HAS_TRACEMALLOC = True
+except ImportError:
+    HAS_TRACEMALLOC = False
+
+
+# =================================
+# Shared Test Helpers
+# =================================
+
+class MockGlobalEndpointManager:
+    """Mock global endpoint manager for testing."""
+    def is_circuit_breaker_applicable(self, request):
+        return False
+
+
+class MockClient:
+    """Mock Cosmos client for testing partition split retry logic."""
+    def __init__(self):
+        self._global_endpoint_manager = MockGlobalEndpointManager()
+        self.refresh_routing_map_provider_call_count = 0
+
+    def refresh_routing_map_provider(self):
+        self.refresh_routing_map_provider_call_count += 1
+
+    def reset_counts(self):
+        """Reset call counts for reuse in tests."""
+        self.refresh_routing_map_provider_call_count = 0
+
+
+def create_410_partition_split_error():
+    """Create a 410 partition split error for testing."""
+    error = exceptions.CosmosHttpResponseError(
+        status_code=StatusCodes.GONE,
+        message="Partition key range is gone"
+    )
+    error.sub_status = SubStatusCodes.PARTITION_KEY_RANGE_GONE
+    return error
+
+
+def raise_410_partition_split_error(*args, **kwargs):
+    """Raise a 410 partition split error - for use as mock side_effect."""
+    raise create_410_partition_split_error()
+
+
+# ==========================
+# Test Class
+# ==========================
+
[email protected]
+class TestPartitionSplitRetryUnit(unittest.TestCase):
+    """
+    Sync unit tests for 410 partition split retry logic.
+    """
+
+    def test_execution_context_state_reset_on_partition_split(self):
+        """
+        Test that execution context state is properly reset on 410 partition 
split retry.
+        Verifies the fix where the while loop in _fetch_items_helper_no_retries
+        would not execute after a retry because _has_started was still True.
+        """
+        mock_client = MockClient()
+
+        def mock_fetch_function(options):
+            return ([{"id": "1"}], {})
+
+        context = _DefaultQueryExecutionContext(mock_client, {}, 
mock_fetch_function)
+
+        # simulate state after first successful fetch but before 410 error
+        context._has_started = True
+        context._continuation = None
+
+        # Verify the loop condition without state reset - this is false
+        loop_condition_without_reset = context._continuation or not 
context._has_started
+        assert not loop_condition_without_reset, \
+            "Without state reset, loop condition should be False"
+
+        # Verify _fetch_items_helper_no_retries returns empty when state is 
not reset
+        fetch_was_called = [False]
+
+        def tracking_fetch(options):
+            fetch_was_called[0] = True
+            return ([{"id": "1"}], {})
+
+        result = context._fetch_items_helper_no_retries(tracking_fetch)
+        assert not fetch_was_called[0], \
+            "Fetch should NOT be called when _has_started=True and 
_continuation=None"
+        assert result == [], \
+            "Should return empty list when while loop doesn't execute"
+
+        # Now reset state
+        context._has_started = False
+        context._continuation = None
+
+        # verify the loop condition with state reset
+        loop_condition_with_reset = context._continuation or not 
context._has_started
+        assert loop_condition_with_reset, \
+            "With state reset, loop condition should be True"
+
+        # verify _fetch_items_helper_no_retries works after state reset
+        result = context._fetch_items_helper_no_retries(tracking_fetch)
+        assert fetch_was_called[0], \
+            "Fetch SHOULD be called after state reset"
+        assert result == [{"id": "1"}], \
+            "Should return documents after state reset"
+
+    @patch('azure.cosmos._retry_utility.Execute')
+    def test_retry_with_410_resets_state_and_succeeds(self, mock_execute):
+        """
+        Test the full retry flow: 410 partition split error triggers state 
reset and retry succeeds.
+        """
+        mock_client = MockClient()
+        expected_docs = [{"id": "success"}]
+        call_count = [0]
+
+        def execute_side_effect(*args, **kwargs):
+            call_count[0] += 1
+            if call_count[0] == 1:
+                raise create_410_partition_split_error()
+            return expected_docs
+
+        mock_execute.side_effect = execute_side_effect
+
+        def mock_fetch_function(options):
+            return (expected_docs, {})
+
+        context = _DefaultQueryExecutionContext(mock_client, {}, 
mock_fetch_function)
+        result = context._fetch_items_helper_with_retries(mock_fetch_function)
+
+        assert call_count[0] == 2, "Should have retried once after 410"
+        assert mock_client.refresh_routing_map_provider_call_count == 1, \
+            "refresh_routing_map_provider should be called once on 410"
+        assert result == expected_docs, "Should return expected documents 
after retry"
+
+    @patch('azure.cosmos._retry_utility.Execute')
+    def test_pk_range_query_skips_410_retry_to_prevent_recursion(self, 
mock_execute):
+        """
+        Test that partition key range queries (marked with 
_internal_pk_range_fetch=True)
+        skip the 410 partition split retry logic to prevent infinite recursion.
+
+        When a 410 partition split error occurs:
+        1. SDK calls refresh_routing_map_provider() which clears the routing 
map cache
+        2. SDK retries the query
+        3. Retry needs partition key ranges, which triggers 
_ReadPartitionKeyRanges
+        4. If _ReadPartitionKeyRanges also uses 410 retry logic and gets a 410,
+           it would call refresh_routing_map_provider() again, creating 
infinite recursion
+
+        This test verifies that queries with _internal_pk_range_fetch=True do 
not
+        trigger the 410 retry with refresh logic.
+        """
+        mock_client = MockClient()
+        options = {"_internal_pk_range_fetch": True}
+
+        mock_execute.side_effect = raise_410_partition_split_error
+
+        def mock_fetch_function(options):
+            return ([{"id": "1"}], {})
+
+        context = _DefaultQueryExecutionContext(mock_client, options, 
mock_fetch_function)
+
+        with pytest.raises(exceptions.CosmosHttpResponseError) as exc_info:
+            context._fetch_items_helper_with_retries(mock_fetch_function)
+
+        assert exc_info.value.status_code == StatusCodes.GONE
+        assert mock_client.refresh_routing_map_provider_call_count == 0, \
+            "refresh_routing_map_provider should NOT be called for PK range 
queries"
+        assert mock_execute.call_count == 1, \
+            "Execute should only be called once - no retry for PK range 
queries"
+
+    @patch('azure.cosmos._retry_utility.Execute')
+    def test_410_retry_behavior_with_and_without_pk_range_flag(self, 
mock_execute):
+        """
+        Test that verifies the fix for the partition split recursion problem.
+
+        The fix ensures:
+        - Regular queries retry up to 3 times on 410, calling refresh each time
+        - PK range queries (with _internal_pk_range_fetch flag) skip retry 
entirely,
+          preventing infinite recursion when refresh_routing_map_provider 
triggers
+          another PK range query that also gets a 410
+        """
+        mock_client = MockClient()
+
+        mock_execute.side_effect = raise_410_partition_split_error
+
+        def mock_fetch_function(options):
+            return ([{"id": "1"}], {})
+
+        # Test 1: Regular query (no flag) - should retry 3 times
+        context = _DefaultQueryExecutionContext(mock_client, {}, 
mock_fetch_function)
+
+        with pytest.raises(exceptions.CosmosHttpResponseError):
+            context._fetch_items_helper_with_retries(mock_fetch_function)
+
+        assert mock_client.refresh_routing_map_provider_call_count == 3, \
+            f"Expected 3 refresh calls, got 
{mock_client.refresh_routing_map_provider_call_count}"
+        assert mock_execute.call_count == 4, \
+            f"Expected 4 Execute calls, got {mock_execute.call_count}"
+
+        # Test 2: PK range query (with flag) - should NOT retry
+        mock_client.reset_counts()
+        mock_execute.reset_mock()
+        mock_execute.side_effect = raise_410_partition_split_error
+
+        options_with_flag = {"_internal_pk_range_fetch": True}
+        context_pk_range = _DefaultQueryExecutionContext(mock_client, 
options_with_flag, mock_fetch_function)
+
+        with pytest.raises(exceptions.CosmosHttpResponseError):
+            
context_pk_range._fetch_items_helper_with_retries(mock_fetch_function)
+
+        assert mock_client.refresh_routing_map_provider_call_count == 0, \
+            f"With flag, expected 0 refresh calls, got 
{mock_client.refresh_routing_map_provider_call_count}"
+        assert mock_execute.call_count == 1, \
+            f"With flag, expected 1 Execute call, got 
{mock_execute.call_count}"
+
+    @pytest.mark.skipif(not HAS_TRACEMALLOC, reason="tracemalloc not available 
in PyPy")
+    @patch('azure.cosmos._retry_utility.Execute')
+    def test_memory_bounded_no_leak_on_410_retries(self, mock_execute):
+        """
+        Test that memory usage is bounded during 410 partition split retries.
+        - Execute calls are bounded (max 4: 1 initial + 3 retries)
+        - Refresh calls are bounded (max 3)
+        - Memory growth is minimal (no recursive accumulation)
+        - No infinite recursion (max depth = 0 for PK range queries)
+        """
+        # tracemalloc.start() begins tracing memory allocations to detect leaks
+        tracemalloc.start()
+        # gc.collect() forces garbage collection to get accurate baseline 
memory measurement
+        gc.collect()
+        # take_snapshot() captures current memory state for comparison after 
test
+        snapshot_before = tracemalloc.take_snapshot()
+        start_time = time.time()
+
+        mock_client = MockClient()
+
+        mock_execute.side_effect = raise_410_partition_split_error
+
+        def mock_fetch_function(options):
+            return ([{"id": "1"}], {})
+
+        # Test regular query - should have bounded retries
+        context = _DefaultQueryExecutionContext(mock_client, {}, 
mock_fetch_function)
+
+        with pytest.raises(exceptions.CosmosHttpResponseError):
+            context._fetch_items_helper_with_retries(mock_fetch_function)
+
+        elapsed_time = time.time() - start_time
+        # gc.collect() before snapshot ensures we measure actual leaks, not 
pending garbage
+        gc.collect()
+        snapshot_after = tracemalloc.take_snapshot()
+        # compare_to() shows memory difference between snapshots to identify 
growth
+        top_stats = snapshot_after.compare_to(snapshot_before, 'lineno')
+        memory_growth = sum(stat.size_diff for stat in top_stats if 
stat.size_diff > 0)
+        peak_memory = tracemalloc.get_traced_memory()[1]
+        # tracemalloc.stop() ends memory tracing and frees tracing overhead
+        tracemalloc.stop()
+
+        # Collect metrics
+        execute_calls = mock_execute.call_count
+        refresh_calls = mock_client.refresh_routing_map_provider_call_count
+
+        # Print metrics
+        print(f"\n{'=' * 60}")
+        print("MEMORY METRICS - Partition Split Memory Verification")
+        print(f"{'=' * 60}")
+        print(f"Metrics:")
+        print(f"  - Execute calls:   {execute_calls} (bounded)")
+        print(f"  - Refresh calls:   {refresh_calls}")
+        print(f"  - Elapsed time:    {elapsed_time:.2f}s")
+        print(f"  - Memory growth:   {memory_growth / 1024:.2f} KB")
+        print(f"  - Peak memory:     {peak_memory / 1024:.2f} KB")
+        print(f"{'=' * 60}")
+
+        assert execute_calls == 4, \
+            f"Execute calls should be bounded to 4, got {execute_calls}"
+        assert refresh_calls == 3, \
+            f"Refresh calls should be bounded to 3, got {refresh_calls}"
+        assert elapsed_time < 1.0, \
+            f"Should complete quickly (< 1s), took {elapsed_time:.2f}s - 
indicates no infinite loop"
+        assert memory_growth < 500 * 1024, \
+            f"Memory growth should be < 500KB, got {memory_growth / 1024:.2f} 
KB - indicates no memory leak"
+
+        # Test PK range query - should have NO retries (prevents recursion)
+        mock_client.reset_counts()
+        mock_execute.reset_mock()
+        mock_execute.side_effect = raise_410_partition_split_error
+
+        options_with_flag = {"_internal_pk_range_fetch": True}
+        context_pk = _DefaultQueryExecutionContext(mock_client, 
options_with_flag, mock_fetch_function)
+
+        with pytest.raises(exceptions.CosmosHttpResponseError):
+            context_pk._fetch_items_helper_with_retries(mock_fetch_function)
+
+        pk_execute_calls = mock_execute.call_count
+        pk_refresh_calls = mock_client.refresh_routing_map_provider_call_count
+
+        print(f"\nPK Range Query:")
+        print(f"  - Execute calls:   {pk_execute_calls} (no retry)")
+        print(f"  - Refresh calls:   {pk_refresh_calls} (no recursion)")
+        print(f"{'=' * 60}\n")
+
+        assert pk_execute_calls == 1, \
+            f"PK range query should have 1 execute call, got 
{pk_execute_calls}"
+        assert pk_refresh_calls == 0, \
+            f"PK range query should have 0 refresh calls, got 
{pk_refresh_calls}"
+
+
+if __name__ == "__main__":
+    unittest.main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_cosmos-4.14.4/tests/test_partition_split_retry_unit_async.py 
new/azure_cosmos-4.14.5/tests/test_partition_split_retry_unit_async.py
--- old/azure_cosmos-4.14.4/tests/test_partition_split_retry_unit_async.py      
1970-01-01 01:00:00.000000000 +0100
+++ new/azure_cosmos-4.14.5/tests/test_partition_split_retry_unit_async.py      
2026-01-15 23:45:55.000000000 +0100
@@ -0,0 +1,317 @@
+# The MIT License (MIT)
+# Copyright (c) Microsoft Corporation. All rights reserved.
+
+"""
+Async unit tests for partition split (410) retry logic.
+"""
+
+import gc
+import time
+import unittest
+from unittest.mock import patch
+
+import pytest
+
+from azure.cosmos import exceptions
+from azure.cosmos.http_constants import StatusCodes, SubStatusCodes
+from azure.cosmos.aio import CosmosClient  # noqa: F401 - needed to resolve 
circular imports
+from azure.cosmos._execution_context.aio.base_execution_context import 
_DefaultQueryExecutionContext
+
+# tracemalloc is not available in PyPy, so we import conditionally
+try:
+    import tracemalloc
+    HAS_TRACEMALLOC = True
+except ImportError:
+    HAS_TRACEMALLOC = False
+
+
+# ====================================
+# Shared Test Helpers
+# ====================================
+
+class MockGlobalEndpointManager:
+    """Mock global endpoint manager for testing."""
+    def is_circuit_breaker_applicable(self, request):
+        return False
+
+
+class MockClient:
+    """Mock Cosmos client for testing partition split retry logic."""
+    def __init__(self):
+        self._global_endpoint_manager = MockGlobalEndpointManager()
+        self.refresh_routing_map_provider_call_count = 0
+
+    def refresh_routing_map_provider(self):
+        self.refresh_routing_map_provider_call_count += 1
+
+    def reset_counts(self):
+        """Reset call counts for reuse in tests."""
+        self.refresh_routing_map_provider_call_count = 0
+
+
+def create_410_partition_split_error():
+    """Create a 410 partition split error for testing."""
+    error = exceptions.CosmosHttpResponseError(
+        status_code=StatusCodes.GONE,
+        message="Partition key range is gone"
+    )
+    error.sub_status = SubStatusCodes.PARTITION_KEY_RANGE_GONE
+    return error
+
+
+def raise_410_partition_split_error(*args, **kwargs):
+    """Raise a 410 partition split error - for use as mock side_effect."""
+    raise create_410_partition_split_error()
+
+
+# ===============================
+# Test Class
+# ===============================
+
+
+
[email protected]
+class TestPartitionSplitRetryUnitAsync(unittest.IsolatedAsyncioTestCase):
+    """
+    Async unit tests for 410 partition split retry logic.
+    """
+
+    async def 
test_execution_context_state_reset_on_partition_split_async(self):
+        """
+        Test that execution context state is properly reset on 410 partition 
split retry (async).
+        Verifies the fix for a bug where the while loop in 
_fetch_items_helper_no_retries
+        would not execute after a retry because _has_started was still True.
+
+        """
+        mock_client = MockClient()
+
+        async def mock_fetch_function(options):
+            return ([{"id": "1"}], {})
+
+        context = _DefaultQueryExecutionContext(mock_client, {}, 
mock_fetch_function)
+
+        # Simulate state AFTER first successful fetch but BEFORE 410 error
+        context._has_started = True
+        context._continuation = None
+
+        # Verify the loop condition WITHOUT state reset - this is FALSE
+        loop_condition_without_reset = context._continuation or not 
context._has_started
+        assert not loop_condition_without_reset, \
+            "Without state reset, loop condition should be False"
+
+        # Verify _fetch_items_helper_no_retries returns empty when state is 
not reset
+        fetch_was_called = [False]
+
+        async def tracking_fetch(options):
+            fetch_was_called[0] = True
+            return ([{"id": "1"}], {})
+
+        result = await context._fetch_items_helper_no_retries(tracking_fetch)
+        assert not fetch_was_called[0], \
+            "Fetch should NOT be called when _has_started=True and 
_continuation=None"
+        assert result == [], \
+            "Should return empty list when while loop doesn't execute"
+
+        # reset state
+        context._has_started = False
+        context._continuation = None
+
+        # Verify _fetch_items_helper_no_retries works after state reset
+        result = await context._fetch_items_helper_no_retries(tracking_fetch)
+        assert fetch_was_called[0], \
+            "Fetch SHOULD be called after state reset"
+        assert result == [{"id": "1"}], \
+            "Should return documents after state reset"
+
+    @patch('azure.cosmos.aio._retry_utility_async.ExecuteAsync')
+    async def test_retry_with_410_resets_state_and_succeeds_async(self, 
mock_execute):
+        """
+        Test the full retry flow: 410 partition split error triggers state 
reset and retry succeeds (async).
+        """
+        mock_client = MockClient()
+        expected_docs = [{"id": "success"}]
+        call_count = [0]
+
+        async def execute_side_effect(*args, **kwargs):
+            call_count[0] += 1
+            if call_count[0] == 1:
+                raise create_410_partition_split_error()
+            return expected_docs
+
+        mock_execute.side_effect = execute_side_effect
+
+        async def mock_fetch_function(options):
+            return (expected_docs, {})
+
+        context = _DefaultQueryExecutionContext(mock_client, {}, 
mock_fetch_function)
+        result = await 
context._fetch_items_helper_with_retries(mock_fetch_function)
+
+        assert call_count[0] == 2, "Should have retried once after 410"
+        assert mock_client.refresh_routing_map_provider_call_count == 1, \
+            "refresh_routing_map_provider should be called once on 410"
+        assert result == expected_docs, "Should return expected documents 
after retry"
+
+    @patch('azure.cosmos.aio._retry_utility_async.ExecuteAsync')
+    async def 
test_pk_range_query_skips_410_retry_to_prevent_recursion_async(self, 
mock_execute):
+        """
+        Test that partition key range queries skip 410 retry to prevent 
recursion (async).
+        """
+        mock_client = MockClient()
+        options = {"_internal_pk_range_fetch": True}
+
+        mock_execute.side_effect = raise_410_partition_split_error
+
+        async def mock_fetch_function(options):
+            return ([{"id": "1"}], {})
+
+        context = _DefaultQueryExecutionContext(mock_client, options, 
mock_fetch_function)
+
+        with pytest.raises(exceptions.CosmosHttpResponseError) as exc_info:
+            await context._fetch_items_helper_with_retries(mock_fetch_function)
+
+        assert exc_info.value.status_code == StatusCodes.GONE
+        assert mock_client.refresh_routing_map_provider_call_count == 0, \
+            "refresh_routing_map_provider should NOT be called for PK range 
queries"
+        assert mock_execute.call_count == 1, \
+            "ExecuteAsync should only be called once - no retry for PK range 
queries"
+
+    @patch('azure.cosmos.aio._retry_utility_async.ExecuteAsync')
+    async def 
test_410_retry_behavior_with_and_without_pk_range_flag_async(self, 
mock_execute):
+        """
+        Test that verifies the fix for the partition split recursion problem 
(async).
+
+        The fix ensures:
+        - Regular queries retry up to 3 times on 410, calling refresh each time
+        - PK range queries (with _internal_pk_range_fetch flag) skip retry 
entirely,
+          preventing infinite recursion when refresh_routing_map_provider 
triggers
+          another PK range query that also gets a 410
+        """
+        mock_client = MockClient()
+
+        mock_execute.side_effect = raise_410_partition_split_error
+
+        async def mock_fetch_function(options):
+            return ([{"id": "1"}], {})
+
+        # Test 1: Regular query (no flag) - should retry 3 times
+        context = _DefaultQueryExecutionContext(mock_client, {}, 
mock_fetch_function)
+
+        with pytest.raises(exceptions.CosmosHttpResponseError):
+            await context._fetch_items_helper_with_retries(mock_fetch_function)
+
+        assert mock_client.refresh_routing_map_provider_call_count == 3, \
+            f"Expected 3 refresh calls, got 
{mock_client.refresh_routing_map_provider_call_count}"
+        assert mock_execute.call_count == 4, \
+            f"Expected 4 ExecuteAsync calls, got {mock_execute.call_count}"
+
+        # Test 2: PK range query (with flag) - should NOT retry
+        mock_client.reset_counts()
+        mock_execute.reset_mock()
+        mock_execute.side_effect = raise_410_partition_split_error
+
+        options_with_flag = {"_internal_pk_range_fetch": True}
+        context_pk_range = _DefaultQueryExecutionContext(mock_client, 
options_with_flag, mock_fetch_function)
+
+        with pytest.raises(exceptions.CosmosHttpResponseError):
+            await 
context_pk_range._fetch_items_helper_with_retries(mock_fetch_function)
+
+        assert mock_client.refresh_routing_map_provider_call_count == 0, \
+            f"With flag, expected 0 refresh calls, got 
{mock_client.refresh_routing_map_provider_call_count}"
+        assert mock_execute.call_count == 1, \
+            f"With flag, expected 1 ExecuteAsync call, got 
{mock_execute.call_count}"
+
+    @pytest.mark.skipif(not HAS_TRACEMALLOC, reason="tracemalloc not available 
in PyPy")
+    @patch('azure.cosmos.aio._retry_utility_async.ExecuteAsync')
+    async def test_memory_bounded_no_leak_on_410_retries_async(self, 
mock_execute):
+        """
+        Test that memory usage is bounded during 410 partition split retries.
+        - Execute calls are bounded (max 4: 1 initial + 3 retries)
+        - Refresh calls are bounded (max 3)
+        - Memory growth is minimal (no recursive accumulation)
+        - No infinite recursion (max depth = 0 for PK range queries)
+        """
+        # tracemalloc.start() begins tracing memory allocations to detect leaks
+        tracemalloc.start()
+        # gc.collect() forces garbage collection to get accurate baseline 
memory measurement
+        gc.collect()
+        # take_snapshot() captures current memory state for comparison after 
test
+        snapshot_before = tracemalloc.take_snapshot()
+        start_time = time.time()
+
+        mock_client = MockClient()
+
+        mock_execute.side_effect = raise_410_partition_split_error
+
+        async def mock_fetch_function(options):
+            return ([{"id": "1"}], {})
+
+        # Test regular query - should have bounded retries
+        context = _DefaultQueryExecutionContext(mock_client, {}, 
mock_fetch_function)
+
+        with pytest.raises(exceptions.CosmosHttpResponseError):
+            await context._fetch_items_helper_with_retries(mock_fetch_function)
+
+        elapsed_time = time.time() - start_time
+        # gc.collect() before snapshot ensures we measure actual leaks, not 
pending garbage
+        gc.collect()
+        snapshot_after = tracemalloc.take_snapshot()
+        # compare_to() shows memory difference between snapshots to identify 
growth
+        top_stats = snapshot_after.compare_to(snapshot_before, 'lineno')
+        memory_growth = sum(stat.size_diff for stat in top_stats if 
stat.size_diff > 0)
+        peak_memory = tracemalloc.get_traced_memory()[1]
+        # tracemalloc.stop() ends memory tracing and frees tracing overhead
+        tracemalloc.stop()
+
+        # Collect metrics
+        execute_calls = mock_execute.call_count
+        refresh_calls = mock_client.refresh_routing_map_provider_call_count
+
+        # Print metrics
+        print(f"\n{'=' * 60}")
+        print("MEMORY METRICS (Async) - Partition Split Memory Verification")
+        print(f"{'=' * 60}")
+        print(f"Metrics:")
+        print(f"  - Execute calls:   {execute_calls} (bounded)")
+        print(f"  - Refresh calls:   {refresh_calls}")
+        print(f"  - Elapsed time:    {elapsed_time:.2f}s")
+        print(f"  - Memory growth:   {memory_growth / 1024:.2f} KB")
+        print(f"  - Peak memory:     {peak_memory / 1024:.2f} KB")
+        print(f"{'=' * 60}")
+
+        assert execute_calls == 4, \
+            f"Execute calls should be bounded to 4, got {execute_calls}"
+        assert refresh_calls == 3, \
+            f"Refresh calls should be bounded to 3, got {refresh_calls}"
+        assert elapsed_time < 1.0, \
+            f"Should complete quickly (< 1s), took {elapsed_time:.2f}s - 
indicates no infinite loop"
+        assert memory_growth < 500 * 1024, \
+            f"Memory growth should be < 500KB, got {memory_growth / 1024:.2f} 
KB - indicates no memory leak"
+
+        # Test PK range query - should have NO retries (prevents recursion)
+        mock_client.reset_counts()
+        mock_execute.reset_mock()
+        mock_execute.side_effect = raise_410_partition_split_error
+
+        options_with_flag = {"_internal_pk_range_fetch": True}
+        context_pk = _DefaultQueryExecutionContext(mock_client, 
options_with_flag, mock_fetch_function)
+
+        with pytest.raises(exceptions.CosmosHttpResponseError):
+            await 
context_pk._fetch_items_helper_with_retries(mock_fetch_function)
+
+        pk_execute_calls = mock_execute.call_count
+        pk_refresh_calls = mock_client.refresh_routing_map_provider_call_count
+
+        print(f"\nPK Range Query:")
+        print(f"  - Execute calls:   {pk_execute_calls} (no retry)")
+        print(f"  - Refresh calls:   {pk_refresh_calls} (no recursion)")
+        print(f"{'=' * 60}\n")
+
+        assert pk_execute_calls == 1, \
+            f"PK range query should have 1 execute call, got 
{pk_execute_calls}"
+        assert pk_refresh_calls == 0, \
+            f"PK range query should have 0 refresh calls, got 
{pk_refresh_calls}"
+
+
+if __name__ == "__main__":
+    unittest.main()
+

Reply via email to