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: 4 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
- Only generate Python3 SDKs #1297
- Don't reformat initial query parameters into the next link #1297

**Breaking Changes in Version Tolerant**

- Don't generate operations with more than two body types. SDK authors need to implement this operation themselves #1300

### 2022-07-13 - 5.19.0

| Library | Min Version |
Expand Down
19 changes: 15 additions & 4 deletions autorest/codegen/models/base_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------
import logging
from abc import abstractmethod
from typing import Any, Dict, List, Optional, TypeVar, Union, TYPE_CHECKING, Generic
from .base_model import BaseModel
Expand All @@ -27,6 +28,8 @@
from .operation import Operation
from .request_builder import RequestBuilder

_LOGGER = logging.getLogger(__name__)


class BaseBuilder(Generic[ParameterListType], BaseModel):
"""Base class for Operations and Request Builders"""
Expand All @@ -39,7 +42,6 @@ def __init__(
parameters: ParameterListType,
*,
overloads=None,
abstract: bool = False,
want_tracing: bool = True,
) -> None:
super().__init__(yaml_data=yaml_data, code_model=code_model)
Expand All @@ -50,14 +52,23 @@ def __init__(
overloads or []
)
self._summary: str = yaml_data.get("summary", "")
# for operations where we don't know what to do, we mark them as abstract so users implement
# in patch.py
self.abstract = abstract
self.want_tracing = want_tracing
self.group_name: str = yaml_data["groupName"]
self.is_overload: bool = yaml_data["isOverload"]
self.api_versions: List[str] = yaml_data["apiVersions"]

if code_model.options["version_tolerant"] and yaml_data.get("abstract"):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

basically moved abstract marking code to m4reformatter, and moved the warning to base builder. This centralizes our code more

_LOGGER.warning(
'Not going to generate operation "%s" because we are unable to generate this '
"type of operation right now. "
'Please write your own custom operation in the "_patch.py" file '
"following https://aka.ms/azsdk/python/dpcodegen/python/customize",
name,
)
self.abstract = True
else:
self.abstract = False

@property
def summary(self) -> Optional[str]:
if self.abstract:
Expand Down
2 changes: 0 additions & 2 deletions autorest/codegen/models/lro_operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ def __init__(
overloads: Optional[List[Operation]] = None,
public: bool = True,
want_tracing: bool = True,
abstract: bool = False,
) -> None:
super().__init__(
code_model=code_model,
Expand All @@ -46,7 +45,6 @@ def __init__(
overloads=overloads,
public=public,
want_tracing=want_tracing,
abstract=abstract,
)
self.name = "begin_" + self.name
self.lro_options: Dict[str, Any] = self.yaml_data.get("lroOptions", {})
Expand Down
20 changes: 0 additions & 20 deletions autorest/codegen/models/operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------
import logging
from itertools import chain
from typing import (
Dict,
Expand Down Expand Up @@ -43,8 +42,6 @@
if TYPE_CHECKING:
from .code_model import CodeModel

_LOGGER = logging.getLogger(__name__)

ResponseType = TypeVar(
"ResponseType",
bound=Union[Response, PagingResponse, LROResponse, LROPagingResponse],
Expand All @@ -67,15 +64,13 @@ def __init__(
overloads: Optional[List["Operation"]] = None,
public: bool = True,
want_tracing: bool = True,
abstract: bool = False,
) -> None:
super().__init__(
code_model=code_model,
yaml_data=yaml_data,
name=name,
parameters=parameters,
overloads=overloads,
abstract=abstract,
want_tracing=want_tracing,
)
self.overloads: List["Operation"] = overloads or []
Expand Down Expand Up @@ -429,20 +424,6 @@ def from_yaml(cls, yaml_data: Dict[str, Any], code_model: "CodeModel"):
cls.from_yaml(overload, code_model)
for overload in yaml_data.get("overloads", [])
]
abstract = False
if (
code_model.options["version_tolerant"]
and parameter_list.has_body
and isinstance(parameter_list.body_parameter, MultipartBodyParameter)
):
_LOGGER.warning(
'Not going to generate operation "%s" because it has multipart / urlencoded body parameters. '
"Multipart / urlencoded body parameters are not supported for version tolerant generation right now. "
'Please write your own custom operation in the "_patch.py" file '
"following https://aka.ms/azsdk/python/dpcodegen/python/customize",
name,
)
abstract = True

return cls(
yaml_data=yaml_data,
Expand All @@ -454,7 +435,6 @@ def from_yaml(cls, yaml_data: Dict[str, Any], code_model: "CodeModel"):
responses=responses,
exceptions=exceptions,
want_tracing=not yaml_data["isOverload"],
abstract=abstract,
)


Expand Down
2 changes: 0 additions & 2 deletions autorest/codegen/models/paging_operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ def __init__(
overloads: Optional[List[Operation]] = None,
public: bool = True,
want_tracing: bool = True,
abstract: bool = False,
override_success_response_to_200: bool = False,
) -> None:
super().__init__(
Expand All @@ -52,7 +51,6 @@ def __init__(
overloads=overloads,
public=public,
want_tracing=want_tracing,
abstract=abstract,
)
self.next_request_builder: Optional[
Union[RequestBuilder, OverloadedRequestBuilder]
Expand Down
22 changes: 0 additions & 22 deletions autorest/codegen/models/request_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------
import logging
from typing import (
Any,
Callable,
Expand All @@ -22,12 +21,10 @@
OverloadedRequestBuilderParameterList,
)
from .imports import FileImport, ImportType, TypingSection, MsrestImportType
from .request_builder_parameter import RequestBuilderMultipartBodyParameter

if TYPE_CHECKING:
from .code_model import CodeModel

_LOGGER = logging.getLogger(__name__)
ParameterListType = TypeVar(
"ParameterListType",
bound=Union[RequestBuilderParameterList, OverloadedRequestBuilderParameterList],
Expand All @@ -43,15 +40,13 @@ def __init__(
parameters: ParameterListType,
*,
overloads: Optional[List["RequestBuilder"]] = None,
abstract: bool = False,
) -> None:
super().__init__(
code_model=code_model,
yaml_data=yaml_data,
name=name,
parameters=parameters,
overloads=overloads,
abstract=abstract,
want_tracing=False,
)
self.overloads: List["RequestBuilder"] = overloads or []
Expand Down Expand Up @@ -147,31 +142,14 @@ def from_yaml(cls, yaml_data: Dict[str, Any], code_model: "CodeModel"):
RequestBuilder.from_yaml(rb_yaml_data, code_model)
for rb_yaml_data in yaml_data.get("overloads", [])
]
abstract = False
parameter_list = cls.parameter_list_type()(yaml_data, code_model)
if (
code_model.options["version_tolerant"]
and parameter_list.has_body
and isinstance(
parameter_list.body_parameter, RequestBuilderMultipartBodyParameter
)
):
_LOGGER.warning(
'Not going to generate operation "%s" because it has multipart / urlencoded body parameters. '
"Multipart / urlencoded body parameters are not supported for version tolerant generation right now. "
'Please write your own custom operation in the "_patch.py" file '
"following https://aka.ms/azsdk/python/dpcodegen/python/customize",
name,
)
abstract = True

return cls(
yaml_data=yaml_data,
code_model=code_model,
name=name,
parameters=parameter_list,
overloads=overloads,
abstract=abstract,
)


Expand Down
5 changes: 5 additions & 0 deletions autorest/codegen/serializers/builder_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -825,10 +825,15 @@ def _create_request_builder_call(
f" {parameter.client_name}={parameter.name_in_high_level_operation},"
)
if request_builder.overloads:
seen_body_params = set()
for overload in request_builder.overloads:
body_param = cast(
RequestBuilderBodyParameter, overload.parameters.body_parameter
)
if body_param.client_name in seen_body_params:
continue
seen_body_params.add(body_param.client_name)

retval.append(
f" {body_param.client_name}={body_param.name_in_high_level_operation},"
)
Expand Down
8 changes: 8 additions & 0 deletions autorest/m4reformatter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,13 @@ def _update_operation_helper(
in_overriden = (
body_parameter["type"]["type"] == "combined" if body_parameter else False
)
abstract = False
if body_parameter and (
body_parameter.get("entries")
or len(body_parameter["type"].get("types", [])) > 2
):
# this means it's formdata or urlencoded, or there are more than 2 types of body
abstract = True
return {
"name": yaml_data["language"]["default"]["name"],
"description": yaml_data["language"]["default"]["description"],
Expand All @@ -520,6 +527,7 @@ def _update_operation_helper(
"discriminator": "operation",
"isOverload": is_overload,
"apiVersions": _get_api_versions(yaml_data.get("apiVersions", [])),
"abstract": abstract,
}

def get_operation_creator(
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"@autorest/system-requirements": "~1.0.0"
},
"devDependencies": {
"@microsoft.azure/autorest.testserver": "^3.3.28"
"@microsoft.azure/autorest.testserver": "^3.3.29"
},
"files": [
"autorest/**/*.py",
Expand Down
3 changes: 2 additions & 1 deletion test/unittests/test_optional_return_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ def code_model():
}},
options={
"show_send_request": True,
"builders_visibility": "public"
"builders_visibility": "public",
"version_tolerant": True
},
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,11 @@ async def test_binary_body_three_content_types(self, client):

content = "hello, world"
await client.binary_body_with_three_content_types(content, content_type="text/plain")

@pytest.mark.asyncio
async def test_body_three_types(self, client):
json_input = {"hello":"world"}
await client.body_three_types(json_input)

content = b"hello, world"
await client.body_three_types(content)
7 changes: 7 additions & 0 deletions test/vanilla/legacy/AcceptanceTests/test_media_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ def test_binary_body_three_content_types(self, client):
content = "hello, world"
client.binary_body_with_three_content_types(content, content_type="text/plain")

def test_body_three_types(self, client):
json_input = {"hello":"world"}
client.body_three_types(json_input)

content = b"hello, world"
client.body_three_types(content)

def test_models(self):
from mediatypes.models import SourcePath

Expand Down
Loading