diff --git a/.chronus/changes/python-fix-nightly-2026-1-3-9-2-18.md b/.chronus/changes/python-fix-nightly-2026-1-3-9-2-18.md new file mode 100644 index 00000000000..6ea9b8d973e --- /dev/null +++ b/.chronus/changes/python-fix-nightly-2026-1-3-9-2-18.md @@ -0,0 +1,7 @@ +--- +changeKind: internal +packages: + - "@typespec/http-client-python" +--- + +Add test case \ No newline at end of file diff --git a/.chronus/changes/python-fix-nightly-2026-1-4-6-52-8.md b/.chronus/changes/python-fix-nightly-2026-1-4-6-52-8.md new file mode 100644 index 00000000000..64bf9ba2bfe --- /dev/null +++ b/.chronus/changes/python-fix-nightly-2026-1-4-6-52-8.md @@ -0,0 +1,7 @@ +--- +changeKind: fix +packages: + - "@typespec/http-client-python" +--- + +Fix import for xml paging \ No newline at end of file diff --git a/packages/http-client-python/generator/pygen/codegen/models/operation.py b/packages/http-client-python/generator/pygen/codegen/models/operation.py index f5fb1c6241d..9036dac6eb1 100644 --- a/packages/http-client-python/generator/pygen/codegen/models/operation.py +++ b/packages/http-client-python/generator/pygen/codegen/models/operation.py @@ -284,6 +284,10 @@ def get_request_builder_import( def need_deserialize(self) -> bool: return any(r.type and not isinstance(r.type, BinaryIteratorType) for r in self.responses) + @property + def enable_import_deserialize_xml(self) -> bool: + return any(xml_serializable(str(r.default_content_type)) for r in self.responses + self.exceptions) + def imports( # pylint: disable=too-many-branches, disable=too-many-statements self, async_mode: bool, **kwargs: Any ) -> FileImport: @@ -443,7 +447,7 @@ def imports( # pylint: disable=too-many-branches, disable=too-many-statements ImportType.LOCAL, ) file_import.add_import("json", ImportType.STDLIB) - if any(xml_serializable(str(r.default_content_type)) for r in self.responses + self.exceptions): + if self.enable_import_deserialize_xml: file_import.add_submodule_import(relative_path, "_deserialize_xml", ImportType.LOCAL) elif self.need_deserialize: file_import.add_submodule_import(relative_path, "_deserialize", ImportType.LOCAL) diff --git a/packages/http-client-python/generator/pygen/codegen/models/paging_operation.py b/packages/http-client-python/generator/pygen/codegen/models/paging_operation.py index bba3a904f1c..6246062e69c 100644 --- a/packages/http-client-python/generator/pygen/codegen/models/paging_operation.py +++ b/packages/http-client-python/generator/pygen/codegen/models/paging_operation.py @@ -17,6 +17,7 @@ from .model_type import ModelType from .list_type import ListType from .parameter import Parameter +from ...utils import xml_serializable if TYPE_CHECKING: from .code_model import CodeModel @@ -135,6 +136,10 @@ def cls_type_annotation(self, *, async_mode: bool, **kwargs: Any) -> str: def has_optional_return_type(self) -> bool: return False + @property + def enable_import_deserialize_xml(self): + return any(xml_serializable(str(r.default_content_type)) for r in self.exceptions) + def imports(self, async_mode: bool, **kwargs: Any) -> FileImport: if self.abstract: return FileImport(self.code_model) @@ -185,7 +190,6 @@ def imports(self, async_mode: bool, **kwargs: Any) -> FileImport: file_import.add_submodule_import(relative_path, "_deserialize", ImportType.LOCAL) if self.is_xml_paging: file_import.add_submodule_import("xml.etree", "ElementTree", ImportType.STDLIB, alias="ET") - file_import.add_submodule_import(relative_path, "_convert_element", ImportType.LOCAL) return file_import diff --git a/packages/http-client-python/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_operationtemplates_async.py b/packages/http-client-python/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_operationtemplates_async.py index 21fc5d68738..2c1bc0fc4b6 100644 --- a/packages/http-client-python/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_operationtemplates_async.py +++ b/packages/http-client-python/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_operationtemplates_async.py @@ -176,6 +176,18 @@ async def test_optional_body_provider_post_with_body(client): assert result.status == "Changed to requested allowance" +@pytest.mark.asyncio +async def test_lro_begin_export_array(client): + result = await ( + await client.lro.begin_export_array( + body=models.ExportRequest(format="csv"), + ) + ).result() + assert len(result) == 2 + assert result[0].content == "order1,product1,1" + assert result[1].content == "order2,product2,2" + + @pytest.mark.asyncio async def test_lro_paging_begin_post_paging_lro(client): poller = await client.lro_paging.begin_post_paging_lro( diff --git a/packages/http-client-python/generator/test/azure/mock_api_tests/asynctests/test_azure_resource_manager_multi_service_older_versions_async.py b/packages/http-client-python/generator/test/azure/mock_api_tests/asynctests/test_azure_resource_manager_multi_service_older_versions_async.py new file mode 100644 index 00000000000..d9f36f938f3 --- /dev/null +++ b/packages/http-client-python/generator/test/azure/mock_api_tests/asynctests/test_azure_resource_manager_multi_service_older_versions_async.py @@ -0,0 +1,111 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import pytest +from azure.resourcemanager.multiserviceolderversions.combined.aio import CombinedClient +from azure.resourcemanager.multiserviceolderversions.combined.models import ( + VirtualMachine, + Disk, + VirtualMachineProperties, + DiskProperties, +) + + +@pytest.fixture +async def client(credential, authentication_policy): + """Create a Combined async client for testing.""" + return CombinedClient( + credential=credential, + subscription_id="00000000-0000-0000-0000-000000000000", + base_url="http://localhost:3000", + authentication_policy=authentication_policy, + polling_interval=0.1, + ) + + +@pytest.mark.asyncio +async def test_virtual_machines_get(client): + """Test getting a virtual machine.""" + resource_group_name = "test-rg" + vm_name = "vm-old1" + + result = await client.virtual_machines.get(resource_group_name=resource_group_name, vm_name=vm_name) + + assert result is not None + assert isinstance(result, VirtualMachine) + assert result.name == vm_name + assert result.location == "eastus" + assert result.properties is not None + assert result.properties.provisioning_state == "Succeeded" + assert result.properties.size == "Standard_D2s_v3" + + +@pytest.mark.asyncio +async def test_virtual_machines_create_or_update(client): + """Test creating or updating a virtual machine.""" + resource_group_name = "test-rg" + vm_name = "vm-old1" + + vm_resource = VirtualMachine( + location="eastus", + properties=VirtualMachineProperties(size="Standard_D2s_v3"), + ) + + poller = await client.virtual_machines.begin_create_or_update( + resource_group_name=resource_group_name, + vm_name=vm_name, + resource=vm_resource, + ) + + result = await poller.result() + assert result is not None + assert isinstance(result, VirtualMachine) + assert result.location == "eastus" + assert result.properties is not None + assert result.properties.provisioning_state == "Succeeded" + assert result.properties.size == "Standard_D2s_v3" + + +@pytest.mark.asyncio +async def test_disks_get(client): + """Test getting a disk.""" + resource_group_name = "test-rg" + disk_name = "disk-old1" + + result = await client.disks.get(resource_group_name=resource_group_name, disk_name=disk_name) + + assert result is not None + assert isinstance(result, Disk) + assert result.name == disk_name + assert result.location == "eastus" + assert result.properties is not None + assert result.properties.provisioning_state == "Succeeded" + assert result.properties.disk_size_gb == 128 + + +@pytest.mark.asyncio +async def test_disks_create_or_update(client): + """Test creating or updating a disk.""" + resource_group_name = "test-rg" + disk_name = "disk-old1" + + disk_resource = Disk( + location="eastus", + properties=DiskProperties(disk_size_gb=128), + ) + + poller = await client.disks.begin_create_or_update( + resource_group_name=resource_group_name, + disk_name=disk_name, + resource=disk_resource, + ) + + result = await poller.result() + assert result is not None + assert isinstance(result, Disk) + assert result.location == "eastus" + assert result.properties is not None + assert result.properties.provisioning_state == "Succeeded" + assert result.properties.disk_size_gb == 128 diff --git a/packages/http-client-python/generator/test/azure/mock_api_tests/asynctests/test_azure_resource_manager_multi_service_shared_models_async.py b/packages/http-client-python/generator/test/azure/mock_api_tests/asynctests/test_azure_resource_manager_multi_service_shared_models_async.py new file mode 100644 index 00000000000..ee1c21bfbe1 --- /dev/null +++ b/packages/http-client-python/generator/test/azure/mock_api_tests/asynctests/test_azure_resource_manager_multi_service_shared_models_async.py @@ -0,0 +1,132 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import pytest +from azure.resourcemanager.multiservicesharedmodels.combined.aio import CombinedClient +from azure.resourcemanager.multiservicesharedmodels.combined.models import ( + VirtualMachine, + VirtualMachineProperties, + StorageAccount, + StorageAccountProperties, + SharedMetadata, +) + + +@pytest.fixture +async def client(credential, authentication_policy): + """Create a Combined async client for testing.""" + return CombinedClient( + credential=credential, + subscription_id="00000000-0000-0000-0000-000000000000", + base_url="http://localhost:3000", + authentication_policy=authentication_policy, + polling_interval=0.1, + ) + + +@pytest.mark.asyncio +async def test_virtual_machines_get(client): + """Test getting a virtual machine with shared metadata.""" + resource_group_name = "test-rg" + vm_name = "vm-shared1" + + result = await client.virtual_machines.get(resource_group_name=resource_group_name, vm_name=vm_name) + + assert result is not None + assert isinstance(result, VirtualMachine) + assert result.name == vm_name + assert result.location == "eastus" + assert result.type == "Microsoft.Compute/virtualMachinesShared" + assert result.properties is not None + assert result.properties.provisioning_state == "Succeeded" + assert result.properties.metadata is not None + assert result.properties.metadata.created_by == "user@example.com" + assert result.properties.metadata.tags == {"environment": "production"} + + +@pytest.mark.asyncio +async def test_virtual_machines_create_or_update(client): + """Test creating or updating a virtual machine with shared metadata.""" + resource_group_name = "test-rg" + vm_name = "vm-shared1" + + vm_resource = VirtualMachine( + location="eastus", + properties=VirtualMachineProperties( + metadata=SharedMetadata( + created_by="user@example.com", + tags={"environment": "production"}, + ), + ), + ) + + poller = await client.virtual_machines.begin_create_or_update( + resource_group_name=resource_group_name, + vm_name=vm_name, + resource=vm_resource, + ) + + result = await poller.result() + assert result is not None + assert isinstance(result, VirtualMachine) + assert result.location == "eastus" + assert result.properties is not None + assert result.properties.provisioning_state == "Succeeded" + assert result.properties.metadata is not None + assert result.properties.metadata.created_by == "user@example.com" + assert result.properties.metadata.tags == {"environment": "production"} + + +@pytest.mark.asyncio +async def test_storage_accounts_get(client): + """Test getting a storage account with shared metadata.""" + resource_group_name = "test-rg" + account_name = "account1" + + result = await client.storage_accounts.get(resource_group_name=resource_group_name, account_name=account_name) + + assert result is not None + assert isinstance(result, StorageAccount) + assert result.name == account_name + assert result.location == "westus" + assert result.type == "Microsoft.Storage/storageAccounts" + assert result.properties is not None + assert result.properties.provisioning_state == "Succeeded" + assert result.properties.metadata is not None + assert result.properties.metadata.created_by == "admin@example.com" + assert result.properties.metadata.tags == {"department": "engineering"} + + +@pytest.mark.asyncio +async def test_storage_accounts_create_or_update(client): + """Test creating or updating a storage account with shared metadata.""" + resource_group_name = "test-rg" + account_name = "account1" + + storage_resource = StorageAccount( + location="westus", + properties=StorageAccountProperties( + metadata=SharedMetadata( + created_by="admin@example.com", + tags={"department": "engineering"}, + ), + ), + ) + + poller = await client.storage_accounts.begin_create_or_update( + resource_group_name=resource_group_name, + account_name=account_name, + resource=storage_resource, + ) + + result = await poller.result() + assert result is not None + assert isinstance(result, StorageAccount) + assert result.location == "westus" + assert result.properties is not None + assert result.properties.provisioning_state == "Succeeded" + assert result.properties.metadata is not None + assert result.properties.metadata.created_by == "admin@example.com" + assert result.properties.metadata.tags == {"department": "engineering"} diff --git a/packages/http-client-python/generator/test/azure/mock_api_tests/test_azure_arm_operationtemplates.py b/packages/http-client-python/generator/test/azure/mock_api_tests/test_azure_arm_operationtemplates.py index 9895d78d8cb..c86c95ef4a9 100644 --- a/packages/http-client-python/generator/test/azure/mock_api_tests/test_azure_arm_operationtemplates.py +++ b/packages/http-client-python/generator/test/azure/mock_api_tests/test_azure_arm_operationtemplates.py @@ -156,6 +156,15 @@ def test_optional_body_provider_post_with_body(client): assert result.status == "Changed to requested allowance" +def test_lro_begin_export_array(client): + result = client.lro.begin_export_array( + body=models.ExportRequest(format="csv"), + ).result() + assert len(result) == 2 + assert result[0].content == "order1,product1,1" + assert result[1].content == "order2,product2,2" + + def test_lro_paging_begin_post_paging_lro(client): result = client.lro_paging.begin_post_paging_lro( resource_group_name=RESOURCE_GROUP_NAME, diff --git a/packages/http-client-python/generator/test/azure/mock_api_tests/test_azure_resource_manager_multi_service_older_versions.py b/packages/http-client-python/generator/test/azure/mock_api_tests/test_azure_resource_manager_multi_service_older_versions.py new file mode 100644 index 00000000000..e98b0e07796 --- /dev/null +++ b/packages/http-client-python/generator/test/azure/mock_api_tests/test_azure_resource_manager_multi_service_older_versions.py @@ -0,0 +1,107 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import pytest +from azure.resourcemanager.multiserviceolderversions.combined import CombinedClient +from azure.resourcemanager.multiserviceolderversions.combined.models import ( + VirtualMachine, + Disk, + VirtualMachineProperties, + DiskProperties, +) + + +@pytest.fixture +def client(credential, authentication_policy): + """Create a Combined client for testing.""" + return CombinedClient( + credential=credential, + subscription_id="00000000-0000-0000-0000-000000000000", + base_url="http://localhost:3000", + authentication_policy=authentication_policy, + polling_interval=0.1, + ) + + +def test_virtual_machines_get(client): + """Test getting a virtual machine.""" + resource_group_name = "test-rg" + vm_name = "vm-old1" + + result = client.virtual_machines.get(resource_group_name=resource_group_name, vm_name=vm_name) + + assert result is not None + assert isinstance(result, VirtualMachine) + assert result.name == vm_name + assert result.location == "eastus" + assert result.properties is not None + assert result.properties.provisioning_state == "Succeeded" + assert result.properties.size == "Standard_D2s_v3" + + +def test_virtual_machines_create_or_update(client): + """Test creating or updating a virtual machine.""" + resource_group_name = "test-rg" + vm_name = "vm-old1" + + vm_resource = VirtualMachine( + location="eastus", + properties=VirtualMachineProperties(size="Standard_D2s_v3"), + ) + + poller = client.virtual_machines.begin_create_or_update( + resource_group_name=resource_group_name, + vm_name=vm_name, + resource=vm_resource, + ) + + result = poller.result() + assert result is not None + assert isinstance(result, VirtualMachine) + assert result.location == "eastus" + assert result.properties is not None + assert result.properties.provisioning_state == "Succeeded" + assert result.properties.size == "Standard_D2s_v3" + + +def test_disks_get(client): + """Test getting a disk.""" + resource_group_name = "test-rg" + disk_name = "disk-old1" + + result = client.disks.get(resource_group_name=resource_group_name, disk_name=disk_name) + + assert result is not None + assert isinstance(result, Disk) + assert result.name == disk_name + assert result.location == "eastus" + assert result.properties is not None + assert result.properties.provisioning_state == "Succeeded" + assert result.properties.disk_size_gb == 128 + + +def test_disks_create_or_update(client): + """Test creating or updating a disk.""" + resource_group_name = "test-rg" + disk_name = "disk-old1" + + disk_resource = Disk( + location="eastus", + properties=DiskProperties(disk_size_gb=128), + ) + + poller = client.disks.begin_create_or_update( + resource_group_name=resource_group_name, + disk_name=disk_name, + resource=disk_resource, + ) + + result = poller.result() + assert result is not None + assert isinstance(result, Disk) + assert result.location == "eastus" + assert result.properties is not None + assert result.properties.provisioning_state == "Succeeded" + assert result.properties.disk_size_gb == 128 diff --git a/packages/http-client-python/generator/test/azure/mock_api_tests/test_azure_resource_manager_multi_service_shared_models.py b/packages/http-client-python/generator/test/azure/mock_api_tests/test_azure_resource_manager_multi_service_shared_models.py new file mode 100644 index 00000000000..0e3f67ebc10 --- /dev/null +++ b/packages/http-client-python/generator/test/azure/mock_api_tests/test_azure_resource_manager_multi_service_shared_models.py @@ -0,0 +1,128 @@ +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import pytest +from azure.resourcemanager.multiservicesharedmodels.combined import CombinedClient +from azure.resourcemanager.multiservicesharedmodels.combined.models import ( + VirtualMachine, + VirtualMachineProperties, + StorageAccount, + StorageAccountProperties, + SharedMetadata, +) + + +@pytest.fixture +def client(credential, authentication_policy): + """Create a Combined client for testing.""" + return CombinedClient( + credential=credential, + subscription_id="00000000-0000-0000-0000-000000000000", + base_url="http://localhost:3000", + authentication_policy=authentication_policy, + polling_interval=0.1, + ) + + +def test_virtual_machines_get(client): + """Test getting a virtual machine with shared metadata.""" + resource_group_name = "test-rg" + vm_name = "vm-shared1" + + result = client.virtual_machines.get(resource_group_name=resource_group_name, vm_name=vm_name) + + assert result is not None + assert isinstance(result, VirtualMachine) + assert result.name == vm_name + assert result.location == "eastus" + assert result.type == "Microsoft.Compute/virtualMachinesShared" + assert result.properties is not None + assert result.properties.provisioning_state == "Succeeded" + assert result.properties.metadata is not None + assert result.properties.metadata.created_by == "user@example.com" + assert result.properties.metadata.tags == {"environment": "production"} + + +def test_virtual_machines_create_or_update(client): + """Test creating or updating a virtual machine with shared metadata.""" + resource_group_name = "test-rg" + vm_name = "vm-shared1" + + vm_resource = VirtualMachine( + location="eastus", + properties=VirtualMachineProperties( + metadata=SharedMetadata( + created_by="user@example.com", + tags={"environment": "production"}, + ), + ), + ) + + poller = client.virtual_machines.begin_create_or_update( + resource_group_name=resource_group_name, + vm_name=vm_name, + resource=vm_resource, + ) + + result = poller.result() + assert result is not None + assert isinstance(result, VirtualMachine) + assert result.location == "eastus" + assert result.properties is not None + assert result.properties.provisioning_state == "Succeeded" + assert result.properties.metadata is not None + assert result.properties.metadata.created_by == "user@example.com" + assert result.properties.metadata.tags == {"environment": "production"} + + +def test_storage_accounts_get(client): + """Test getting a storage account with shared metadata.""" + resource_group_name = "test-rg" + account_name = "account1" + + result = client.storage_accounts.get(resource_group_name=resource_group_name, account_name=account_name) + + assert result is not None + assert isinstance(result, StorageAccount) + assert result.name == account_name + assert result.location == "westus" + assert result.type == "Microsoft.Storage/storageAccounts" + assert result.properties is not None + assert result.properties.provisioning_state == "Succeeded" + assert result.properties.metadata is not None + assert result.properties.metadata.created_by == "admin@example.com" + assert result.properties.metadata.tags == {"department": "engineering"} + + +def test_storage_accounts_create_or_update(client): + """Test creating or updating a storage account with shared metadata.""" + resource_group_name = "test-rg" + account_name = "account1" + + storage_resource = StorageAccount( + location="westus", + properties=StorageAccountProperties( + metadata=SharedMetadata( + created_by="admin@example.com", + tags={"department": "engineering"}, + ), + ), + ) + + poller = client.storage_accounts.begin_create_or_update( + resource_group_name=resource_group_name, + account_name=account_name, + resource=storage_resource, + ) + + result = poller.result() + assert result is not None + assert isinstance(result, StorageAccount) + assert result.location == "westus" + assert result.properties is not None + assert result.properties.provisioning_state == "Succeeded" + assert result.properties.metadata is not None + assert result.properties.metadata.created_by == "admin@example.com" + assert result.properties.metadata.tags == {"department": "engineering"} diff --git a/packages/http-client-python/generator/test/azure/requirements.txt b/packages/http-client-python/generator/test/azure/requirements.txt index 605b54125e2..8c9d1fd91a9 100644 --- a/packages/http-client-python/generator/test/azure/requirements.txt +++ b/packages/http-client-python/generator/test/azure/requirements.txt @@ -37,6 +37,8 @@ azure-mgmt-core==1.6.0 -e ./generated/azure-resource-manager-resources -e ./generated/azure-resource-manager-method-subscription-id -e ./generated/azure-resource-manager-multi-service +-e ./generated/azure-resource-manager-multi-service-older-versions +-e ./generated/azure-resource-manager-multi-service-shared-models -e ./generated/azure-versioning-previewversion -e ./generated/client-namespace -e ./generated/azure-payload-pageable diff --git a/packages/http-client-python/generator/test/generic_mock_api_tests/asynctests/test_payload_pageable_async.py b/packages/http-client-python/generator/test/generic_mock_api_tests/asynctests/test_payload_pageable_async.py index 45c5d12de49..c14800bb7d6 100644 --- a/packages/http-client-python/generator/test/generic_mock_api_tests/asynctests/test_payload_pageable_async.py +++ b/packages/http-client-python/generator/test/generic_mock_api_tests/asynctests/test_payload_pageable_async.py @@ -115,8 +115,13 @@ async def test_list_without_continuation(client: PageableClient): assert_result(result) -# after https://github.com/microsoft/typespec/pull/9455 released, we could enable this test again -# @pytest.mark.asyncio -# async def test_xml_pagination_list_with_next_link(client: PageableClient): -# result = [p async for p in client.xml_pagination.list_with_next_link()] -# assert_result(result) +@pytest.mark.asyncio +async def test_xml_pagination_list_with_continuation(client: PageableClient): + result = [p async for p in client.xml_pagination.list_with_continuation()] + assert_result(result) + + +@pytest.mark.asyncio +async def test_xml_pagination_list_with_next_link(client: PageableClient): + result = [p async for p in client.xml_pagination.list_with_next_link()] + assert_result(result) diff --git a/packages/http-client-python/generator/test/generic_mock_api_tests/asynctests/test_payload_xml_async.py b/packages/http-client-python/generator/test/generic_mock_api_tests/asynctests/test_payload_xml_async.py index 07905890cc3..28693b8c286 100644 --- a/packages/http-client-python/generator/test/generic_mock_api_tests/asynctests/test_payload_xml_async.py +++ b/packages/http-client-python/generator/test/generic_mock_api_tests/asynctests/test_payload_xml_async.py @@ -117,3 +117,12 @@ async def test_model_with_encoded_names(client: XmlClient): model = ModelWithEncodedNames(model_data=SimpleModel(name="foo", age=123), colors=["red", "green", "blue"]) assert await client.model_with_encoded_names_value.get() == model await client.model_with_encoded_names_value.put(model) + + +@pytest.mark.asyncio +async def test_xml_error_value(client: XmlClient, core_library): + with pytest.raises(core_library.exceptions.HttpResponseError) as ex: + await client.xml_error_value.get() + assert ex.value.status_code == 400 + assert ex.value.model.message == "Something went wrong" + assert ex.value.model.code == 400 diff --git a/packages/http-client-python/generator/test/generic_mock_api_tests/test_payload_pageable.py b/packages/http-client-python/generator/test/generic_mock_api_tests/test_payload_pageable.py index 1302cb8b957..66cc77022d5 100644 --- a/packages/http-client-python/generator/test/generic_mock_api_tests/test_payload_pageable.py +++ b/packages/http-client-python/generator/test/generic_mock_api_tests/test_payload_pageable.py @@ -83,7 +83,11 @@ def test_list_without_continuation(client: PageableClient): assert_result(result) -# # after https://github.com/microsoft/typespec/pull/9455 released, we could enable this test again -# def test_xml_pagination_list_with_next_link(client: PageableClient): -# result = list(client.xml_pagination.list_with_next_link()) -# assert_result(result) +def test_xml_pagination_list_with_continuation(client: PageableClient): + result = list(client.xml_pagination.list_with_continuation()) + assert_result(result) + + +def test_xml_pagination_list_with_next_link(client: PageableClient): + result = list(client.xml_pagination.list_with_next_link()) + assert_result(result) diff --git a/packages/http-client-python/generator/test/generic_mock_api_tests/test_payload_xml.py b/packages/http-client-python/generator/test/generic_mock_api_tests/test_payload_xml.py index 252b6abbd4d..f5e7a2da671 100644 --- a/packages/http-client-python/generator/test/generic_mock_api_tests/test_payload_xml.py +++ b/packages/http-client-python/generator/test/generic_mock_api_tests/test_payload_xml.py @@ -105,3 +105,11 @@ def test_model_with_encoded_names(client: XmlClient): model = ModelWithEncodedNames(model_data=SimpleModel(name="foo", age=123), colors=["red", "green", "blue"]) assert client.model_with_encoded_names_value.get() == model client.model_with_encoded_names_value.put(model) + + +def test_xml_error_value(client: XmlClient, core_library): + with pytest.raises(core_library.exceptions.HttpResponseError) as ex: + client.xml_error_value.get() + assert ex.value.status_code == 400 + assert ex.value.model.message == "Something went wrong" + assert ex.value.model.code == 400 diff --git a/packages/http-client-python/package-lock.json b/packages/http-client-python/package-lock.json index ef4f18aa854..4e173ed3521 100644 --- a/packages/http-client-python/package-lock.json +++ b/packages/http-client-python/package-lock.json @@ -17,7 +17,7 @@ "tsx": "~4.19.1" }, "devDependencies": { - "@azure-tools/azure-http-specs": "0.1.0-alpha.36", + "@azure-tools/azure-http-specs": "0.1.0-alpha.37-dev.1", "@azure-tools/typespec-autorest": "~0.64.1", "@azure-tools/typespec-azure-core": "~0.64.0", "@azure-tools/typespec-azure-resource-manager": "~0.64.1", @@ -29,7 +29,7 @@ "@typespec/compiler": "^1.8.0", "@typespec/events": "~0.78.0", "@typespec/http": "^1.8.0", - "@typespec/http-specs": "0.1.0-alpha.32-dev.1", + "@typespec/http-specs": "0.1.0-alpha.32-dev.5", "@typespec/openapi": "^1.8.0", "@typespec/rest": "~0.78.0", "@typespec/spec-api": "0.1.0-alpha.12", @@ -66,25 +66,25 @@ } }, "node_modules/@azure-tools/azure-http-specs": { - "version": "0.1.0-alpha.36", - "resolved": "https://registry.npmjs.org/@azure-tools/azure-http-specs/-/azure-http-specs-0.1.0-alpha.36.tgz", - "integrity": "sha512-tn6qiiTA+ToLmOqj4CSJNAbeuSUj6hIRiXzDhR8b7jilFLnXQ2MYKnJNnjL2O/CDd0utWUqg/2kNlQitSLnxmA==", + "version": "0.1.0-alpha.37-dev.1", + "resolved": "https://registry.npmjs.org/@azure-tools/azure-http-specs/-/azure-http-specs-0.1.0-alpha.37-dev.1.tgz", + "integrity": "sha512-lGu4bBoN8ghpHWUwRJK2auHcY+AUpPkcVbD18Z06FBi66vR8m7e0dczOl40YpUKUlbjlGjZon9QT2iSp9hKoWA==", "dev": true, "license": "MIT", "dependencies": { - "@typespec/spec-api": "^0.1.0-alpha.12", - "@typespec/spector": "^0.1.0-alpha.22" + "@typespec/spec-api": "^0.1.0-alpha.12 || >=0.1.0-alpha.13-dev <0.1.0-alpha.13", + "@typespec/spector": "^0.1.0-alpha.22 || >=0.1.0-alpha.23-dev <0.1.0-alpha.23" }, "engines": { "node": ">=20.0.0" }, "peerDependencies": { - "@azure-tools/typespec-azure-core": "^0.64.0", + "@azure-tools/typespec-azure-core": "^0.64.0 || >=0.65.0-dev <0.65.0", "@typespec/compiler": "^1.8.0", "@typespec/http": "^1.8.0", - "@typespec/rest": "^0.78.0", - "@typespec/versioning": "^0.78.0", - "@typespec/xml": "^0.78.0" + "@typespec/rest": "^0.78.0 || >=0.79.0-dev <0.79.0", + "@typespec/versioning": "^0.78.0 || >=0.79.0-dev <0.79.0", + "@typespec/xml": "^0.78.0 || >=0.79.0-dev <0.79.0" } }, "node_modules/@azure-tools/typespec-autorest": { @@ -2318,9 +2318,9 @@ } }, "node_modules/@typespec/http-specs": { - "version": "0.1.0-alpha.32-dev.1", - "resolved": "https://registry.npmjs.org/@typespec/http-specs/-/http-specs-0.1.0-alpha.32-dev.1.tgz", - "integrity": "sha512-b+uzFhToERrmV154eqnCoQiw4Jekn+DRamfZVAl7ndVeayDq9zLNZyPnCmeU1+bdKxUGO8WoGkpA9BeGP3teeA==", + "version": "0.1.0-alpha.32-dev.5", + "resolved": "https://registry.npmjs.org/@typespec/http-specs/-/http-specs-0.1.0-alpha.32-dev.5.tgz", + "integrity": "sha512-MD1nWHuste79REtadDyPGTTAZwgGCGD/kB9K8zNX2nTTbAMiWzUTBhpztZtQ+A08G3Snn1ZwSFy4OTyYkHCg6g==", "dev": true, "license": "MIT", "dependencies": { diff --git a/packages/http-client-python/package.json b/packages/http-client-python/package.json index 2e0ea438167..081ffab2d4e 100644 --- a/packages/http-client-python/package.json +++ b/packages/http-client-python/package.json @@ -82,7 +82,7 @@ "@azure-tools/typespec-azure-resource-manager": "~0.64.1", "@azure-tools/typespec-azure-rulesets": "~0.64.0", "@azure-tools/typespec-client-generator-core": "~0.64.6", - "@azure-tools/azure-http-specs": "0.1.0-alpha.36", + "@azure-tools/azure-http-specs": "0.1.0-alpha.37-dev.1", "@typespec/compiler": "^1.8.0", "@typespec/http": "^1.8.0", "@typespec/openapi": "^1.8.0", @@ -94,7 +94,7 @@ "@typespec/sse": "~0.78.0", "@typespec/streams": "~0.78.0", "@typespec/xml": "~0.78.0", - "@typespec/http-specs": "0.1.0-alpha.32-dev.1", + "@typespec/http-specs": "0.1.0-alpha.32-dev.5", "@types/js-yaml": "~4.0.5", "@types/node": "~24.1.0", "@types/semver": "7.5.8",