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 2023-09-15 22:05:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-azure-core (Old)
 and      /work/SRC/openSUSE:Factory/.python-azure-core.new.1766 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-azure-core"

Fri Sep 15 22:05:52 2023 rev:43 rq:1111566 version:1.29.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-azure-core/python-azure-core.changes      
2023-08-23 15:00:00.946247749 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-azure-core.new.1766/python-azure-core.changes
    2023-09-15 22:11:26.049918928 +0200
@@ -1,0 +2,8 @@
+Fri Sep 15 09:41:14 UTC 2023 - John Paul Adrian Glaubitz 
<adrian.glaub...@suse.com>
+
+- New upstream release
+  + Version 1.29.4
+  + For detailed information about changes see the
+    CHANGELOG.md file provided with this package
+
+-------------------------------------------------------------------

Old:
----
  azure-core-1.29.3.tar.gz

New:
----
  azure-core-1.29.4.tar.gz

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

Other differences:
------------------
++++++ python-azure-core.spec ++++++
--- /var/tmp/diff_new_pack.SquIEr/_old  2023-09-15 22:11:27.201960119 +0200
+++ /var/tmp/diff_new_pack.SquIEr/_new  2023-09-15 22:11:27.205960262 +0200
@@ -21,7 +21,7 @@
 %define skip_python2 1
 %endif
 Name:           python-azure-core
-Version:        1.29.3
+Version:        1.29.4
 Release:        0
 Summary:        Microsoft Azure Core Library for Python
 License:        MIT

++++++ azure-core-1.29.3.tar.gz -> azure-core-1.29.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-core-1.29.3/CHANGELOG.md 
new/azure-core-1.29.4/CHANGELOG.md
--- old/azure-core-1.29.3/CHANGELOG.md  2023-08-22 21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/CHANGELOG.md  2023-09-07 19:37:17.000000000 +0200
@@ -1,5 +1,15 @@
 # Release History
 
+## 1.29.4 (2023-09-07)
+
+### Bugs Fixed
+
+- Fixed the issue that some urls trigger an infinite loop. #31346
+- Fixed issue where IndexError was raised if multipart responses did not match 
the number of requests. #31471
+- Fixed issue unbound variable exception if dict is invalid in 
CloudEvent.from_dict. #31835
+- Fixed issue asyncBearerTokenCredentialPolicy is not backward compatible with 
SansIOHTTPPolicy. #31836
+- Fixed issue mypy complains with new version of azure-core. #31564
+
 ## 1.29.3 (2023-08-22)
 
 ### Bugs Fixed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-core-1.29.3/PKG-INFO 
new/azure-core-1.29.4/PKG-INFO
--- old/azure-core-1.29.3/PKG-INFO      2023-08-22 21:16:02.061326500 +0200
+++ new/azure-core-1.29.4/PKG-INFO      2023-09-07 19:38:17.038747800 +0200
@@ -1,11 +1,12 @@
 Metadata-Version: 2.1
 Name: azure-core
-Version: 1.29.3
+Version: 1.29.4
 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
 Author-email: azpysdkh...@microsoft.com
 License: MIT License
+Keywords: azure,azure sdk
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 3 :: Only
@@ -18,8 +19,12 @@
 Classifier: License :: OSI Approved :: MIT License
 Requires-Python: >=3.7
 Description-Content-Type: text/markdown
-Provides-Extra: aio
 License-File: LICENSE
+Requires-Dist: requests>=2.18.4
+Requires-Dist: six>=1.11.0
+Requires-Dist: typing-extensions>=4.6.0
+Provides-Extra: aio
+Requires-Dist: aiohttp>=3.0; extra == "aio"
 
 
 # Azure Core shared client library for Python
@@ -282,6 +287,16 @@
 
 # Release History
 
+## 1.29.4 (2023-09-07)
+
+### Bugs Fixed
+
+- Fixed the issue that some urls trigger an infinite loop. #31346
+- Fixed issue where IndexError was raised if multipart responses did not match 
the number of requests. #31471
+- Fixed issue unbound variable exception if dict is invalid in 
CloudEvent.from_dict. #31835
+- Fixed issue asyncBearerTokenCredentialPolicy is not backward compatible with 
SansIOHTTPPolicy. #31836
+- Fixed issue mypy complains with new version of azure-core. #31564
+
 ## 1.29.3 (2023-08-22)
 
 ### Bugs Fixed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-core-1.29.3/azure/core/_pipeline_client.py 
new/azure-core-1.29.4/azure/core/_pipeline_client.py
--- old/azure-core-1.29.3/azure/core/_pipeline_client.py        2023-08-22 
21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/azure/core/_pipeline_client.py        2023-09-07 
19:37:17.000000000 +0200
@@ -172,7 +172,8 @@
                 policies = policies_1
 
         if transport is None:
-            from .pipeline.transport import RequestsTransport  # pylint: 
disable=no-name-in-module
+            # Use private import for better typing, mypy and pyright don't 
like PEP562
+            from .pipeline.transport._requests_basic import RequestsTransport
 
             transport = RequestsTransport(**kwargs)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-core-1.29.3/azure/core/_pipeline_client_async.py 
new/azure-core-1.29.4/azure/core/_pipeline_client_async.py
--- old/azure-core-1.29.3/azure/core/_pipeline_client_async.py  2023-08-22 
21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/azure/core/_pipeline_client_async.py  2023-09-07 
19:37:17.000000000 +0200
@@ -254,7 +254,8 @@
                 policies = policies_1
 
         if not transport:
-            from .pipeline.transport import AioHttpTransport  # pylint: 
disable=no-name-in-module
+            # Use private import for better typing, mypy and pyright don't 
like PEP562
+            from .pipeline.transport._aiohttp import AioHttpTransport
 
             transport = AioHttpTransport(**kwargs)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-core-1.29.3/azure/core/_version.py 
new/azure-core-1.29.4/azure/core/_version.py
--- old/azure-core-1.29.3/azure/core/_version.py        2023-08-22 
21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/azure/core/_version.py        2023-09-07 
19:37:17.000000000 +0200
@@ -9,4 +9,4 @@
 # regenerated.
 # --------------------------------------------------------------------------
 
-VERSION = "1.29.3"
+VERSION = "1.29.4"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-core-1.29.3/azure/core/credentials_async.py 
new/azure-core-1.29.4/azure/core/credentials_async.py
--- old/azure-core-1.29.3/azure/core/credentials_async.py       2023-08-22 
21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/azure/core/credentials_async.py       2023-09-07 
19:37:17.000000000 +0200
@@ -29,6 +29,7 @@
         :rtype: AccessToken
         :return: An AccessToken instance containing the token string and its 
expiration time in Unix time.
         """
+        ...
 
     async def close(self) -> None:
         pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-core-1.29.3/azure/core/exceptions.py 
new/azure-core-1.29.4/azure/core/exceptions.py
--- old/azure-core-1.29.3/azure/core/exceptions.py      2023-08-22 
21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/azure/core/exceptions.py      2023-09-07 
19:37:17.000000000 +0200
@@ -40,6 +40,7 @@
     TypeVar,
     Generic,
     Dict,
+    NoReturn,
     TYPE_CHECKING,
 )
 from typing_extensions import Protocol, runtime_checkable
@@ -79,7 +80,7 @@
 ]
 
 
-def raise_with_traceback(exception: Callable, *args: Any, **kwargs: Any) -> 
None:
+def raise_with_traceback(exception: Callable, *args: Any, **kwargs: Any) -> 
NoReturn:
     """Raise exception with a specified traceback.
     This MUST be called inside a "except" clause.
 
@@ -113,18 +114,18 @@
 
     @property
     def reason(self) -> Optional[str]:
-        pass
+        ...
 
     @property
     def status_code(self) -> Optional[int]:
-        pass
+        ...
 
     def text(self) -> str:
-        pass
+        ...
 
     @property
     def request(self) -> object:  # object as type, since all we need is str() 
on it
-        pass
+        ...
 
 
 class ErrorMap(Generic[KeyType, ValueType]):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-core-1.29.3/azure/core/messaging.py 
new/azure-core-1.29.4/azure/core/messaging.py
--- old/azure-core-1.29.3/azure/core/messaging.py       2023-08-22 
21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/azure/core/messaging.py       2023-09-07 
19:37:17.000000000 +0200
@@ -192,26 +192,26 @@
         except KeyError as err:
             # https://github.com/cloudevents/spec Cloud event spec requires 
source, type,
             # specversion. We autopopulate everything other than source, type.
-            if not all(_ in event for _ in ("source", "type")):
-                if all(
-                    _ in event
-                    for _ in (
-                        "subject",
-                        "eventType",
-                        "data",
-                        "dataVersion",
-                        "id",
-                        "eventTime",
-                    )
-                ):
-                    raise ValueError(
-                        "The event you are trying to parse follows the 
Eventgrid Schema. You can parse"
-                        + " EventGrid events using EventGridEvent.from_dict 
method in the azure-eventgrid library."
-                    ) from err
+            # So we will assume the KeyError is coming from source/type access.
+            if all(
+                key in event
+                for key in (
+                    "subject",
+                    "eventType",
+                    "data",
+                    "dataVersion",
+                    "id",
+                    "eventTime",
+                )
+            ):
                 raise ValueError(
-                    "The event does not conform to the cloud event spec 
https://github.com/cloudevents/spec.";
-                    + " The `source` and `type` params are required."
+                    "The event you are trying to parse follows the Eventgrid 
Schema. You can parse"
+                    + " EventGrid events using EventGridEvent.from_dict method 
in the azure-eventgrid library."
                 ) from err
+            raise ValueError(
+                "The event does not conform to the cloud event spec 
https://github.com/cloudevents/spec.";
+                + " The `source` and `type` params are required."
+            ) from err
         return event_obj
 
     @classmethod
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-core-1.29.3/azure/core/pipeline/_tools.py 
new/azure-core-1.29.4/azure/core/pipeline/_tools.py
--- old/azure-core-1.29.3/azure/core/pipeline/_tools.py 2023-08-22 
21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/azure/core/pipeline/_tools.py 2023-09-07 
19:37:17.000000000 +0200
@@ -23,14 +23,19 @@
 # IN THE SOFTWARE.
 #
 # --------------------------------------------------------------------------
-from typing import TYPE_CHECKING
+from __future__ import annotations
+from typing import TYPE_CHECKING, Union, Callable, TypeVar
+from typing_extensions import TypeGuard, ParamSpec
 
 if TYPE_CHECKING:
-    from typing import Any
-    from azure.core.rest import HttpResponse as RestHttpResponse
+    from azure.core.rest import HttpResponse, HttpRequest, AsyncHttpResponse
 
 
-def await_result(func, *args, **kwargs):
+P = ParamSpec("P")
+T = TypeVar("T")
+
+
+def await_result(func: Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> T:
     """If func returns an awaitable, raise that this runner can't handle it.
 
     :param func: The function to run.
@@ -47,7 +52,7 @@
     return result
 
 
-def is_rest(obj) -> bool:
+def is_rest(obj: object) -> TypeGuard[Union[HttpRequest, HttpResponse, 
AsyncHttpResponse]]:
     """Return whether a request or a response is a rest request / response.
 
     Checking whether the response has the object content can sometimes result
@@ -63,7 +68,7 @@
     return hasattr(obj, "is_stream_consumed") or hasattr(obj, "content")
 
 
-def handle_non_stream_rest_response(response: "RestHttpResponse") -> None:
+def handle_non_stream_rest_response(response: HttpResponse) -> None:
     """Handle reading and closing of non stream rest responses.
     For our new rest responses, we have to call .read() and .close() for our 
non-stream
     responses. This way, we load in the body for users to access.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-core-1.29.3/azure/core/pipeline/_tools_async.py 
new/azure-core-1.29.4/azure/core/pipeline/_tools_async.py
--- old/azure-core-1.29.3/azure/core/pipeline/_tools_async.py   2023-08-22 
21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/azure/core/pipeline/_tools_async.py   2023-09-07 
19:37:17.000000000 +0200
@@ -23,13 +23,27 @@
 # IN THE SOFTWARE.
 #
 # --------------------------------------------------------------------------
-from typing import TYPE_CHECKING
+from typing import TYPE_CHECKING, Callable, TypeVar, Awaitable, Union, overload
+from typing_extensions import ParamSpec
 
 if TYPE_CHECKING:
     from ..rest import AsyncHttpResponse as RestAsyncHttpResponse
 
+P = ParamSpec("P")
+T = TypeVar("T")
 
-async def await_result(func, *args, **kwargs):
+
+@overload
+async def await_result(func: Callable[P, Awaitable[T]], *args: P.args, 
**kwargs: P.kwargs) -> T:
+    ...
+
+
+@overload
+async def await_result(func: Callable[P, T], *args: P.args, **kwargs: 
P.kwargs) -> T:
+    ...
+
+
+async def await_result(func: Callable[P, Union[T, Awaitable[T]]], *args: 
P.args, **kwargs: P.kwargs) -> T:
     """If func returns an awaitable, await it.
 
     :param func: The function to run.
@@ -40,9 +54,8 @@
     :return: The result of the function
     """
     result = func(*args, **kwargs)
-    if hasattr(result, "__await__"):
-        # type ignore on await: https://github.com/python/mypy/issues/7587
-        return await result  # type: ignore
+    if isinstance(result, Awaitable):
+        return await result
     return result
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-core-1.29.3/azure/core/pipeline/policies/_authentication_async.py 
new/azure-core-1.29.4/azure/core/pipeline/policies/_authentication_async.py
--- old/azure-core-1.29.3/azure/core/pipeline/policies/_authentication_async.py 
2023-08-22 21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/azure/core/pipeline/policies/_authentication_async.py 
2023-09-07 19:37:17.000000000 +0200
@@ -92,28 +92,28 @@
         await await_result(self.on_request, request)
         try:
             response = await self.next.send(request)
-            await await_result(self.on_response, request, response)
         except Exception:  # pylint:disable=broad-except
-            handled = await await_result(self.on_exception, request)
-            if not handled:
-                raise
+            await await_result(self.on_exception, request)
+            raise
         else:
-            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)
-                    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
-                        # token from the request so clear the 
'insecure_domain_change' tag
-                        request.context.options.pop("insecure_domain_change", 
False)
-                        try:
-                            response = await self.next.send(request)
-                            await await_result(self.on_response, request, 
response)
-                        except Exception:  # pylint:disable=broad-except
-                            handled = await await_result(self.on_exception, 
request)
-                            if not handled:
-                                raise
+            await await_result(self.on_response, request, response)
+
+        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)
+                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
+                    # token from the request so clear the 
'insecure_domain_change' tag
+                    request.context.options.pop("insecure_domain_change", 
False)
+                    try:
+                        response = await self.next.send(request)
+                    except Exception:  # pylint:disable=broad-except
+                        await await_result(self.on_exception, request)
+                        raise
+                    else:
+                        await await_result(self.on_response, request, response)
 
         return response
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-core-1.29.3/azure/core/pipeline/policies/_distributed_tracing.py 
new/azure-core-1.29.4/azure/core/pipeline/policies/_distributed_tracing.py
--- old/azure-core-1.29.3/azure/core/pipeline/policies/_distributed_tracing.py  
2023-08-22 21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/azure/core/pipeline/policies/_distributed_tracing.py  
2023-09-07 19:37:17.000000000 +0200
@@ -26,7 +26,7 @@
 """Traces network calls using the implementation library from the settings."""
 import logging
 import sys
-import urllib
+import urllib.parse
 from typing import TYPE_CHECKING, Optional, Tuple, TypeVar, Union, Any, Type
 from types import TracebackType
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-core-1.29.3/azure/core/pipeline/transport/_aiohttp.py 
new/azure-core-1.29.4/azure/core/pipeline/transport/_aiohttp.py
--- old/azure-core-1.29.3/azure/core/pipeline/transport/_aiohttp.py     
2023-08-22 21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/azure/core/pipeline/transport/_aiohttp.py     
2023-09-07 19:37:17.000000000 +0200
@@ -23,6 +23,7 @@
 # IN THE SOFTWARE.
 #
 # --------------------------------------------------------------------------
+from __future__ import annotations
 import sys
 from typing import Any, Optional, AsyncIterator as AsyncIteratorType, 
TYPE_CHECKING, overload, cast, Union, Type
 from types import TracebackType
@@ -56,6 +57,7 @@
         HttpRequest as RestHttpRequest,
         AsyncHttpResponse as RestAsyncHttpResponse,
     )
+    from ...rest._aiohttp import RestAioHttpTransportResponse
 
 # Matching requests, because why not?
 CONTENT_CHUNK_SIZE = 10 * 1024
@@ -91,6 +93,8 @@
         self._loop = loop
         self._session_owner = session_owner
         self.session = session
+        if not self._session_owner and not self.session:
+            raise ValueError("session_owner cannot be False if no session is 
provided")
         self.connection_config = ConnectionConfiguration(**kwargs)
         self._use_env_settings = kwargs.pop("use_env_settings", True)
 
@@ -118,8 +122,9 @@
             if self._loop is not None:
                 clientsession_kwargs["loop"] = self._loop
             self.session = aiohttp.ClientSession(**clientsession_kwargs)
-        if self.session is not None:
-            await self.session.__aenter__()
+        # pyright has trouble to understand that self.session is not None, 
since we raised at worst in the init
+        self.session = cast(aiohttp.ClientSession, self.session)
+        await self.session.__aenter__()
 
     async def close(self):
         """Closes the connection."""
@@ -188,7 +193,7 @@
         """
 
     @overload
-    async def send(self, request: "RestHttpRequest", **config: Any) -> 
"RestAsyncHttpResponse":
+    async def send(self, request: RestHttpRequest, **config: Any) -> 
RestAsyncHttpResponse:
         """Send the `azure.core.rest` request using this HTTP sender.
 
         Will pre-load the body into memory to be available with a sync method.
@@ -206,8 +211,8 @@
         """
 
     async def send(
-        self, request: Union[HttpRequest, "RestHttpRequest"], **config
-    ) -> Union[AsyncHttpResponse, "RestAsyncHttpResponse"]:
+        self, request: Union[HttpRequest, RestHttpRequest], **config
+    ) -> Union[AsyncHttpResponse, RestAsyncHttpResponse]:
         """Send the request using this HTTP sender.
 
         Will pre-load the body into memory to be available with a sync method.
@@ -240,7 +245,7 @@
                     config["proxy"] = proxies[protocol]
                     break
 
-        response: Optional[Union[AsyncHttpResponse, "RestAsyncHttpResponse"]] 
= None
+        response: Optional[Union[AsyncHttpResponse, RestAsyncHttpResponse]] = 
None
         config["ssl"] = self._build_ssl_config(
             cert=config.pop("connection_cert", self.connection_config.cert),
             verify=config.pop("connection_verify", 
self.connection_config.verify),
@@ -262,7 +267,7 @@
                 data=self._get_request_data(request),
                 timeout=socket_timeout,
                 allow_redirects=False,
-                **config
+                **config,
             )
             if _is_rest(request):
                 from azure.core.rest._aiohttp import 
RestAioHttpTransportResponse
@@ -307,7 +312,33 @@
         on the *content-encoding* header.
     """
 
-    def __init__(self, pipeline: AsyncPipeline, response: AsyncHttpResponse, 
*, decompress: bool = True) -> None:
+    @overload
+    def __init__(
+        self,
+        pipeline: AsyncPipeline[HttpRequest, AsyncHttpResponse],
+        response: AioHttpTransportResponse,
+        *,
+        decompress: bool = True,
+    ) -> None:
+        ...
+
+    @overload
+    def __init__(
+        self,
+        pipeline: AsyncPipeline[RestHttpRequest, RestAsyncHttpResponse],
+        response: RestAioHttpTransportResponse,
+        *,
+        decompress: bool = True,
+    ) -> None:
+        ...
+
+    def __init__(
+        self,
+        pipeline: AsyncPipeline,
+        response: Union[AioHttpTransportResponse, 
RestAioHttpTransportResponse],
+        *,
+        decompress: bool = True,
+    ) -> None:
         self.pipeline = pipeline
         self.request = response.request
         self.response = response
@@ -380,7 +411,7 @@
         aiohttp_response: aiohttp.ClientResponse,
         block_size: Optional[int] = None,
         *,
-        decompress: bool = True
+        decompress: bool = True,
     ) -> None:
         super(AioHttpTransportResponse, self).__init__(request, 
aiohttp_response, block_size=block_size)
         # 
https://aiohttp.readthedocs.io/en/stable/client_reference.html#aiohttp.ClientResponse
@@ -462,7 +493,9 @@
         except aiohttp.client_exceptions.ClientError as err:
             raise ServiceRequestError(err, error=err) from err
 
-    def stream_download(self, pipeline, **kwargs) -> AsyncIteratorType[bytes]:
+    def stream_download(
+        self, pipeline: AsyncPipeline[HttpRequest, AsyncHttpResponse], **kwargs
+    ) -> AsyncIteratorType[bytes]:
         """Generator for streaming response body data.
 
         :param pipeline: The pipeline object
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-core-1.29.3/azure/core/pipeline/transport/_base.py 
new/azure-core-1.29.4/azure/core/pipeline/transport/_base.py
--- old/azure-core-1.29.3/azure/core/pipeline/transport/_base.py        
2023-08-22 21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/azure/core/pipeline/transport/_base.py        
2023-09-07 19:37:17.000000000 +0200
@@ -23,6 +23,7 @@
 # IN THE SOFTWARE.
 #
 # --------------------------------------------------------------------------
+from __future__ import annotations
 import abc
 from email.message import Message
 import json
@@ -48,6 +49,7 @@
     Sequence,
     MutableMapping,
     ContextManager,
+    TYPE_CHECKING,
 )
 
 from http.client import HTTPResponse as _HTTPResponse
@@ -68,9 +70,12 @@
 
 HTTPResponseType = TypeVar("HTTPResponseType")
 HTTPRequestType = TypeVar("HTTPRequestType")
-PipelineType = TypeVar("PipelineType")
 DataType = Union[bytes, str, Dict[str, Union[str, int]]]
 
+if TYPE_CHECKING:
+    # We need a transport to define a pipeline, this "if" avoid a circular 
import
+    from azure.core.pipeline import Pipeline
+
 _LOGGER = logging.getLogger(__name__)
 
 binary_type = str
@@ -89,6 +94,7 @@
     :rtype: str
     :returns: Template completed
     """
+    last_template = template
     components = template.split("/")
     while components:
         try:
@@ -97,7 +103,11 @@
             formatted_components = template.split("/")
             components = [c for c in formatted_components if 
"{{{}}}".format(key.args[0]) not in c]
             template = "/".join(components)
-    # No URL sections left - returning None
+            if last_template == template:
+                raise ValueError(
+                    f"The value provided for the url part '{template}' was 
incorrect, and resulted in an invalid url"
+                ) from key
+            last_template = template
 
 
 def _urljoin(base_url: str, stub_url: str) -> str:
@@ -488,7 +498,7 @@
 
 
 class HttpResponse(_HttpResponseBase):  # pylint: disable=abstract-method
-    def stream_download(self, pipeline: PipelineType, **kwargs: Any) -> 
Iterator[bytes]:
+    def stream_download(self, pipeline: Pipeline[HttpRequest, "HttpResponse"], 
**kwargs: Any) -> Iterator[bytes]:
         """Generator for streaming request body data.
 
         Should be implemented by sub-classes if streaming download
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-core-1.29.3/azure/core/pipeline/transport/_base_async.py 
new/azure-core-1.29.4/azure/core/pipeline/transport/_base_async.py
--- old/azure-core-1.29.3/azure/core/pipeline/transport/_base_async.py  
2023-08-22 21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/azure/core/pipeline/transport/_base_async.py  
2023-09-07 19:37:17.000000000 +0200
@@ -32,23 +32,25 @@
     TypeVar,
     Generic,
     Any,
-    TYPE_CHECKING,
     AsyncContextManager,
     Optional,
     Type,
+    TYPE_CHECKING,
 )
 from types import TracebackType
 
 from ._base import _HttpResponseBase, _HttpClientTransportResponse, HttpRequest
 from ...utils._pipeline_transport_rest_shared_async import _PartGenerator
 
-if TYPE_CHECKING:
-    from ..._pipeline_client_async import AsyncPipelineClient
 
 AsyncHTTPResponseType = TypeVar("AsyncHTTPResponseType")
 HTTPResponseType = TypeVar("HTTPResponseType")
 HTTPRequestType = TypeVar("HTTPRequestType")
 
+if TYPE_CHECKING:
+    # We need a transport to define a pipeline, this "if" avoid a circular 
import
+    from .._base_async import AsyncPipeline
+
 
 class _ResponseStopIteration(Exception):
     pass
@@ -76,7 +78,7 @@
     """
 
     def stream_download(
-        self, pipeline: AsyncPipelineClient[HttpRequest, "AsyncHttpResponse"], 
**kwargs: Any
+        self, pipeline: AsyncPipeline[HttpRequest, "AsyncHttpResponse"], 
**kwargs: Any
     ) -> AsyncIteratorType[bytes]:
         """Generator for streaming response body data.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-core-1.29.3/azure/core/pipeline/transport/_requests_basic.py 
new/azure-core-1.29.4/azure/core/pipeline/transport/_requests_basic.py
--- old/azure-core-1.29.3/azure/core/pipeline/transport/_requests_basic.py      
2023-08-22 21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/azure/core/pipeline/transport/_requests_basic.py      
2023-09-07 19:37:17.000000000 +0200
@@ -24,7 +24,7 @@
 #
 # --------------------------------------------------------------------------
 import logging
-from typing import Iterator, Optional, Union, TypeVar, overload, TYPE_CHECKING
+from typing import Iterator, Optional, Union, TypeVar, overload, cast, 
TYPE_CHECKING
 from urllib3.util.retry import Retry
 from urllib3.exceptions import (
     DecodeError as CoreDecodeError,
@@ -247,6 +247,8 @@
     def __init__(self, **kwargs) -> None:
         self.session = kwargs.get("session", None)
         self._session_owner = kwargs.get("session_owner", True)
+        if not self._session_owner and not self.session:
+            raise ValueError("session_owner cannot be False if no session is 
provided")
         self.connection_config = ConnectionConfiguration(**kwargs)
         self._use_env_settings = kwargs.pop("use_env_settings", True)
 
@@ -274,6 +276,8 @@
         if not self.session and self._session_owner:
             self.session = requests.Session()
             self._init_session(self.session)
+        # pyright has trouble to understand that self.session is not None, 
since we raised at worst in the init
+        self.session = cast(requests.Session, self.session)
 
     def close(self):
         if self._session_owner and self.session:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-core-1.29.3/azure/core/rest/_http_response_impl.py 
new/azure-core-1.29.4/azure/core/rest/_http_response_impl.py
--- old/azure-core-1.29.3/azure/core/rest/_http_response_impl.py        
2023-08-22 21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/azure/core/rest/_http_response_impl.py        
2023-09-07 19:37:17.000000000 +0200
@@ -24,7 +24,7 @@
 #
 # --------------------------------------------------------------------------
 from json import loads
-from typing import cast, Any, Optional, Iterator, MutableMapping, Callable
+from typing import Any, Optional, Iterator, MutableMapping, Callable
 from http.client import HTTPResponse as _HTTPResponse
 from ._helpers import (
     get_charset_encoding,
@@ -344,7 +344,7 @@
 
         If response is good, does nothing.
         """
-        if cast(int, self.status_code) >= 400:
+        if self.status_code >= 400:
             raise HttpResponseError(response=self)
 
     @property
@@ -415,7 +415,7 @@
         :rtype: Iterator[str]
         """
         if self._content is not None:
-            chunk_size = cast(int, self._block_size)
+            chunk_size = self._block_size
             for i in range(0, len(self.content), chunk_size):
                 yield self.content[i : i + chunk_size]
         else:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-core-1.29.3/azure/core/settings.py 
new/azure-core-1.29.4/azure/core/settings.py
--- old/azure-core-1.29.3/azure/core/settings.py        2023-08-22 
21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/azure/core/settings.py        2023-09-07 
19:37:17.000000000 +0200
@@ -31,7 +31,7 @@
 import logging
 import os
 import sys
-from typing import Type, Optional, Callable, cast, Union, Dict, Any, TypeVar, 
Tuple, Generic, Mapping, List
+from typing import Type, Optional, Callable, Union, Dict, Any, TypeVar, Tuple, 
Generic, Mapping, List
 from azure.core.tracing import AbstractSpan
 
 ValidInputType = TypeVar("ValidInputType")
@@ -65,9 +65,9 @@
     :raises ValueError: If conversion to bool fails
 
     """
-    if value in (True, False):
-        return cast(bool, value)
-    val = cast(str, value).lower()
+    if isinstance(value, bool):
+        return value
+    val = value.lower()
     if val in ["yes", "1", "on", "true", "True"]:
         return True
     if val in ["no", "0", "off", "false", "False"]:
@@ -103,9 +103,11 @@
     :raises ValueError: If conversion to log level fails
 
     """
-    if value in set(_levels.values()):
-        return cast(int, value)
-    val = cast(str, value).upper()
+    if isinstance(value, int):
+        # If it's an int, return it. We don't need to check if it's in 
_levels, as custom int levels are allowed.
+        # https://docs.python.org/3/library/logging.html#levels
+        return value
+    val = value.upper()
     level = _levels.get(val)
     if not level:
         raise ValueError("Cannot convert {} to log level, valid values are: 
{}".format(value, ", ".join(_levels)))
@@ -183,7 +185,6 @@
         )
 
     if not isinstance(value, str):
-        value = cast(Type[AbstractSpan], value)
         return value
 
     value = value.lower()
@@ -271,7 +272,7 @@
             return self._convert(value)
 
         # 3. previously user-set value
-        if self._user_value is not _unset:
+        if not isinstance(self._user_value, _Unset):
             return self._convert(self._user_value)
 
         # 2. environment variable
@@ -283,7 +284,7 @@
             return self._convert(self._system_hook())
 
         # 0. implicit default
-        if self._default is not _unset:
+        if not isinstance(self._default, _Unset):
             return self._convert(self._default)
 
         raise RuntimeError("No configured value found for setting %r" % 
self._name)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-core-1.29.3/azure/core/tracing/_abstract_span.py 
new/azure-core-1.29.4/azure/core/tracing/_abstract_span.py
--- old/azure-core-1.29.3/azure/core/tracing/_abstract_span.py  2023-08-22 
21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/azure/core/tracing/_abstract_span.py  2023-09-07 
19:37:17.000000000 +0200
@@ -7,9 +7,9 @@
 from enum import Enum
 from urllib.parse import urlparse
 
-from typing import Any, Sequence, Optional, Union, Callable, Dict, Type
+from typing import Any, Sequence, Optional, Union, Callable, Dict, Type, 
Generic, TypeVar
 from types import TracebackType
-from typing_extensions import Protocol, ContextManager
+from typing_extensions import Protocol, ContextManager, runtime_checkable
 from azure.core.pipeline.transport import HttpRequest, HttpResponse, 
AsyncHttpResponse
 from azure.core.rest import (
     HttpResponse as RestHttpResponse,
@@ -31,6 +31,7 @@
     Sequence[float],
 ]
 Attributes = Dict[str, AttributeValue]
+SpanType = TypeVar("SpanType")
 
 
 class SpanKind(Enum):
@@ -42,7 +43,8 @@
     INTERNAL = 6
 
 
-class AbstractSpan(Protocol):
+@runtime_checkable
+class AbstractSpan(Protocol, Generic[SpanType]):
     """Wraps a span from a distributed tracing implementation.
 
     If a span is given wraps the span. Else a new span is created.
@@ -55,11 +57,11 @@
     """
 
     def __init__(  # pylint: disable=super-init-not-called
-        self, span: Optional[Any] = None, name: Optional[str] = None, 
**kwargs: Any
+        self, span: Optional[SpanType] = None, name: Optional[str] = None, 
**kwargs: Any
     ) -> None:
         pass
 
-    def span(self, name: str = "child_span", **kwargs: Any) -> AbstractSpan:
+    def span(self, name: str = "child_span", **kwargs: Any) -> 
AbstractSpan[SpanType]:
         """
         Create a child span for the current span and append it to the child 
spans list.
         The child span must be wrapped by an implementation of AbstractSpan
@@ -89,7 +91,7 @@
         """
         ...
 
-    def __enter__(self) -> AbstractSpan:
+    def __enter__(self) -> AbstractSpan[SpanType]:
         """Start a span."""
         ...
 
@@ -157,7 +159,7 @@
         ...
 
     @property
-    def span_instance(self) -> Any:
+    def span_instance(self) -> SpanType:
         """
         Returns the span the class is wrapping.
         """
@@ -188,7 +190,7 @@
         ...
 
     @classmethod
-    def get_current_span(cls) -> Any:
+    def get_current_span(cls) -> SpanType:
         """
         Get the current span from the execution context. Return None otherwise.
 
@@ -208,7 +210,7 @@
         ...
 
     @classmethod
-    def set_current_span(cls, span: Any) -> None:
+    def set_current_span(cls, span: SpanType) -> None:
         """Set the given span as the current span in the execution context.
 
         :param span: The span to set as the current span
@@ -226,11 +228,11 @@
         ...
 
     @classmethod
-    def change_context(cls, span: AbstractSpan) -> 
ContextManager[AbstractSpan]:
+    def change_context(cls, span: SpanType) -> ContextManager[SpanType]:
         """Change the context for the life of this context manager.
 
         :param span: The span to run in the new context
-        :type span: AbstractSpan
+        :type span: Any
         :rtype: contextmanager
         :return: A context manager that will run the given span in the new 
context
         """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-core-1.29.3/azure/core/utils/_connection_string_parser.py 
new/azure-core-1.29.4/azure/core/utils/_connection_string_parser.py
--- old/azure-core-1.29.3/azure/core/utils/_connection_string_parser.py 
2023-08-22 21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/azure/core/utils/_connection_string_parser.py 
2023-09-07 19:37:17.000000000 +0200
@@ -26,7 +26,7 @@
     cs_args = [s.split("=", 1) for s in 
conn_str.strip().rstrip(";").split(";")]
     if any(len(tup) != 2 or not all(tup) for tup in cs_args):
         raise ValueError("Connection string is either blank or malformed.")
-    args_dict = dict(cs_args)  # type: ignore
+    args_dict = dict(cs_args)
 
     if len(cs_args) != len(args_dict):
         raise ValueError("Connection string is either blank or malformed.")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/azure-core-1.29.3/azure/core/utils/_pipeline_transport_rest_shared.py 
new/azure-core-1.29.4/azure/core/utils/_pipeline_transport_rest_shared.py
--- old/azure-core-1.29.3/azure/core/utils/_pipeline_transport_rest_shared.py   
2023-08-22 21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/azure/core/utils/_pipeline_transport_rest_shared.py   
2023-09-07 19:37:17.000000000 +0200
@@ -245,10 +245,17 @@
     for index, raw_response in enumerate(message.get_payload()):
         content_type = raw_response.get_content_type()
         if content_type == "application/http":
+            try:
+                matching_request = requests[index]
+            except IndexError:
+                # If we have no matching request, this could mean that we had 
an empty batch.
+                # The request object is only needed to get the HTTP METHOD and 
to store in the response object,
+                # so let's just use the parent request so allow the rest of 
the deserialization to continue.
+                matching_request = response.request
             responses.append(
                 deserialize_response(
                     raw_response.get_payload(decode=True),
-                    requests[index],
+                    matching_request,
                     http_response_type=http_response_type,
                 )
             )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-core-1.29.3/azure_core.egg-info/PKG-INFO 
new/azure-core-1.29.4/azure_core.egg-info/PKG-INFO
--- old/azure-core-1.29.3/azure_core.egg-info/PKG-INFO  2023-08-22 
21:16:01.000000000 +0200
+++ new/azure-core-1.29.4/azure_core.egg-info/PKG-INFO  2023-09-07 
19:38:16.000000000 +0200
@@ -1,11 +1,12 @@
 Metadata-Version: 2.1
 Name: azure-core
-Version: 1.29.3
+Version: 1.29.4
 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
 Author-email: azpysdkh...@microsoft.com
 License: MIT License
+Keywords: azure,azure sdk
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 3 :: Only
@@ -18,8 +19,12 @@
 Classifier: License :: OSI Approved :: MIT License
 Requires-Python: >=3.7
 Description-Content-Type: text/markdown
-Provides-Extra: aio
 License-File: LICENSE
+Requires-Dist: requests>=2.18.4
+Requires-Dist: six>=1.11.0
+Requires-Dist: typing-extensions>=4.6.0
+Provides-Extra: aio
+Requires-Dist: aiohttp>=3.0; extra == "aio"
 
 
 # Azure Core shared client library for Python
@@ -282,6 +287,16 @@
 
 # Release History
 
+## 1.29.4 (2023-09-07)
+
+### Bugs Fixed
+
+- Fixed the issue that some urls trigger an infinite loop. #31346
+- Fixed issue where IndexError was raised if multipart responses did not match 
the number of requests. #31471
+- Fixed issue unbound variable exception if dict is invalid in 
CloudEvent.from_dict. #31835
+- Fixed issue asyncBearerTokenCredentialPolicy is not backward compatible with 
SansIOHTTPPolicy. #31836
+- Fixed issue mypy complains with new version of azure-core. #31564
+
 ## 1.29.3 (2023-08-22)
 
 ### Bugs Fixed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-core-1.29.3/setup.py 
new/azure-core-1.29.4/setup.py
--- old/azure-core-1.29.3/setup.py      2023-08-22 21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/setup.py      2023-09-07 19:37:17.000000000 +0200
@@ -43,6 +43,7 @@
     author="Microsoft Corporation",
     author_email="azpysdkh...@microsoft.com",
     
url="https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/core/azure-core";,
+    keywords="azure, azure sdk",
     classifiers=[
         "Development Status :: 5 - Production/Stable",
         "Programming Language :: Python",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-core-1.29.3/tests/test_basic_transport.py 
new/azure-core-1.29.4/tests/test_basic_transport.py
--- old/azure-core-1.29.3/tests/test_basic_transport.py 2023-08-22 
21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/tests/test_basic_transport.py 2023-09-07 
19:37:17.000000000 +0200
@@ -687,6 +687,41 @@
     assert res1.headers["x-ms-fun"] == "true"
 
 
+@pytest.mark.parametrize("http_request,mock_response", 
request_and_responses_product(MOCK_RESPONSES))
+def test_multipart_receive_with_empty_requests(http_request, mock_response):
+
+    request = http_request("POST", 
"http://account.blob.core.windows.net/?comp=batch";)
+    request.set_multipart_mixed()
+
+    body_as_bytes = (
+        b"--batchresponse_b1e4a276-83db-40e9-b21f-f5bc7f7f905f\r\n"
+        b"Content-Type: application/http\r\n"
+        b"Content-Transfer-Encoding: binary\r\n"
+        b"\r\n"
+        b"HTTP/1.1 400 Bad Request\r\n"
+        b"DataServiceVersion: 1.0;\r\n"
+        b"Content-Type: application/xml;charset=utf-8\r\n"
+        b"\r\n"
+        b'<?xml version="1.0" encoding="utf-8"?><error 
xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";><code>InvalidInput</code><message
 xml:lang="en-US">An error occurred while processing this 
request.\nRequestId:1a930d9b-8002-0020-575c-d1b166000000\nTime:2023-08-17T22:44:06.8465534Z</message></error>\r\n'
+        b"--batchresponse_b1e4a276-83db-40e9-b21f-f5bc7f7f905f--\r\n"
+    )
+
+    response = mock_response(
+        request,
+        body_as_bytes,
+        "multipart/mixed; 
boundary=batchresponse_b1e4a276-83db-40e9-b21f-f5bc7f7f905f",
+    )
+
+    response = response.parts()
+    assert len(response) == 1
+    res0 = response[0]
+    assert res0.status_code == 400
+    assert res0.reason == "Bad Request"
+    assert res0.headers["DataServiceVersion"] == "1.0;"
+    assert res0.request.method == "POST"
+    assert res0.request.url == 
"http://account.blob.core.windows.net/?comp=batch";
+
+
 @pytest.mark.parametrize("mock_response", MOCK_RESPONSES)
 def test_raise_for_status_bad_response(mock_response):
     response = mock_response(request=None, body=None, content_type=None)
@@ -756,6 +791,101 @@
 
 
 @pytest.mark.parametrize("http_request,mock_response", 
request_and_responses_product(MOCK_RESPONSES))
+def test_multipart_receive_with_empty_changeset(http_request, mock_response):
+
+    changeset = http_request(None, None)
+    changeset.set_multipart_mixed()
+    request = http_request("POST", 
"http://account.blob.core.windows.net/?comp=batch";)
+    request.set_multipart_mixed(changeset)
+
+    body_as_bytes = (
+        b"--batchresponse_b1e4a276-83db-40e9-b21f-f5bc7f7f905f\r\n"
+        b"Content-Type: multipart/mixed; 
boundary=changesetresponse_390b0b55-6892-4fce-8427-001ca15662f5\r\n"
+        b"\r\n"
+        b"--changesetresponse_390b0b55-6892-4fce-8427-001ca15662f5\r\n"
+        b"Content-Type: application/http\r\n"
+        b"Content-Transfer-Encoding: binary\r\n"
+        b"\r\n"
+        b"HTTP/1.1 400 Bad Request\r\n"
+        b"DataServiceVersion: 1.0;\r\n"
+        b"Content-Type: application/xml;charset=utf-8\r\n"
+        b"\r\n"
+        b'<?xml version="1.0" encoding="utf-8"?><error 
xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";><code>InvalidInput</code><message
 xml:lang="en-US">An error occurred while processing this 
request.\nRequestId:1a930d9b-8002-0020-575c-d1b166000000\nTime:2023-08-17T22:44:06.8465534Z</message></error>\r\n'
+        b"--changesetresponse_390b0b55-6892-4fce-8427-001ca15662f5--\r\n"
+        b"--batchresponse_b1e4a276-83db-40e9-b21f-f5bc7f7f905f--\r\n"
+    )
+
+    response = mock_response(
+        request, body_as_bytes, "multipart/mixed; 
boundary=batchresponse_b1e4a276-83db-40e9-b21f-f5bc7f7f905f"
+    )
+    parts = []
+    for part in response.parts():
+        parts.append(part)
+    assert len(parts) == 1
+    res0 = parts[0]
+    assert res0.status_code == 400
+    assert res0.reason == "Bad Request"
+    assert "DataServiceVersion" in res0.headers
+    assert res0.request.method == "POST"
+    assert res0.request.url == 
"http://account.blob.core.windows.net/?comp=batch";
+
+    # Test against other HTTP verbs to see if http.client.HttpResponse has any 
concerns.
+    changeset = http_request("PATCH", "https://foo.com";)
+    changeset.set_multipart_mixed()
+    request = http_request("POST", 
"http://account.blob.core.windows.net/?comp=batch";)
+    request.set_multipart_mixed(changeset)
+    response = mock_response(
+        request, body_as_bytes, "multipart/mixed; 
boundary=batchresponse_b1e4a276-83db-40e9-b21f-f5bc7f7f905f"
+    )
+    parts = []
+    for part in response.parts():
+        parts.append(part)
+    assert len(parts) == 1
+    res0 = parts[0]
+    assert res0.status_code == 400
+    assert res0.reason == "Bad Request"
+    assert "DataServiceVersion" in res0.headers
+    assert res0.request.method == "POST"
+    assert res0.request.url == 
"http://account.blob.core.windows.net/?comp=batch";
+
+    changeset = http_request("DELETE", None)
+    changeset.set_multipart_mixed()
+    request = http_request("POST", 
"http://account.blob.core.windows.net/?comp=batch";)
+    request.set_multipart_mixed(changeset)
+    response = mock_response(
+        request, body_as_bytes, "multipart/mixed; 
boundary=batchresponse_b1e4a276-83db-40e9-b21f-f5bc7f7f905f"
+    )
+    parts = []
+    for part in response.parts():
+        parts.append(part)
+    assert len(parts) == 1
+    res0 = parts[0]
+    assert res0.status_code == 400
+    assert res0.reason == "Bad Request"
+    assert "DataServiceVersion" in res0.headers
+    assert res0.request.method == "POST"
+    assert res0.request.url == 
"http://account.blob.core.windows.net/?comp=batch";
+
+    changeset = http_request("HEAD", None)
+    changeset.set_multipart_mixed()
+    request = http_request("POST", 
"http://account.blob.core.windows.net/?comp=batch";)
+    request.set_multipart_mixed(changeset)
+    response = mock_response(
+        request, body_as_bytes, "multipart/mixed; 
boundary=batchresponse_b1e4a276-83db-40e9-b21f-f5bc7f7f905f"
+    )
+    parts = []
+    for part in response.parts():
+        parts.append(part)
+    assert len(parts) == 1
+    res0 = parts[0]
+    assert res0.status_code == 400
+    assert res0.reason == "Bad Request"
+    assert "DataServiceVersion" in res0.headers
+    assert res0.request.method == "POST"
+    assert res0.request.url == 
"http://account.blob.core.windows.net/?comp=batch";
+
+
+@pytest.mark.parametrize("http_request,mock_response", 
request_and_responses_product(MOCK_RESPONSES))
 def test_multipart_receive_with_multiple_changesets(http_request, 
mock_response):
 
     changeset1 = http_request(None, None)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/azure-core-1.29.3/tests/test_pipeline.py 
new/azure-core-1.29.4/tests/test_pipeline.py
--- old/azure-core-1.29.3/tests/test_pipeline.py        2023-08-22 
21:14:14.000000000 +0200
+++ new/azure-core-1.29.4/tests/test_pipeline.py        2023-09-07 
19:37:17.000000000 +0200
@@ -50,7 +50,7 @@
     SansIOHTTPPolicy,
     SensitiveHeaderCleanupPolicy,
 )
-from azure.core.pipeline.transport._base import PipelineClientBase
+from azure.core.pipeline.transport._base import PipelineClientBase, 
_format_url_section
 from azure.core.pipeline.transport import (
     HttpTransport,
     RequestsTransport,
@@ -204,6 +204,18 @@
     assert formatted == 
"https://bing.com/path/subpath?query=testvalue&x=2ndvalue&a=X&c=Y";
 
 
+def test_format_url_braces_with_dot():
+    base_url = "https://bing.com/{aaa.bbb}";
+    with pytest.raises(ValueError):
+        url = _format_url_section(base_url)
+
+
+def test_format_url_single_brace():
+    base_url = "https://bing.com/{aaa.bbb";
+    with pytest.raises(ValueError):
+        url = _format_url_section(base_url)
+
+
 def test_format_incorrect_endpoint():
     # https://github.com/Azure/azure-sdk-for-python/pull/12106
     client = PipelineClientBase("{Endpoint}/text/analytics/v3.0")

Reply via email to