diff --git a/ChangeLog.md b/ChangeLog.md index 59741b8798..bfc380b19f 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,13 +1,14 @@ # Change Log -### 2021-07-06 - 5.8.4 +### 2021-07-13 - 5.8.4 -min Autorest core version: 3.3.0 +min Autorest core version: 3.4.5 min Modelerfour version: 4.19.1 **Bug Fixes** +- Fix case where we have a grouped parameter whose name is a reserved property name #970 - Remove all hosts from global parameters, regardless of how many m4 sends us #972 ### 2021-07-06 - 5.8.3 diff --git a/README.md b/README.md index 22b6aa1cc6..a14312a041 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ modelerfour: pass-thru: - model-deduplicator - subset-reducer -version: ~3.3.0 +version: ~3.4.5 use-extension: "@autorest/modelerfour": ~4.19.1 diff --git a/autorest/codegen/models/parameter.py b/autorest/codegen/models/parameter.py index 60863c7c35..b6ce8a87f1 100644 --- a/autorest/codegen/models/parameter.py +++ b/autorest/codegen/models/parameter.py @@ -5,13 +5,15 @@ # -------------------------------------------------------------------------- from enum import Enum import logging -from typing import Dict, Optional, List, Any, Union, Tuple +from typing import Dict, Optional, List, Any, Union, Tuple, cast from .imports import FileImport, ImportType, TypingSection from .base_model import BaseModel from .base_schema import BaseSchema from .list_schema import ListSchema from .constant_schema import ConstantSchema +from .object_schema import ObjectSchema +from .property import Property _LOGGER = logging.getLogger(__name__) @@ -171,6 +173,18 @@ def in_method_signature(self) -> bool: or self.is_kwarg ) + @property + def corresponding_grouped_property(self) -> Property: + if not self.grouped_by: + raise ValueError("Should only be calling if your parameter is grouped") + try: + return next( + p for p in cast(ObjectSchema, self.grouped_by.schema).properties + if any(op for op in p.yaml_data['originalParameter'] if id(op) == self.id) + ) + except StopIteration: + raise ValueError("There is not a corresponding grouped property for your parameter.") + @property def in_method_code(self) -> bool: return not (self.constant and self.location == ParameterLocation.Other) diff --git a/autorest/codegen/templates/operation_tools.jinja2 b/autorest/codegen/templates/operation_tools.jinja2 index 46b9764b44..dea43a108d 100644 --- a/autorest/codegen/templates/operation_tools.jinja2 +++ b/autorest/codegen/templates/operation_tools.jinja2 @@ -90,7 +90,7 @@ deserialized = self._deserialize('{{ response.serialization_type }}', pipeline_r {% for grouper_name, grouped_parameters in operation.parameters.grouped|groupby("grouped_by.serialized_name") %} if {{ grouper_name }} is not None: {% for grouped_parameter in grouped_parameters %} - {{ grouped_parameter.serialized_name }} = {{ grouper_name }}.{{ grouped_parameter.serialized_name.lstrip('_') }} + {{ grouped_parameter.serialized_name }} = {{ grouper_name }}.{{ grouped_parameter.corresponding_grouped_property.name }} {% endfor %} {% endfor %} {% endif %} diff --git a/package.json b/package.json index e6da4331f7..ed78217c24 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ }, "devDependencies": { "@autorest/autorest": "^3.0.0", - "@microsoft.azure/autorest.testserver": "^3.0.26" + "@microsoft.azure/autorest.testserver": "^3.0.27" }, "files": [ "autorest/**/*.py", diff --git a/test/azure/AcceptanceTests/asynctests/test_parameter.py b/test/azure/AcceptanceTests/asynctests/test_parameter.py index d00ba2d004..4465c714a8 100644 --- a/test/azure/AcceptanceTests/asynctests/test_parameter.py +++ b/test/azure/AcceptanceTests/asynctests/test_parameter.py @@ -150,6 +150,15 @@ async def test_post_shared_parameter_group_object(self, client, header_parameter first_group = FirstParameterGroup(header_one = header_parameter) await client.parameter_grouping.post_shared_parameter_group_object(first_group) + @pytest.mark.asyncio + async def test_post_reserved_words(self, client): + from azureparametergrouping.models import ParameterGroupingPostReservedWordsParameters + group = ParameterGroupingPostReservedWordsParameters( + from_property="bob", + accept="yes" + ) + await client.parameter_grouping.post_reserved_words(group) + @pytest.mark.asyncio async def test_subscription_in_credentials(self, azure_client): # valid_api_version = '2.0' diff --git a/test/azure/AcceptanceTests/test_parameter.py b/test/azure/AcceptanceTests/test_parameter.py index f305c174c9..bdbd38d4a1 100644 --- a/test/azure/AcceptanceTests/test_parameter.py +++ b/test/azure/AcceptanceTests/test_parameter.py @@ -139,6 +139,14 @@ def test_post_shared_parameter_group_object(self, client, header_parameter): first_group = FirstParameterGroup(header_one = header_parameter) client.parameter_grouping.post_shared_parameter_group_object(first_group) + def test_post_reserved_words(self, client): + from azureparametergrouping.models import ParameterGroupingPostReservedWordsParameters + group = ParameterGroupingPostReservedWordsParameters( + from_property="bob", + accept="yes" + ) + client.parameter_grouping.post_reserved_words(group) + def test_subscription_in_credentials(self, azure_client): # valid_api_version = '2.0' azure_client.subscription_in_credentials.post_method_global_not_provided_valid() diff --git a/test/azure/Expected/AcceptanceTests/AzureParameterGrouping/azureparametergrouping/aio/operations/_parameter_grouping_operations.py b/test/azure/Expected/AcceptanceTests/AzureParameterGrouping/azureparametergrouping/aio/operations/_parameter_grouping_operations.py index 23ab16e2ed..4440aa99b7 100644 --- a/test/azure/Expected/AcceptanceTests/AzureParameterGrouping/azureparametergrouping/aio/operations/_parameter_grouping_operations.py +++ b/test/azure/Expected/AcceptanceTests/AzureParameterGrouping/azureparametergrouping/aio/operations/_parameter_grouping_operations.py @@ -168,6 +168,62 @@ async def post_optional( post_optional.metadata = {"url": "/parameterGrouping/postOptional"} # type: ignore + @distributed_trace_async + async def post_reserved_words( + self, + parameter_grouping_post_reserved_words_parameters: Optional[ + "_models.ParameterGroupingPostReservedWordsParameters" + ] = None, + **kwargs: Any + ) -> None: + """Post a grouped parameters with reserved words. + + :param parameter_grouping_post_reserved_words_parameters: Parameter group. + :type parameter_grouping_post_reserved_words_parameters: ~azureparametergrouping.models.ParameterGroupingPostReservedWordsParameters + :keyword callable cls: A custom type or function that will be passed the direct response + :return: None, or the result of cls(response) + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop("cls", None) # type: ClsType[None] + error_map = {401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError} + error_map.update(kwargs.pop("error_map", {})) + + _from = None + _accept = None + if parameter_grouping_post_reserved_words_parameters is not None: + _from = parameter_grouping_post_reserved_words_parameters.from_property + _accept = parameter_grouping_post_reserved_words_parameters.accept + accept = "application/json" + + # Construct URL + url = self.post_reserved_words.metadata["url"] # type: ignore + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + if _from is not None: + query_parameters["from"] = self._serialize.query("from", _from, "str") + if _accept is not None: + query_parameters["accept"] = self._serialize.query("accept", _accept, "str") + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters["Accept"] = self._serialize.header("accept", accept, "str") + + request = self._client.post(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize.failsafe_deserialize(_models.Error, response) + raise HttpResponseError(response=response, model=error) + + if cls: + return cls(pipeline_response, None, {}) + + post_reserved_words.metadata = {"url": "/parameterGrouping/postReservedWords"} # type: ignore + @distributed_trace_async async def post_multi_param_groups( self, diff --git a/test/azure/Expected/AcceptanceTests/AzureParameterGrouping/azureparametergrouping/models/__init__.py b/test/azure/Expected/AcceptanceTests/AzureParameterGrouping/azureparametergrouping/models/__init__.py index 09db761ce7..b334a96146 100644 --- a/test/azure/Expected/AcceptanceTests/AzureParameterGrouping/azureparametergrouping/models/__init__.py +++ b/test/azure/Expected/AcceptanceTests/AzureParameterGrouping/azureparametergrouping/models/__init__.py @@ -12,12 +12,14 @@ from ._models_py3 import ParameterGroupingPostMultiParamGroupsSecondParamGroup from ._models_py3 import ParameterGroupingPostOptionalParameters from ._models_py3 import ParameterGroupingPostRequiredParameters + from ._models_py3 import ParameterGroupingPostReservedWordsParameters except (SyntaxError, ImportError): from ._models import Error # type: ignore from ._models import FirstParameterGroup # type: ignore from ._models import ParameterGroupingPostMultiParamGroupsSecondParamGroup # type: ignore from ._models import ParameterGroupingPostOptionalParameters # type: ignore from ._models import ParameterGroupingPostRequiredParameters # type: ignore + from ._models import ParameterGroupingPostReservedWordsParameters # type: ignore __all__ = [ "Error", @@ -25,4 +27,5 @@ "ParameterGroupingPostMultiParamGroupsSecondParamGroup", "ParameterGroupingPostOptionalParameters", "ParameterGroupingPostRequiredParameters", + "ParameterGroupingPostReservedWordsParameters", ] diff --git a/test/azure/Expected/AcceptanceTests/AzureParameterGrouping/azureparametergrouping/models/_models.py b/test/azure/Expected/AcceptanceTests/AzureParameterGrouping/azureparametergrouping/models/_models.py index 603a2ea6b0..2eefe40396 100644 --- a/test/azure/Expected/AcceptanceTests/AzureParameterGrouping/azureparametergrouping/models/_models.py +++ b/test/azure/Expected/AcceptanceTests/AzureParameterGrouping/azureparametergrouping/models/_models.py @@ -123,3 +123,23 @@ def __init__(self, **kwargs): self.query = kwargs.get("query", 30) self.path = kwargs["path"] self.body = kwargs["body"] + + +class ParameterGroupingPostReservedWordsParameters(msrest.serialization.Model): + """Parameter group. + + :param from_property: 'from' is a reserved word. Pass in 'bob' to pass. + :type from_property: str + :param accept: 'accept' is a reserved word. Pass in 'yes' to pass. + :type accept: str + """ + + _attribute_map = { + "from_property": {"key": "from", "type": "str"}, + "accept": {"key": "accept", "type": "str"}, + } + + def __init__(self, **kwargs): + super(ParameterGroupingPostReservedWordsParameters, self).__init__(**kwargs) + self.from_property = kwargs.get("from_property", None) + self.accept = kwargs.get("accept", None) diff --git a/test/azure/Expected/AcceptanceTests/AzureParameterGrouping/azureparametergrouping/models/_models_py3.py b/test/azure/Expected/AcceptanceTests/AzureParameterGrouping/azureparametergrouping/models/_models_py3.py index 6d4b5652b8..b7fde76a42 100644 --- a/test/azure/Expected/AcceptanceTests/AzureParameterGrouping/azureparametergrouping/models/_models_py3.py +++ b/test/azure/Expected/AcceptanceTests/AzureParameterGrouping/azureparametergrouping/models/_models_py3.py @@ -127,3 +127,23 @@ def __init__( self.query = query self.path = path self.body = body + + +class ParameterGroupingPostReservedWordsParameters(msrest.serialization.Model): + """Parameter group. + + :param from_property: 'from' is a reserved word. Pass in 'bob' to pass. + :type from_property: str + :param accept: 'accept' is a reserved word. Pass in 'yes' to pass. + :type accept: str + """ + + _attribute_map = { + "from_property": {"key": "from", "type": "str"}, + "accept": {"key": "accept", "type": "str"}, + } + + def __init__(self, *, from_property: Optional[str] = None, accept: Optional[str] = None, **kwargs): + super(ParameterGroupingPostReservedWordsParameters, self).__init__(**kwargs) + self.from_property = from_property + self.accept = accept diff --git a/test/azure/Expected/AcceptanceTests/AzureParameterGrouping/azureparametergrouping/operations/_parameter_grouping_operations.py b/test/azure/Expected/AcceptanceTests/AzureParameterGrouping/azureparametergrouping/operations/_parameter_grouping_operations.py index 6527b4c94c..de8312488f 100644 --- a/test/azure/Expected/AcceptanceTests/AzureParameterGrouping/azureparametergrouping/operations/_parameter_grouping_operations.py +++ b/test/azure/Expected/AcceptanceTests/AzureParameterGrouping/azureparametergrouping/operations/_parameter_grouping_operations.py @@ -174,6 +174,61 @@ def post_optional( post_optional.metadata = {"url": "/parameterGrouping/postOptional"} # type: ignore + @distributed_trace + def post_reserved_words( + self, + parameter_grouping_post_reserved_words_parameters=None, # type: Optional["_models.ParameterGroupingPostReservedWordsParameters"] + **kwargs # type: Any + ): + # type: (...) -> None + """Post a grouped parameters with reserved words. + + :param parameter_grouping_post_reserved_words_parameters: Parameter group. + :type parameter_grouping_post_reserved_words_parameters: ~azureparametergrouping.models.ParameterGroupingPostReservedWordsParameters + :keyword callable cls: A custom type or function that will be passed the direct response + :return: None, or the result of cls(response) + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop("cls", None) # type: ClsType[None] + error_map = {401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError} + error_map.update(kwargs.pop("error_map", {})) + + _from = None + _accept = None + if parameter_grouping_post_reserved_words_parameters is not None: + _from = parameter_grouping_post_reserved_words_parameters.from_property + _accept = parameter_grouping_post_reserved_words_parameters.accept + accept = "application/json" + + # Construct URL + url = self.post_reserved_words.metadata["url"] # type: ignore + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + if _from is not None: + query_parameters["from"] = self._serialize.query("from", _from, "str") + if _accept is not None: + query_parameters["accept"] = self._serialize.query("accept", _accept, "str") + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters["Accept"] = self._serialize.header("accept", accept, "str") + + request = self._client.post(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = self._deserialize.failsafe_deserialize(_models.Error, response) + raise HttpResponseError(response=response, model=error) + + if cls: + return cls(pipeline_response, None, {}) + + post_reserved_words.metadata = {"url": "/parameterGrouping/postReservedWords"} # type: ignore + @distributed_trace def post_multi_param_groups( self,