Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion sdk/core/azure-core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@

### Bugs Fixed

- Fixed `PipelineClient.format_url` to preserve the leading slash when the URL template starts with `/?`. #45218

### Other Changes

## 1.38.1 (2026-02-10)

### Bugs Fixed

- Fixed `PipelineClient.format_url` to avoid adding trailing slashes when the URL template contains only query parameters. #45044
- Fixed `PipelineClient.format_url` to avoid adding trailing slashes when the URL template contains only query parameters. #45044

## 1.38.0 (2026-01-12)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def _urljoin(base_url: str, stub_url: str) -> str:
# https://docs.python.org/3/library/collections.html?highlight=namedtuple#collections.namedtuple
if stub_url_path:
parsed_base_url = parsed_base_url._replace(
path=parsed_base_url.path.rstrip("/") + "/" + stub_url_path,
path=parsed_base_url.path.rstrip("/") + "/" + stub_url_path.lstrip("/"),
)
if stub_url_query:
query_params = [stub_url_query]
Expand Down Expand Up @@ -662,7 +662,6 @@ def format_url(self, url_template: str, **kwargs: Any) -> str:
if url:
parsed = urlparse(url)
if not parsed.scheme or not parsed.netloc:
url = url.lstrip("/")
try:
base = self._base_url.format(**kwargs).rstrip("/")
except KeyError as key:
Expand Down
7 changes: 7 additions & 0 deletions sdk/core/azure-core/tests/test_basic_transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,16 @@ def test_http_request_serialization(http_request):

def test_url_join():
assert _urljoin("devstoreaccount1", "?testdir") == "devstoreaccount1?testdir"
assert _urljoin("devstoreaccount1", "?testdir=foo") == "devstoreaccount1?testdir=foo"
assert _urljoin("devstoreaccount1/api", "?a=1") == "devstoreaccount1/api?a=1"
assert (
_urljoin("devstoreaccount1", "/?restype=service&comp=properties")
== "devstoreaccount1/?restype=service&comp=properties"
)
assert _urljoin("devstoreaccount1", "") == "devstoreaccount1"
assert _urljoin("devstoreaccount1", "testdir/") == "devstoreaccount1/testdir/"
assert _urljoin("devstoreaccount1/", "") == "devstoreaccount1/"
assert _urljoin("devstoreaccount1/", "/testdir/") == "devstoreaccount1/testdir/"
assert _urljoin("devstoreaccount1/", "testdir/") == "devstoreaccount1/testdir/"
assert _urljoin("devstoreaccount1?a=1", "testdir/") == "devstoreaccount1/testdir/?a=1"
assert _urljoin("devstoreaccount1", "testdir/?b=2") == "devstoreaccount1/testdir/?b=2"
Expand Down
34 changes: 34 additions & 0 deletions sdk/core/azure-core/tests/test_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

from azure.core.configuration import Configuration
from azure.core.pipeline import Pipeline
from azure.core.rest import HttpRequest
from azure.core import PipelineClient
from azure.core.pipeline.policies import (
SansIOHTTPPolicy,
Expand Down Expand Up @@ -206,6 +207,39 @@ def test_format_url_double_query():
assert formatted == "https://bing.com/path/subpath?query=testvalue&x=2ndvalue&a=X&c=Y"


def test_format_url_query_strings():
client = PipelineClientBase("https://foo.core.windows.net")
formatted = client.format_url("/")
assert formatted == "https://foo.core.windows.net/"

formatted = client.format_url("/?a=X&c=Y")
assert formatted == "https://foo.core.windows.net/?a=X&c=Y"

formatted = client.format_url("?a=X&c=Y")
assert formatted == "https://foo.core.windows.net?a=X&c=Y"

formatted = client.format_url("/Tables/?a=X&c=Y")
assert formatted == "https://foo.core.windows.net/Tables/?a=X&c=Y"

formatted = client.format_url("/Tables?a=X&c=Y")
assert formatted == "https://foo.core.windows.net/Tables?a=X&c=Y"


def test_format_url_from_http_request():
client = PipelineClientBase("https://foo.core.windows.net")

_url = "/"
_params = {"foo": "bar"}
request = HttpRequest("GET", _url, params=_params)
formatted = client.format_url(request.url)
assert formatted == "https://foo.core.windows.net/?foo=bar"

_url = "?restype=service&comp=properties"
request = HttpRequest("GET", _url)
formatted = client.format_url(request.url)
assert formatted == "https://foo.core.windows.net?restype=service&comp=properties"


def test_format_url_braces_with_dot():
base_url = "https://bing.com/{aaa.bbb}"
with pytest.raises(ValueError):
Expand Down
2 changes: 1 addition & 1 deletion sdk/tables/azure-data-tables/assets.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "python",
"TagPrefix": "python/tables/azure-data-tables",
"Tag": "python/tables/azure-data-tables_afc53b2631"
"Tag": "python/tables/azure-data-tables_48a9914a75"
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
# --------------------------------------------------------------------------
import time
import pytest
from packaging.version import Version

from devtools_testutils import AzureRecordedTestCase, recorded_by_proxy

Expand All @@ -18,7 +17,6 @@
TableRetentionPolicy,
TableCorsRule,
)
from azure.core import VERSION as core_version
from azure.core.exceptions import ResourceNotFoundError, HttpResponseError

from _shared.testcase import TableTestCase
Expand Down Expand Up @@ -184,18 +182,15 @@ def test_client_with_url_ends_with_table_name(
assert ("table specified does not exist") in str(exc.value)
assert ("Please check your account URL.") in str(exc.value)

# Azure Core 1.38.1 introduced a change to URL formatting which can cause recording mismatches in
# mindependency checks.
if Version(core_version) >= Version("1.38.1") or self.is_live:
with pytest.raises(HttpResponseError) as exc:
tsc.set_service_properties(analytics_logging=TableAnalyticsLogging(write=True))
assert ("URI is invalid") in str(exc.value)
assert ("Please check your account URL.") in str(exc.value)

with pytest.raises(HttpResponseError) as exc:
tsc.get_service_properties()
assert ("URI is invalid") in str(exc.value)
assert ("Please check your account URL.") in str(exc.value)
with pytest.raises(HttpResponseError) as exc:
tsc.set_service_properties(analytics_logging=TableAnalyticsLogging(write=True))
assert ("URI is invalid") in str(exc.value)
assert ("Please check your account URL.") in str(exc.value)

with pytest.raises(HttpResponseError) as exc:
tsc.get_service_properties()
assert ("URI is invalid") in str(exc.value)
assert ("Please check your account URL.") in str(exc.value)

tsc.delete_table(table_name)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------
from packaging.version import Version
import time
import pytest

from devtools_testutils import AzureRecordedTestCase
from devtools_testutils.aio import recorded_by_proxy_async

from azure.core import VERSION as core_version
from azure.core.exceptions import ResourceNotFoundError, HttpResponseError

from azure.data.tables import TableAnalyticsLogging, TableMetrics, TableRetentionPolicy, TableCorsRule
Expand Down Expand Up @@ -185,18 +183,15 @@ async def test_client_with_url_ends_with_table_name(
assert ("table specified does not exist") in str(exc.value)
assert ("Please check your account URL.") in str(exc.value)

# Azure Core 1.38.1 introduced a change to URL formatting which can cause recording mismatches in
# mindependency checks.
if Version(core_version) >= Version("1.38.1") or self.is_live:
with pytest.raises(HttpResponseError) as exc:
await tsc.set_service_properties(analytics_logging=TableAnalyticsLogging(write=True))
assert ("URI is invalid") in str(exc.value)
assert ("Please check your account URL.") in str(exc.value)

with pytest.raises(HttpResponseError) as exc:
await tsc.get_service_properties()
assert ("URI is invalid") in str(exc.value)
assert ("Please check your account URL.") in str(exc.value)
with pytest.raises(HttpResponseError) as exc:
await tsc.set_service_properties(analytics_logging=TableAnalyticsLogging(write=True))
assert ("URI is invalid") in str(exc.value)
assert ("Please check your account URL.") in str(exc.value)

with pytest.raises(HttpResponseError) as exc:
await tsc.get_service_properties()
assert ("URI is invalid") in str(exc.value)
assert ("Please check your account URL.") in str(exc.value)

await tsc.delete_table(table_name)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,15 @@ def test_client_with_url_ends_with_table_name(self, tables_cosmos_account_name,
assert ("Server failed to authenticate the request") in str(exc.value)
assert ("Please check your account URL.") in str(exc.value)

# Azure Core 1.38.1 introduced a change to URL formatting which can cause recording mismatches in
# mindependency checks.
if Version(core_version) >= Version("1.38.1") or self.is_live:
with pytest.raises(HttpResponseError) as exc:
tsc.set_service_properties(analytics_logging=TableAnalyticsLogging(write=True))
assert ("Server failed to authenticate the request") in str(exc.value)
assert ("Please check your account URL.") in str(exc.value)

with pytest.raises(HttpResponseError) as exc:
tsc.get_service_properties()
assert ("Server failed to authenticate the request") in str(exc.value)
assert ("Please check your account URL.") in str(exc.value)
with pytest.raises(HttpResponseError) as exc:
tsc.set_service_properties(analytics_logging=TableAnalyticsLogging(write=True))
assert ("Server failed to authenticate the request") in str(exc.value)
assert ("Please check your account URL.") in str(exc.value)

with pytest.raises(HttpResponseError) as exc:
tsc.get_service_properties()
assert ("Server failed to authenticate the request") in str(exc.value)
assert ("Please check your account URL.") in str(exc.value)

with pytest.raises(HttpResponseError) as exc:
tsc.delete_table(table_name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,13 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------
from packaging.version import Version
import pytest

from devtools_testutils import AzureRecordedTestCase
from devtools_testutils.aio import recorded_by_proxy_async

from azure.data.tables import TableAnalyticsLogging, TableMetrics, TableRetentionPolicy, TableCorsRule
from azure.data.tables.aio import TableServiceClient
from azure.core import VERSION as core_version
from azure.core.exceptions import HttpResponseError

from _shared.asynctestcase import AsyncTableTestCase
Expand Down Expand Up @@ -73,18 +71,15 @@ async def test_client_with_url_ends_with_table_name(
assert ("Server failed to authenticate the request") in str(exc.value)
assert ("Please check your account URL.") in str(exc.value)

# Azure Core 1.38.1 introduced a change to URL formatting which can cause recording mismatches in
# mindependency checks.
if Version(core_version) >= Version("1.38.1") or self.is_live:
with pytest.raises(HttpResponseError) as exc:
await tsc.set_service_properties(analytics_logging=TableAnalyticsLogging(write=True))
assert ("Server failed to authenticate the request") in str(exc.value)
assert ("Please check your account URL.") in str(exc.value)

with pytest.raises(HttpResponseError) as exc:
await tsc.get_service_properties()
assert ("Server failed to authenticate the request") in str(exc.value)
assert ("Please check your account URL.") in str(exc.value)
with pytest.raises(HttpResponseError) as exc:
await tsc.set_service_properties(analytics_logging=TableAnalyticsLogging(write=True))
assert ("Server failed to authenticate the request") in str(exc.value)
assert ("Please check your account URL.") in str(exc.value)

with pytest.raises(HttpResponseError) as exc:
await tsc.get_service_properties()
assert ("Server failed to authenticate the request") in str(exc.value)
assert ("Please check your account URL.") in str(exc.value)

with pytest.raises(HttpResponseError) as exc:
await tsc.delete_table(table_name)
Expand Down
Loading