Skip to content
Draft
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: feature
packages:
- "@typespec/http-client-python"
---

Add mock API test coverage for `@encode(string)` on boolean properties (`encode/boolean` Spector scenarios). Fix Python generator to correctly serialize and deserialize boolean values encoded as strings (case-insensitive `true`/`false`).
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ export const AZURE_EMITTER_OPTIONS: Record<
"client/overload": {
namespace: "client.overload",
},
"encode/boolean": {
namespace: "encode.boolean",
},
"encode/duration": {
namespace: "encode.duration",
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ def default_template_representation_declaration(self) -> str:


class BooleanType(PrimitiveType):
def __init__(self, yaml_data: dict[str, Any], code_model: "CodeModel") -> None:
super().__init__(yaml_data=yaml_data, code_model=code_model)
if yaml_data.get("encode") == "string":
self.encode = "str"

def serialization_type(self, **kwargs: Any) -> str:
return "bool"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,12 @@ def _deserialize_int_as_str(attr):
return int(attr)


def _deserialize_bool_as_str(attr):
if isinstance(attr, bool):
return attr
return attr.lower() == "true"


_DESERIALIZE_MAPPING = {
datetime: _deserialize_datetime,
date: _deserialize_date,
Expand Down Expand Up @@ -375,6 +381,8 @@ _DESERIALIZE_MAPPING_WITHFORMAT = {
def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = None):
if annotation is int and rf and rf._format == "str":
return _deserialize_int_as_str
if annotation is bool and rf and rf._format == "str":
return _deserialize_bool_as_str
if annotation is str and rf and rf._format in _ARRAY_ENCODE_MAPPING:
return functools.partial(_deserialize_array_encoded, _ARRAY_ENCODE_MAPPING[rf._format])
if rf and rf._format:
Expand Down
14 changes: 7 additions & 7 deletions packages/http-client-python/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/http-client-python/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@
"@typespec/sse": "~0.83.0",
"@typespec/streams": "~0.83.0",
"@typespec/xml": "~0.83.0",
"@typespec/http-specs": "0.1.0-alpha.39-dev.2",
"@typespec/http-specs": "0.1.0-alpha.39-dev.4",
"@types/js-yaml": "~4.0.5",
"@types/node": "~25.0.2",
"@types/semver": "7.5.8",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------
import pytest
import pytest_asyncio
from encode.boolean.aio import BooleanClient
from encode.boolean import models


@pytest_asyncio.fixture
async def client():
async with BooleanClient() as client:
yield client


@pytest.mark.asyncio
async def test_property_true_lower(client: BooleanClient):
result = await client.property.true_lower(models.BoolAsStringProperty(value=True))
assert result.value is True
assert result["value"] == "true"


@pytest.mark.asyncio
async def test_property_false_lower(client: BooleanClient):
result = await client.property.false_lower(models.BoolAsStringProperty(value=False))
assert result.value is False
assert result["value"] == "false"


@pytest.mark.asyncio
async def test_property_true_upper(client: BooleanClient):
result = await client.property.true_upper(models.BoolAsStringProperty(value=True))
assert result.value is True
assert result["value"] == "TRUE"


@pytest.mark.asyncio
async def test_property_false_mixed(client: BooleanClient):
result = await client.property.false_mixed(models.BoolAsStringProperty(value=False))
assert result.value is False
assert result["value"] == "FaLsE"
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# -------------------------------------------------------------------------
# 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 encode.boolean import BooleanClient, models


@pytest.fixture
def client():
with BooleanClient() as client:
yield client


def test_property_true_lower(client: BooleanClient):
result = client.property.true_lower(models.BoolAsStringProperty(value=True))
assert result.value is True
assert result["value"] == "true"


def test_property_false_lower(client: BooleanClient):
result = client.property.false_lower(models.BoolAsStringProperty(value=False))
assert result.value is False
assert result["value"] == "false"


def test_property_true_upper(client: BooleanClient):
result = client.property.true_upper(models.BoolAsStringProperty(value=True))
assert result.value is True
assert result["value"] == "TRUE"


def test_property_false_mixed(client: BooleanClient):
result = client.property.false_mixed(models.BoolAsStringProperty(value=False))
assert result.value is False
assert result["value"] == "FaLsE"
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------
import pytest
import pytest_asyncio
from encode.boolean.aio import BooleanClient
from encode.boolean.property import models


@pytest_asyncio.fixture
async def client():
async with BooleanClient() as client:
yield client


@pytest.mark.asyncio
async def test_property_true_lower(client: BooleanClient):
result = await client.property.true_lower(models.BoolAsStringProperty(value=True))
assert result.value is True
assert result["value"] == "true"


@pytest.mark.asyncio
async def test_property_false_lower(client: BooleanClient):
result = await client.property.false_lower(models.BoolAsStringProperty(value=False))
assert result.value is False
assert result["value"] == "false"


@pytest.mark.asyncio
async def test_property_true_upper(client: BooleanClient):
result = await client.property.true_upper(models.BoolAsStringProperty(value=True))
assert result.value is True
assert result["value"] == "TRUE"


@pytest.mark.asyncio
async def test_property_false_mixed(client: BooleanClient):
result = await client.property.false_mixed(models.BoolAsStringProperty(value=False))
assert result.value is False
assert result["value"] == "FaLsE"
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# -------------------------------------------------------------------------
# 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 encode.boolean import BooleanClient
from encode.boolean.property import models


@pytest.fixture
def client():
with BooleanClient() as client:
yield client


def test_property_true_lower(client: BooleanClient):
result = client.property.true_lower(models.BoolAsStringProperty(value=True))
assert result.value is True
assert result["value"] == "true"


def test_property_false_lower(client: BooleanClient):
result = client.property.false_lower(models.BoolAsStringProperty(value=False))
assert result.value is False
assert result["value"] == "false"


def test_property_true_upper(client: BooleanClient):
result = client.property.true_upper(models.BoolAsStringProperty(value=True))
assert result.value is True
assert result["value"] == "TRUE"


def test_property_false_mixed(client: BooleanClient):
result = client.property.false_mixed(models.BoolAsStringProperty(value=False))
assert result.value is False
assert result["value"] == "FaLsE"
Loading