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-09-10 17:40:59
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-azure-cosmos (Old)
 and      /work/SRC/openSUSE:Factory/.python-azure-cosmos.new.1265 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-azure-cosmos"

Thu Sep 10 17:40:59 2026 rev:27 rq:1376834 version:4.16.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-azure-cosmos/python-azure-cosmos.changes  
2026-08-06 16:27:01.894557681 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-azure-cosmos.new.1265/python-azure-cosmos.changes
        2026-09-10 17:41:05.035929829 +0200
@@ -1,0 +2,8 @@
+Tue Sep  8 07:30:25 UTC 2026 - John Paul Adrian Glaubitz 
<[email protected]>
+
+- New upstream release
+  + Version 4.16.4
+  + For detailed information about changes see the
+    CHANGELOG.md file provided with this package
+
+-------------------------------------------------------------------

Old:
----
  azure_cosmos-4.16.3.tar.gz

New:
----
  azure_cosmos-4.16.4.tar.gz

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

Other differences:
------------------
++++++ python-azure-cosmos.spec ++++++
--- /var/tmp/diff_new_pack.TIJoHw/_old  2026-09-10 17:41:05.814962354 +0200
+++ /var/tmp/diff_new_pack.TIJoHw/_new  2026-09-10 17:41:05.815962396 +0200
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-azure-cosmos
-Version:        4.16.3
+Version:        4.16.4
 Release:        0
 Summary:        Microsoft Azure Cosmos client library for Python
 License:        MIT

++++++ azure_cosmos-4.16.3.tar.gz -> azure_cosmos-4.16.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_cosmos-4.16.3/CHANGELOG.md 
new/azure_cosmos-4.16.4/CHANGELOG.md
--- old/azure_cosmos-4.16.3/CHANGELOG.md        2026-07-29 23:49:45.000000000 
+0200
+++ new/azure_cosmos-4.16.4/CHANGELOG.md        2026-09-02 01:44:33.000000000 
+0200
@@ -1,4 +1,15 @@
 ## Release History
+> [!IMPORTANT]
+> We strongly recommend that customers use at least version 4.16.3 of 
`azure-cosmos`.
+
+### 4.16.4 (2026-09-02)
+
+#### Bugs Fixed
+* Fixed regression with handling of v1 legacy containers when passing `{}` as 
a partition key. `{}` and `NonePartitionKeyValue` now both resolve to the 
`Undefined` effective partition key. See [PR 
48422](https://github.com/Azure/azure-sdk-for-python/pull/48422)
+* Fixed the same `TypeError` on system key (migrated) containers, where a 
missing partition key value resolves to `_Empty` instead of `Undefined`. It now 
maps to the minimum effective partition key. See [PR 
48422](https://github.com/Azure/azure-sdk-for-python/pull/48422)
+
+#### Other Changes
+* Marked the Throughput Buckets feature as GA. See 
[48838](https://github.com/Azure/azure-sdk-for-python/pull/48838).
 
 ### 4.16.3 (2026-07-29)
 
@@ -71,8 +82,6 @@
 * Enhanced error logging by attaching endpoint information to exceptions 
during database account retrieval. See [PR 
44484](https://github.com/Azure/azure-sdk-for-python/pull/44484)
 
 ### 4.15.0 (2026-02-19)
-> [!IMPORTANT]
-> We strongly recommend that customers use at least version 4.15.0 of 
`azure-cosmos`.
 
 #### Features Added
 * GA support of Per Partition Automatic Failover and AvailabilityStrategy 
features.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_cosmos-4.16.3/PKG-INFO 
new/azure_cosmos-4.16.4/PKG-INFO
--- old/azure_cosmos-4.16.3/PKG-INFO    2026-07-29 23:50:48.016196700 +0200
+++ new/azure_cosmos-4.16.4/PKG-INFO    2026-09-02 01:46:02.723432500 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: azure-cosmos
-Version: 4.16.3
+Version: 4.16.4
 Summary: Microsoft Azure Cosmos Client Library for Python
 Home-page: https://github.com/Azure/azure-sdk-for-python
 Author: Microsoft Corporation
@@ -1010,7 +1010,7 @@
 
 You can find our sync samples [here][cosmos_index_sample] and our async 
samples [here][cosmos_index_sample_async] as well for additional guidance.
 
-### Public Preview - Throughput Buckets
+### Throughput Buckets
 When multiple workloads share the same Azure Cosmos DB container, resource 
contention can lead to throttling, increased latency, and potential business 
impact.
 To address this, Cosmos DB allows you to allocate throughput buckets, which 
help manage resource consumption for workloads sharing a Cosmos DB container by 
limiting the maximum throughput a bucket can consume.
 However, throughput isn't reserved for any bucket, it remains shared across 
all workloads.
@@ -1352,6 +1352,17 @@
 
 
 ## Release History
+> [!IMPORTANT]
+> We strongly recommend that customers use at least version 4.16.3 of 
`azure-cosmos`.
+
+### 4.16.4 (2026-09-02)
+
+#### Bugs Fixed
+* Fixed regression with handling of v1 legacy containers when passing `{}` as 
a partition key. `{}` and `NonePartitionKeyValue` now both resolve to the 
`Undefined` effective partition key. See [PR 
48422](https://github.com/Azure/azure-sdk-for-python/pull/48422)
+* Fixed the same `TypeError` on system key (migrated) containers, where a 
missing partition key value resolves to `_Empty` instead of `Undefined`. It now 
maps to the minimum effective partition key. See [PR 
48422](https://github.com/Azure/azure-sdk-for-python/pull/48422)
+
+#### Other Changes
+* Marked the Throughput Buckets feature as GA. See 
[48838](https://github.com/Azure/azure-sdk-for-python/pull/48838).
 
 ### 4.16.3 (2026-07-29)
 
@@ -1424,8 +1435,6 @@
 * Enhanced error logging by attaching endpoint information to exceptions 
during database account retrieval. See [PR 
44484](https://github.com/Azure/azure-sdk-for-python/pull/44484)
 
 ### 4.15.0 (2026-02-19)
-> [!IMPORTANT]
-> We strongly recommend that customers use at least version 4.15.0 of 
`azure-cosmos`.
 
 #### Features Added
 * GA support of Per Partition Automatic Failover and AvailabilityStrategy 
features.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_cosmos-4.16.3/README.md 
new/azure_cosmos-4.16.4/README.md
--- old/azure_cosmos-4.16.3/README.md   2026-07-29 23:49:45.000000000 +0200
+++ new/azure_cosmos-4.16.4/README.md   2026-09-02 01:44:33.000000000 +0200
@@ -963,7 +963,7 @@
 
 You can find our sync samples [here][cosmos_index_sample] and our async 
samples [here][cosmos_index_sample_async] as well for additional guidance.
 
-### Public Preview - Throughput Buckets
+### Throughput Buckets
 When multiple workloads share the same Azure Cosmos DB container, resource 
contention can lead to throttling, increased latency, and potential business 
impact.
 To address this, Cosmos DB allows you to allocate throughput buckets, which 
help manage resource consumption for workloads sharing a Cosmos DB container by 
limiting the maximum throughput a bucket can consume.
 However, throughput isn't reserved for any bucket, it remains shared across 
all workloads.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_cosmos-4.16.3/azure/cosmos/_version.py 
new/azure_cosmos-4.16.4/azure/cosmos/_version.py
--- old/azure_cosmos-4.16.3/azure/cosmos/_version.py    2026-07-29 
23:49:45.000000000 +0200
+++ new/azure_cosmos-4.16.4/azure/cosmos/_version.py    2026-09-02 
01:44:33.000000000 +0200
@@ -19,4 +19,4 @@
 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 # SOFTWARE.
 
-VERSION = "4.16.3"
+VERSION = "4.16.4"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_cosmos-4.16.3/azure/cosmos/aio/_container.py 
new/azure_cosmos-4.16.4/azure/cosmos/aio/_container.py
--- old/azure_cosmos-4.16.3/azure/cosmos/aio/_container.py      2026-07-29 
23:49:45.000000000 +0200
+++ new/azure_cosmos-4.16.4/azure/cosmos/aio/_container.py      2026-09-02 
01:44:33.000000000 +0200
@@ -263,7 +263,7 @@
         :keyword int retry_write: Indicates how many times the SDK should 
automatically retry this write operation, even if
             the operation is not guaranteed to be idempotent. This should only 
be enabled if the application can
             tolerate such risks or has logic to safely detect and handle 
duplicate operations. Default is None (no retries).
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword Union[bool, dict[str, Any]] availability_strategy: Enables an 
availability strategy by using cross-region request hedging.
             Can be True (use client config if present, otherwise use default 
values: threshold_ms=500, threshold_steps_ms=100),
             False (disable hedging even if client has it enabled),
@@ -350,7 +350,7 @@
         :keyword Literal["High", "Low"] priority: Priority based execution 
allows users to set a priority for each
             request. Once the user has reached their provisioned throughput, 
low priority requests are throttled
             before high priority requests start getting throttled. Feature 
must first be enabled at the account level.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword Sequence[str] excluded_locations: Excluded locations to be 
skipped from preferred locations. The locations
             in this list are specified as the names of the azure Cosmos 
locations like, 'West US', 'East US' and so on.
             If all preferred locations were excluded, primary/hub location 
will be used.
@@ -424,7 +424,7 @@
         :keyword Literal["High", "Low"] priority: Priority based execution 
allows users to set a priority for each
             request. Once the user has reached their provisioned throughput, 
low priority requests are throttled
             before high priority requests start getting throttled. Feature 
must first be enabled at the account level.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword Sequence[str] excluded_locations: Excluded locations to be 
skipped from preferred locations. The locations
             in this list are specified as the names of the azure Cosmos 
locations like, 'West US', 'East US' and so on.
             If all preferred locations were excluded, primary/hub location 
will be used.
@@ -498,7 +498,7 @@
         :keyword Literal["High", "Low"] priority: Priority based execution 
allows users to set a priority for each
             request. Once the user has reached their provisioned throughput, 
low priority requests are throttled
             before high priority requests start getting throttled. Feature 
must first be enabled at the account level.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword Union[bool, dict[str, Any]] availability_strategy: Enables an 
availability strategy by using cross-region request hedging.
             Can be True (use client config if present, otherwise use default 
values: threshold_ms=500, threshold_steps_ms=100),
             False (disable hedging even if client has it enabled),
@@ -1290,7 +1290,7 @@
         :keyword int retry_write: Indicates how many times the SDK should 
automatically retry this write operation, even if
             the operation is not guaranteed to be idempotent. This should only 
be enabled if the application can
             tolerate such risks or has logic to safely detect and handle 
duplicate operations. Default is None (no retries).
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword Sequence[str] excluded_locations: Excluded locations to be 
skipped from preferred locations. The locations
             in this list are specified as the names of the azure Cosmos 
locations like, 'West US', 'East US' and so on.
             If all preferred locations were excluded, primary/hub location 
will be used.
@@ -1429,7 +1429,7 @@
         :keyword int retry_write: Indicates how many times the SDK should 
automatically retry this write operation, even if
             the operation is not guaranteed to be idempotent. This should only 
be enabled if the application can
             tolerate such risks or has logic to safely detect and handle 
duplicate operations. Default is None (no retries).
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword Sequence[str] excluded_locations: Excluded locations to be 
skipped from preferred locations. The locations
             in this list are specified as the names of the azure Cosmos 
locations like, 'West US', 'East US' and so on.
             If all preferred locations were excluded, primary/hub location 
will be used.
@@ -1530,7 +1530,7 @@
         :keyword int retry_write: Indicates how many times the SDK should 
automatically retry this write operation, even if
             the operation is not guaranteed to be idempotent. This should only 
be enabled if the application can
             tolerate such risks or has logic to safely detect and handle 
duplicate operations. Default is None (no retries).
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword Sequence[str] excluded_locations: Excluded locations to be 
skipped from preferred locations. The locations
             in this list are specified as the names of the azure Cosmos 
locations like, 'West US', 'East US' and so on.
             If all preferred locations were excluded, primary/hub location 
will be used.
@@ -1628,7 +1628,7 @@
             tolerate such risks or has logic to safely detect and handle 
duplicate operations. Default is None (no retries).
         :keyword response_hook: A callable invoked with the response metadata.
         :paramtype response_hook: Callable[[Mapping[str, str], None], None]
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword Union[bool, dict[str, Any]] availability_strategy: Enables an 
availability strategy by using cross-region request hedging.
             Can be True (use client config if present, otherwise use default 
values: threshold_ms=500, threshold_steps_ms=100),
             False (disable hedging even if client has it enabled),
@@ -1907,7 +1907,7 @@
             If all preferred locations were excluded, primary/hub location 
will be used.
             This excluded_location will override existing excluded_locations 
in client level.
         :keyword Callable response_hook: A callable invoked with the response 
metadata.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :rtype: None
         """
         etag = kwargs.get('etag')
@@ -1978,7 +1978,7 @@
         :keyword int retry_write: Indicates how many times the SDK should 
automatically retry this write operation, even if
             the operation is not guaranteed to be idempotent. This should only 
be enabled if the application can
             tolerate such risks or has logic to safely detect and handle 
duplicate operations. Default is None (no retries).
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :returns: A CosmosList representing the items after the batch 
operations went through.
         :keyword Union[bool, dict[str, Any]] availability_strategy: Enables an 
availability strategy by using cross-region request hedging.
             Can be True (use client config if present, otherwise use default 
values: threshold_ms=500, threshold_steps_ms=100),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_cosmos-4.16.3/azure/cosmos/aio/_cosmos_client.py 
new/azure_cosmos-4.16.4/azure/cosmos/aio/_cosmos_client.py
--- old/azure_cosmos-4.16.3/azure/cosmos/aio/_cosmos_client.py  2026-07-29 
23:49:45.000000000 +0200
+++ new/azure_cosmos-4.16.4/azure/cosmos/aio/_cosmos_client.py  2026-09-02 
01:44:33.000000000 +0200
@@ -183,7 +183,7 @@
         level (to log all requests) or at a single request level. Requests 
will be logged at INFO level.
     :keyword bool no_response_on_write: Indicates whether service should be 
instructed to skip sending 
         response payloads for write operations on items by default unless 
specified differently per operation.
-    :keyword int throughput_bucket: The desired throughput bucket for the 
client
+    :keyword int throughput_bucket: The desired throughput bucket for the 
client.
     :keyword str user_agent_suffix: Allows user agent suffix to be specified 
when creating client
     :keyword Union[bool, dict[str, Any]] availability_strategy:
         Enables an availability strategy by using cross-region request hedging.
@@ -300,7 +300,7 @@
         :keyword dict[str, str] initial_headers: Initial headers to be sent as 
part of the request.
         :keyword Callable[[dict[str, str], dict[str, Any]], None] 
response_hook: A callable invoked with
             the response metadata.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword bool return_properties: Specifies whether to return either a 
DatabaseProxy
             or a Tuple containing a DatabaseProxy and the associated database 
properties.
         :raises ~azure.cosmos.exceptions.CosmosResourceExistsError: Database 
with the given ID already exists.
@@ -340,7 +340,7 @@
         :keyword dict[str, str] initial_headers: Initial headers to be sent as 
part of the request.
         :keyword Callable[[dict[str, str], dict[str, Any]], None] 
response_hook: A callable invoked with
             the response metadata.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword bool return_properties: Specifies whether to return either a 
DatabaseProxy
             or a Tuple containing a DatabaseProxy and the associated database 
properties.
         :raises ~azure.cosmos.exceptions.CosmosResourceExistsError: Database 
with the given ID already exists.
@@ -375,7 +375,7 @@
         :keyword dict[str, str] initial_headers: Initial headers to be sent as 
part of the request.
         :keyword Callable[[dict[str, str], dict[str, Any]], None] 
response_hook: A callable invoked with
             the response metadata.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword bool return_properties: Specifies whether to return either a 
DatabaseProxy
             or a Tuple containing a DatabaseProxy and the associated database 
properties.
         :raises ~azure.cosmos.exceptions.CosmosResourceExistsError: Database 
with the given ID already exists.
@@ -456,7 +456,7 @@
         :keyword dict[str, str] initial_headers: Initial headers to be sent as 
part of the request.
         :keyword Callable[[dict[str, str], dict[str, Any]], None] 
response_hook: A callable invoked with
             the response metadata.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword bool return_properties: Specifies whether to return either a 
DatabaseProxy
             or a Tuple containing a DatabaseProxy and the associated database 
properties.
         :raises ~azure.cosmos.exceptions.CosmosHttpResponseError: The database 
read or creation failed.
@@ -492,7 +492,7 @@
         :keyword dict[str, str] initial_headers: Initial headers to be sent as 
part of the request.
         :keyword Callable[[dict[str, str], dict[str, Any]], None] 
response_hook: A callable invoked with
             the response metadata.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword bool return_properties: Specifies whether to return either a 
DatabaseProxy
             or a Tuple containing a DatabaseProxy and the associated database 
properties.
         :raises ~azure.cosmos.exceptions.CosmosHttpResponseError: The database 
read or creation failed.
@@ -523,7 +523,7 @@
         :keyword dict[str, str] initial_headers: Initial headers to be sent as 
part of the request.
         :keyword Callable[[dict[str, str], dict[str, Any]], None] 
response_hook: A callable invoked with
             the response metadata.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword bool return_properties: Specifies whether to return either a 
DatabaseProxy
             or a Tuple containing a DatabaseProxy and the associated database 
properties.
         :raises ~azure.cosmos.exceptions.CosmosHttpResponseError: The database 
read or creation failed.
@@ -605,7 +605,7 @@
         :keyword str session_token: Token for use with Session consistency.
         :keyword dict[str, str] initial_headers: Initial headers to be sent as 
part of the request.
         :keyword response_hook: A callable invoked with the response metadata.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :paramtype response_hook: Callable[[Mapping[str, Any]], None]
         :returns: An AsyncItemPaged of database properties (dicts).
         :rtype: AsyncItemPaged[dict[str, str]]
@@ -651,7 +651,7 @@
         :keyword str session_token: Token for use with Session consistency.
         :keyword dict[str, str] initial_headers: Initial headers to be sent as 
part of the request.
         :keyword response_hook: A callable invoked with the response metadata.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :paramtype response_hook: Callable[[Mapping[str, Any]], None]
         :returns: An AsyncItemPaged of database properties (dicts).
         :rtype: AsyncItemPaged[dict[str, str]]
@@ -695,7 +695,7 @@
         :type database: Union[str, ~azure.cosmos.DatabaseProxy, dict[str, Any]]
         :keyword dict[str, str] initial_headers: Initial headers to be sent as 
part of the request.
         :keyword response_hook: A callable invoked with the response metadata.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :paramtype response_hook: Callable[[Mapping[str, Any]], None]
         :raises ~azure.cosmos.exceptions.CosmosHttpResponseError: If the 
database couldn't be deleted.
         :rtype: None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_cosmos-4.16.3/azure/cosmos/container.py 
new/azure_cosmos-4.16.4/azure/cosmos/container.py
--- old/azure_cosmos-4.16.3/azure/cosmos/container.py   2026-07-29 
23:49:45.000000000 +0200
+++ new/azure_cosmos-4.16.4/azure/cosmos/container.py   2026-09-02 
01:44:33.000000000 +0200
@@ -251,7 +251,7 @@
         :keyword Literal["High", "Low"] priority: Priority based execution 
allows users to set a priority for each
             request. Once the user has reached their provisioned throughput, 
low priority requests are throttled
             before high priority requests start getting throttled. Feature 
must first be enabled at the account level.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword Sequence[str] excluded_locations: Excluded locations to be 
skipped from preferred locations. The locations
             in this list are specified as the names of the azure Cosmos 
locations like, 'West US', 'East US' and so on.
             If all preferred locations were excluded, primary/hub location 
will be used.
@@ -339,7 +339,7 @@
         :keyword Literal["High", "Low"] priority: Priority based execution 
allows users to set a priority for each
             request. Once the user has reached their provisioned throughput, 
low priority requests are throttled
             before high priority requests start getting throttled. Feature 
must first be enabled at the account level.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword Union[bool, dict[str, Any]] availability_strategy: Enables an 
availability strategy by using cross-region request hedging.
             Can be True (use client config if present, otherwise use default 
values: threshold_ms=500, threshold_steps_ms=100),
             False (disable hedging even if client has it enabled),
@@ -413,7 +413,7 @@
         :keyword Literal["High", "Low"] priority: Priority based execution 
allows users to set a priority for each
             request. Once the user has reached their provisioned throughput, 
low priority requests are throttled
             before high priority requests start getting throttled. Feature 
must first be enabled at the account level.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword Sequence[str] excluded_locations: Excluded locations to be 
skipped from preferred locations. The locations
             in this list are specified as the names of the azure Cosmos 
locations like, 'West US', 'East US' and so on.
             If all preferred locations were excluded, primary/hub location 
will be used.
@@ -1199,7 +1199,7 @@
         :keyword int retry_write: Indicates how many times the SDK should 
automatically retry this write operation, even if
             the operation is not guaranteed to be idempotent. This should only 
be enabled if the application can
             tolerate such risks or has logic to safely detect and handle 
duplicate operations. Default is None (no retries).
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword Sequence[str] excluded_locations: Excluded locations to be 
skipped from preferred locations. The locations
             in this list are specified as the names of the azure Cosmos 
locations like, 'West US', 'East US' and so on.
             If all preferred locations were excluded, primary/hub location 
will be used.
@@ -1303,7 +1303,7 @@
         :keyword int retry_write: Indicates how many times the SDK should 
automatically retry this write operation, even if
             the operation is not guaranteed to be idempotent. This should only 
be enabled if the application can
             tolerate such risks or has logic to safely detect and handle 
duplicate operations. Default is None (no retries).
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword Sequence[str] excluded_locations: Excluded locations to be 
skipped from preferred locations. The locations
             in this list are specified as the names of the azure Cosmos 
locations like, 'West US', 'East US' and so on.
             If all preferred locations were excluded, primary/hub location 
will be used.
@@ -1406,7 +1406,7 @@
         :keyword int retry_write: Indicates how many times the SDK should 
automatically retry this write operation, even if
             the operation is not guaranteed to be idempotent. This should only 
be enabled if the application can
             tolerate such risks or has logic to safely detect and handle 
duplicate operations. Default is None (no retries).
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword Sequence[str] excluded_locations: Excluded locations to be 
skipped from preferred locations. The locations
             in this list are specified as the names of the azure Cosmos 
locations like, 'West US', 'East US' and so on.
             If all preferred locations were excluded, primary/hub location 
will be used.
@@ -1522,7 +1522,7 @@
         :keyword int retry_write: Indicates how many times the SDK should 
automatically retry this write operation, even if
             the operation is not guaranteed to be idempotent. This should only 
be enabled if the application can
             tolerate such risks or has logic to safely detect and handle 
duplicate operations. Default is None (no retries).
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword Sequence[str] excluded_locations: Excluded locations to be 
skipped from preferred locations. The locations
             in this list are specified as the names of the azure Cosmos 
locations like, 'West US', 'East US' and so on.
             If all preferred locations were excluded, primary/hub location 
will be used.
@@ -1609,7 +1609,7 @@
         :keyword int retry_write: Indicates how many times the SDK should 
automatically retry this write operation, even if
             the operation is not guaranteed to be idempotent. This should only 
be enabled if the application can
             tolerate such risks or has logic to safely detect and handle 
duplicate operations. Default is None (no retries).
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword Union[bool, dict[str, Any]] availability_strategy: Enables an 
availability strategy by using cross-region request hedging.
             Can be True (use client config if present, otherwise use default 
values: threshold_ms=500, threshold_steps_ms=100),
             False (disable hedging even if client has it enabled),
@@ -1707,7 +1707,7 @@
         :keyword int retry_write: Indicates how many times the SDK should 
automatically retry this write operation, even if
             the operation is not guaranteed to be idempotent. This should only 
be enabled if the application can
             tolerate such risks or has logic to safely detect and handle 
duplicate operations. Default is None (no retries).
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword Sequence[str] excluded_locations: Excluded locations to be 
skipped from preferred locations. The locations
             in this list are specified as the names of the azure Cosmos 
locations like, 'West US', 'East US' and so on.
             If all preferred locations were excluded, primary/hub location 
will be used.
@@ -2011,7 +2011,7 @@
         :keyword str pre_trigger_include: trigger id to be used as pre 
operation trigger.
         :keyword str post_trigger_include: trigger id to be used as post 
operation trigger.
         :keyword str session_token: Token for use with Session consistency.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword Sequence[str] excluded_locations: Excluded locations to be 
skipped from preferred locations. The locations
             in this list are specified as the names of the azure Cosmos 
locations like, 'West US', 'East US' and so on.
             If all preferred locations were excluded, primary/hub location 
will be used.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_cosmos-4.16.3/azure/cosmos/cosmos_client.py 
new/azure_cosmos-4.16.4/azure/cosmos/cosmos_client.py
--- old/azure_cosmos-4.16.3/azure/cosmos/cosmos_client.py       2026-07-29 
23:49:45.000000000 +0200
+++ new/azure_cosmos-4.16.4/azure/cosmos/cosmos_client.py       2026-09-02 
01:44:33.000000000 +0200
@@ -205,7 +205,7 @@
         level (to log all requests) or at a single request level. Requests 
will be logged at INFO level.
     :keyword bool no_response_on_write: Indicates whether service should be 
instructed to skip sending 
         response payloads on write operations for items.
-    :keyword int throughput_bucket: The desired throughput bucket for the 
client
+    :keyword int throughput_bucket: The desired throughput bucket for the 
client.
     :keyword str user_agent_suffix: Allows user agent suffix to be specified 
when creating client
     :keyword Union[bool, dict[str, Any]] availability_strategy:
         Enables an availability strategy by using cross-region request hedging.
@@ -324,7 +324,7 @@
             for this database.
         :keyword dict[str, str] initial_headers: Initial headers to be sent as 
part of the request.
         :keyword response_hook: A callable invoked with the response metadata.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword Callable[[Mapping[str, Any]], None] response_hook: A callable 
invoked with the response metadata.
         :keyword bool return_properties: Specifies whether to return either a 
DatabaseProxy
             or a Tuple containing a DatabaseProxy and the associated database 
properties.
@@ -362,7 +362,7 @@
             for this database.
         :keyword Dict[str, str] initial_headers: Initial headers to be sent as 
part of the request.
         :keyword Callable[[Mapping[str, Any]], None] response_hook: A callable 
invoked with the response metadata.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword bool return_properties: Specifies whether to return either a 
DatabaseProxy
             or a Tuple containing a DatabaseProxy and the associated database 
properties.
         :returns: A tuple of `DatabaseProxy` and CosmosDict with the database 
properties.
@@ -394,7 +394,7 @@
             for this database.
         :keyword dict[str, str] initial_headers: Initial headers to be sent as 
part of the request.
         :keyword Callable[[Mapping[str, Any]], None] response_hook: A callable 
invoked with the response metadata.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword bool return_properties: Specifies whether to return either a 
DatabaseProxy
             or a Tuple containing a DatabaseProxy and the associated database 
properties.
         :returns: A `DatabaseProxy` instance representing the database or a 
tuple of `DatabaseProxy`
@@ -478,7 +478,7 @@
             for this database.
         :keyword dict[str, str] initial_headers: Initial headers to be sent as 
part of the request.
         :keyword Callable[[Mapping[str, Any]], None] response_hook: A callable 
invoked with the response metadata.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword bool return_properties: Specifies whether to return either a 
DatabaseProxy
             or a Tuple containing a DatabaseProxy and the associated database 
properties.
         :returns: A `DatabaseProxy` instance representing the database.
@@ -512,7 +512,7 @@
             for this database.
         :keyword dict[str, str] initial_headers: Initial headers to be sent as 
part of the request.
         :keyword Callable[[Mapping[str, Any]], None] response_hook: A callable 
invoked with the response metadata.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword bool return_properties: Specifies whether to return either a 
DatabaseProxy
             or a Tuple containing a DatabaseProxy and the associated database 
properties.
         :returns: A tuple of `DatabaseProxy` and CosmosDict with the database 
properties.
@@ -541,7 +541,7 @@
             for this database.
         :keyword dict[str, str] initial_headers: Initial headers to be sent as 
part of the request.
         :keyword Callable[[Mapping[str, Any]], None] response_hook: A callable 
invoked with the response metadata.
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :keyword bool return_properties: Specifies whether to return either a 
DatabaseProxy
             or a Tuple containing a DatabaseProxy and the associated database 
properties.
         :returns: A `DatabaseProxy` instance representing the database or a 
tuple of `DatabaseProxy`
@@ -628,7 +628,7 @@
         :keyword dict[str, str] initial_headers: Initial headers to be sent as 
part of the request.
         :keyword response_hook: A callable invoked with the response metadata.
         :paramtype response_hook: Callable[[Mapping[str, str]], None]
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :returns: An Iterable of database properties (dicts).
         :rtype: Iterable[dict[str, str]]
         """
@@ -680,7 +680,7 @@
         :keyword dict[str, str] initial_headers: Initial headers to be sent as 
part of the request.
         :keyword response_hook: A callable invoked with the response metadata.
         :paramtype response_hook: Callable[[Mapping[str, str]], None]
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :returns: An Iterable of database properties (dicts).
         :rtype: Iterable[dict[str, str]]
         """
@@ -737,7 +737,7 @@
         :keyword dict[str, str] initial_headers: Initial headers to be sent as 
part of the request.
         :keyword response_hook: A callable invoked with the response metadata.
         :paramtype response_hook: Callable[[Mapping[str, str]], None]
-        :keyword int throughput_bucket: The desired throughput bucket for the 
client
+        :keyword int throughput_bucket: The desired throughput bucket for the 
client.
         :raises ~azure.cosmos.exceptions.CosmosHttpResponseError: If the 
database couldn't be deleted.
         :rtype: None
         """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_cosmos-4.16.3/azure/cosmos/partition_key.py 
new/azure_cosmos-4.16.4/azure/cosmos/partition_key.py
--- old/azure_cosmos-4.16.3/azure/cosmos/partition_key.py       2026-07-29 
23:49:45.000000000 +0200
+++ new/azure_cosmos-4.16.4/azure/cosmos/partition_key.py       2026-09-02 
01:44:33.000000000 +0200
@@ -23,7 +23,7 @@
 from io import BytesIO
 import binascii
 import struct
-from typing import Any, IO, Sequence, Type, Union, cast, overload
+from typing import Any, IO, Mapping, Sequence, Type, Union, cast, overload
 from typing_extensions import Literal
 
 from ._cosmos_integers import _UInt32, _UInt64, _UInt128
@@ -33,6 +33,12 @@
 
 _MaximumExclusiveEffectivePartitionKey = 0xFF
 _MinimumInclusiveEffectivePartitionKey = 0x00
+# The minimum effective partition key is the empty hex string, and its 
immediate successor is "00":
+# effective partition keys are compared as hex strings, so nothing sorts 
between the two. Using the
+# successor as an exclusive upper bound keeps the range normalized, since an 
inclusive point range at
+# the minimum normalizes to an empty range.
+_MinimumInclusiveEffectivePartitionKeyString = ""
+_MinimumEffectivePartitionKeySuccessorString = "00"
 _MaxStringChars = 100
 _MaxStringBytesToAppend = 100
 _MaxPartitionKeyBinarySize = \
@@ -217,6 +223,15 @@
             self,
             pk_value: PartitionKeyType
     ) -> _Range:
+        # _Empty is the sentinel for a partition key value missing from an 
item in a system key
+        # (migrated) container. Unlike the other sentinels it does not stand 
for a partition key
+        # *component*, it stands for an empty list of components -- it is 
serialized on the wire as
+        # `[]` rather than `[{}]` -- so it has no binary encoding and cannot 
be hashed. It maps to
+        # the minimum effective partition key, which is what hashing an empty 
component list yields.
+        if isinstance(pk_value, _Empty):
+            return _Range(_MinimumInclusiveEffectivePartitionKeyString,
+                          _MinimumEffectivePartitionKeySuccessorString, True, 
False)
+
         if self._is_prefix_partition_key(pk_value):
             return self._get_epk_range_for_prefix_partition_key(
                 cast(_SequentialPartitionKeyType, pk_value))
@@ -246,7 +261,8 @@
         if isinstance(pk_value, str):
             
truncated_components.append(PartitionKey._truncate_for_v1_hashing(pk_value))
         else:
-            truncated_components = [PartitionKey._truncate_for_v1_hashing(v) 
for v in pk_value]
+            truncated_components = 
[PartitionKey._truncate_for_v1_hashing(_normalize_undefined_component(v))
+                                    for v in pk_value]
         with BytesIO() as ms:
             for component in truncated_components:
                 if isinstance(component, int) and not isinstance(component, 
bool):
@@ -335,7 +351,7 @@
     ) -> str:
         with BytesIO() as ms:
             for component in pk_value:
-                PartitionKey._write_for_hashing_v2(component, ms)
+                
PartitionKey._write_for_hashing_v2(_normalize_undefined_component(component), 
ms)
 
             ms_bytes = ms.getvalue()
             hash128 = _murmurhash3_128(bytearray(ms_bytes), _UInt128(0, 0))
@@ -358,7 +374,7 @@
             binary_writer = ms  # In Python, you can write bytes directly to a 
BytesIO object
 
             # Assuming paths[i] is the correct object to call 
write_for_hashing_v2 on
-            PartitionKey._write_for_hashing_v2(value, binary_writer)
+            
PartitionKey._write_for_hashing_v2(_normalize_undefined_component(value), 
binary_writer)
 
             ms_bytes = ms.getvalue()
             hash128 = _murmurhash3_128(bytearray(ms_bytes), _UInt128(0, 0))
@@ -388,6 +404,23 @@
     return _Undefined()
 
 
+def _normalize_undefined_component(value: Any) -> Any:
+    """Normalize the sentinels that mean "the item has no value for this 
partition key path".
+
+    ``{}`` is the legacy spelling of an absent partition key value, and 
``NonePartitionKeyValue``
+    is the modern one. Both are serialized on the wire as ``[{}]`` and must 
therefore hash to
+    ``Undefined``, not ``Null``. Without this normalization ``{}`` raises 
``TypeError`` on Hash V1
+    partition keys and hashes to the ``Null`` effective partition key on Hash 
V2 ones.
+
+    :param any value: A single partition key component.
+    :return: ``_Undefined()`` when the component means "no value", otherwise 
the component itself.
+    :rtype: any
+    """
+    if value is NonePartitionKeyValue or (isinstance(value, Mapping) and not 
value):
+        return _Undefined()
+    return value
+
+
 def _to_hex(bytes_object: bytearray, start: int, length: int) -> str:
     return binascii.hexlify(bytes_object[start:start + length]).decode()
 
@@ -459,7 +492,9 @@
         utf8_value = value.encode('utf-8')
         short_string = len(utf8_value) <= _MaxStringBytesToAppend
 
-        for index in range(short_string and len(utf8_value) or 
_MaxStringBytesToAppend + 1):
+        # `short_string and len(...) or ...` mis-evaluates to the long-string 
branch for the
+        # empty string, which then indexes past the end of `utf8_value`.
+        for index in range(len(utf8_value) if short_string else 
_MaxStringBytesToAppend + 1):
             char_byte = utf8_value[index]
             char_byte += 1
             binary_writer.write(bytes([char_byte]))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_cosmos-4.16.3/azure_cosmos.egg-info/PKG-INFO 
new/azure_cosmos-4.16.4/azure_cosmos.egg-info/PKG-INFO
--- old/azure_cosmos-4.16.3/azure_cosmos.egg-info/PKG-INFO      2026-07-29 
23:50:47.000000000 +0200
+++ new/azure_cosmos-4.16.4/azure_cosmos.egg-info/PKG-INFO      2026-09-02 
01:46:02.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: azure-cosmos
-Version: 4.16.3
+Version: 4.16.4
 Summary: Microsoft Azure Cosmos Client Library for Python
 Home-page: https://github.com/Azure/azure-sdk-for-python
 Author: Microsoft Corporation
@@ -1010,7 +1010,7 @@
 
 You can find our sync samples [here][cosmos_index_sample] and our async 
samples [here][cosmos_index_sample_async] as well for additional guidance.
 
-### Public Preview - Throughput Buckets
+### Throughput Buckets
 When multiple workloads share the same Azure Cosmos DB container, resource 
contention can lead to throttling, increased latency, and potential business 
impact.
 To address this, Cosmos DB allows you to allocate throughput buckets, which 
help manage resource consumption for workloads sharing a Cosmos DB container by 
limiting the maximum throughput a bucket can consume.
 However, throughput isn't reserved for any bucket, it remains shared across 
all workloads.
@@ -1352,6 +1352,17 @@
 
 
 ## Release History
+> [!IMPORTANT]
+> We strongly recommend that customers use at least version 4.16.3 of 
`azure-cosmos`.
+
+### 4.16.4 (2026-09-02)
+
+#### Bugs Fixed
+* Fixed regression with handling of v1 legacy containers when passing `{}` as 
a partition key. `{}` and `NonePartitionKeyValue` now both resolve to the 
`Undefined` effective partition key. See [PR 
48422](https://github.com/Azure/azure-sdk-for-python/pull/48422)
+* Fixed the same `TypeError` on system key (migrated) containers, where a 
missing partition key value resolves to `_Empty` instead of `Undefined`. It now 
maps to the minimum effective partition key. See [PR 
48422](https://github.com/Azure/azure-sdk-for-python/pull/48422)
+
+#### Other Changes
+* Marked the Throughput Buckets feature as GA. See 
[48838](https://github.com/Azure/azure-sdk-for-python/pull/48838).
 
 ### 4.16.3 (2026-07-29)
 
@@ -1424,8 +1435,6 @@
 * Enhanced error logging by attaching endpoint information to exceptions 
during database account retrieval. See [PR 
44484](https://github.com/Azure/azure-sdk-for-python/pull/44484)
 
 ### 4.15.0 (2026-02-19)
-> [!IMPORTANT]
-> We strongly recommend that customers use at least version 4.15.0 of 
`azure-cosmos`.
 
 #### Features Added
 * GA support of Per Partition Automatic Failover and AvailabilityStrategy 
features.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_cosmos-4.16.3/azure_cosmos.egg-info/SOURCES.txt 
new/azure_cosmos-4.16.4/azure_cosmos.egg-info/SOURCES.txt
--- old/azure_cosmos-4.16.3/azure_cosmos.egg-info/SOURCES.txt   2026-07-29 
23:50:47.000000000 +0200
+++ new/azure_cosmos-4.16.4/azure_cosmos.egg-info/SOURCES.txt   2026-09-02 
01:46:02.000000000 +0200
@@ -285,6 +285,7 @@
 tests/test_orderby.py
 tests/test_partition_key.py
 tests/test_partition_key_async.py
+tests/test_partition_key_undefined_unit.py
 tests/test_partition_split_query.py
 tests/test_partition_split_query_async.py
 tests/test_partition_split_retry_unit.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_cosmos-4.16.3/tests/test_partition_key_undefined_unit.py 
new/azure_cosmos-4.16.4/tests/test_partition_key_undefined_unit.py
--- old/azure_cosmos-4.16.3/tests/test_partition_key_undefined_unit.py  
1970-01-01 01:00:00.000000000 +0100
+++ new/azure_cosmos-4.16.4/tests/test_partition_key_undefined_unit.py  
2026-09-02 01:44:33.000000000 +0200
@@ -0,0 +1,125 @@
+# The MIT License (MIT)
+# Copyright (c) Microsoft Corporation. All rights reserved.
+
+"""Unit tests for how "no partition key value" sentinels are hashed.
+
+``{}`` is the legacy spelling of "this item has no value for the partition key 
path".
+It is serialized on the wire as ``[{}]``, exactly like 
``NonePartitionKeyValue``, so both
+must produce the ``Undefined`` effective partition key.
+
+Regression coverage for 
https://github.com/Azure/azure-sdk-for-python/issues/48420 where
+``query_items(query, partition_key={})`` raised
+``TypeError: Unexpected type for PK component: <class 'dict'>`` on Hash V1 
containers, and
+silently resolved to the ``Null`` effective partition key on Hash V2 
containers.
+
+``_Empty`` is the equivalent sentinel for system key (migrated) containers. It 
is serialized
+as ``[]`` rather than ``[{}]`` -- an empty list of partition key components 
rather than a single
+undefined one -- so it resolves to the minimum effective partition key instead.
+"""
+
+import unittest
+
+import pytest
+
+from azure.cosmos.partition_key import (
+    NonePartitionKeyValue,
+    PartitionKey,
+    _Empty,
+    _Undefined,
+)
+
+UNDEFINED_EQUIVALENTS = ({}, NonePartitionKeyValue)
+
+
[email protected]
[email protected]
+class TestUndefinedPartitionKeyHashingUnitTest(unittest.TestCase):
+
+    def test_undefined_equivalents_match_undefined_epk(self):
+        for version in (1, 2):
+            expected = PartitionKey(
+                path="/pk", kind="Hash", version=version
+            )._get_epk_range_for_partition_key(_Undefined())
+            for pk_value in UNDEFINED_EQUIVALENTS:
+                with self.subTest(version=version, pk_value=pk_value):
+                    actual = PartitionKey(
+                        path="/pk", kind="Hash", version=version
+                    )._get_epk_range_for_partition_key(pk_value)
+                    self.assertEqual(actual.min, expected.min)
+                    self.assertEqual(actual.max, expected.max)
+
+    def test_undefined_equivalents_differ_from_null_epk(self):
+        for version in (1, 2):
+            null_epk = PartitionKey(
+                path="/pk", kind="Hash", version=version
+            )._get_epk_range_for_partition_key(None)
+            for pk_value in UNDEFINED_EQUIVALENTS:
+                with self.subTest(version=version, pk_value=pk_value):
+                    actual = PartitionKey(
+                        path="/pk", kind="Hash", version=version
+                    )._get_epk_range_for_partition_key(pk_value)
+                    self.assertNotEqual(
+                        actual.min, null_epk.min,
+                        "An absent partition key value must not hash to the 
Null EPK.",
+                    )
+
+    def test_undefined_equivalents_match_undefined_epk_for_multi_hash(self):
+        pk_definition = PartitionKey(path=["/a", "/b"], kind="MultiHash", 
version=2)
+        expected = 
pk_definition._get_epk_range_for_partition_key([_Undefined(), "z"])
+        for pk_value in UNDEFINED_EQUIVALENTS:
+            with self.subTest(pk_value=pk_value):
+                actual = 
pk_definition._get_epk_range_for_partition_key([pk_value, "z"])
+                self.assertEqual(actual.min, expected.min)
+                self.assertEqual(actual.max, expected.max)
+
+    def test_defined_values_are_unaffected(self):
+        """Normalization must not alter any value that does have a partition 
key value."""
+        for version in (1, 2):
+            pk_definition = PartitionKey(path="/pk", kind="Hash", 
version=version)
+            for pk_value in (None, True, False, 0, 1, -1, 3.5, "", "a", "x" * 
150):
+                with self.subTest(version=version, pk_value=pk_value):
+                    epk = 
pk_definition._get_epk_range_for_partition_key(pk_value)
+                    self.assertIsNotNone(epk.min)
+
+    def test_empty_resolves_to_minimum_epk(self):
+        """``_Empty`` is an empty component list, so it maps to the minimum 
effective partition key."""
+        for pk_definition in (
+            PartitionKey(path="/pk", kind="Hash", version=1),
+            PartitionKey(path="/pk", kind="Hash", version=2),
+            PartitionKey(path=["/a", "/b"], kind="MultiHash", version=2),
+        ):
+            with self.subTest(kind=pk_definition.kind, 
version=pk_definition.version):
+                epk = pk_definition._get_epk_range_for_partition_key(_Empty())
+                self.assertEqual(epk.min, "")
+                self.assertEqual(epk.max, "00")
+                self.assertTrue(epk.isMinInclusive)
+                self.assertFalse(epk.isMaxInclusive)
+
+    def test_empty_range_survives_normalization(self):
+        """The range must stay non-empty once normalized, otherwise it matches 
no feed range.
+
+        An inclusive point range at the minimum effective partition key 
normalizes to an empty
+        range, which would silently resolve to no partitions at all.
+        """
+        for version in (1, 2):
+            with self.subTest(version=version):
+                epk = PartitionKey(
+                    path="/pk", kind="Hash", version=version
+                )._get_epk_range_for_partition_key(_Empty())
+                normalized = epk.to_normalized_range()
+                self.assertFalse(normalized.isEmpty())
+                self.assertEqual(normalized, epk)
+
+    def test_empty_differs_from_undefined(self):
+        """``_Empty`` and ``_Undefined`` are distinct sentinels with distinct 
wire forms."""
+        for version in (1, 2):
+            with self.subTest(version=version):
+                pk_definition = PartitionKey(path="/pk", kind="Hash", 
version=version)
+                self.assertNotEqual(
+                    
pk_definition._get_epk_range_for_partition_key(_Empty()).min,
+                    
pk_definition._get_epk_range_for_partition_key(_Undefined()).min,
+                )
+
+
+if __name__ == "__main__":
+    unittest.main()

Reply via email to