@typespec/http-client-python 0.4.4 → 0.5.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.
Files changed (156) hide show
  1. package/dist/emitter/emitter.d.ts.map +1 -1
  2. package/dist/emitter/emitter.js +110 -24
  3. package/dist/emitter/emitter.js.map +1 -1
  4. package/dist/emitter/http.js +1 -1
  5. package/dist/emitter/http.js.map +1 -1
  6. package/dist/emitter/lib.d.ts +1 -0
  7. package/dist/emitter/lib.d.ts.map +1 -1
  8. package/dist/emitter/lib.js +1 -0
  9. package/dist/emitter/lib.js.map +1 -1
  10. package/dist/emitter/run-python3.d.ts +2 -0
  11. package/dist/emitter/run-python3.d.ts.map +1 -0
  12. package/dist/emitter/run-python3.js +19 -0
  13. package/dist/emitter/run-python3.js.map +1 -0
  14. package/dist/emitter/system-requirements.d.ts +17 -0
  15. package/dist/emitter/system-requirements.d.ts.map +1 -0
  16. package/dist/emitter/system-requirements.js +167 -0
  17. package/dist/emitter/system-requirements.js.map +1 -0
  18. package/emitter/src/emitter.ts +111 -23
  19. package/emitter/src/http.ts +1 -1
  20. package/emitter/src/lib.ts +2 -0
  21. package/emitter/src/run-python3.ts +20 -0
  22. package/emitter/src/system-requirements.ts +261 -0
  23. package/emitter/temp/tsconfig.tsbuildinfo +1 -1
  24. package/eng/scripts/Test-Packages.ps1 +1 -1
  25. package/eng/scripts/ci/regenerate.ts +20 -8
  26. package/eng/scripts/setup/__pycache__/venvtools.cpython-38.pyc +0 -0
  27. package/eng/scripts/setup/build.ts +16 -0
  28. package/eng/scripts/setup/build_pygen_wheel.py +40 -0
  29. package/eng/scripts/setup/install.py +9 -8
  30. package/eng/scripts/setup/install.ts +12 -0
  31. package/eng/scripts/setup/prepare.py +3 -1
  32. package/eng/scripts/setup/prepare.ts +11 -0
  33. package/eng/scripts/setup/run-python3.ts +1 -6
  34. package/generator/build/lib/pygen/__init__.py +107 -0
  35. package/generator/build/lib/pygen/_version.py +7 -0
  36. package/generator/build/lib/pygen/black.py +71 -0
  37. package/generator/build/lib/pygen/codegen/__init__.py +357 -0
  38. package/generator/build/lib/pygen/codegen/_utils.py +17 -0
  39. package/generator/build/lib/pygen/codegen/models/__init__.py +204 -0
  40. package/generator/build/lib/pygen/codegen/models/base.py +186 -0
  41. package/generator/build/lib/pygen/codegen/models/base_builder.py +118 -0
  42. package/generator/build/lib/pygen/codegen/models/client.py +435 -0
  43. package/generator/build/lib/pygen/codegen/models/code_model.py +237 -0
  44. package/generator/build/lib/pygen/codegen/models/combined_type.py +149 -0
  45. package/generator/build/lib/pygen/codegen/models/constant_type.py +129 -0
  46. package/generator/build/lib/pygen/codegen/models/credential_types.py +214 -0
  47. package/generator/build/lib/pygen/codegen/models/dictionary_type.py +127 -0
  48. package/generator/build/lib/pygen/codegen/models/enum_type.py +238 -0
  49. package/generator/build/lib/pygen/codegen/models/imports.py +291 -0
  50. package/generator/build/lib/pygen/codegen/models/list_type.py +143 -0
  51. package/generator/build/lib/pygen/codegen/models/lro_operation.py +142 -0
  52. package/generator/build/lib/pygen/codegen/models/lro_paging_operation.py +32 -0
  53. package/generator/build/lib/pygen/codegen/models/model_type.py +357 -0
  54. package/generator/build/lib/pygen/codegen/models/operation.py +509 -0
  55. package/generator/build/lib/pygen/codegen/models/operation_group.py +184 -0
  56. package/generator/build/lib/pygen/codegen/models/paging_operation.py +155 -0
  57. package/generator/build/lib/pygen/codegen/models/parameter.py +412 -0
  58. package/generator/build/lib/pygen/codegen/models/parameter_list.py +387 -0
  59. package/generator/build/lib/pygen/codegen/models/primitive_types.py +659 -0
  60. package/generator/build/lib/pygen/codegen/models/property.py +170 -0
  61. package/generator/build/lib/pygen/codegen/models/request_builder.py +189 -0
  62. package/generator/build/lib/pygen/codegen/models/request_builder_parameter.py +115 -0
  63. package/generator/build/lib/pygen/codegen/models/response.py +348 -0
  64. package/generator/build/lib/pygen/codegen/models/utils.py +21 -0
  65. package/generator/build/lib/pygen/codegen/serializers/__init__.py +574 -0
  66. package/generator/build/lib/pygen/codegen/serializers/base_serializer.py +21 -0
  67. package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +1533 -0
  68. package/generator/build/lib/pygen/codegen/serializers/client_serializer.py +294 -0
  69. package/generator/build/lib/pygen/codegen/serializers/enum_serializer.py +15 -0
  70. package/generator/build/lib/pygen/codegen/serializers/general_serializer.py +213 -0
  71. package/generator/build/lib/pygen/codegen/serializers/import_serializer.py +126 -0
  72. package/generator/build/lib/pygen/codegen/serializers/metadata_serializer.py +198 -0
  73. package/generator/build/lib/pygen/codegen/serializers/model_init_serializer.py +33 -0
  74. package/generator/build/lib/pygen/codegen/serializers/model_serializer.py +335 -0
  75. package/generator/build/lib/pygen/codegen/serializers/operation_groups_serializer.py +89 -0
  76. package/generator/build/lib/pygen/codegen/serializers/operations_init_serializer.py +44 -0
  77. package/generator/build/lib/pygen/codegen/serializers/parameter_serializer.py +221 -0
  78. package/generator/build/lib/pygen/codegen/serializers/patch_serializer.py +19 -0
  79. package/generator/build/lib/pygen/codegen/serializers/request_builders_serializer.py +52 -0
  80. package/generator/build/lib/pygen/codegen/serializers/sample_serializer.py +168 -0
  81. package/generator/build/lib/pygen/codegen/serializers/test_serializer.py +292 -0
  82. package/generator/build/lib/pygen/codegen/serializers/types_serializer.py +31 -0
  83. package/generator/build/lib/pygen/codegen/serializers/utils.py +68 -0
  84. package/generator/build/lib/pygen/codegen/templates/client.py.jinja2 +37 -0
  85. package/generator/build/lib/pygen/codegen/templates/client_container.py.jinja2 +12 -0
  86. package/generator/build/lib/pygen/codegen/templates/config.py.jinja2 +73 -0
  87. package/generator/build/lib/pygen/codegen/templates/config_container.py.jinja2 +16 -0
  88. package/generator/build/lib/pygen/codegen/templates/conftest.py.jinja2 +28 -0
  89. package/generator/build/lib/pygen/codegen/templates/enum.py.jinja2 +13 -0
  90. package/generator/build/lib/pygen/codegen/templates/enum_container.py.jinja2 +10 -0
  91. package/generator/build/lib/pygen/codegen/templates/init.py.jinja2 +24 -0
  92. package/generator/build/lib/pygen/codegen/templates/keywords.jinja2 +27 -0
  93. package/generator/build/lib/pygen/codegen/templates/lro_operation.py.jinja2 +16 -0
  94. package/generator/build/lib/pygen/codegen/templates/lro_paging_operation.py.jinja2 +18 -0
  95. package/generator/build/lib/pygen/codegen/templates/macros.jinja2 +12 -0
  96. package/generator/build/lib/pygen/codegen/templates/metadata.json.jinja2 +167 -0
  97. package/generator/build/lib/pygen/codegen/templates/model_base.py.jinja2 +1174 -0
  98. package/generator/build/lib/pygen/codegen/templates/model_container.py.jinja2 +15 -0
  99. package/generator/build/lib/pygen/codegen/templates/model_dpg.py.jinja2 +97 -0
  100. package/generator/build/lib/pygen/codegen/templates/model_init.py.jinja2 +33 -0
  101. package/generator/build/lib/pygen/codegen/templates/model_msrest.py.jinja2 +92 -0
  102. package/generator/build/lib/pygen/codegen/templates/operation.py.jinja2 +21 -0
  103. package/generator/build/lib/pygen/codegen/templates/operation_group.py.jinja2 +75 -0
  104. package/generator/build/lib/pygen/codegen/templates/operation_groups_container.py.jinja2 +19 -0
  105. package/generator/build/lib/pygen/codegen/templates/operation_tools.jinja2 +81 -0
  106. package/generator/build/lib/pygen/codegen/templates/operations_folder_init.py.jinja2 +17 -0
  107. package/generator/build/lib/pygen/codegen/templates/packaging_templates/CHANGELOG.md.jinja2 +6 -0
  108. package/generator/build/lib/pygen/codegen/templates/packaging_templates/LICENSE.jinja2 +21 -0
  109. package/generator/build/lib/pygen/codegen/templates/packaging_templates/MANIFEST.in.jinja2 +8 -0
  110. package/generator/build/lib/pygen/codegen/templates/packaging_templates/README.md.jinja2 +107 -0
  111. package/generator/build/lib/pygen/codegen/templates/packaging_templates/dev_requirements.txt.jinja2 +9 -0
  112. package/generator/build/lib/pygen/codegen/templates/packaging_templates/setup.py.jinja2 +108 -0
  113. package/generator/build/lib/pygen/codegen/templates/paging_operation.py.jinja2 +21 -0
  114. package/generator/build/lib/pygen/codegen/templates/patch.py.jinja2 +19 -0
  115. package/generator/build/lib/pygen/codegen/templates/pkgutil_init.py.jinja2 +1 -0
  116. package/generator/build/lib/pygen/codegen/templates/request_builder.py.jinja2 +28 -0
  117. package/generator/build/lib/pygen/codegen/templates/request_builders.py.jinja2 +10 -0
  118. package/generator/build/lib/pygen/codegen/templates/rest_init.py.jinja2 +12 -0
  119. package/generator/build/lib/pygen/codegen/templates/sample.py.jinja2 +44 -0
  120. package/generator/build/lib/pygen/codegen/templates/serialization.py.jinja2 +2117 -0
  121. package/generator/build/lib/pygen/codegen/templates/test.py.jinja2 +50 -0
  122. package/generator/build/lib/pygen/codegen/templates/testpreparer.py.jinja2 +26 -0
  123. package/generator/build/lib/pygen/codegen/templates/types.py.jinja2 +7 -0
  124. package/generator/build/lib/pygen/codegen/templates/validation.py.jinja2 +38 -0
  125. package/generator/build/lib/pygen/codegen/templates/vendor.py.jinja2 +96 -0
  126. package/generator/build/lib/pygen/codegen/templates/version.py.jinja2 +4 -0
  127. package/generator/build/lib/pygen/m2r.py +65 -0
  128. package/generator/build/lib/pygen/preprocess/__init__.py +515 -0
  129. package/generator/build/lib/pygen/preprocess/helpers.py +27 -0
  130. package/generator/build/lib/pygen/preprocess/python_mappings.py +226 -0
  131. package/generator/build/lib/pygen/utils.py +163 -0
  132. package/generator/component-detection-pip-report.json +134 -0
  133. package/generator/dev_requirements.txt +0 -1
  134. package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
  135. package/generator/pygen/codegen/__init__.py +4 -4
  136. package/generator/pygen.egg-info/PKG-INFO +7 -4
  137. package/generator/pygen.egg-info/requires.txt +7 -4
  138. package/generator/setup.py +7 -4
  139. package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_flatten_async.py +1 -1
  140. package/generator/test/{generic_mock_api_tests/asynctests/test_payload_pageable_async.py → azure/mock_api_tests/asynctests/test_azure_payload_pageable_async.py} +1 -1
  141. package/generator/test/azure/mock_api_tests/conftest.py +5 -4
  142. package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_flatten.py +1 -1
  143. package/generator/test/{generic_mock_api_tests/test_payload_pageable.py → azure/mock_api_tests/test_azure_payload_pageable.py} +1 -1
  144. package/generator/test/{generic_mock_api_tests → azure/mock_api_tests}/test_resiliency_srv_driven.py +4 -2
  145. package/generator/test/{generic_mock_api_tests/asynctests → azure/mock_api_tests}/test_resiliency_srv_driven_async.py +3 -2
  146. package/generator/test/azure/requirements.txt +9 -8
  147. package/generator/test/generic_mock_api_tests/conftest.py +9 -4
  148. package/generator/test/unbranded/mock_api_tests/conftest.py +4 -4
  149. package/generator/test/unbranded/mock_api_tests/test_unbranded.py +1 -1
  150. package/generator/test/unbranded/requirements.txt +1 -8
  151. package/package.json +10 -10
  152. package/generator/requirements.txt +0 -12
  153. /package/generator/test/{generic_mock_api_tests → azure/mock_api_tests}/asynctests/test_client_naming_async.py +0 -0
  154. /package/generator/test/{generic_mock_api_tests → azure/mock_api_tests}/asynctests/test_client_structure_async.py +0 -0
  155. /package/generator/test/{generic_mock_api_tests → azure/mock_api_tests}/test_client_naming.py +0 -0
  156. /package/generator/test/{generic_mock_api_tests → azure/mock_api_tests}/test_client_structure.py +0 -0
@@ -0,0 +1,50 @@
1
+ {% set prefix_lower = test.prefix|lower %}
2
+ {% set client_var = "self.client" if code_model.options["azure_arm"] else "client" %}
3
+ {% set async = "async " if test.is_async else "" %}
4
+ {% set async_suffix = "_async" if test.is_async else "" %}
5
+ # coding=utf-8
6
+ {{ code_model.options['license_header'] }}
7
+ import pytest
8
+ {{ imports }}
9
+
10
+ {% if code_model.options["azure_arm"] %}
11
+ AZURE_LOCATION = "eastus"
12
+ {% endif %}
13
+
14
+ @pytest.mark.skip("you may need to update the auto-generated test case before run it")
15
+ class {{ test.test_class_name }}({{ test.base_test_class_name }}):
16
+ {% if code_model.options["azure_arm"] %}
17
+ def setup_method(self, method):
18
+ {% if test.is_async %}
19
+ self.client = self.create_mgmt_client({{ test.client_name }}, is_async=True)
20
+ {% else %}
21
+ self.client = self.create_mgmt_client({{ test.client_name }})
22
+ {% endif %}
23
+ {% endif %}
24
+ {% for testcase in test.testcases %}
25
+ {% if code_model.options["azure_arm"] %}
26
+ @{{ test.preparer_name }}(location=AZURE_LOCATION)
27
+ {% else %}
28
+ @{{ test.preparer_name }}()
29
+ {% endif %}
30
+ @recorded_by_proxy{{ async_suffix }}
31
+ {% if code_model.options["azure_arm"] %}
32
+ {{ async }}def test_{{ testcase.name }}(self, resource_group):
33
+ {% else %}
34
+ {{ async }}def test_{{ testcase.name }}(self, {{ prefix_lower }}_endpoint):
35
+ {{ client_var }} = self.{{ test.create_client_name }}(endpoint={{ prefix_lower }}_endpoint)
36
+ {% endif %}
37
+ {{testcase.response }}{{ client_var }}{{ testcase.operation_group_prefix }}.{{ testcase.operation.name }}(
38
+ {% for key, value in testcase.params.items() %}
39
+ {% if code_model.options["azure_arm"] and key == "resource_group_name" %}
40
+ {{ key }}=resource_group.name,
41
+ {% else %}
42
+ {{ key }}={{ value|indent(12) }},
43
+ {% endif %}
44
+ {% endfor %}
45
+ ){{ testcase.operation_suffix }}
46
+ {{ testcase.extra_operation }}
47
+ # please add some check logic here by yourself
48
+ # ...
49
+
50
+ {% endfor %}
@@ -0,0 +1,26 @@
1
+ # coding=utf-8
2
+ {{ code_model.options['license_header'] }}
3
+ {{ imports }}
4
+
5
+ {% for test_name in test_names %}
6
+ {% set extra_async = ", is_async=True" if test_name.is_async else ""%}
7
+ {% set prefix_lower = test_name.prefix|lower %}
8
+ class {{ test_name.base_test_class_name }}(AzureRecordedTestCase):
9
+
10
+ def {{ test_name.create_client_name }}(self, endpoint):
11
+ credential = self.get_credential({{ test_name.client_name }}{{ extra_async }})
12
+ return self.create_client_from_credential(
13
+ {{ test_name.client_name }},
14
+ credential=credential,
15
+ endpoint=endpoint,
16
+ )
17
+
18
+ {% if not test_name.is_async %}
19
+ {{ test_name.preparer_name }} = functools.partial(
20
+ PowerShellPreparer,
21
+ "{{ prefix_lower }}",
22
+ {{ prefix_lower }}_endpoint="https://fake_{{ prefix_lower }}_endpoint.com"
23
+ )
24
+ {% endif %}
25
+
26
+ {% endfor %}
@@ -0,0 +1,7 @@
1
+ # coding=utf-8
2
+ {{ code_model.options['license_header'] }}
3
+
4
+ {{ imports }}
5
+ {% for nu in code_model.named_unions %}
6
+ {{nu.name}} = {{nu.type_definition()}}
7
+ {% endfor %}
@@ -0,0 +1,38 @@
1
+ {{ code_model.options['license_header'] }}
2
+ import functools
3
+
4
+ def api_version_validation(**kwargs):
5
+ params_added_on = kwargs.pop("params_added_on", {})
6
+ method_added_on = kwargs.pop("method_added_on", "")
7
+
8
+ def decorator(func):
9
+ @functools.wraps(func)
10
+ def wrapper(*args, **kwargs):
11
+ try:
12
+ # this assumes the client has an _api_version attribute
13
+ client = args[0]
14
+ client_api_version = client._config.api_version # pylint: disable=protected-access
15
+ except AttributeError:
16
+ return func(*args, **kwargs)
17
+
18
+ if method_added_on > client_api_version:
19
+ raise ValueError(
20
+ f"'{func.__name__}' is not available in API version "
21
+ f"{client_api_version}. Pass service API version {method_added_on} or newer to your client."
22
+ )
23
+
24
+ unsupported = {
25
+ parameter: api_version
26
+ for api_version, parameters in params_added_on.items()
27
+ for parameter in parameters
28
+ if parameter in kwargs and api_version > client_api_version
29
+ }
30
+ if unsupported:
31
+ raise ValueError("".join([
32
+ f"'{param}' is not available in API version {client_api_version}. "
33
+ f"Use service API version {version} or newer.\n"
34
+ for param, version in unsupported.items()
35
+ ]))
36
+ return func(*args, **kwargs)
37
+ return wrapper
38
+ return decorator
@@ -0,0 +1,96 @@
1
+ {% import 'keywords.jinja2' as keywords with context %}
2
+ {{ code_model.options['license_header'] }}
3
+
4
+ {{ imports }}
5
+
6
+ {% if code_model.need_mixin_abc %}
7
+ {% for client in clients | selectattr("has_mixin") %}
8
+ {% set pylint_disable = "# pylint: disable=name-too-long" if (client.name | length) + ("MixinABC" | length) > 40 else "" %}
9
+ class {{ client.name }}MixinABC( {{ pylint_disable }}
10
+ ABC
11
+ ):
12
+ """DO NOT use this class. It is for internal typing use only."""
13
+ _client: "{{ keywords.async_class }}PipelineClient"
14
+ _config: {{ client.name }}Configuration
15
+ _serialize: "Serializer"
16
+ _deserialize: "Deserializer"
17
+ {% endfor %}
18
+ {% endif %}
19
+ {% if code_model.has_abstract_operations %}
20
+
21
+ def raise_if_not_implemented(cls, abstract_methods):
22
+ not_implemented = [f for f in abstract_methods if not callable(getattr(cls, f, None))]
23
+ if not_implemented:
24
+ raise NotImplementedError("The following methods on operation group '{}' are not implemented: '{}'."
25
+ " Please refer to https://aka.ms/azsdk/python/dpcodegen/python/customize to learn how to customize.".format(
26
+ cls.__name__, '\', \''.join(not_implemented))
27
+ )
28
+ {% endif %}
29
+
30
+ {% if code_model.has_etag %}
31
+ def quote_etag(etag: Optional[str]) -> Optional[str]:
32
+ if not etag or etag == "*":
33
+ return etag
34
+ if etag.startswith("W/"):
35
+ return etag
36
+ if etag.startswith('"') and etag.endswith('"'):
37
+ return etag
38
+ if etag.startswith("'") and etag.endswith("'"):
39
+ return etag
40
+ return '"' + etag + '"'
41
+
42
+
43
+ def prep_if_match(etag: Optional[str], match_condition: Optional[MatchConditions]) -> Optional[str]:
44
+ if match_condition == MatchConditions.IfNotModified:
45
+ if_match = quote_etag(etag) if etag else None
46
+ return if_match
47
+ if match_condition == MatchConditions.IfPresent:
48
+ return "*"
49
+ return None
50
+
51
+
52
+ def prep_if_none_match(etag: Optional[str], match_condition: Optional[MatchConditions]) -> Optional[str]:
53
+ if match_condition == MatchConditions.IfModified:
54
+ if_none_match = quote_etag(etag) if etag else None
55
+ return if_none_match
56
+ if match_condition == MatchConditions.IfMissing:
57
+ return "*"
58
+ return None
59
+ {% endif %}
60
+ {% if code_model.has_form_data and code_model.options["models_mode"] == "dpg" and not async_mode %}
61
+ # file-like tuple could be `(filename, IO (or bytes))` or `(filename, IO (or bytes), content_type)`
62
+ FileContent = Union[str, bytes, IO[str], IO[bytes]]
63
+
64
+ FileType = Union[
65
+ # file (or bytes)
66
+ FileContent,
67
+ # (filename, file (or bytes))
68
+ Tuple[Optional[str], FileContent],
69
+ # (filename, file (or bytes), content_type)
70
+ Tuple[Optional[str], FileContent, Optional[str]],
71
+ ]
72
+
73
+ def serialize_multipart_data_entry(data_entry: Any) -> Any:
74
+ if isinstance(data_entry, (list, tuple, dict, Model)):
75
+ return json.dumps(data_entry, cls=SdkJSONEncoder, exclude_readonly=True)
76
+ return data_entry
77
+
78
+ def prepare_multipart_form_data(
79
+ body: Mapping[str, Any], multipart_fields: List[str], data_fields: List[str]
80
+ ) -> Tuple[List[FileType], Dict[str, Any]]:
81
+ files: List[FileType] = []
82
+ data: Dict[str, Any] = {}
83
+ for multipart_field in multipart_fields:
84
+ multipart_entry = body.get(multipart_field)
85
+ if isinstance(multipart_entry, list):
86
+ files.extend([(multipart_field, e) for e in multipart_entry ])
87
+ elif multipart_entry:
88
+ files.append((multipart_field, multipart_entry))
89
+
90
+ for data_field in data_fields:
91
+ data_entry = body.get(data_field)
92
+ if data_entry:
93
+ data[data_field] = serialize_multipart_data_entry(data_entry)
94
+
95
+ return files, data
96
+ {% endif %}
@@ -0,0 +1,4 @@
1
+ # coding=utf-8
2
+ {{ code_model.options['license_header'] }}
3
+
4
+ VERSION = "{{ code_model.options['package_version'] }}"
@@ -0,0 +1,65 @@
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
+ """An MD to RST plugin.
7
+ """
8
+ import logging
9
+ from typing import Any, Dict, Set, Union
10
+
11
+ import m2r2
12
+
13
+ from . import YamlUpdatePlugin
14
+ from .utils import parse_args
15
+
16
+
17
+ _LOGGER = logging.getLogger(__name__)
18
+
19
+
20
+ class GeneratorRenderer(m2r2.RestRenderer):
21
+ """Redefine the concept of inline HTML in the renderer, we don't want to define a new format
22
+ in the description/summary.
23
+ """
24
+
25
+ def inline_html(self, html: str) -> str:
26
+ """Do not render inline HTML with a role definition."""
27
+ return r"\ :code:`{}`".format(html)
28
+
29
+
30
+ class M2R(YamlUpdatePlugin):
31
+ """A plugin to convert any description and summary from MD to RST."""
32
+
33
+ def update_yaml(self, yaml_data: Dict[str, Any]) -> None:
34
+ """Convert in place the YAML str."""
35
+ self._convert_docstring_no_cycles(yaml_data, set())
36
+
37
+ def _convert_docstring_no_cycles(self, yaml_data: Union[Dict[str, Any], str], node_list: Set[int]) -> None:
38
+ """Walk the YAML tree to convert MD to RST."""
39
+ if id(yaml_data) in node_list:
40
+ return
41
+ node_list.add(id(yaml_data))
42
+
43
+ if isinstance(yaml_data, list):
44
+ for elt in yaml_data:
45
+ self._convert_docstring_no_cycles(elt, node_list)
46
+ elif isinstance(yaml_data, dict):
47
+ for key, value in yaml_data.items():
48
+ if key in ["description", "summary"]:
49
+ yaml_data[key] = self.convert_to_rst(value)
50
+ continue
51
+ self._convert_docstring_no_cycles(value, node_list)
52
+
53
+ @staticmethod
54
+ def convert_to_rst(string_to_convert: str) -> str:
55
+ """Convert that string from MD to RST."""
56
+ try:
57
+ return m2r2.convert(string_to_convert, renderer=GeneratorRenderer()).strip()
58
+ except Exception: # pylint: disable=broad-except
59
+ return string_to_convert
60
+
61
+
62
+ if __name__ == "__main__":
63
+ # CADL pipeline will call this
64
+ args, unknown_args = parse_args()
65
+ M2R(output_folder=args.output_folder, cadl_file=args.cadl_file, **unknown_args).process()