Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-azure-core for 
openSUSE:Factory checked in at 2025-09-14 18:49:05
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-azure-core (Old)
 and      /work/SRC/openSUSE:Factory/.python-azure-core.new.1977 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-azure-core"

Sun Sep 14 18:49:05 2025 rev:56 rq:1304279 version:1.35.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-azure-core/python-azure-core.changes      
2025-07-15 16:43:41.463503481 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-azure-core.new.1977/python-azure-core.changes
    2025-09-14 18:49:29.648383492 +0200
@@ -1,0 +2,8 @@
+Fri Sep 12 10:00:31 UTC 2025 - John Paul Adrian Glaubitz 
<[email protected]>
+
+- New upstream release
+  + Version 1.35.1
+  + For detailed information about changes see the
+    CHANGELOG.md file provided with this package
+
+-------------------------------------------------------------------

Old:
----
  azure_core-1.35.0.tar.gz

New:
----
  azure_core-1.35.1.tar.gz

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

Other differences:
------------------
++++++ python-azure-core.spec ++++++
--- /var/tmp/diff_new_pack.9MNar0/_old  2025-09-14 18:49:30.192406289 +0200
+++ /var/tmp/diff_new_pack.9MNar0/_new  2025-09-14 18:49:30.196406457 +0200
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-azure-core
-Version:        1.35.0
+Version:        1.35.1
 Release:        0
 Summary:        Microsoft Azure Core Library for Python
 License:        MIT

++++++ azure_core-1.35.0.tar.gz -> azure_core-1.35.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_core-1.35.0/CHANGELOG.md 
new/azure_core-1.35.1/CHANGELOG.md
--- old/azure_core-1.35.0/CHANGELOG.md  2025-07-03 01:50:16.000000000 +0200
+++ new/azure_core-1.35.1/CHANGELOG.md  2025-09-11 23:05:23.000000000 +0200
@@ -1,5 +1,15 @@
 # Release History
 
+## 1.35.1 (2025-09-11)
+
+### Bugs Fixed
+
+- Fixed an issue where the `retry_backoff_max` parameter in `RetryPolicy` and 
`AsyncRetryPolicy` constructors was being ignored, causing retry operations to 
use default maximum backoff values instead of the user-specified limits. #42444
+
+### Other Changes
+
+- `BearerTokenCredentialPolicy` and `AsyncBearerTokenCredentialPolicy` will 
now properly surface credential exceptions when handling claims challenges. 
Previously, exceptions from credential token requests were suppressed; now they 
are raised and chained with the original 401 `HttpResponseError` response for 
better debugging visibility. #42536
+
 ## 1.35.0 (2025-07-02)
 
 ### Features Added
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_core-1.35.0/PKG-INFO 
new/azure_core-1.35.1/PKG-INFO
--- old/azure_core-1.35.0/PKG-INFO      2025-07-03 01:51:52.409240000 +0200
+++ new/azure_core-1.35.1/PKG-INFO      2025-09-11 23:06:22.317217000 +0200
@@ -1,6 +1,6 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.4
 Name: azure-core
-Version: 1.35.0
+Version: 1.35.1
 Summary: Microsoft Azure Core Library for Python
 Home-page: 
https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/core/azure-core
 Author: Microsoft Corporation
@@ -27,6 +27,19 @@
 Requires-Dist: aiohttp>=3.0; extra == "aio"
 Provides-Extra: tracing
 Requires-Dist: opentelemetry-api~=1.26; extra == "tracing"
+Dynamic: author
+Dynamic: author-email
+Dynamic: classifier
+Dynamic: description
+Dynamic: description-content-type
+Dynamic: home-page
+Dynamic: keywords
+Dynamic: license
+Dynamic: license-file
+Dynamic: provides-extra
+Dynamic: requires-dist
+Dynamic: requires-python
+Dynamic: summary
 
 
 # Azure Core shared client library for Python
@@ -259,6 +272,33 @@
 )
 ```
 
+## Logging
+
+Azure libraries follow the guidance of Python's standard 
[logging](https://docs.python.org/3/library/logging.html) module. By following 
the Python documentation on logging, you should be able to configure logging 
for Azure libraries effectively.
+
+Azure library loggers use a dot-based separated syntax, where the first 
section is always `azure`, followed by the package name. For example, the Azure 
Core library uses logger names that start with `azure.core`.
+
+Here's an example of how to configure logging for Azure libraries:
+
+```python
+import logging
+import sys
+
+# Enable detailed console logs across Azure libraries
+azure_logger = logging.getLogger("azure")
+azure_logger.setLevel(logging.DEBUG)
+azure_logger.addHandler(logging.StreamHandler(stream=sys.stdout))
+
+# Exclude detailed logs for network calls associated with getting Entra ID 
token.
+identity_logger = logging.getLogger("azure.identity")
+identity_logger.setLevel(logging.ERROR)
+
+# Make sure regular (redacted) detailed azure.core logs are not shown, as we 
are about to
+# turn on non-redacted logs by passing 'logging_enable=True' to the client 
constructor 
+logger = logging.getLogger("azure.core.pipeline.policies.http_logging_policy")
+logger.setLevel(logging.ERROR)
+```
+
 ## Contributing
 
 This project welcomes contributions and suggestions. Most contributions require
@@ -284,6 +324,16 @@
 
 # Release History
 
+## 1.35.1 (2025-09-11)
+
+### Bugs Fixed
+
+- Fixed an issue where the `retry_backoff_max` parameter in `RetryPolicy` and 
`AsyncRetryPolicy` constructors was being ignored, causing retry operations to 
use default maximum backoff values instead of the user-specified limits. #42444
+
+### Other Changes
+
+- `BearerTokenCredentialPolicy` and `AsyncBearerTokenCredentialPolicy` will 
now properly surface credential exceptions when handling claims challenges. 
Previously, exceptions from credential token requests were suppressed; now they 
are raised and chained with the original 401 `HttpResponseError` response for 
better debugging visibility. #42536
+
 ## 1.35.0 (2025-07-02)
 
 ### Features Added
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_core-1.35.0/README.md 
new/azure_core-1.35.1/README.md
--- old/azure_core-1.35.0/README.md     2025-07-03 01:50:16.000000000 +0200
+++ new/azure_core-1.35.1/README.md     2025-09-11 23:05:23.000000000 +0200
@@ -229,6 +229,33 @@
 )
 ```
 
+## Logging
+
+Azure libraries follow the guidance of Python's standard 
[logging](https://docs.python.org/3/library/logging.html) module. By following 
the Python documentation on logging, you should be able to configure logging 
for Azure libraries effectively.
+
+Azure library loggers use a dot-based separated syntax, where the first 
section is always `azure`, followed by the package name. For example, the Azure 
Core library uses logger names that start with `azure.core`.
+
+Here's an example of how to configure logging for Azure libraries:
+
+```python
+import logging
+import sys
+
+# Enable detailed console logs across Azure libraries
+azure_logger = logging.getLogger("azure")
+azure_logger.setLevel(logging.DEBUG)
+azure_logger.addHandler(logging.StreamHandler(stream=sys.stdout))
+
+# Exclude detailed logs for network calls associated with getting Entra ID 
token.
+identity_logger = logging.getLogger("azure.identity")
+identity_logger.setLevel(logging.ERROR)
+
+# Make sure regular (redacted) detailed azure.core logs are not shown, as we 
are about to
+# turn on non-redacted logs by passing 'logging_enable=True' to the client 
constructor 
+logger = logging.getLogger("azure.core.pipeline.policies.http_logging_policy")
+logger.setLevel(logging.ERROR)
+```
+
 ## Contributing
 
 This project welcomes contributions and suggestions. Most contributions require
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_core-1.35.0/azure/core/_version.py 
new/azure_core-1.35.1/azure/core/_version.py
--- old/azure_core-1.35.0/azure/core/_version.py        2025-07-03 
01:50:16.000000000 +0200
+++ new/azure_core-1.35.1/azure/core/_version.py        2025-09-11 
23:05:23.000000000 +0200
@@ -9,4 +9,4 @@
 # regenerated.
 # --------------------------------------------------------------------------
 
-VERSION = "1.35.0"
+VERSION = "1.35.1"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_core-1.35.0/azure/core/pipeline/policies/_authentication.py 
new/azure_core-1.35.1/azure/core/pipeline/policies/_authentication.py
--- old/azure_core-1.35.0/azure/core/pipeline/policies/_authentication.py       
2025-07-03 01:50:16.000000000 +0200
+++ new/azure_core-1.35.1/azure/core/pipeline/policies/_authentication.py       
2025-09-11 23:05:23.000000000 +0200
@@ -6,12 +6,14 @@
 import time
 import base64
 from typing import TYPE_CHECKING, Optional, TypeVar, MutableMapping, Any, 
Union, cast
+
 from azure.core.credentials import (
     TokenCredential,
     SupportsTokenInfo,
     TokenRequestOptions,
     TokenProvider,
 )
+from azure.core.exceptions import HttpResponseError
 from azure.core.pipeline import PipelineRequest, PipelineResponse
 from azure.core.pipeline.transport import (
     HttpResponse as LegacyHttpResponse,
@@ -165,7 +167,20 @@
         if response.http_response.status_code == 401:
             self._token = None  # any cached token is invalid
             if "WWW-Authenticate" in response.http_response.headers:
-                request_authorized = self.on_challenge(request, response)
+                try:
+                    request_authorized = self.on_challenge(request, response)
+                except Exception as ex:
+                    # If the response is streamed, read it so the error 
message is immediately available to the user.
+                    # Otherwise, a generic error message will be given and the 
user will have to read the response
+                    # body to see the actual error.
+                    if response.context.options.get("stream"):
+                        try:
+                            response.http_response.read()  # type: ignore
+                        except Exception:  # pylint:disable=broad-except
+                            pass
+                    # Raise the exception from the token request with the 
original 401 response
+                    raise ex from 
HttpResponseError(response=response.http_response)
+
                 if request_authorized:
                     # if we receive a challenge response, we retrieve a new 
token
                     # which matches the new target. In this case, we don't 
want to remove
@@ -200,14 +215,11 @@
             encoded_claims = get_challenge_parameter(headers, "Bearer", 
"claims")
             if not encoded_claims:
                 return False
-            try:
-                padding_needed = -len(encoded_claims) % 4
-                claims = base64.urlsafe_b64decode(encoded_claims + "=" * 
padding_needed).decode("utf-8")
-                if claims:
-                    self.authorize_request(request, *self._scopes, 
claims=claims)
-                    return True
-            except Exception:  # pylint:disable=broad-except
-                return False
+            padding_needed = -len(encoded_claims) % 4
+            claims = base64.urlsafe_b64decode(encoded_claims + "=" * 
padding_needed).decode("utf-8")
+            if claims:
+                self.authorize_request(request, *self._scopes, claims=claims)
+                return True
         return False
 
     def on_response(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_core-1.35.0/azure/core/pipeline/policies/_authentication_async.py 
new/azure_core-1.35.1/azure/core/pipeline/policies/_authentication_async.py
--- old/azure_core-1.35.0/azure/core/pipeline/policies/_authentication_async.py 
2025-07-03 01:50:16.000000000 +0200
+++ new/azure_core-1.35.1/azure/core/pipeline/policies/_authentication_async.py 
2025-09-11 23:05:23.000000000 +0200
@@ -13,6 +13,7 @@
     AsyncSupportsTokenInfo,
     AsyncTokenProvider,
 )
+from azure.core.exceptions import HttpResponseError
 from azure.core.pipeline import PipelineRequest, PipelineResponse
 from azure.core.pipeline.policies import AsyncHTTPPolicy
 from azure.core.pipeline.policies._authentication import (
@@ -110,7 +111,21 @@
         if response.http_response.status_code == 401:
             self._token = None  # any cached token is invalid
             if "WWW-Authenticate" in response.http_response.headers:
-                request_authorized = await self.on_challenge(request, response)
+                try:
+                    request_authorized = await self.on_challenge(request, 
response)
+                except Exception as ex:
+                    # If the response is streamed, read it so the error 
message is immediately available to the user.
+                    # Otherwise, a generic error message will be given and the 
user will have to read the response
+                    # body to see the actual error.
+                    if response.context.options.get("stream"):
+                        try:
+                            await response.http_response.read()  # type: ignore
+                        except Exception:  # pylint:disable=broad-except
+                            pass
+
+                    # Raise the exception from the token request with the 
original 401 response
+                    raise ex from 
HttpResponseError(response=response.http_response)
+
                 if request_authorized:
                     # if we receive a challenge response, we retrieve a new 
token
                     # which matches the new target. In this case, we don't 
want to remove
@@ -145,14 +160,11 @@
             encoded_claims = get_challenge_parameter(headers, "Bearer", 
"claims")
             if not encoded_claims:
                 return False
-            try:
-                padding_needed = -len(encoded_claims) % 4
-                claims = base64.urlsafe_b64decode(encoded_claims + "=" * 
padding_needed).decode("utf-8")
-                if claims:
-                    await self.authorize_request(request, *self._scopes, 
claims=claims)
-                    return True
-            except Exception:  # pylint:disable=broad-except
-                return False
+            padding_needed = -len(encoded_claims) % 4
+            claims = base64.urlsafe_b64decode(encoded_claims + "=" * 
padding_needed).decode("utf-8")
+            if claims:
+                await self.authorize_request(request, *self._scopes, 
claims=claims)
+                return True
         return False
 
     def on_response(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_core-1.35.0/azure/core/pipeline/policies/_retry.py 
new/azure_core-1.35.1/azure/core/pipeline/policies/_retry.py
--- old/azure_core-1.35.0/azure/core/pipeline/policies/_retry.py        
2025-07-03 01:50:16.000000000 +0200
+++ new/azure_core-1.35.1/azure/core/pipeline/policies/_retry.py        
2025-09-11 23:05:23.000000000 +0200
@@ -118,7 +118,7 @@
             "read": options.pop("retry_read", self.read_retries),
             "status": options.pop("retry_status", self.status_retries),
             "backoff": options.pop("retry_backoff_factor", 
self.backoff_factor),
-            "max_backoff": options.pop("retry_backoff_max", self.BACKOFF_MAX),
+            "max_backoff": options.pop("retry_backoff_max", self.backoff_max),
             "methods": options.pop("retry_on_methods", self._method_whitelist),
             "timeout": options.pop("timeout", self.timeout),
             "history": [],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_core-1.35.0/azure_core.egg-info/PKG-INFO 
new/azure_core-1.35.1/azure_core.egg-info/PKG-INFO
--- old/azure_core-1.35.0/azure_core.egg-info/PKG-INFO  2025-07-03 
01:51:52.000000000 +0200
+++ new/azure_core-1.35.1/azure_core.egg-info/PKG-INFO  2025-09-11 
23:06:22.000000000 +0200
@@ -1,6 +1,6 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.4
 Name: azure-core
-Version: 1.35.0
+Version: 1.35.1
 Summary: Microsoft Azure Core Library for Python
 Home-page: 
https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/core/azure-core
 Author: Microsoft Corporation
@@ -27,6 +27,19 @@
 Requires-Dist: aiohttp>=3.0; extra == "aio"
 Provides-Extra: tracing
 Requires-Dist: opentelemetry-api~=1.26; extra == "tracing"
+Dynamic: author
+Dynamic: author-email
+Dynamic: classifier
+Dynamic: description
+Dynamic: description-content-type
+Dynamic: home-page
+Dynamic: keywords
+Dynamic: license
+Dynamic: license-file
+Dynamic: provides-extra
+Dynamic: requires-dist
+Dynamic: requires-python
+Dynamic: summary
 
 
 # Azure Core shared client library for Python
@@ -259,6 +272,33 @@
 )
 ```
 
+## Logging
+
+Azure libraries follow the guidance of Python's standard 
[logging](https://docs.python.org/3/library/logging.html) module. By following 
the Python documentation on logging, you should be able to configure logging 
for Azure libraries effectively.
+
+Azure library loggers use a dot-based separated syntax, where the first 
section is always `azure`, followed by the package name. For example, the Azure 
Core library uses logger names that start with `azure.core`.
+
+Here's an example of how to configure logging for Azure libraries:
+
+```python
+import logging
+import sys
+
+# Enable detailed console logs across Azure libraries
+azure_logger = logging.getLogger("azure")
+azure_logger.setLevel(logging.DEBUG)
+azure_logger.addHandler(logging.StreamHandler(stream=sys.stdout))
+
+# Exclude detailed logs for network calls associated with getting Entra ID 
token.
+identity_logger = logging.getLogger("azure.identity")
+identity_logger.setLevel(logging.ERROR)
+
+# Make sure regular (redacted) detailed azure.core logs are not shown, as we 
are about to
+# turn on non-redacted logs by passing 'logging_enable=True' to the client 
constructor 
+logger = logging.getLogger("azure.core.pipeline.policies.http_logging_policy")
+logger.setLevel(logging.ERROR)
+```
+
 ## Contributing
 
 This project welcomes contributions and suggestions. Most contributions require
@@ -284,6 +324,16 @@
 
 # Release History
 
+## 1.35.1 (2025-09-11)
+
+### Bugs Fixed
+
+- Fixed an issue where the `retry_backoff_max` parameter in `RetryPolicy` and 
`AsyncRetryPolicy` constructors was being ignored, causing retry operations to 
use default maximum backoff values instead of the user-specified limits. #42444
+
+### Other Changes
+
+- `BearerTokenCredentialPolicy` and `AsyncBearerTokenCredentialPolicy` will 
now properly surface credential exceptions when handling claims challenges. 
Previously, exceptions from credential token requests were suppressed; now they 
are raised and chained with the original 401 `HttpResponseError` response for 
better debugging visibility. #42536
+
 ## 1.35.0 (2025-07-02)
 
 ### Features Added
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_core-1.35.0/tests/async_tests/test_authentication_async.py 
new/azure_core-1.35.1/tests/async_tests/test_authentication_async.py
--- old/azure_core-1.35.0/tests/async_tests/test_authentication_async.py        
2025-07-03 01:50:16.000000000 +0200
+++ new/azure_core-1.35.1/tests/async_tests/test_authentication_async.py        
2025-09-11 23:05:23.000000000 +0200
@@ -12,7 +12,7 @@
 
 from azure.core.credentials import AccessToken, AccessTokenInfo
 from azure.core.credentials_async import AsyncTokenCredential, 
AsyncSupportsTokenInfo
-from azure.core.exceptions import ServiceRequestError
+from azure.core.exceptions import ServiceRequestError, HttpResponseError, 
ClientAuthenticationError
 from azure.core.pipeline import AsyncPipeline, PipelineRequest, 
PipelineContext, PipelineResponse
 from azure.core.pipeline.policies import (
     AsyncBearerTokenCredentialPolicy,
@@ -640,3 +640,98 @@
 
     # Verify the Authorization header was set correctly
     assert request.http_request.headers["Authorization"] == "Bearer 
claims_token"
+
+
[email protected]
[email protected]("http_request", HTTP_REQUESTS)
+async def 
test_async_bearer_policy_on_challenge_exception_chaining(http_request):
+    """Test that exceptions during async on_challenge are chained with 
HttpResponseError"""
+
+    # Mock credential that raises an exception during get_token_info with 
claims
+    async def mock_get_token_info(*scopes, options=None):
+        if options and "claims" in options:
+            raise ClientAuthenticationError("Failed to request token info with 
claims")
+        return AccessTokenInfo("initial_token", int(time.time()) + 3600)
+
+    fake_credential = Mock(
+        spec_set=["get_token", "get_token_info"],
+        get_token=AsyncMock(return_value=AccessToken("fallback", 
int(time.time()) + 3600)),
+        get_token_info=mock_get_token_info,
+    )
+    policy = AsyncBearerTokenCredentialPolicy(fake_credential, "scope")
+
+    # Create a 401 response with insufficient_claims challenge
+    test_claims = '{"access_token":{"foo":"bar"}}'
+    encoded_claims = 
base64.urlsafe_b64encode(test_claims.encode()).decode().rstrip("=")
+    challenge_header = f'Bearer error="insufficient_claims", 
claims="{encoded_claims}"'
+
+    response_mock = Mock(status_code=401, headers={"WWW-Authenticate": 
challenge_header})
+
+    # Mock transport that returns the 401 response
+    async def mock_transport_send(request):
+        return response_mock
+
+    transport = Mock(send=mock_transport_send)
+    pipeline = AsyncPipeline(transport=transport, policies=[policy])
+
+    # Execute the request and verify exception chaining
+    with pytest.raises(ClientAuthenticationError) as exc_info:
+        await pipeline.run(http_request("GET", "https://example.com";))
+
+    # Verify the original exception is preserved
+    original_exception = exc_info.value
+    assert original_exception.message == "Failed to request token info with 
claims"
+
+    # Verify the exception is chained with HttpResponseError
+    assert original_exception.__cause__ is not None
+    assert isinstance(original_exception.__cause__, HttpResponseError)
+
+    # Verify the HttpResponseError contains the original 401 response
+    http_response_error = original_exception.__cause__
+    assert http_response_error.response is response_mock
+
+
[email protected]
[email protected]("http_request", HTTP_REQUESTS)
+async def 
test_async_bearer_policy_reads_streamed_response_on_challenge_exception(http_request):
+    """Test that the async policy reads streamed response body when 
on_challenge raises exception"""
+
+    # Create a credential that will raise an exception when get_token is 
called with claims
+    async def failing_get_token(*scopes, **kwargs):
+        if "claims" in kwargs:
+            raise ClientAuthenticationError("Failed to get token with claims")
+        return AccessToken("initial_token", int(time.time()) + 3600)
+
+    credential = Mock(spec_set=["get_token"], get_token=failing_get_token)
+    policy = AsyncBearerTokenCredentialPolicy(credential, "scope")
+
+    # Create a 401 response with insufficient_claims challenge that will 
trigger the exception
+    test_claims = '{"access_token":{"foo":"bar"}}'
+    encoded_claims = 
base64.urlsafe_b64encode(test_claims.encode()).decode().rstrip("=")
+    challenge_header = f'Bearer error="insufficient_claims", 
claims="{encoded_claims}"'
+
+    # Create the mock HTTP response with stream reading capability
+    http_response_mock = Mock()
+    http_response_mock.status_code = 401
+    http_response_mock.headers = {"WWW-Authenticate": challenge_header}
+    http_response_mock.read = AsyncMock(return_value=b"Error details from 
server")
+
+    # Mock transport that returns the HTTP response directly (it will be 
wrapped by Pipeline)
+    async def mock_transport_send(request, **kwargs):
+        return http_response_mock
+
+    transport = Mock(send=mock_transport_send)
+
+    # Create pipeline with stream option
+    pipeline = AsyncPipeline(transport=transport, policies=[policy])
+
+    # Execute the request and verify exception handling
+    with pytest.raises(ClientAuthenticationError) as exc_info:
+        await pipeline.run(http_request("GET", "https://example.com";), 
stream=True)
+
+    # Verify that the response.read() was called to consume the stream
+    http_response_mock.read.assert_called_once()
+
+    # Verify the exception chaining
+    assert exc_info.value.__cause__ is not None
+    assert isinstance(exc_info.value.__cause__, HttpResponseError)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure_core-1.35.0/tests/async_tests/test_retry_policy_async.py 
new/azure_core-1.35.1/tests/async_tests/test_retry_policy_async.py
--- old/azure_core-1.35.0/tests/async_tests/test_retry_policy_async.py  
2025-07-03 01:50:16.000000000 +0200
+++ new/azure_core-1.35.1/tests/async_tests/test_retry_policy_async.py  
2025-09-11 23:05:23.000000000 +0200
@@ -314,3 +314,99 @@
         await pipeline.run(http_request("GET", "http://localhost/";))
 
     assert transport.sleep.call_count == 1
+
+
+def test_configure_retries_uses_constructor_values():
+    """Test that configure_retries method correctly gets values from 
constructor."""
+    # Test with custom constructor values
+    retry_policy = AsyncRetryPolicy(
+        retry_total=5,
+        retry_connect=2,
+        retry_read=4,
+        retry_status=1,
+        retry_backoff_factor=0.5,
+        retry_backoff_max=60,
+        timeout=300,
+    )
+
+    # Call configure_retries with empty options to ensure it uses constructor 
values
+    retry_settings = retry_policy.configure_retries({})
+
+    # Verify that configure_retries returns constructor values as defaults
+    assert retry_settings["total"] == 5
+    assert retry_settings["connect"] == 2
+    assert retry_settings["read"] == 4
+    assert retry_settings["status"] == 1
+    assert retry_settings["backoff"] == 0.5
+    assert retry_settings["max_backoff"] == 60
+    assert retry_settings["timeout"] == 300
+    assert retry_settings["methods"] == frozenset(["HEAD", "GET", "PUT", 
"DELETE", "OPTIONS", "TRACE"])
+    assert retry_settings["history"] == []
+
+
+def test_configure_retries_options_override_constructor():
+    """Test that options passed to configure_retries override constructor 
values."""
+    # Test with custom constructor values
+    retry_policy = AsyncRetryPolicy(
+        retry_total=5,
+        retry_connect=2,
+        retry_read=4,
+        retry_status=1,
+        retry_backoff_factor=0.5,
+        retry_backoff_max=60,
+        timeout=300,
+    )
+
+    # Call configure_retries with options that should override constructor 
values
+    options = {
+        "retry_total": 8,
+        "retry_connect": 6,
+        "retry_read": 7,
+        "retry_status": 3,
+        "retry_backoff_factor": 1.0,
+        "retry_backoff_max": 180,
+        "timeout": 600,
+        "retry_on_methods": frozenset(["GET", "POST"]),
+    }
+    retry_settings = retry_policy.configure_retries(options)
+
+    # Verify that configure_retries returns option values, not constructor 
values
+    assert retry_settings["total"] == 8
+    assert retry_settings["connect"] == 6
+    assert retry_settings["read"] == 7
+    assert retry_settings["status"] == 3
+    assert retry_settings["backoff"] == 1.0
+    assert retry_settings["max_backoff"] == 180
+    assert retry_settings["timeout"] == 600
+    assert retry_settings["methods"] == frozenset(["GET", "POST"])
+    assert retry_settings["history"] == []
+
+    # Verify options dict was modified (values were popped)
+    assert "retry_total" not in options
+    assert "retry_connect" not in options
+    assert "retry_read" not in options
+    assert "retry_status" not in options
+    assert "retry_backoff_factor" not in options
+    assert "retry_backoff_max" not in options
+    assert "timeout" not in options
+    assert "retry_on_methods" not in options
+
+
+def test_configure_retries_default_values():
+    """Test that configure_retries uses default values when no constructor 
args or options provided."""
+    # Test with default constructor
+    retry_policy = AsyncRetryPolicy()
+
+    # Call configure_retries with empty options
+    retry_settings = retry_policy.configure_retries({})
+
+    # Verify default values from RetryPolicyBase.__init__
+    assert retry_settings["total"] == 10  # default retry_total
+    assert retry_settings["connect"] == 3  # default retry_connect
+    assert retry_settings["read"] == 3  # default retry_read
+    assert retry_settings["status"] == 3  # default retry_status
+    assert retry_settings["backoff"] == 0.8  # default retry_backoff_factor
+    assert retry_settings["max_backoff"] == 120  # default retry_backoff_max 
(BACKOFF_MAX)
+    assert retry_settings["timeout"] == 604800  # default timeout
+    assert retry_settings["methods"] == frozenset(["HEAD", "GET", "PUT", 
"DELETE", "OPTIONS", "TRACE"])
+    assert retry_settings["history"] == []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_core-1.35.0/tests/test_authentication.py 
new/azure_core-1.35.1/tests/test_authentication.py
--- old/azure_core-1.35.0/tests/test_authentication.py  2025-07-03 
01:50:16.000000000 +0200
+++ new/azure_core-1.35.1/tests/test_authentication.py  2025-09-11 
23:05:23.000000000 +0200
@@ -16,7 +16,7 @@
     AzureNamedKeyCredential,
     AccessTokenInfo,
 )
-from azure.core.exceptions import ServiceRequestError
+from azure.core.exceptions import ServiceRequestError, HttpResponseError, 
ClientAuthenticationError
 from azure.core.pipeline import Pipeline, PipelineRequest, PipelineContext, 
PipelineResponse
 from azure.core.pipeline.transport import HttpTransport, HttpRequest
 from azure.core.pipeline.policies import (
@@ -837,3 +837,93 @@
 
     # Verify the Authorization header was set correctly
     assert request.http_request.headers["Authorization"] == "Bearer 
claims_token"
+
+
[email protected]("http_request", HTTP_REQUESTS)
+def test_bearer_policy_on_challenge_exception_chaining(http_request):
+    """Test that exceptions during on_challenge are chained with 
HttpResponseError"""
+
+    # Mock credential that raises an exception during get_token_info with 
claims
+    def mock_get_token_info(*scopes, options=None):
+        if options and "claims" in options:
+            raise ClientAuthenticationError("Failed to request token info with 
claims")
+        return AccessTokenInfo("initial_token", int(time.time()) + 3600)
+
+    fake_credential = Mock(
+        spec_set=["get_token", "get_token_info"],
+        get_token=Mock(return_value=AccessToken("fallback", int(time.time()) + 
3600)),
+        get_token_info=mock_get_token_info,
+    )
+    policy = BearerTokenCredentialPolicy(fake_credential, "scope")
+
+    # Create a 401 response with insufficient_claims challenge
+    test_claims = '{"access_token":{"foo":"bar"}}'
+    encoded_claims = 
base64.urlsafe_b64encode(test_claims.encode()).decode().rstrip("=")
+    challenge_header = f'Bearer error="insufficient_claims", 
claims="{encoded_claims}"'
+
+    response_mock = Mock(status_code=401, headers={"WWW-Authenticate": 
challenge_header})
+
+    # Mock transport that returns the 401 response
+    def mock_transport_send(request):
+        return response_mock
+
+    transport = Mock(send=mock_transport_send)
+    pipeline = Pipeline(transport=transport, policies=[policy])
+
+    # Execute the request and verify exception chaining
+    with pytest.raises(ClientAuthenticationError) as exc_info:
+        pipeline.run(http_request("GET", "https://example.com";))
+
+    # Verify the original exception is preserved
+    original_exception = exc_info.value
+    assert original_exception.message == "Failed to request token info with 
claims"
+
+    # Verify the exception is chained with HttpResponseError
+    assert original_exception.__cause__ is not None
+    assert isinstance(original_exception.__cause__, HttpResponseError)
+
+    # Verify the HttpResponseError contains the original 401 response
+    http_response_error = original_exception.__cause__
+    assert http_response_error.response is response_mock
+
+
[email protected]("http_request", HTTP_REQUESTS)
+def 
test_bearer_policy_reads_streamed_response_on_challenge_exception(http_request):
+    """Test that the policy reads streamed response body when on_challenge 
raises exception"""
+
+    # Create a credential that will raise an exception when get_token is 
called with claims
+    def failing_get_token(*scopes, **kwargs):
+        if "claims" in kwargs:
+            raise ClientAuthenticationError("Failed to get token with claims")
+        return AccessToken("initial_token", int(time.time()) + 3600)
+
+    credential = Mock(spec_set=["get_token"], get_token=failing_get_token)
+    policy = BearerTokenCredentialPolicy(credential, "scope")
+
+    # Create a 401 response with insufficient_claims challenge that will 
trigger the exception
+    test_claims = '{"access_token":{"foo":"bar"}}'
+    encoded_claims = 
base64.urlsafe_b64encode(test_claims.encode()).decode().rstrip("=")
+    challenge_header = f'Bearer error="insufficient_claims", 
claims="{encoded_claims}"'
+
+    # Create the mock HTTP response with stream reading capability
+    http_response_mock = Mock()
+    http_response_mock.status_code = 401
+    http_response_mock.headers = {"WWW-Authenticate": challenge_header}
+    http_response_mock.read = Mock(return_value=b"Error details from server")
+
+    # Mock transport that returns the HTTP response directly (it will be 
wrapped by Pipeline)
+    transport = Mock(send=Mock(return_value=http_response_mock))
+
+    # Create pipeline with stream option
+    pipeline = Pipeline(transport=transport, policies=[policy])
+
+    # Execute the request and verify exception handling
+    with pytest.raises(ClientAuthenticationError) as exc_info:
+        pipeline.run(http_request("GET", "https://example.com";), stream=True)
+
+    # Verify that the response.read() was called to consume the stream
+    http_response_mock.read.assert_called_once()
+
+    # Verify the exception chaining
+    assert exc_info.value.__cause__ is not None
+    assert isinstance(exc_info.value.__cause__, HttpResponseError)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure_core-1.35.0/tests/test_retry_policy.py 
new/azure_core-1.35.1/tests/test_retry_policy.py
--- old/azure_core-1.35.0/tests/test_retry_policy.py    2025-07-03 
01:50:16.000000000 +0200
+++ new/azure_core-1.35.1/tests/test_retry_policy.py    2025-09-11 
23:05:23.000000000 +0200
@@ -314,3 +314,99 @@
         pipeline.run(http_request("GET", "http://localhost/";))
 
     assert transport.sleep.call_count == 1
+
+
+def test_configure_retries_uses_constructor_values():
+    """Test that configure_retries method correctly gets values from 
constructor."""
+    # Test with custom constructor values
+    retry_policy = RetryPolicy(
+        retry_total=5,
+        retry_connect=2,
+        retry_read=4,
+        retry_status=1,
+        retry_backoff_factor=0.5,
+        retry_backoff_max=60,
+        timeout=300,
+    )
+
+    # Call configure_retries with empty options to ensure it uses constructor 
values
+    retry_settings = retry_policy.configure_retries({})
+
+    # Verify that configure_retries returns constructor values as defaults
+    assert retry_settings["total"] == 5
+    assert retry_settings["connect"] == 2
+    assert retry_settings["read"] == 4
+    assert retry_settings["status"] == 1
+    assert retry_settings["backoff"] == 0.5
+    assert retry_settings["max_backoff"] == 60
+    assert retry_settings["timeout"] == 300
+    assert retry_settings["methods"] == frozenset(["HEAD", "GET", "PUT", 
"DELETE", "OPTIONS", "TRACE"])
+    assert retry_settings["history"] == []
+
+
+def test_configure_retries_options_override_constructor():
+    """Test that options passed to configure_retries override constructor 
values."""
+    # Test with custom constructor values
+    retry_policy = RetryPolicy(
+        retry_total=5,
+        retry_connect=2,
+        retry_read=4,
+        retry_status=1,
+        retry_backoff_factor=0.5,
+        retry_backoff_max=60,
+        timeout=300,
+    )
+
+    # Call configure_retries with options that should override constructor 
values
+    options = {
+        "retry_total": 8,
+        "retry_connect": 6,
+        "retry_read": 7,
+        "retry_status": 3,
+        "retry_backoff_factor": 1.0,
+        "retry_backoff_max": 180,
+        "timeout": 600,
+        "retry_on_methods": frozenset(["GET", "POST"]),
+    }
+    retry_settings = retry_policy.configure_retries(options)
+
+    # Verify that configure_retries returns option values, not constructor 
values
+    assert retry_settings["total"] == 8
+    assert retry_settings["connect"] == 6
+    assert retry_settings["read"] == 7
+    assert retry_settings["status"] == 3
+    assert retry_settings["backoff"] == 1.0
+    assert retry_settings["max_backoff"] == 180
+    assert retry_settings["timeout"] == 600
+    assert retry_settings["methods"] == frozenset(["GET", "POST"])
+    assert retry_settings["history"] == []
+
+    # Verify options dict was modified (values were popped)
+    assert "retry_total" not in options
+    assert "retry_connect" not in options
+    assert "retry_read" not in options
+    assert "retry_status" not in options
+    assert "retry_backoff_factor" not in options
+    assert "retry_backoff_max" not in options
+    assert "timeout" not in options
+    assert "retry_on_methods" not in options
+
+
+def test_configure_retries_default_values():
+    """Test that configure_retries uses default values when no constructor 
args or options provided."""
+    # Test with default constructor
+    retry_policy = RetryPolicy()
+
+    # Call configure_retries with empty options
+    retry_settings = retry_policy.configure_retries({})
+
+    # Verify default values from RetryPolicyBase.__init__
+    assert retry_settings["total"] == 10  # default retry_total
+    assert retry_settings["connect"] == 3  # default retry_connect
+    assert retry_settings["read"] == 3  # default retry_read
+    assert retry_settings["status"] == 3  # default retry_status
+    assert retry_settings["backoff"] == 0.8  # default retry_backoff_factor
+    assert retry_settings["max_backoff"] == 120  # default retry_backoff_max 
(BACKOFF_MAX)
+    assert retry_settings["timeout"] == 604800  # default timeout
+    assert retry_settings["methods"] == frozenset(["HEAD", "GET", "PUT", 
"DELETE", "OPTIONS", "TRACE"])
+    assert retry_settings["history"] == []

Reply via email to