@typespec/http-client-python 0.19.1 → 0.19.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.
- package/dist/emitter/http.js +8 -0
- package/dist/emitter/http.js.map +1 -1
- package/dist/emitter/utils.d.ts.map +1 -1
- package/dist/emitter/utils.js +4 -0
- package/dist/emitter/utils.js.map +1 -1
- package/emitter/src/http.ts +8 -0
- package/emitter/src/utils.ts +4 -0
- package/emitter/temp/tsconfig.tsbuildinfo +1 -1
- package/eng/scripts/ci/conf.py +57 -0
- package/eng/scripts/ci/run_sphinx_build.py +117 -0
- package/eng/scripts/setup/__pycache__/package_manager.cpython-311.pyc +0 -0
- package/eng/scripts/setup/__pycache__/venvtools.cpython-311.pyc +0 -0
- package/generator/build/lib/pygen/codegen/models/operation.py +3 -3
- package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +29 -12
- package/generator/build/lib/pygen/codegen/serializers/parameter_serializer.py +3 -1
- package/generator/build/lib/pygen/codegen/templates/macros.jinja2 +33 -15
- package/generator/build/lib/pygen/codegen/templates/operation_tools.jinja2 +1 -15
- package/generator/component-detection-pip-report.json +6 -6
- package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
- package/generator/pygen/codegen/models/operation.py +3 -3
- package/generator/pygen/codegen/serializers/builder_serializer.py +29 -12
- package/generator/pygen/codegen/serializers/parameter_serializer.py +3 -1
- package/generator/pygen/codegen/templates/macros.jinja2 +33 -15
- package/generator/pygen/codegen/templates/operation_tools.jinja2 +1 -15
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_versioning_previewversion_async.py +53 -0
- package/generator/test/azure/mock_api_tests/test_azure_versioning_previewversion.py +50 -0
- package/generator/test/azure/requirements.txt +1 -0
- package/generator/test/azure/tox.ini +16 -8
- package/generator/test/dev_requirements.txt +4 -0
- package/generator/test/generic_mock_api_tests/asynctests/test_encode_bytes_async.py +1 -2
- package/generator/test/generic_mock_api_tests/asynctests/test_versioning_removed_async.py +16 -5
- package/generator/test/generic_mock_api_tests/test_encode_bytes.py +1 -2
- package/generator/test/generic_mock_api_tests/test_typetest_scalar.py +5 -0
- package/generator/test/generic_mock_api_tests/test_versioning_removed.py +16 -5
- package/generator/test/unbranded/tox.ini +16 -8
- package/package.json +2 -2
- package/eng/scripts/setup/__pycache__/package_manager.cpython-39.pyc +0 -0
- package/eng/scripts/setup/__pycache__/venvtools.cpython-39.pyc +0 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
|
|
3
|
+
# --------------------------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
5
|
+
# Licensed under the MIT License. See License.txt in the project root for license information.
|
|
6
|
+
# --------------------------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
# Central Sphinx configuration for all generated packages
|
|
9
|
+
|
|
10
|
+
import sys
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
# Basic project information
|
|
14
|
+
project = "Generated Python SDK"
|
|
15
|
+
copyright = "Microsoft Corporation"
|
|
16
|
+
author = "Microsoft Corporation"
|
|
17
|
+
|
|
18
|
+
# Sphinx extensions
|
|
19
|
+
extensions = [
|
|
20
|
+
"sphinx.ext.autodoc",
|
|
21
|
+
"sphinx.ext.napoleon",
|
|
22
|
+
"sphinx.ext.viewcode",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
# Napoleon settings for Google and NumPy style docstrings
|
|
26
|
+
napoleon_google_docstring = True
|
|
27
|
+
napoleon_numpy_docstring = True
|
|
28
|
+
napoleon_include_init_with_doc = True
|
|
29
|
+
napoleon_include_private_with_doc = False
|
|
30
|
+
napoleon_include_special_with_doc = True
|
|
31
|
+
napoleon_use_admonition_for_examples = False
|
|
32
|
+
napoleon_use_admonition_for_notes = False
|
|
33
|
+
napoleon_use_admonition_for_references = False
|
|
34
|
+
napoleon_use_ivar = True
|
|
35
|
+
napoleon_use_param = True
|
|
36
|
+
napoleon_use_rtype = True
|
|
37
|
+
napoleon_use_keyword = True
|
|
38
|
+
|
|
39
|
+
# Autodoc settings
|
|
40
|
+
autodoc_default_options = {
|
|
41
|
+
"members": True,
|
|
42
|
+
"undoc-members": True,
|
|
43
|
+
"show-inheritance": True,
|
|
44
|
+
"special-members": "__init__",
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
# HTML theme and output
|
|
48
|
+
html_theme = "basic"
|
|
49
|
+
html_static_path = []
|
|
50
|
+
html_show_sourcelink = False
|
|
51
|
+
html_show_sphinx = False
|
|
52
|
+
|
|
53
|
+
# Suppress warnings for missing references
|
|
54
|
+
suppress_warnings = []
|
|
55
|
+
|
|
56
|
+
# Master document
|
|
57
|
+
master_doc = "index"
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
|
|
3
|
+
# --------------------------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
5
|
+
# Licensed under the MIT License. See License.txt in the project root for license information.
|
|
6
|
+
# --------------------------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
# This script is used to execute sphinx documentation build within a tox environment.
|
|
9
|
+
# It uses a central sphinx configuration and validates docstrings by running sphinx-build.
|
|
10
|
+
|
|
11
|
+
from subprocess import check_call, CalledProcessError
|
|
12
|
+
import os
|
|
13
|
+
import logging
|
|
14
|
+
import sys
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from util import run_check
|
|
17
|
+
|
|
18
|
+
logging.getLogger().setLevel(logging.INFO)
|
|
19
|
+
|
|
20
|
+
# Get the central Sphinx config directory
|
|
21
|
+
SPHINX_CONF_DIR = os.path.abspath(os.path.dirname(__file__))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _create_minimal_index_rst(docs_dir, package_name, module_names):
|
|
25
|
+
"""Create a minimal index.rst file for sphinx to process."""
|
|
26
|
+
index_rst_content = f"""{package_name}
|
|
27
|
+
{"=" * len(package_name)}
|
|
28
|
+
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
for module_name in module_names:
|
|
32
|
+
index_rst_content += f"""
|
|
33
|
+
{module_name}
|
|
34
|
+
{"-" * len(module_name)}
|
|
35
|
+
|
|
36
|
+
.. automodule:: {module_name}
|
|
37
|
+
:members:
|
|
38
|
+
:undoc-members:
|
|
39
|
+
:show-inheritance:
|
|
40
|
+
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
index_rst_path = docs_dir / "index.rst"
|
|
44
|
+
with open(index_rst_path, "w") as f:
|
|
45
|
+
f.write(index_rst_content)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _single_dir_sphinx(mod):
|
|
49
|
+
"""Run sphinx-build on a single package directory."""
|
|
50
|
+
|
|
51
|
+
# Find the actual Python package directories
|
|
52
|
+
package_dirs = [
|
|
53
|
+
d for d in mod.iterdir() if d.is_dir() and not d.name.startswith("_") and (d / "__init__.py").exists()
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
if not package_dirs:
|
|
57
|
+
logging.info(f"No Python package found in {mod}, skipping sphinx build")
|
|
58
|
+
return True
|
|
59
|
+
|
|
60
|
+
# Get the main package directory
|
|
61
|
+
main_package = package_dirs[0]
|
|
62
|
+
|
|
63
|
+
# Find submodules
|
|
64
|
+
module_names = []
|
|
65
|
+
for item in main_package.iterdir():
|
|
66
|
+
if item.is_dir() and (item / "__init__.py").exists():
|
|
67
|
+
module_names.append(f"{main_package.name}.{item.name}")
|
|
68
|
+
|
|
69
|
+
# If no submodules, just use the main package
|
|
70
|
+
if not module_names:
|
|
71
|
+
module_names = [main_package.name]
|
|
72
|
+
|
|
73
|
+
# Create docs directory structure
|
|
74
|
+
docs_dir = mod / "docs"
|
|
75
|
+
docs_dir.mkdir(exist_ok=True)
|
|
76
|
+
|
|
77
|
+
# Create index.rst with the correct module names
|
|
78
|
+
_create_minimal_index_rst(docs_dir, mod.stem, module_names)
|
|
79
|
+
|
|
80
|
+
# Set up output directory
|
|
81
|
+
output_dir = mod / "_build" / "html"
|
|
82
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
83
|
+
|
|
84
|
+
# Add the package to sys.path so sphinx can import it
|
|
85
|
+
sys.path.insert(0, str(mod.absolute()))
|
|
86
|
+
|
|
87
|
+
try:
|
|
88
|
+
result = check_call(
|
|
89
|
+
[
|
|
90
|
+
sys.executable,
|
|
91
|
+
"-m",
|
|
92
|
+
"sphinx",
|
|
93
|
+
"-b",
|
|
94
|
+
"html", # Build HTML output
|
|
95
|
+
"-c",
|
|
96
|
+
SPHINX_CONF_DIR, # Use central config
|
|
97
|
+
"-W", # Treat warnings as errors
|
|
98
|
+
"--keep-going", # Continue to get all errors
|
|
99
|
+
"-E", # Don't use cached environment
|
|
100
|
+
"-q", # Quiet mode (only show warnings/errors)
|
|
101
|
+
str(docs_dir.absolute()), # Source directory
|
|
102
|
+
str(output_dir.absolute()), # Output directory
|
|
103
|
+
]
|
|
104
|
+
)
|
|
105
|
+
logging.info(f"Sphinx build completed successfully for {mod.stem}")
|
|
106
|
+
return True
|
|
107
|
+
except CalledProcessError as e:
|
|
108
|
+
logging.error(f"{mod.stem} exited with sphinx build error {e.returncode}")
|
|
109
|
+
return False
|
|
110
|
+
finally:
|
|
111
|
+
# Remove from sys.path
|
|
112
|
+
if str(mod.absolute()) in sys.path:
|
|
113
|
+
sys.path.remove(str(mod.absolute()))
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
if __name__ == "__main__":
|
|
117
|
+
run_check("sphinx", _single_dir_sphinx, "Sphinx documentation build")
|
|
Binary file
|
|
Binary file
|
|
@@ -200,10 +200,10 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
|
|
|
200
200
|
if isinstance(exception_schema, ModelType):
|
|
201
201
|
pylint_disable = " # pylint: disable=protected-access" if exception_schema.internal else ""
|
|
202
202
|
return (
|
|
203
|
-
exception_schema.type_annotation(skip_quote=True, serialize_namespace=serialize_namespace)
|
|
204
|
-
|
|
203
|
+
f"{exception_schema.type_annotation(skip_quote=True, serialize_namespace=serialize_namespace)},"
|
|
204
|
+
f"{pylint_disable}"
|
|
205
205
|
)
|
|
206
|
-
return None if self.code_model.options["models-mode"] == "dpg" else "'object'"
|
|
206
|
+
return None if self.code_model.options["models-mode"] == "dpg" else "'object',"
|
|
207
207
|
|
|
208
208
|
@property
|
|
209
209
|
def non_default_errors(self) -> list[Response]:
|
|
@@ -1053,10 +1053,13 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]):
|
|
|
1053
1053
|
f" error = _failsafe_deserialize({type_annotation},{pylint_disable}\n response)"
|
|
1054
1054
|
)
|
|
1055
1055
|
else:
|
|
1056
|
-
retval.
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1056
|
+
retval.extend(
|
|
1057
|
+
[
|
|
1058
|
+
" error = self._deserialize.failsafe_deserialize(",
|
|
1059
|
+
f" {type_annotation},{pylint_disable}",
|
|
1060
|
+
" pipeline_response,",
|
|
1061
|
+
" )",
|
|
1062
|
+
]
|
|
1060
1063
|
)
|
|
1061
1064
|
# add build-in error type
|
|
1062
1065
|
# TODO: we should decide whether need to this wrapper for customized error type
|
|
@@ -1097,10 +1100,13 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]):
|
|
|
1097
1100
|
f"{type_annotation},{pylint_disable}\n response)"
|
|
1098
1101
|
)
|
|
1099
1102
|
else:
|
|
1100
|
-
retval.
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1103
|
+
retval.extend(
|
|
1104
|
+
[
|
|
1105
|
+
" error = self._deserialize.failsafe_deserialize(",
|
|
1106
|
+
f" {type_annotation},{pylint_disable}",
|
|
1107
|
+
" pipeline_response,",
|
|
1108
|
+
" )",
|
|
1109
|
+
]
|
|
1104
1110
|
)
|
|
1105
1111
|
condition = "elif"
|
|
1106
1112
|
# default error handling
|
|
@@ -1111,11 +1117,22 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]):
|
|
|
1111
1117
|
if builder.non_default_errors:
|
|
1112
1118
|
retval.append(" else:")
|
|
1113
1119
|
if self.code_model.options["models-mode"] == "dpg":
|
|
1114
|
-
retval.
|
|
1120
|
+
retval.extend(
|
|
1121
|
+
[
|
|
1122
|
+
f"{indent}error = _failsafe_deserialize(",
|
|
1123
|
+
f"{indent} {default_error_deserialization}",
|
|
1124
|
+
f"{indent} response,",
|
|
1125
|
+
f"{indent})",
|
|
1126
|
+
]
|
|
1127
|
+
)
|
|
1115
1128
|
else:
|
|
1116
|
-
retval.
|
|
1117
|
-
|
|
1118
|
-
|
|
1129
|
+
retval.extend(
|
|
1130
|
+
[
|
|
1131
|
+
f"{indent}error = self._deserialize.failsafe_deserialize(",
|
|
1132
|
+
f"{indent} {default_error_deserialization}",
|
|
1133
|
+
f"{indent} pipeline_response,",
|
|
1134
|
+
f"{indent})",
|
|
1135
|
+
]
|
|
1119
1136
|
)
|
|
1120
1137
|
retval.append(
|
|
1121
1138
|
" raise HttpResponseError(response=response{}{})".format(
|
|
@@ -202,9 +202,11 @@ class ParameterSerializer:
|
|
|
202
202
|
if is_content_type_optional and not type_annotation.startswith("Optional[")
|
|
203
203
|
else type_annotation
|
|
204
204
|
)
|
|
205
|
-
if kwarg.client_default_value is not None or kwarg.optional:
|
|
205
|
+
if kwarg.client_default_value is not None or kwarg.optional or kwarg.constant:
|
|
206
206
|
if check_client_input and kwarg.check_client_input:
|
|
207
207
|
default_value = f"self._config.{kwarg.client_name}"
|
|
208
|
+
elif kwarg.constant:
|
|
209
|
+
default_value = kwarg.type.get_declaration(None)
|
|
208
210
|
else:
|
|
209
211
|
default_value = kwarg.client_default_value_declaration
|
|
210
212
|
if check_kwarg_dict and (kwarg.location in [ParameterLocation.HEADER, ParameterLocation.QUERY]):
|
|
@@ -1,21 +1,39 @@
|
|
|
1
1
|
{% macro wrap_model_string(doc_string, wrap_string, suffix_string="") %}
|
|
2
|
-
{
|
|
3
|
-
{%- set
|
|
4
|
-
{
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
{%-
|
|
15
|
-
{%- set
|
|
2
|
+
{# Check if this is a sphinx documentation line that should not have extra prefix spacing #}
|
|
3
|
+
{%- set is_sphinx_doc = doc_string.strip().startswith(':ivar') or doc_string.strip().startswith(':vartype') or doc_string.strip().startswith(':param') or doc_string.strip().startswith(':type') -%}
|
|
4
|
+
{# Custom handling for bullet points - normalization is now done in preprocessing #}
|
|
5
|
+
{% set enable_custom_handling = "* " in doc_string %}
|
|
6
|
+
{%- if enable_custom_handling -%}
|
|
7
|
+
{%- set lines = doc_string.split('\n') -%}
|
|
8
|
+
{%- set result_lines = [] -%}
|
|
9
|
+
{%- for line in lines -%}
|
|
10
|
+
{%- if line.startswith('* ') -%}
|
|
11
|
+
{# Handle bullet points with proper continuation alignment #}
|
|
12
|
+
{%- set bullet_content = line[2:] -%}
|
|
13
|
+
{%- set base_indent = wrap_string.lstrip('\n') -%}
|
|
14
|
+
{%- set bullet_line = base_indent + ' * ' + bullet_content -%}
|
|
15
|
+
{%- set continuation_spaces = base_indent + ' ' -%}
|
|
16
|
+
{%- set wrapped = bullet_line | wordwrap(width=95, break_long_words=False, break_on_hyphens=False, wrapstring='\n' + continuation_spaces) -%}
|
|
17
|
+
{%- set _ = result_lines.append(wrapped) -%}
|
|
18
|
+
{%- elif line.strip() -%}
|
|
19
|
+
{%- set wrapped = line.strip() | wordwrap(width=95, break_long_words=False, break_on_hyphens=False, wrapstring=wrap_string) -%}
|
|
20
|
+
{%- set _ = result_lines.append(wrapped) -%}
|
|
21
|
+
{%- else -%}
|
|
22
|
+
{%- set _ = result_lines.append('') -%}
|
|
23
|
+
{%- endif -%}
|
|
24
|
+
{%- endfor -%}
|
|
25
|
+
{%- set original_result = result_lines | join('\n') -%}
|
|
26
|
+
{%- else -%}
|
|
27
|
+
{# Regular text handling #}
|
|
28
|
+
{%- set original_result = doc_string | wordwrap(width=95, break_long_words=False, break_on_hyphens=False, wrapstring=wrap_string) -%}
|
|
29
|
+
{%- endif -%}
|
|
16
30
|
{% set list_result = original_result.split('\n') %}
|
|
17
31
|
{% for line in list_result %}
|
|
18
|
-
{
|
|
32
|
+
{%- if is_sphinx_doc and enable_custom_handling -%}
|
|
33
|
+
{%- set prefix = "" -%}
|
|
34
|
+
{%- else -%}
|
|
35
|
+
{%- set prefix = "" if loop.index == 1 else " " -%}
|
|
36
|
+
{%- endif -%}
|
|
19
37
|
{% set suffix = suffix_string if list_result | length == loop.index %}
|
|
20
38
|
{{ prefix }}{{ line }}{{ suffix }}
|
|
21
39
|
{% endfor %}
|
|
@@ -1,18 +1,4 @@
|
|
|
1
|
-
{% macro wrap_string(string, wrapstring, width=95) %}
|
|
2
|
-
{%- set lines = string.split('\n') -%}
|
|
3
|
-
{%- set processed_lines = [] -%}
|
|
4
|
-
{%- for line in lines -%}
|
|
5
|
-
{%- set stripped = line.strip() -%}
|
|
6
|
-
{%- if stripped.startswith('* ') -%}
|
|
7
|
-
{%- set bullet_with_indent = stripped -%}
|
|
8
|
-
{%- set wrapped = bullet_with_indent | wordwrap(width=width, break_long_words=False, break_on_hyphens=False, wrapstring=wrapstring + ' ') -%}
|
|
9
|
-
{%- set _ = processed_lines.append(wrapped) -%}
|
|
10
|
-
{%- elif stripped -%}
|
|
11
|
-
{%- set wrapped = line | wordwrap(width=width, break_long_words=False, break_on_hyphens=False, wrapstring=wrapstring) -%}
|
|
12
|
-
{%- set _ = processed_lines.append(wrapped) -%}
|
|
13
|
-
{%- endif -%}
|
|
14
|
-
{%- endfor -%}
|
|
15
|
-
{{ processed_lines | join('\n') | replace("\\", "\\\\") }}{%- endmacro %}
|
|
1
|
+
{% macro wrap_string(string, wrapstring, width=95) %}{{ string | replace("\\", "\\\\") | wordwrap(width=width, break_long_words=False, break_on_hyphens=False, wrapstring=wrapstring)}}{% endmacro %}
|
|
16
2
|
|
|
17
3
|
{% macro description(builder, serializer) %}
|
|
18
4
|
{% set example_template = serializer.example_template(builder) %}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "1",
|
|
3
|
-
"pip_version": "25.
|
|
3
|
+
"pip_version": "25.3",
|
|
4
4
|
"install": [
|
|
5
5
|
{
|
|
6
6
|
"download_info": {
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"license-file"
|
|
24
24
|
],
|
|
25
25
|
"summary": "Easily download, build, install, upgrade, and uninstall Python packages",
|
|
26
|
+
"description": ".. |pypi-version| image:: https://img.shields.io/pypi/v/setuptools.svg\n :target: https://pypi.org/project/setuptools\n\n.. |py-version| image:: https://img.shields.io/pypi/pyversions/setuptools.svg\n\n.. |test-badge| image:: https://github.com/pypa/setuptools/actions/workflows/main.yml/badge.svg\n :target: https://github.com/pypa/setuptools/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. |ruff-badge| image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json\n :target: https://github.com/astral-sh/ruff\n :alt: Ruff\n\n.. |docs-badge| image:: https://img.shields.io/readthedocs/setuptools/latest.svg\n :target: https://setuptools.pypa.io\n\n.. |skeleton-badge| image:: https://img.shields.io/badge/skeleton-2025-informational\n :target: https://blog.jaraco.com/skeleton\n\n.. |codecov-badge| image:: https://img.shields.io/codecov/c/github/pypa/setuptools/master.svg?logo=codecov&logoColor=white\n :target: https://codecov.io/gh/pypa/setuptools\n\n.. |tidelift-badge| image:: https://tidelift.com/badges/github/pypa/setuptools?style=flat\n :target: https://tidelift.com/subscription/pkg/pypi-setuptools?utm_source=pypi-setuptools&utm_medium=readme\n\n.. |discord-badge| image:: https://img.shields.io/discord/803025117553754132\n :target: https://discord.com/channels/803025117553754132/815945031150993468\n :alt: Discord\n\n|pypi-version| |py-version| |test-badge| |ruff-badge| |docs-badge| |skeleton-badge| |codecov-badge| |discord-badge|\n\nSee the `Quickstart <https://setuptools.pypa.io/en/latest/userguide/quickstart.html>`_\nand the `User's Guide <https://setuptools.pypa.io/en/latest/userguide/>`_ for\ninstructions on how to use Setuptools.\n\nQuestions and comments should be directed to `GitHub Discussions\n<https://github.com/pypa/setuptools/discussions>`_.\nBug reports and especially tested patches may be\nsubmitted directly to the `bug tracker\n<https://github.com/pypa/setuptools/issues>`_.\n\n\nCode of Conduct\n===============\n\nEveryone interacting in the setuptools project's codebases, issue trackers,\nchat rooms, and fora is expected to follow the\n`PSF Code of Conduct <https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md>`_.\n\n\nFor Enterprise\n==============\n\nAvailable as part of the Tidelift Subscription.\n\nSetuptools and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.\n\n`Learn more <https://tidelift.com/subscription/pkg/pypi-setuptools?utm_source=pypi-setuptools&utm_medium=referral&utm_campaign=github>`_.\n",
|
|
26
27
|
"description_content_type": "text/x-rst",
|
|
27
28
|
"keywords": [
|
|
28
29
|
"CPAN",
|
|
@@ -116,22 +117,21 @@
|
|
|
116
117
|
"cover",
|
|
117
118
|
"enabler",
|
|
118
119
|
"type"
|
|
119
|
-
]
|
|
120
|
-
"description": ".. |pypi-version| image:: https://img.shields.io/pypi/v/setuptools.svg\n :target: https://pypi.org/project/setuptools\n\n.. |py-version| image:: https://img.shields.io/pypi/pyversions/setuptools.svg\n\n.. |test-badge| image:: https://github.com/pypa/setuptools/actions/workflows/main.yml/badge.svg\n :target: https://github.com/pypa/setuptools/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. |ruff-badge| image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json\n :target: https://github.com/astral-sh/ruff\n :alt: Ruff\n\n.. |docs-badge| image:: https://img.shields.io/readthedocs/setuptools/latest.svg\n :target: https://setuptools.pypa.io\n\n.. |skeleton-badge| image:: https://img.shields.io/badge/skeleton-2025-informational\n :target: https://blog.jaraco.com/skeleton\n\n.. |codecov-badge| image:: https://img.shields.io/codecov/c/github/pypa/setuptools/master.svg?logo=codecov&logoColor=white\n :target: https://codecov.io/gh/pypa/setuptools\n\n.. |tidelift-badge| image:: https://tidelift.com/badges/github/pypa/setuptools?style=flat\n :target: https://tidelift.com/subscription/pkg/pypi-setuptools?utm_source=pypi-setuptools&utm_medium=readme\n\n.. |discord-badge| image:: https://img.shields.io/discord/803025117553754132\n :target: https://discord.com/channels/803025117553754132/815945031150993468\n :alt: Discord\n\n|pypi-version| |py-version| |test-badge| |ruff-badge| |docs-badge| |skeleton-badge| |codecov-badge| |discord-badge|\n\nSee the `Quickstart <https://setuptools.pypa.io/en/latest/userguide/quickstart.html>`_\nand the `User's Guide <https://setuptools.pypa.io/en/latest/userguide/>`_ for\ninstructions on how to use Setuptools.\n\nQuestions and comments should be directed to `GitHub Discussions\n<https://github.com/pypa/setuptools/discussions>`_.\nBug reports and especially tested patches may be\nsubmitted directly to the `bug tracker\n<https://github.com/pypa/setuptools/issues>`_.\n\n\nCode of Conduct\n===============\n\nEveryone interacting in the setuptools project's codebases, issue trackers,\nchat rooms, and fora is expected to follow the\n`PSF Code of Conduct <https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md>`_.\n\n\nFor Enterprise\n==============\n\nAvailable as part of the Tidelift Subscription.\n\nSetuptools and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.\n\n`Learn more <https://tidelift.com/subscription/pkg/pypi-setuptools?utm_source=pypi-setuptools&utm_medium=referral&utm_campaign=github>`_.\n"
|
|
120
|
+
]
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
],
|
|
124
124
|
"environment": {
|
|
125
125
|
"implementation_name": "cpython",
|
|
126
|
-
"implementation_version": "3.
|
|
126
|
+
"implementation_version": "3.11.13",
|
|
127
127
|
"os_name": "posix",
|
|
128
128
|
"platform_machine": "x86_64",
|
|
129
129
|
"platform_release": "6.11.0-1018-azure",
|
|
130
130
|
"platform_system": "Linux",
|
|
131
131
|
"platform_version": "#18~24.04.1-Ubuntu SMP Sat Jun 28 04:46:03 UTC 2025",
|
|
132
|
-
"python_full_version": "3.
|
|
132
|
+
"python_full_version": "3.11.13",
|
|
133
133
|
"platform_python_implementation": "CPython",
|
|
134
|
-
"python_version": "3.
|
|
134
|
+
"python_version": "3.11",
|
|
135
135
|
"sys_platform": "linux"
|
|
136
136
|
}
|
|
137
137
|
}
|
|
Binary file
|
|
@@ -200,10 +200,10 @@ class OperationBase( # pylint: disable=too-many-public-methods,too-many-instanc
|
|
|
200
200
|
if isinstance(exception_schema, ModelType):
|
|
201
201
|
pylint_disable = " # pylint: disable=protected-access" if exception_schema.internal else ""
|
|
202
202
|
return (
|
|
203
|
-
exception_schema.type_annotation(skip_quote=True, serialize_namespace=serialize_namespace)
|
|
204
|
-
|
|
203
|
+
f"{exception_schema.type_annotation(skip_quote=True, serialize_namespace=serialize_namespace)},"
|
|
204
|
+
f"{pylint_disable}"
|
|
205
205
|
)
|
|
206
|
-
return None if self.code_model.options["models-mode"] == "dpg" else "'object'"
|
|
206
|
+
return None if self.code_model.options["models-mode"] == "dpg" else "'object',"
|
|
207
207
|
|
|
208
208
|
@property
|
|
209
209
|
def non_default_errors(self) -> list[Response]:
|
|
@@ -1053,10 +1053,13 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]):
|
|
|
1053
1053
|
f" error = _failsafe_deserialize({type_annotation},{pylint_disable}\n response)"
|
|
1054
1054
|
)
|
|
1055
1055
|
else:
|
|
1056
|
-
retval.
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1056
|
+
retval.extend(
|
|
1057
|
+
[
|
|
1058
|
+
" error = self._deserialize.failsafe_deserialize(",
|
|
1059
|
+
f" {type_annotation},{pylint_disable}",
|
|
1060
|
+
" pipeline_response,",
|
|
1061
|
+
" )",
|
|
1062
|
+
]
|
|
1060
1063
|
)
|
|
1061
1064
|
# add build-in error type
|
|
1062
1065
|
# TODO: we should decide whether need to this wrapper for customized error type
|
|
@@ -1097,10 +1100,13 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]):
|
|
|
1097
1100
|
f"{type_annotation},{pylint_disable}\n response)"
|
|
1098
1101
|
)
|
|
1099
1102
|
else:
|
|
1100
|
-
retval.
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1103
|
+
retval.extend(
|
|
1104
|
+
[
|
|
1105
|
+
" error = self._deserialize.failsafe_deserialize(",
|
|
1106
|
+
f" {type_annotation},{pylint_disable}",
|
|
1107
|
+
" pipeline_response,",
|
|
1108
|
+
" )",
|
|
1109
|
+
]
|
|
1104
1110
|
)
|
|
1105
1111
|
condition = "elif"
|
|
1106
1112
|
# default error handling
|
|
@@ -1111,11 +1117,22 @@ class _OperationSerializer(_BuilderBaseSerializer[OperationType]):
|
|
|
1111
1117
|
if builder.non_default_errors:
|
|
1112
1118
|
retval.append(" else:")
|
|
1113
1119
|
if self.code_model.options["models-mode"] == "dpg":
|
|
1114
|
-
retval.
|
|
1120
|
+
retval.extend(
|
|
1121
|
+
[
|
|
1122
|
+
f"{indent}error = _failsafe_deserialize(",
|
|
1123
|
+
f"{indent} {default_error_deserialization}",
|
|
1124
|
+
f"{indent} response,",
|
|
1125
|
+
f"{indent})",
|
|
1126
|
+
]
|
|
1127
|
+
)
|
|
1115
1128
|
else:
|
|
1116
|
-
retval.
|
|
1117
|
-
|
|
1118
|
-
|
|
1129
|
+
retval.extend(
|
|
1130
|
+
[
|
|
1131
|
+
f"{indent}error = self._deserialize.failsafe_deserialize(",
|
|
1132
|
+
f"{indent} {default_error_deserialization}",
|
|
1133
|
+
f"{indent} pipeline_response,",
|
|
1134
|
+
f"{indent})",
|
|
1135
|
+
]
|
|
1119
1136
|
)
|
|
1120
1137
|
retval.append(
|
|
1121
1138
|
" raise HttpResponseError(response=response{}{})".format(
|
|
@@ -202,9 +202,11 @@ class ParameterSerializer:
|
|
|
202
202
|
if is_content_type_optional and not type_annotation.startswith("Optional[")
|
|
203
203
|
else type_annotation
|
|
204
204
|
)
|
|
205
|
-
if kwarg.client_default_value is not None or kwarg.optional:
|
|
205
|
+
if kwarg.client_default_value is not None or kwarg.optional or kwarg.constant:
|
|
206
206
|
if check_client_input and kwarg.check_client_input:
|
|
207
207
|
default_value = f"self._config.{kwarg.client_name}"
|
|
208
|
+
elif kwarg.constant:
|
|
209
|
+
default_value = kwarg.type.get_declaration(None)
|
|
208
210
|
else:
|
|
209
211
|
default_value = kwarg.client_default_value_declaration
|
|
210
212
|
if check_kwarg_dict and (kwarg.location in [ParameterLocation.HEADER, ParameterLocation.QUERY]):
|
|
@@ -1,21 +1,39 @@
|
|
|
1
1
|
{% macro wrap_model_string(doc_string, wrap_string, suffix_string="") %}
|
|
2
|
-
{
|
|
3
|
-
{%- set
|
|
4
|
-
{
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
{%-
|
|
15
|
-
{%- set
|
|
2
|
+
{# Check if this is a sphinx documentation line that should not have extra prefix spacing #}
|
|
3
|
+
{%- set is_sphinx_doc = doc_string.strip().startswith(':ivar') or doc_string.strip().startswith(':vartype') or doc_string.strip().startswith(':param') or doc_string.strip().startswith(':type') -%}
|
|
4
|
+
{# Custom handling for bullet points - normalization is now done in preprocessing #}
|
|
5
|
+
{% set enable_custom_handling = "* " in doc_string %}
|
|
6
|
+
{%- if enable_custom_handling -%}
|
|
7
|
+
{%- set lines = doc_string.split('\n') -%}
|
|
8
|
+
{%- set result_lines = [] -%}
|
|
9
|
+
{%- for line in lines -%}
|
|
10
|
+
{%- if line.startswith('* ') -%}
|
|
11
|
+
{# Handle bullet points with proper continuation alignment #}
|
|
12
|
+
{%- set bullet_content = line[2:] -%}
|
|
13
|
+
{%- set base_indent = wrap_string.lstrip('\n') -%}
|
|
14
|
+
{%- set bullet_line = base_indent + ' * ' + bullet_content -%}
|
|
15
|
+
{%- set continuation_spaces = base_indent + ' ' -%}
|
|
16
|
+
{%- set wrapped = bullet_line | wordwrap(width=95, break_long_words=False, break_on_hyphens=False, wrapstring='\n' + continuation_spaces) -%}
|
|
17
|
+
{%- set _ = result_lines.append(wrapped) -%}
|
|
18
|
+
{%- elif line.strip() -%}
|
|
19
|
+
{%- set wrapped = line.strip() | wordwrap(width=95, break_long_words=False, break_on_hyphens=False, wrapstring=wrap_string) -%}
|
|
20
|
+
{%- set _ = result_lines.append(wrapped) -%}
|
|
21
|
+
{%- else -%}
|
|
22
|
+
{%- set _ = result_lines.append('') -%}
|
|
23
|
+
{%- endif -%}
|
|
24
|
+
{%- endfor -%}
|
|
25
|
+
{%- set original_result = result_lines | join('\n') -%}
|
|
26
|
+
{%- else -%}
|
|
27
|
+
{# Regular text handling #}
|
|
28
|
+
{%- set original_result = doc_string | wordwrap(width=95, break_long_words=False, break_on_hyphens=False, wrapstring=wrap_string) -%}
|
|
29
|
+
{%- endif -%}
|
|
16
30
|
{% set list_result = original_result.split('\n') %}
|
|
17
31
|
{% for line in list_result %}
|
|
18
|
-
{
|
|
32
|
+
{%- if is_sphinx_doc and enable_custom_handling -%}
|
|
33
|
+
{%- set prefix = "" -%}
|
|
34
|
+
{%- else -%}
|
|
35
|
+
{%- set prefix = "" if loop.index == 1 else " " -%}
|
|
36
|
+
{%- endif -%}
|
|
19
37
|
{% set suffix = suffix_string if list_result | length == loop.index %}
|
|
20
38
|
{{ prefix }}{{ line }}{{ suffix }}
|
|
21
39
|
{% endfor %}
|
|
@@ -1,18 +1,4 @@
|
|
|
1
|
-
{% macro wrap_string(string, wrapstring, width=95) %}
|
|
2
|
-
{%- set lines = string.split('\n') -%}
|
|
3
|
-
{%- set processed_lines = [] -%}
|
|
4
|
-
{%- for line in lines -%}
|
|
5
|
-
{%- set stripped = line.strip() -%}
|
|
6
|
-
{%- if stripped.startswith('* ') -%}
|
|
7
|
-
{%- set bullet_with_indent = stripped -%}
|
|
8
|
-
{%- set wrapped = bullet_with_indent | wordwrap(width=width, break_long_words=False, break_on_hyphens=False, wrapstring=wrapstring + ' ') -%}
|
|
9
|
-
{%- set _ = processed_lines.append(wrapped) -%}
|
|
10
|
-
{%- elif stripped -%}
|
|
11
|
-
{%- set wrapped = line | wordwrap(width=width, break_long_words=False, break_on_hyphens=False, wrapstring=wrapstring) -%}
|
|
12
|
-
{%- set _ = processed_lines.append(wrapped) -%}
|
|
13
|
-
{%- endif -%}
|
|
14
|
-
{%- endfor -%}
|
|
15
|
-
{{ processed_lines | join('\n') | replace("\\", "\\\\") }}{%- endmacro %}
|
|
1
|
+
{% macro wrap_string(string, wrapstring, width=95) %}{{ string | replace("\\", "\\\\") | wordwrap(width=width, break_long_words=False, break_on_hyphens=False, wrapstring=wrapstring)}}{% endmacro %}
|
|
16
2
|
|
|
17
3
|
{% macro description(builder, serializer) %}
|
|
18
4
|
{% set example_template = serializer.example_template(builder) %}
|
package/generator/test/azure/mock_api_tests/asynctests/test_azure_versioning_previewversion_async.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
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 pytest
|
|
7
|
+
from specs.azure.versioning.previewversion.aio import PreviewVersionClient
|
|
8
|
+
from specs.azure.versioning.previewversion.models import UpdateWidgetColorRequest
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@pytest.fixture
|
|
12
|
+
async def client():
|
|
13
|
+
async with PreviewVersionClient() as client:
|
|
14
|
+
yield client
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@pytest.fixture
|
|
18
|
+
async def stable_client():
|
|
19
|
+
async with PreviewVersionClient(api_version="2024-06-01") as client:
|
|
20
|
+
yield client
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@pytest.mark.asyncio
|
|
24
|
+
async def test_get_widget(client: PreviewVersionClient):
|
|
25
|
+
result = await client.get_widget(id="widget-123")
|
|
26
|
+
assert result.id == "widget-123"
|
|
27
|
+
assert result.name == "Sample Widget"
|
|
28
|
+
assert result.color == "blue"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@pytest.mark.asyncio
|
|
32
|
+
async def test_update_widget_color(client: PreviewVersionClient):
|
|
33
|
+
color_update = UpdateWidgetColorRequest(color="red")
|
|
34
|
+
result = await client.update_widget_color(id="widget-123", color_update=color_update)
|
|
35
|
+
assert result.id == "widget-123"
|
|
36
|
+
assert result.name == "Sample Widget"
|
|
37
|
+
assert result.color == "red"
|
|
38
|
+
|
|
39
|
+
with pytest.raises(ValueError):
|
|
40
|
+
async with PreviewVersionClient(api_version="2024-06-01") as stable_client:
|
|
41
|
+
await stable_client.update_widget_color(id="widget-123", color_update=color_update)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@pytest.mark.asyncio
|
|
45
|
+
async def test_list_widgets(stable_client: PreviewVersionClient):
|
|
46
|
+
result = await stable_client.list_widgets(name="test")
|
|
47
|
+
assert len(result.widgets) == 1
|
|
48
|
+
assert result.widgets[0].id == "widget-1"
|
|
49
|
+
assert result.widgets[0].name == "test"
|
|
50
|
+
|
|
51
|
+
with pytest.raises(ValueError):
|
|
52
|
+
async with PreviewVersionClient(api_version="2024-06-01") as client:
|
|
53
|
+
await client.list_widgets(name="test", color="test")
|