@typespec/http-client-python 0.9.0 → 0.9.2-dev.1
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.
- package/dist/emitter/emitter.js +2 -0
- package/dist/emitter/emitter.js.map +1 -1
- package/dist/emitter/run-python3.js +1 -1
- package/emitter/src/emitter.ts +1 -0
- package/emitter/src/run-python3.ts +1 -1
- package/emitter/temp/tsconfig.tsbuildinfo +1 -1
- package/eng/scripts/Build-Packages.ps1 +7 -5
- package/eng/scripts/ci/format.ts +1 -1
- package/eng/scripts/ci/mypy.ini +1 -1
- package/eng/scripts/ci/pylintrc +1 -1
- package/eng/scripts/ci/pyrightconfig.json +1 -1
- package/eng/scripts/ci/run-ci.ts +1 -0
- package/eng/scripts/ci/run_pylint.py +1 -1
- package/eng/scripts/ci/utils.ts +5 -3
- package/eng/scripts/setup/__pycache__/{venvtools.cpython-38.pyc → venvtools.cpython-39.pyc} +0 -0
- package/eng/scripts/setup/build_pygen_wheel.py +3 -3
- package/eng/scripts/setup/install.py +2 -2
- package/eng/scripts/setup/prepare.py +2 -2
- package/generator/build/lib/pygen/codegen/__init__.py +0 -1
- package/generator/build/lib/pygen/codegen/_utils.py +1 -1
- package/generator/build/lib/pygen/codegen/models/code_model.py +1 -1
- package/generator/build/lib/pygen/codegen/models/imports.py +2 -13
- package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +1 -3
- package/generator/build/lib/pygen/codegen/templates/model_base.py.jinja2 +9 -13
- package/generator/build/lib/pygen/codegen/templates/packaging_templates/README.md.jinja2 +2 -2
- package/generator/build/lib/pygen/codegen/templates/packaging_templates/setup.py.jinja2 +1 -2
- package/generator/component-detection-pip-report.json +70 -71
- package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
- package/generator/pygen/codegen/__init__.py +0 -1
- package/generator/pygen/codegen/_utils.py +1 -1
- package/generator/pygen/codegen/models/code_model.py +1 -1
- package/generator/pygen/codegen/models/imports.py +2 -13
- package/generator/pygen/codegen/serializers/builder_serializer.py +1 -3
- package/generator/pygen/codegen/templates/model_base.py.jinja2 +9 -13
- package/generator/pygen/codegen/templates/packaging_templates/README.md.jinja2 +2 -2
- package/generator/pygen/codegen/templates/packaging_templates/setup.py.jinja2 +1 -2
- package/generator/pygen.egg-info/PKG-INFO +11 -2
- package/generator/setup.py +0 -1
- package/generator/test/generic_mock_api_tests/asynctests/test_encode_bytes_async.py +0 -7
- package/generator/test/generic_mock_api_tests/conftest.py +3 -3
- package/generator/test/generic_mock_api_tests/test_encode_bytes.py +0 -7
- package/generator/test/unittests/conftest.py +14 -0
- package/generator/test/unittests/requirements.txt +3 -0
- package/generator/test/unittests/test_enums.py +52 -0
- package/generator/test/unittests/test_name_converter.py +43 -0
- package/generator/test/unittests/test_optional_return_type.py +268 -0
- package/generator/test/unittests/test_parameter_ordering.py +104 -0
- package/generator/test/unittests/tox.ini +5 -0
- package/package.json +1 -1
- /package/generator/test/{generic_mock_api_tests/data → data}/image.jpg +0 -0
- /package/generator/test/{generic_mock_api_tests/data → data}/image.png +0 -0
- /package/generator/test/{generic_mock_api_tests/unittests → unittests}/test_model_base_serialization.py +0 -0
- /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]):
|
|
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)
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
+
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
|
package/generator/setup.py
CHANGED
|
@@ -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
|
-
|
|
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(
|
|
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(
|
|
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,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
|