diff --git a/packages/autorest.python/CHANGELOG.md b/packages/autorest.python/CHANGELOG.md index 613b53a2153..97cf5559ccd 100644 --- a/packages/autorest.python/CHANGELOG.md +++ b/packages/autorest.python/CHANGELOG.md @@ -1,5 +1,11 @@ # Release +## 6.35.3 + +### Bump dependencies + +- Regular release + ## 6.35.2 No changes, version bump only. diff --git a/packages/autorest.python/package.json b/packages/autorest.python/package.json index c1fa3adb6eb..fe8ce6599a2 100644 --- a/packages/autorest.python/package.json +++ b/packages/autorest.python/package.json @@ -1,6 +1,6 @@ { "name": "@autorest/python", - "version": "6.35.2", + "version": "6.35.3", "description": "The Python extension for generators in AutoRest.", "scripts": { "start": "node ./scripts/run-python3.js ./scripts/start.py", @@ -29,7 +29,7 @@ }, "homepage": "https://github.com/Azure/autorest.python/blob/main/README.md", "dependencies": { - "@typespec/http-client-python": "~0.12.2", + "@typespec/http-client-python": "~0.12.3", "@autorest/system-requirements": "~1.0.2", "fs-extra": "~11.2.0", "tsx": "~4.19.1" diff --git a/packages/typespec-python/CHANGELOG.md b/packages/typespec-python/CHANGELOG.md index 4feb490b853..5b958ae4be0 100644 --- a/packages/typespec-python/CHANGELOG.md +++ b/packages/typespec-python/CHANGELOG.md @@ -1,5 +1,13 @@ # Release +## 0.45.3 + +### Bump dependencies + +- [#3103](https://github.com/Azure/autorest.python/pull/3103) Add support for `validate-versioning` flag, so users can toggle whether they get api versioning validation +- [#3103](https://github.com/Azure/autorest.python/pull/3103) Validate api versions by looking at ordering of api versions from spec + + ## 0.45.2 No changes, version bump only. diff --git a/packages/typespec-python/package.json b/packages/typespec-python/package.json index 467838017d8..bb164b10ad2 100644 --- a/packages/typespec-python/package.json +++ b/packages/typespec-python/package.json @@ -1,6 +1,6 @@ { "name": "@azure-tools/typespec-python", - "version": "0.45.2", + "version": "0.45.3", "author": "Microsoft Corporation", "description": "TypeSpec emitter for Python SDKs", "homepage": "https://github.com/Azure/autorest.python", @@ -67,7 +67,7 @@ "js-yaml": "~4.1.0", "semver": "~7.6.2", "tsx": "~4.19.1", - "@typespec/http-client-python": "~0.12.2", + "@typespec/http-client-python": "~0.12.3", "fs-extra": "~11.2.0" }, "devDependencies": { diff --git a/packages/typespec-python/test/azure/generated/azure-payload-pageable/specs/azure/payload/pageable/_validation.py b/packages/typespec-python/test/azure/generated/azure-payload-pageable/specs/azure/payload/pageable/_validation.py index 752b2822f9d..f5af3a4eb8a 100644 --- a/packages/typespec-python/test/azure/generated/azure-payload-pageable/specs/azure/payload/pageable/_validation.py +++ b/packages/typespec-python/test/azure/generated/azure-payload-pageable/specs/azure/payload/pageable/_validation.py @@ -10,6 +10,22 @@ def api_version_validation(**kwargs): params_added_on = kwargs.pop("params_added_on", {}) method_added_on = kwargs.pop("method_added_on", "") + api_versions_list = kwargs.pop("api_versions_list", []) + + def _index_with_default(value: str, default: int = -1) -> int: + """Get the index of value in lst, or return default if not found. + + :param value: The value to search for in the api_versions_list. + :type value: str + :param default: The default value to return if the value is not found. + :type default: int + :return: The index of the value in the list, or the default value if not found. + :rtype: int + """ + try: + return api_versions_list.index(value) + except ValueError: + return default def decorator(func): @functools.wraps(func) @@ -21,7 +37,7 @@ def wrapper(*args, **kwargs): except AttributeError: return func(*args, **kwargs) - if method_added_on > client_api_version: + if _index_with_default(method_added_on) > _index_with_default(client_api_version): raise ValueError( f"'{func.__name__}' is not available in API version " f"{client_api_version}. Pass service API version {method_added_on} or newer to your client." @@ -31,7 +47,7 @@ def wrapper(*args, **kwargs): parameter: api_version for api_version, parameters in params_added_on.items() for parameter in parameters - if parameter in kwargs and api_version > client_api_version + if parameter in kwargs and _index_with_default(api_version) > _index_with_default(client_api_version) } if unsupported: raise ValueError( diff --git a/packages/typespec-python/test/azure/generated/resiliency-srv-driven2/resiliency/srv/driven2/_operations/_operations.py b/packages/typespec-python/test/azure/generated/resiliency-srv-driven2/resiliency/srv/driven2/_operations/_operations.py index b64a9559a99..e454bc2aa90 100644 --- a/packages/typespec-python/test/azure/generated/resiliency-srv-driven2/resiliency/srv/driven2/_operations/_operations.py +++ b/packages/typespec-python/test/azure/generated/resiliency-srv-driven2/resiliency/srv/driven2/_operations/_operations.py @@ -98,6 +98,7 @@ class ResiliencyServiceDrivenClientOperationsMixin( # pylint: disable=name-too- @distributed_trace @api_version_validation( method_added_on="v2", + api_versions_list=["v2"], ) def add_operation(self, **kwargs: Any) -> None: # pylint: disable=inconsistent-return-statements """Added operation. @@ -149,6 +150,7 @@ def add_operation(self, **kwargs: Any) -> None: # pylint: disable=inconsistent- @distributed_trace @api_version_validation( params_added_on={"v2": ["new_parameter"]}, + api_versions_list=["v1", "v2"], ) def from_none(self, *, new_parameter: Optional[str] = None, **kwargs: Any) -> bool: """Test that grew up from accepting no parameters to an optional input parameter. @@ -204,6 +206,7 @@ def from_none(self, *, new_parameter: Optional[str] = None, **kwargs: Any) -> bo @distributed_trace @api_version_validation( params_added_on={"v2": ["new_parameter"]}, + api_versions_list=["v1", "v2"], ) def from_one_required( # pylint: disable=inconsistent-return-statements self, *, parameter: str, new_parameter: Optional[str] = None, **kwargs: Any @@ -264,6 +267,7 @@ def from_one_required( # pylint: disable=inconsistent-return-statements @distributed_trace @api_version_validation( params_added_on={"v2": ["new_parameter"]}, + api_versions_list=["v1", "v2"], ) def from_one_optional( # pylint: disable=inconsistent-return-statements self, *, parameter: Optional[str] = None, new_parameter: Optional[str] = None, **kwargs: Any diff --git a/packages/typespec-python/test/azure/generated/resiliency-srv-driven2/resiliency/srv/driven2/_validation.py b/packages/typespec-python/test/azure/generated/resiliency-srv-driven2/resiliency/srv/driven2/_validation.py index 752b2822f9d..f5af3a4eb8a 100644 --- a/packages/typespec-python/test/azure/generated/resiliency-srv-driven2/resiliency/srv/driven2/_validation.py +++ b/packages/typespec-python/test/azure/generated/resiliency-srv-driven2/resiliency/srv/driven2/_validation.py @@ -10,6 +10,22 @@ def api_version_validation(**kwargs): params_added_on = kwargs.pop("params_added_on", {}) method_added_on = kwargs.pop("method_added_on", "") + api_versions_list = kwargs.pop("api_versions_list", []) + + def _index_with_default(value: str, default: int = -1) -> int: + """Get the index of value in lst, or return default if not found. + + :param value: The value to search for in the api_versions_list. + :type value: str + :param default: The default value to return if the value is not found. + :type default: int + :return: The index of the value in the list, or the default value if not found. + :rtype: int + """ + try: + return api_versions_list.index(value) + except ValueError: + return default def decorator(func): @functools.wraps(func) @@ -21,7 +37,7 @@ def wrapper(*args, **kwargs): except AttributeError: return func(*args, **kwargs) - if method_added_on > client_api_version: + if _index_with_default(method_added_on) > _index_with_default(client_api_version): raise ValueError( f"'{func.__name__}' is not available in API version " f"{client_api_version}. Pass service API version {method_added_on} or newer to your client." @@ -31,7 +47,7 @@ def wrapper(*args, **kwargs): parameter: api_version for api_version, parameters in params_added_on.items() for parameter in parameters - if parameter in kwargs and api_version > client_api_version + if parameter in kwargs and _index_with_default(api_version) > _index_with_default(client_api_version) } if unsupported: raise ValueError( diff --git a/packages/typespec-python/test/azure/generated/resiliency-srv-driven2/resiliency/srv/driven2/aio/_operations/_operations.py b/packages/typespec-python/test/azure/generated/resiliency-srv-driven2/resiliency/srv/driven2/aio/_operations/_operations.py index 634a062fd6b..26180854a94 100644 --- a/packages/typespec-python/test/azure/generated/resiliency-srv-driven2/resiliency/srv/driven2/aio/_operations/_operations.py +++ b/packages/typespec-python/test/azure/generated/resiliency-srv-driven2/resiliency/srv/driven2/aio/_operations/_operations.py @@ -43,6 +43,7 @@ class ResiliencyServiceDrivenClientOperationsMixin( # pylint: disable=name-too- @distributed_trace_async @api_version_validation( method_added_on="v2", + api_versions_list=["v2"], ) async def add_operation(self, **kwargs: Any) -> None: """Added operation. @@ -94,6 +95,7 @@ async def add_operation(self, **kwargs: Any) -> None: @distributed_trace_async @api_version_validation( params_added_on={"v2": ["new_parameter"]}, + api_versions_list=["v1", "v2"], ) async def from_none(self, *, new_parameter: Optional[str] = None, **kwargs: Any) -> bool: """Test that grew up from accepting no parameters to an optional input parameter. @@ -149,6 +151,7 @@ async def from_none(self, *, new_parameter: Optional[str] = None, **kwargs: Any) @distributed_trace_async @api_version_validation( params_added_on={"v2": ["new_parameter"]}, + api_versions_list=["v1", "v2"], ) async def from_one_required(self, *, parameter: str, new_parameter: Optional[str] = None, **kwargs: Any) -> None: """Operation that grew up from accepting one required parameter to accepting a required parameter @@ -207,6 +210,7 @@ async def from_one_required(self, *, parameter: str, new_parameter: Optional[str @distributed_trace_async @api_version_validation( params_added_on={"v2": ["new_parameter"]}, + api_versions_list=["v1", "v2"], ) async def from_one_optional( self, *, parameter: Optional[str] = None, new_parameter: Optional[str] = None, **kwargs: Any diff --git a/packages/typespec-python/test/azure/generated/versioning-added/versioning/added/_validation.py b/packages/typespec-python/test/azure/generated/versioning-added/versioning/added/_validation.py index 752b2822f9d..f5af3a4eb8a 100644 --- a/packages/typespec-python/test/azure/generated/versioning-added/versioning/added/_validation.py +++ b/packages/typespec-python/test/azure/generated/versioning-added/versioning/added/_validation.py @@ -10,6 +10,22 @@ def api_version_validation(**kwargs): params_added_on = kwargs.pop("params_added_on", {}) method_added_on = kwargs.pop("method_added_on", "") + api_versions_list = kwargs.pop("api_versions_list", []) + + def _index_with_default(value: str, default: int = -1) -> int: + """Get the index of value in lst, or return default if not found. + + :param value: The value to search for in the api_versions_list. + :type value: str + :param default: The default value to return if the value is not found. + :type default: int + :return: The index of the value in the list, or the default value if not found. + :rtype: int + """ + try: + return api_versions_list.index(value) + except ValueError: + return default def decorator(func): @functools.wraps(func) @@ -21,7 +37,7 @@ def wrapper(*args, **kwargs): except AttributeError: return func(*args, **kwargs) - if method_added_on > client_api_version: + if _index_with_default(method_added_on) > _index_with_default(client_api_version): raise ValueError( f"'{func.__name__}' is not available in API version " f"{client_api_version}. Pass service API version {method_added_on} or newer to your client." @@ -31,7 +47,7 @@ def wrapper(*args, **kwargs): parameter: api_version for api_version, parameters in params_added_on.items() for parameter in parameters - if parameter in kwargs and api_version > client_api_version + if parameter in kwargs and _index_with_default(api_version) > _index_with_default(client_api_version) } if unsupported: raise ValueError( diff --git a/packages/typespec-python/test/azure/generated/versioning-added/versioning/added/aio/operations/_operations.py b/packages/typespec-python/test/azure/generated/versioning-added/versioning/added/aio/operations/_operations.py index 7edcf3f99e1..68f935e55e4 100644 --- a/packages/typespec-python/test/azure/generated/versioning-added/versioning/added/aio/operations/_operations.py +++ b/packages/typespec-python/test/azure/generated/versioning-added/versioning/added/aio/operations/_operations.py @@ -113,6 +113,7 @@ async def v2_in_interface( @api_version_validation( method_added_on="v2", params_added_on={"v2": ["content_type", "accept"]}, + api_versions_list=["v2"], ) async def v2_in_interface(self, body: Union[_models.ModelV2, JSON, IO[bytes]], **kwargs: Any) -> _models.ModelV2: """v2_in_interface. @@ -244,6 +245,7 @@ async def v1( @distributed_trace_async @api_version_validation( params_added_on={"v2": ["header_v2"]}, + api_versions_list=["v1", "v2"], ) async def v1( self, body: Union[_models.ModelV1, JSON, IO[bytes]], *, header_v2: str, **kwargs: Any @@ -366,6 +368,7 @@ async def v2(self, body: IO[bytes], *, content_type: str = "application/json", * @api_version_validation( method_added_on="v2", params_added_on={"v2": ["content_type", "accept"]}, + api_versions_list=["v2"], ) async def v2(self, body: Union[_models.ModelV2, JSON, IO[bytes]], **kwargs: Any) -> _models.ModelV2: """v2. diff --git a/packages/typespec-python/test/azure/generated/versioning-added/versioning/added/operations/_operations.py b/packages/typespec-python/test/azure/generated/versioning-added/versioning/added/operations/_operations.py index db11f9b3456..c045852e337 100644 --- a/packages/typespec-python/test/azure/generated/versioning-added/versioning/added/operations/_operations.py +++ b/packages/typespec-python/test/azure/generated/versioning-added/versioning/added/operations/_operations.py @@ -160,6 +160,7 @@ def v2_in_interface( @api_version_validation( method_added_on="v2", params_added_on={"v2": ["content_type", "accept"]}, + api_versions_list=["v2"], ) def v2_in_interface(self, body: Union[_models.ModelV2, JSON, IO[bytes]], **kwargs: Any) -> _models.ModelV2: """v2_in_interface. @@ -289,6 +290,7 @@ def v1( @distributed_trace @api_version_validation( params_added_on={"v2": ["header_v2"]}, + api_versions_list=["v1", "v2"], ) def v1(self, body: Union[_models.ModelV1, JSON, IO[bytes]], *, header_v2: str, **kwargs: Any) -> _models.ModelV1: """v1. @@ -407,6 +409,7 @@ def v2(self, body: IO[bytes], *, content_type: str = "application/json", **kwarg @api_version_validation( method_added_on="v2", params_added_on={"v2": ["content_type", "accept"]}, + api_versions_list=["v2"], ) def v2(self, body: Union[_models.ModelV2, JSON, IO[bytes]], **kwargs: Any) -> _models.ModelV2: """v2. diff --git a/packages/typespec-python/test/unbranded/generated/versioning-added/versioning/added/_validation.py b/packages/typespec-python/test/unbranded/generated/versioning-added/versioning/added/_validation.py index 964148cf00e..0fda5b387eb 100644 --- a/packages/typespec-python/test/unbranded/generated/versioning-added/versioning/added/_validation.py +++ b/packages/typespec-python/test/unbranded/generated/versioning-added/versioning/added/_validation.py @@ -4,6 +4,22 @@ def api_version_validation(**kwargs): params_added_on = kwargs.pop("params_added_on", {}) method_added_on = kwargs.pop("method_added_on", "") + api_versions_list = kwargs.pop("api_versions_list", []) + + def _index_with_default(value: str, default: int = -1) -> int: + """Get the index of value in lst, or return default if not found. + + :param value: The value to search for in the api_versions_list. + :type value: str + :param default: The default value to return if the value is not found. + :type default: int + :return: The index of the value in the list, or the default value if not found. + :rtype: int + """ + try: + return api_versions_list.index(value) + except ValueError: + return default def decorator(func): @functools.wraps(func) @@ -15,7 +31,7 @@ def wrapper(*args, **kwargs): except AttributeError: return func(*args, **kwargs) - if method_added_on > client_api_version: + if _index_with_default(method_added_on) > _index_with_default(client_api_version): raise ValueError( f"'{func.__name__}' is not available in API version " f"{client_api_version}. Pass service API version {method_added_on} or newer to your client." @@ -25,7 +41,7 @@ def wrapper(*args, **kwargs): parameter: api_version for api_version, parameters in params_added_on.items() for parameter in parameters - if parameter in kwargs and api_version > client_api_version + if parameter in kwargs and _index_with_default(api_version) > _index_with_default(client_api_version) } if unsupported: raise ValueError( diff --git a/packages/typespec-python/test/unbranded/generated/versioning-added/versioning/added/aio/operations/_operations.py b/packages/typespec-python/test/unbranded/generated/versioning-added/versioning/added/aio/operations/_operations.py index 516a79fe7ea..cb9ac3da19f 100644 --- a/packages/typespec-python/test/unbranded/generated/versioning-added/versioning/added/aio/operations/_operations.py +++ b/packages/typespec-python/test/unbranded/generated/versioning-added/versioning/added/aio/operations/_operations.py @@ -104,6 +104,7 @@ async def v2_in_interface( @api_version_validation( method_added_on="v2", params_added_on={"v2": ["content_type", "accept"]}, + api_versions_list=["v2"], ) async def v2_in_interface(self, body: Union[_models.ModelV2, JSON, IO[bytes]], **kwargs: Any) -> _models.ModelV2: """v2_in_interface. @@ -232,6 +233,7 @@ async def v1( @api_version_validation( params_added_on={"v2": ["header_v2"]}, + api_versions_list=["v1", "v2"], ) async def v1( self, body: Union[_models.ModelV1, JSON, IO[bytes]], *, header_v2: str, **kwargs: Any @@ -353,6 +355,7 @@ async def v2(self, body: IO[bytes], *, content_type: str = "application/json", * @api_version_validation( method_added_on="v2", params_added_on={"v2": ["content_type", "accept"]}, + api_versions_list=["v2"], ) async def v2(self, body: Union[_models.ModelV2, JSON, IO[bytes]], **kwargs: Any) -> _models.ModelV2: """v2. diff --git a/packages/typespec-python/test/unbranded/generated/versioning-added/versioning/added/operations/_operations.py b/packages/typespec-python/test/unbranded/generated/versioning-added/versioning/added/operations/_operations.py index 8261ec2c41f..ec4ac7053ec 100644 --- a/packages/typespec-python/test/unbranded/generated/versioning-added/versioning/added/operations/_operations.py +++ b/packages/typespec-python/test/unbranded/generated/versioning-added/versioning/added/operations/_operations.py @@ -152,6 +152,7 @@ def v2_in_interface( @api_version_validation( method_added_on="v2", params_added_on={"v2": ["content_type", "accept"]}, + api_versions_list=["v2"], ) def v2_in_interface(self, body: Union[_models.ModelV2, JSON, IO[bytes]], **kwargs: Any) -> _models.ModelV2: """v2_in_interface. @@ -278,6 +279,7 @@ def v1( @api_version_validation( params_added_on={"v2": ["header_v2"]}, + api_versions_list=["v1", "v2"], ) def v1(self, body: Union[_models.ModelV1, JSON, IO[bytes]], *, header_v2: str, **kwargs: Any) -> _models.ModelV1: """v1. @@ -393,6 +395,7 @@ def v2(self, body: IO[bytes], *, content_type: str = "application/json", **kwarg @api_version_validation( method_added_on="v2", params_added_on={"v2": ["content_type", "accept"]}, + api_versions_list=["v2"], ) def v2(self, body: Union[_models.ModelV2, JSON, IO[bytes]], **kwargs: Any) -> _models.ModelV2: """v2. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fa5d2102154..0e858d1fba5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -60,8 +60,8 @@ importers: specifier: ~1.0.2 version: 1.0.2 '@typespec/http-client-python': - specifier: ~0.12.2 - version: 0.12.2(vtfeo5eqzs4rgrlyo4lexnsefm) + specifier: ~0.12.3 + version: 0.12.3(vtfeo5eqzs4rgrlyo4lexnsefm) fs-extra: specifier: ~11.2.0 version: 11.2.0 @@ -82,8 +82,8 @@ importers: packages/typespec-python: dependencies: '@typespec/http-client-python': - specifier: ~0.12.2 - version: 0.12.2(vtfeo5eqzs4rgrlyo4lexnsefm) + specifier: ~0.12.3 + version: 0.12.3(vtfeo5eqzs4rgrlyo4lexnsefm) fs-extra: specifier: ~11.2.0 version: 11.2.0 @@ -1684,8 +1684,8 @@ packages: peerDependencies: '@typespec/compiler': ^1.1.0 - '@typespec/http-client-python@0.12.2': - resolution: {integrity: sha512-GyYl/6wKUxZ2ZcG40sgHxmRZEnJScqpxtVTpz1TslQhdD3TphDYOhp19KnzsBCrfUb5xhgE1l3vECFu2iZQkeg==} + '@typespec/http-client-python@0.12.3': + resolution: {integrity: sha512-uKk/L1IpY/pUihARPOKfpqttreV0WLPN2edWiWi9VSsSJ+t3CTD2A4dWkM7TgJaJhQD2iLz3VtJhgsvYFW4NFw==} engines: {node: '>=20.0.0'} peerDependencies: '@azure-tools/typespec-autorest': '>=0.56.0 <1.0.0' @@ -6437,7 +6437,7 @@ snapshots: dependencies: '@typespec/compiler': 1.1.0(@types/node@22.13.17) - '@typespec/http-client-python@0.12.2(vtfeo5eqzs4rgrlyo4lexnsefm)': + '@typespec/http-client-python@0.12.3(vtfeo5eqzs4rgrlyo4lexnsefm)': dependencies: '@azure-tools/typespec-autorest': 0.57.0(wa525ucocerxeq5dfczkewujl4) '@azure-tools/typespec-azure-core': 0.57.0(@typespec/compiler@1.1.0(@types/node@22.13.17))(@typespec/http@1.1.0(@typespec/compiler@1.1.0(@types/node@22.13.17))(@typespec/streams@0.71.0(@typespec/compiler@1.1.0(@types/node@22.13.17))))(@typespec/rest@0.71.0(@typespec/compiler@1.1.0(@types/node@22.13.17))(@typespec/http@1.1.0(@typespec/compiler@1.1.0(@types/node@22.13.17))(@typespec/streams@0.71.0(@typespec/compiler@1.1.0(@types/node@22.13.17)))))