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
<[email protected]>
+
+- 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: [email protected]
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: [email protected]
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="[email protected]",
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"
[email protected]("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"
+
+
[email protected]("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")