@typespec/http-client-python 0.9.1 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/emitter/emitter.d.ts.map +1 -1
  2. package/dist/emitter/emitter.js +1 -2
  3. package/dist/emitter/emitter.js.map +1 -1
  4. package/dist/emitter/run-python3.js +1 -1
  5. package/dist/emitter/utils.d.ts +0 -1
  6. package/dist/emitter/utils.d.ts.map +1 -1
  7. package/dist/emitter/utils.js +2 -6
  8. package/dist/emitter/utils.js.map +1 -1
  9. package/emitter/src/emitter.ts +1 -4
  10. package/emitter/src/run-python3.ts +1 -1
  11. package/emitter/src/utils.ts +2 -7
  12. package/emitter/temp/tsconfig.tsbuildinfo +1 -1
  13. package/eng/scripts/Build-Packages.ps1 +7 -5
  14. package/eng/scripts/ci/format.ts +1 -1
  15. package/eng/scripts/ci/mypy.ini +1 -1
  16. package/eng/scripts/ci/pylintrc +1 -1
  17. package/eng/scripts/ci/pyrightconfig.json +1 -1
  18. package/eng/scripts/ci/regenerate.ts +39 -3
  19. package/eng/scripts/ci/run-ci.ts +1 -0
  20. package/eng/scripts/ci/run_pylint.py +1 -1
  21. package/eng/scripts/ci/utils.ts +5 -3
  22. package/eng/scripts/setup/__pycache__/{venvtools.cpython-38.pyc → venvtools.cpython-39.pyc} +0 -0
  23. package/eng/scripts/setup/build_pygen_wheel.py +3 -3
  24. package/eng/scripts/setup/install.py +2 -2
  25. package/eng/scripts/setup/prepare.py +2 -2
  26. package/generator/build/lib/pygen/codegen/__init__.py +0 -1
  27. package/generator/build/lib/pygen/codegen/_utils.py +1 -1
  28. package/generator/build/lib/pygen/codegen/models/imports.py +2 -13
  29. package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +1 -3
  30. package/generator/build/lib/pygen/codegen/templates/model_base.py.jinja2 +9 -13
  31. package/generator/build/lib/pygen/codegen/templates/packaging_templates/README.md.jinja2 +2 -2
  32. package/generator/build/lib/pygen/codegen/templates/packaging_templates/setup.py.jinja2 +1 -2
  33. package/generator/component-detection-pip-report.json +70 -71
  34. package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
  35. package/generator/pygen/codegen/__init__.py +0 -1
  36. package/generator/pygen/codegen/_utils.py +1 -1
  37. package/generator/pygen/codegen/models/imports.py +2 -13
  38. package/generator/pygen/codegen/serializers/builder_serializer.py +1 -3
  39. package/generator/pygen/codegen/templates/model_base.py.jinja2 +9 -13
  40. package/generator/pygen/codegen/templates/packaging_templates/README.md.jinja2 +2 -2
  41. package/generator/pygen/codegen/templates/packaging_templates/setup.py.jinja2 +1 -2
  42. package/generator/pygen.egg-info/PKG-INFO +11 -2
  43. package/generator/setup.py +0 -1
  44. package/generator/test/generic_mock_api_tests/asynctests/test_encode_bytes_async.py +0 -7
  45. package/generator/test/generic_mock_api_tests/conftest.py +3 -3
  46. package/generator/test/generic_mock_api_tests/test_encode_bytes.py +0 -7
  47. package/generator/test/unittests/conftest.py +14 -0
  48. package/generator/test/unittests/requirements.txt +3 -0
  49. package/generator/test/unittests/test_enums.py +52 -0
  50. package/generator/test/unittests/test_name_converter.py +43 -0
  51. package/generator/test/unittests/test_optional_return_type.py +268 -0
  52. package/generator/test/unittests/test_parameter_ordering.py +104 -0
  53. package/generator/test/unittests/test_sort_schema.py +93 -0
  54. package/generator/test/unittests/tox.ini +5 -0
  55. package/package.json +1 -1
  56. /package/generator/test/{generic_mock_api_tests/data → data}/image.jpg +0 -0
  57. /package/generator/test/{generic_mock_api_tests/data → data}/image.png +0 -0
  58. /package/generator/test/{generic_mock_api_tests/unittests → unittests}/test_model_base_serialization.py +0 -0
  59. /package/generator/test/{generic_mock_api_tests/unittests → unittests}/test_model_base_xml_serialization.py +0 -0
@@ -18,6 +18,7 @@ import email.utils
18
18
  from datetime import datetime, date, time, timedelta, timezone
19
19
  from json import JSONEncoder
20
20
  import xml.etree.ElementTree as ET
21
+ from collections.abc import MutableMapping
21
22
  from typing_extensions import Self
22
23
  import isodate
23
24
  from {{ code_model.core_library }}.exceptions import DeserializationError
@@ -25,11 +26,6 @@ from {{ code_model.core_library }}{{ "" if code_model.is_azure_flavor else ".uti
25
26
  from {{ code_model.core_library }}.{{ "" if code_model.is_azure_flavor else "runtime." }}pipeline import PipelineResponse
26
27
  from {{ code_model.core_library }}.serialization import _Null
27
28
 
28
- if sys.version_info >= (3, 9):
29
- from collections.abc import MutableMapping
30
- else:
31
- from typing import MutableMapping
32
-
33
29
  _LOGGER = logging.getLogger(__name__)
34
30
 
35
31
  __all__ = ["SdkJSONEncoder", "Model", "rest_field", "rest_discriminator"]
@@ -344,7 +340,7 @@ def _get_model(module_name: str, model_name: str):
344
340
  _UNSET = object()
345
341
 
346
342
 
347
- class _MyMutableMapping(MutableMapping[str, typing.Any]): # pylint: disable=unsubscriptable-object
343
+ class _MyMutableMapping(MutableMapping[str, typing.Any]):
348
344
  def __init__(self, data: typing.Dict[str, typing.Any]) -> None:
349
345
  self._data = data
350
346
 
@@ -404,13 +400,13 @@ class _MyMutableMapping(MutableMapping[str, typing.Any]): # pylint: disable=uns
404
400
  return default
405
401
 
406
402
  @typing.overload
407
- def pop(self, key: str) -> typing.Any: ...
403
+ def pop(self, key: str) -> typing.Any: ... # pylint: disable=arguments-differ
408
404
 
409
405
  @typing.overload
410
- def pop(self, key: str, default: _T) -> _T: ...
406
+ def pop(self, key: str, default: _T) -> _T: ... # pylint: disable=signature-differs
411
407
 
412
408
  @typing.overload
413
- def pop(self, key: str, default: typing.Any) -> typing.Any: ...
409
+ def pop(self, key: str, default: typing.Any) -> typing.Any: ... # pylint: disable=signature-differs
414
410
 
415
411
  def pop(self, key: str, default: typing.Any = _UNSET) -> typing.Any:
416
412
  """
@@ -440,7 +436,7 @@ class _MyMutableMapping(MutableMapping[str, typing.Any]): # pylint: disable=uns
440
436
  """
441
437
  self._data.clear()
442
438
 
443
- def update(self, *args: typing.Any, **kwargs: typing.Any) -> None:
439
+ def update(self, *args: typing.Any, **kwargs: typing.Any) -> None: # pylint: disable=arguments-differ
444
440
  """
445
441
  Updates D from mapping/iterable E and F.
446
442
  :param any args: Either a mapping object or an iterable of key-value pairs.
@@ -451,7 +447,7 @@ class _MyMutableMapping(MutableMapping[str, typing.Any]): # pylint: disable=uns
451
447
  def setdefault(self, key: str, default: None = None) -> None: ...
452
448
 
453
449
  @typing.overload
454
- def setdefault(self, key: str, default: typing.Any) -> typing.Any: ...
450
+ def setdefault(self, key: str, default: typing.Any) -> typing.Any: ... # pylint: disable=signature-differs
455
451
 
456
452
  def setdefault(self, key: str, default: typing.Any = _UNSET) -> typing.Any:
457
453
  """
@@ -641,7 +637,7 @@ class Model(_MyMutableMapping):
641
637
  cls._attr_to_rest_field: typing.Dict[str, _RestField] = dict(attr_to_rest_field.items())
642
638
  cls._calculated.add(f"{cls.__module__}.{cls.__qualname__}")
643
639
 
644
- return super().__new__(cls) # pylint: disable=no-value-for-parameter
640
+ return super().__new__(cls)
645
641
 
646
642
  def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None:
647
643
  for base in cls.__bases__:
@@ -677,7 +673,7 @@ class Model(_MyMutableMapping):
677
673
  discriminator_value = data.find(xml_name).text # pyright: ignore
678
674
  else:
679
675
  discriminator_value = data.get(discriminator._rest_name)
680
- mapped_cls = cls.__mapping__.get(discriminator_value, cls) # pyright: ignore
676
+ mapped_cls = cls.__mapping__.get(discriminator_value, cls) # pyright: ignore # pylint: disable=no-member
681
677
  return mapped_cls._deserialize(data, exist_discriminators)
682
678
 
683
679
  def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]:
@@ -3,7 +3,7 @@
3
3
  # Microsoft Azure SDK for Python
4
4
 
5
5
  This is the Microsoft {{package_pprint_name}} Client Library.
6
- This package has been tested with Python 3.8+.
6
+ This package has been tested with Python 3.9+.
7
7
  For a more complete view of Azure libraries, see the [azure sdk python release](https://aka.ms/azsdk/python/all).
8
8
 
9
9
  # Usage
@@ -36,7 +36,7 @@ python -m pip install {{ package_name }}
36
36
 
37
37
  #### Prequisites
38
38
 
39
- - Python 3.8 or later is required to use this package.
39
+ - Python 3.9 or later is required to use this package.
40
40
  - You need an [Azure subscription][azure_sub] to use this package.
41
41
  - An existing {{ package_pprint_name }} instance.
42
42
 
@@ -67,7 +67,6 @@ setup(
67
67
  "Programming Language :: Python",
68
68
  "Programming Language :: Python :: 3 :: Only",
69
69
  "Programming Language :: Python :: 3",
70
- "Programming Language :: Python :: 3.8",
71
70
  "Programming Language :: Python :: 3.9",
72
71
  "Programming Language :: Python :: 3.10",
73
72
  "Programming Language :: Python :: 3.11",
@@ -110,7 +109,7 @@ setup(
110
109
  "typing-extensions>=4.6.0",
111
110
  ],
112
111
  {% if package_mode %}
113
- python_requires=">=3.8",
112
+ python_requires=">=3.9",
114
113
  {% else %}
115
114
  long_description="""\
116
115
  {{ code_model.description }}
@@ -1,4 +1,4 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: pygen
3
3
  Version: 0.1.0
4
4
  Summary: Core Library for Python Generation
@@ -9,7 +9,6 @@ License: MIT License
9
9
  Classifier: Development Status :: 4 - Beta
10
10
  Classifier: Programming Language :: Python
11
11
  Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: Python :: 3.8
13
12
  Classifier: Programming Language :: Python :: 3.9
14
13
  Classifier: Programming Language :: Python :: 3.10
15
14
  Classifier: Programming Language :: Python :: 3.11
@@ -23,5 +22,15 @@ Requires-Dist: Jinja2==3.1.6
23
22
  Requires-Dist: PyYAML==6.0.1
24
23
  Requires-Dist: tomli==2.0.1
25
24
  Requires-Dist: setuptools==70.0.0
25
+ Dynamic: author
26
+ Dynamic: author-email
27
+ Dynamic: classifier
28
+ Dynamic: description
29
+ Dynamic: description-content-type
30
+ Dynamic: home-page
31
+ Dynamic: license
32
+ Dynamic: license-file
33
+ Dynamic: requires-dist
34
+ Dynamic: summary
26
35
 
27
36
  # Core Library for Python Generation
@@ -35,7 +35,6 @@ setup(
35
35
  "Development Status :: 4 - Beta",
36
36
  "Programming Language :: Python",
37
37
  "Programming Language :: Python :: 3",
38
- "Programming Language :: Python :: 3.8",
39
38
  "Programming Language :: Python :: 3.9",
40
39
  "Programming Language :: Python :: 3.10",
41
40
  "Programming Language :: Python :: 3.11",
@@ -97,13 +97,6 @@ async def test_header(client: BytesClient):
97
97
  ],
98
98
  )
99
99
 
100
-
101
- @pytest.fixture
102
- def png_data() -> bytes:
103
- with open(str(FILE_FOLDER / "data/image.png"), "rb") as file_in:
104
- return file_in.read()
105
-
106
-
107
100
  @pytest.mark.asyncio
108
101
  async def test_request_body(client: BytesClient, png_data: bytes):
109
102
  await client.request_body.default(
@@ -10,7 +10,7 @@ import pytest
10
10
  import importlib
11
11
  from pathlib import Path
12
12
 
13
- FILE_FOLDER = Path(__file__).parent
13
+ DATA_FOLDER = Path(__file__).parent.parent
14
14
 
15
15
 
16
16
  def start_server_process():
@@ -65,11 +65,11 @@ def key_credential(core_library):
65
65
 
66
66
  @pytest.fixture
67
67
  def png_data() -> bytes:
68
- with open(str(FILE_FOLDER / "data/image.png"), "rb") as file_in:
68
+ with open(str(DATA_FOLDER / "data/image.png"), "rb") as file_in:
69
69
  return file_in.read()
70
70
 
71
71
 
72
72
  @pytest.fixture
73
73
  def jpg_data() -> bytes:
74
- with open(str(FILE_FOLDER / "data/image.jpg"), "rb") as file_in:
74
+ with open(str(DATA_FOLDER / "data/image.jpg"), "rb") as file_in:
75
75
  return file_in.read()
@@ -94,13 +94,6 @@ def test_header(client: BytesClient):
94
94
  ],
95
95
  )
96
96
 
97
-
98
- @pytest.fixture
99
- def png_data() -> bytes:
100
- with open(str(FILE_FOLDER / "data/image.png"), "rb") as file_in:
101
- return file_in.read()
102
-
103
-
104
97
  def test_request_body(client: BytesClient, png_data: bytes):
105
98
  client.request_body.default(
106
99
  value=png_data,
@@ -0,0 +1,14 @@
1
+ # -------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for
4
+ # license information.
5
+ # --------------------------------------------------------------------------
6
+ import importlib
7
+ import pytest
8
+
9
+ @pytest.fixture
10
+ def core_library():
11
+ try:
12
+ return importlib.import_module("azure.core")
13
+ except ModuleNotFoundError:
14
+ return importlib.import_module("corehttp")
@@ -0,0 +1,3 @@
1
+ -r ../dev_requirements.txt
2
+ -e ../../../generator
3
+ -e ../unbranded/generated/special-words
@@ -0,0 +1,52 @@
1
+ # -------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for
4
+ # license information.
5
+ # --------------------------------------------------------------------------
6
+ from enum import Enum, EnumMeta
7
+
8
+
9
+ class _CaseInsensitiveEnumMeta(EnumMeta):
10
+ def __getitem__(self, name):
11
+ return super().__getitem__(name.upper())
12
+
13
+ def __getattr__(cls, name):
14
+ """Return the enum member matching `name`
15
+ We use __getattr__ instead of descriptors or inserting into the enum
16
+ class' __dict__ in order to support `name` and `value` being both
17
+ properties for enum members (which live in the class' __dict__) and
18
+ enum members themselves.
19
+ """
20
+ try:
21
+ return cls._member_map_[name.upper()]
22
+ except KeyError:
23
+ raise AttributeError(name)
24
+
25
+
26
+ class EnumsWithCallableNames(str, Enum, metaclass=_CaseInsensitiveEnumMeta):
27
+ """Gets the unit of measurement."""
28
+
29
+ COUNT = "count"
30
+ ENCODE = "encode"
31
+ FIND = "find"
32
+ JOIN = "join"
33
+
34
+
35
+ def test_count():
36
+ assert EnumsWithCallableNames.COUNT == "count"
37
+ assert callable(EnumsWithCallableNames.count)
38
+
39
+
40
+ def test_encode():
41
+ assert EnumsWithCallableNames.ENCODE == "encode"
42
+ assert callable(EnumsWithCallableNames.encode)
43
+
44
+
45
+ def test_find():
46
+ assert EnumsWithCallableNames.FIND == "find"
47
+ assert callable(EnumsWithCallableNames.find)
48
+
49
+
50
+ def test_join():
51
+ assert EnumsWithCallableNames.JOIN == "join"
52
+ assert callable(EnumsWithCallableNames.join)
@@ -0,0 +1,43 @@
1
+ # -------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for
4
+ # license information.
5
+ # --------------------------------------------------------------------------
6
+ from pygen.preprocess import PreProcessPlugin
7
+ from pygen.preprocess.python_mappings import PadType
8
+
9
+
10
+ def pad_reserved_words(name: str, pad_type: PadType) -> str:
11
+ return PreProcessPlugin(output_folder="").pad_reserved_words(name, pad_type)
12
+
13
+
14
+ def test_escaped_reserved_words():
15
+ expected_conversion_model = {"Self": "Self", "And": "AndModel"}
16
+ for name in expected_conversion_model:
17
+ assert pad_reserved_words(name, pad_type=PadType.MODEL) == expected_conversion_model[name]
18
+
19
+ expected_conversion_method = {
20
+ "self": "self",
21
+ "and": "and_method",
22
+ "content_type": "content_type",
23
+ }
24
+ for name in expected_conversion_method:
25
+ assert pad_reserved_words(name, pad_type=PadType.METHOD) == expected_conversion_method[name]
26
+
27
+ expected_conversion_parameter = {
28
+ "content_type": "content_type_parameter",
29
+ "request_id": "request_id_parameter",
30
+ "elif": "elif_parameter",
31
+ "self": "self_parameter",
32
+ "continuation_token": "continuation_token_parameter",
33
+ }
34
+ for name in expected_conversion_parameter:
35
+ assert pad_reserved_words(name, pad_type=PadType.PARAMETER) == expected_conversion_parameter[name]
36
+
37
+ expected_conversion_enum = {
38
+ "self": "self",
39
+ "mro": "mro_enum",
40
+ "continuation_token": "continuation_token",
41
+ }
42
+ for name in expected_conversion_enum:
43
+ assert pad_reserved_words(name, pad_type=PadType.ENUM_VALUE) == expected_conversion_enum[name]
@@ -0,0 +1,268 @@
1
+ # -------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Corporation. All rights reserved.
3
+ # Licensed under the MIT License. See License.txt in the project root for
4
+ # license information.
5
+ # --------------------------------------------------------------------------
6
+
7
+ import pytest
8
+ from pygen.codegen.models import (
9
+ Operation,
10
+ LROOperation,
11
+ PagingOperation,
12
+ Response,
13
+ ParameterList,
14
+ CodeModel,
15
+ RequestBuilder,
16
+ Client,
17
+ )
18
+ from pygen.codegen.models.parameter_list import RequestBuilderParameterList
19
+ from pygen.codegen.models.primitive_types import StringType
20
+
21
+
22
+ @pytest.fixture
23
+ def code_model():
24
+ return CodeModel(
25
+ {
26
+ "clients": [
27
+ {
28
+ "name": "client",
29
+ "namespace": "blah",
30
+ "moduleName": "blah",
31
+ "parameters": [],
32
+ "url": "",
33
+ "operationGroups": [],
34
+ }
35
+ ],
36
+ "namespace": "namespace",
37
+ },
38
+ options={
39
+ "show_send_request": True,
40
+ "builders_visibility": "public",
41
+ "show_operations": True,
42
+ "models_mode": "dpg",
43
+ "version_tolerant": True,
44
+ },
45
+ )
46
+
47
+
48
+ @pytest.fixture
49
+ def client(code_model):
50
+ return Client(
51
+ {
52
+ "name": "client",
53
+ "namespace": "blah",
54
+ "moduleName": "blah",
55
+ "parameters": [],
56
+ "url": "",
57
+ "operationGroups": [],
58
+ },
59
+ code_model,
60
+ parameters=[],
61
+ )
62
+
63
+
64
+ @pytest.fixture
65
+ def request_builder(code_model, client):
66
+ return RequestBuilder(
67
+ yaml_data={
68
+ "url": "http://fake.com",
69
+ "method": "GET",
70
+ "groupName": "blah",
71
+ "isOverload": False,
72
+ "apiVersions": [],
73
+ },
74
+ client=client,
75
+ code_model=code_model,
76
+ name="optional_return_type_test",
77
+ parameters=RequestBuilderParameterList({}, code_model, parameters=[]),
78
+ )
79
+
80
+
81
+ @pytest.fixture
82
+ def operation(code_model, request_builder, client):
83
+ return Operation(
84
+ yaml_data={
85
+ "url": "http://fake.com",
86
+ "method": "GET",
87
+ "groupName": "blah",
88
+ "isOverload": False,
89
+ "apiVersions": [],
90
+ },
91
+ client=client,
92
+ code_model=code_model,
93
+ request_builder=request_builder,
94
+ name="optional_return_type_test",
95
+ parameters=ParameterList({}, code_model, []),
96
+ responses=[],
97
+ exceptions=[],
98
+ )
99
+
100
+
101
+ @pytest.fixture
102
+ def lro_operation(code_model, request_builder, client):
103
+ return LROOperation(
104
+ yaml_data={
105
+ "url": "http://fake.com",
106
+ "method": "GET",
107
+ "groupName": "blah",
108
+ "isOverload": False,
109
+ "apiVersions": [],
110
+ },
111
+ client=client,
112
+ code_model=code_model,
113
+ request_builder=request_builder,
114
+ name="lro_optional_return_type_test",
115
+ parameters=ParameterList({}, code_model, []),
116
+ responses=[],
117
+ exceptions=[],
118
+ )
119
+
120
+
121
+ @pytest.fixture
122
+ def paging_operation(code_model, request_builder, client):
123
+ return PagingOperation(
124
+ yaml_data={
125
+ "url": "http://fake.com",
126
+ "method": "GET",
127
+ "groupName": "blah",
128
+ "isOverload": False,
129
+ "apiVersions": [],
130
+ "pagerSync": "blah",
131
+ "pagerAsync": "blah",
132
+ },
133
+ client=client,
134
+ code_model=code_model,
135
+ request_builder=request_builder,
136
+ name="paging_optional_return_type_test",
137
+ parameters=ParameterList({}, code_model, []),
138
+ responses=[],
139
+ exceptions=[],
140
+ )
141
+
142
+
143
+ @pytest.fixture
144
+ def base_type(code_model):
145
+ return StringType({"type": "string"}, code_model)
146
+
147
+
148
+ def test_success_with_body_and_fail_no_body(code_model, operation, base_type):
149
+ operation.responses = [
150
+ Response(
151
+ yaml_data={"statusCodes": [200]},
152
+ code_model=code_model,
153
+ headers=[],
154
+ type=base_type,
155
+ ),
156
+ Response(
157
+ yaml_data={"statusCodes": [202]},
158
+ code_model=code_model,
159
+ headers=[],
160
+ type=base_type,
161
+ ),
162
+ ]
163
+ operation.exceptions = [
164
+ Response(
165
+ yaml_data={"statusCodes": ["default"]},
166
+ code_model=code_model,
167
+ headers=[],
168
+ type=None,
169
+ )
170
+ ]
171
+
172
+ assert operation.has_optional_return_type is False
173
+
174
+
175
+ def test_success_no_body_fail_with_body(code_model, operation, base_type):
176
+ operation.responses = [
177
+ Response(
178
+ yaml_data={"statusCodes": [200]},
179
+ code_model=code_model,
180
+ headers=[],
181
+ type=None,
182
+ )
183
+ ]
184
+ operation.exceptions = [
185
+ Response(
186
+ yaml_data={"statusCodes": ["default"]},
187
+ code_model=code_model,
188
+ headers=[],
189
+ type=base_type,
190
+ )
191
+ ]
192
+
193
+ assert operation.has_optional_return_type is False
194
+
195
+
196
+ def test_optional_return_type_operation(code_model, operation, base_type):
197
+ operation.responses = [
198
+ Response(
199
+ yaml_data={"statusCodes": [200]},
200
+ code_model=code_model,
201
+ headers=[],
202
+ type=base_type,
203
+ ),
204
+ Response(
205
+ yaml_data={"statusCodes": [202]},
206
+ code_model=code_model,
207
+ headers=[],
208
+ type=None,
209
+ ),
210
+ Response(
211
+ yaml_data={"statusCodes": ["default"]},
212
+ code_model=code_model,
213
+ headers=[],
214
+ type=base_type,
215
+ ),
216
+ ]
217
+
218
+ assert operation.has_optional_return_type is True
219
+
220
+
221
+ def test_lro_operation(code_model, lro_operation, base_type):
222
+ lro_operation.responses = [
223
+ Response(
224
+ yaml_data={"statusCodes": [200]},
225
+ code_model=code_model,
226
+ headers=[],
227
+ type=base_type,
228
+ ),
229
+ Response(
230
+ yaml_data={"statusCodes": [202]},
231
+ code_model=code_model,
232
+ headers=[],
233
+ type=None,
234
+ ),
235
+ Response(
236
+ yaml_data={"statusCodes": ["default"]},
237
+ code_model=code_model,
238
+ headers=[],
239
+ type=base_type,
240
+ ),
241
+ ]
242
+
243
+ assert lro_operation.has_optional_return_type is False
244
+
245
+
246
+ def test_paging_operation(code_model, paging_operation, base_type):
247
+ paging_operation.responses = [
248
+ Response(
249
+ yaml_data={"statusCodes": [200]},
250
+ code_model=code_model,
251
+ headers=[],
252
+ type=base_type,
253
+ ),
254
+ Response(
255
+ yaml_data={"statusCodes": [202]},
256
+ code_model=code_model,
257
+ headers=[],
258
+ type=None,
259
+ ),
260
+ Response(
261
+ yaml_data={"statusCodes": ["default"]},
262
+ code_model=code_model,
263
+ headers=[],
264
+ type=base_type,
265
+ ),
266
+ ]
267
+
268
+ assert paging_operation.has_optional_return_type is False