@typespec/http-client-python 0.28.2 → 0.29.0

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 (368) hide show
  1. package/dist/emitter/code-model.d.ts.map +1 -1
  2. package/dist/emitter/code-model.js +7 -6
  3. package/dist/emitter/code-model.js.map +1 -1
  4. package/dist/emitter/constants.d.ts +6 -0
  5. package/dist/emitter/constants.d.ts.map +1 -0
  6. package/dist/emitter/constants.js +27 -0
  7. package/dist/emitter/constants.js.map +1 -0
  8. package/dist/emitter/emitter.d.ts.map +1 -1
  9. package/dist/emitter/emitter.js +193 -119
  10. package/dist/emitter/emitter.js.map +1 -1
  11. package/dist/emitter/http.d.ts.map +1 -1
  12. package/dist/emitter/http.js +33 -1
  13. package/dist/emitter/http.js.map +1 -1
  14. package/dist/emitter/lib.d.ts +37 -3
  15. package/dist/emitter/lib.d.ts.map +1 -1
  16. package/dist/emitter/lib.js +17 -0
  17. package/dist/emitter/lib.js.map +1 -1
  18. package/dist/emitter/run-python3.js +1 -1
  19. package/dist/emitter/run-python3.js.map +1 -1
  20. package/dist/emitter/system-requirements.js +6 -4
  21. package/dist/emitter/system-requirements.js.map +1 -1
  22. package/dist/emitter/types.d.ts +2 -5
  23. package/dist/emitter/types.d.ts.map +1 -1
  24. package/dist/emitter/types.js +86 -63
  25. package/dist/emitter/types.js.map +1 -1
  26. package/dist/emitter/utils.d.ts.map +1 -1
  27. package/dist/emitter/utils.js +16 -17
  28. package/dist/emitter/utils.js.map +1 -1
  29. package/emitter/src/code-model.ts +7 -13
  30. package/emitter/src/constants.ts +27 -0
  31. package/emitter/src/emitter.ts +241 -123
  32. package/emitter/src/http.ts +29 -1
  33. package/emitter/src/lib.ts +24 -0
  34. package/emitter/src/run-python3.ts +1 -1
  35. package/emitter/src/system-requirements.ts +4 -4
  36. package/emitter/src/types.ts +102 -62
  37. package/emitter/src/utils.ts +16 -18
  38. package/emitter/temp/tsconfig.tsbuildinfo +1 -1
  39. package/emitter/test/utils.test.ts +3 -0
  40. package/emitter/tsconfig.build.json +2 -1
  41. package/emitter/tsconfig.json +2 -1
  42. package/eng/scripts/Build-Packages.ps1 +62 -37
  43. package/eng/scripts/Check-GitChanges.ps1 +30 -3
  44. package/eng/scripts/Functions.ps1 +54 -15
  45. package/eng/scripts/Generate.ps1 +42 -8
  46. package/eng/scripts/Generation.psm1 +44 -15
  47. package/eng/scripts/Initialize-Repository.ps1 +29 -11
  48. package/eng/scripts/Test-Packages.ps1 +47 -31
  49. package/eng/scripts/ci/config/eslint-ci.config.mjs +64 -0
  50. package/eng/scripts/ci/{mypy.ini → config/mypy.ini} +1 -1
  51. package/eng/scripts/ci/{pylintrc → config/pylintrc} +1 -1
  52. package/eng/scripts/ci/{pyrightconfig.json → config/pyrightconfig.json} +1 -1
  53. package/eng/scripts/ci/dev_requirements.txt +2 -1
  54. package/eng/scripts/ci/format.ts +232 -2
  55. package/eng/scripts/ci/lint.ts +223 -20
  56. package/eng/scripts/ci/regenerate-common.ts +411 -136
  57. package/eng/scripts/ci/regenerate.ts +247 -101
  58. package/eng/scripts/ci/run-tests.ts +507 -0
  59. package/eng/scripts/ci/run_apiview.py +22 -16
  60. package/eng/scripts/ci/run_mypy.py +34 -23
  61. package/eng/scripts/ci/run_pylint.py +27 -19
  62. package/eng/scripts/ci/run_pyright.py +9 -5
  63. package/eng/scripts/ci/run_sphinx_build.py +24 -9
  64. package/eng/scripts/ci/typecheck.ts +225 -0
  65. package/eng/scripts/ci/util.py +61 -25
  66. package/eng/scripts/ci/utils.ts +5 -5
  67. package/eng/scripts/setup/__pycache__/package_manager.cpython-311.pyc +0 -0
  68. package/eng/scripts/setup/__pycache__/venvtools.cpython-311.pyc +0 -0
  69. package/eng/scripts/setup/build.ts +1 -1
  70. package/eng/scripts/setup/build_pygen_wheel.py +4 -3
  71. package/eng/scripts/setup/install.py +4 -3
  72. package/eng/scripts/setup/install.ts +1 -1
  73. package/eng/scripts/setup/prepare.py +3 -2
  74. package/eng/scripts/setup/prepare.ts +1 -1
  75. package/eng/scripts/setup/run-python3.ts +1 -1
  76. package/eng/scripts/setup/run_batch.py +197 -0
  77. package/eng/scripts/setup/run_tsp.py +3 -3
  78. package/eng/scripts/setup/system-requirements.ts +8 -4
  79. package/eng/scripts/setup/venvtools.py +1 -1
  80. package/generator/build/lib/pygen/__init__.py +1 -3
  81. package/generator/build/lib/pygen/codegen/__init__.py +0 -1
  82. package/generator/build/lib/pygen/codegen/models/base.py +0 -1
  83. package/generator/build/lib/pygen/codegen/models/client.py +2 -1
  84. package/generator/build/lib/pygen/codegen/models/code_model.py +1 -0
  85. package/generator/build/lib/pygen/codegen/models/enum_type.py +0 -1
  86. package/generator/build/lib/pygen/codegen/models/model_type.py +1 -7
  87. package/generator/build/lib/pygen/codegen/models/parameter.py +16 -14
  88. package/generator/build/lib/pygen/codegen/serializers/__init__.py +27 -12
  89. package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +12 -3
  90. package/generator/build/lib/pygen/codegen/serializers/general_serializer.py +6 -2
  91. package/generator/build/lib/pygen/codegen/serializers/import_serializer.py +17 -4
  92. package/generator/build/lib/pygen/codegen/serializers/parameter_serializer.py +17 -11
  93. package/generator/build/lib/pygen/codegen/templates/model_base.py.jinja2 +176 -71
  94. package/generator/build/lib/pygen/codegen/templates/packaging_templates/README.md.jinja2 +11 -3
  95. package/generator/build/lib/pygen/codegen/templates/packaging_templates/pyproject.toml.jinja2 +1 -1
  96. package/generator/build/lib/pygen/codegen/templates/serialization.py.jinja2 +5 -1
  97. package/generator/build/lib/pygen/preprocess/__init__.py +37 -30
  98. package/generator/component-detection-pip-report.json +7 -7
  99. package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
  100. package/generator/pygen/__init__.py +1 -3
  101. package/generator/pygen/codegen/__init__.py +0 -1
  102. package/generator/pygen/codegen/models/base.py +0 -1
  103. package/generator/pygen/codegen/models/client.py +2 -1
  104. package/generator/pygen/codegen/models/code_model.py +1 -0
  105. package/generator/pygen/codegen/models/enum_type.py +0 -1
  106. package/generator/pygen/codegen/models/model_type.py +1 -7
  107. package/generator/pygen/codegen/models/parameter.py +16 -14
  108. package/generator/pygen/codegen/serializers/__init__.py +27 -12
  109. package/generator/pygen/codegen/serializers/builder_serializer.py +12 -3
  110. package/generator/pygen/codegen/serializers/general_serializer.py +6 -2
  111. package/generator/pygen/codegen/serializers/import_serializer.py +17 -4
  112. package/generator/pygen/codegen/serializers/parameter_serializer.py +17 -11
  113. package/generator/pygen/codegen/templates/model_base.py.jinja2 +176 -71
  114. package/generator/pygen/codegen/templates/packaging_templates/README.md.jinja2 +11 -3
  115. package/generator/pygen/codegen/templates/packaging_templates/pyproject.toml.jinja2 +1 -1
  116. package/generator/pygen/codegen/templates/serialization.py.jinja2 +5 -1
  117. package/generator/pygen/preprocess/__init__.py +37 -30
  118. package/generator/pygen.egg-info/PKG-INFO +1 -2
  119. package/generator/pygen.egg-info/requires.txt +1 -1
  120. package/generator/setup.py +1 -2
  121. package/package.json +63 -42
  122. package/eng/scripts/ci/run-ci.ts +0 -89
  123. package/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_commonproperties_async.py +0 -94
  124. package/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_largeheader_async.py +0 -30
  125. package/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_nonresource_async.py +0 -36
  126. package/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_operationtemplates_async.py +0 -205
  127. package/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_resource_async.py +0 -478
  128. package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_access_async.py +0 -101
  129. package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_api_version_header_async.py +0 -18
  130. package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_api_version_path_async.py +0 -18
  131. package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_api_version_query_async.py +0 -18
  132. package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_client_default_value_async.py +0 -46
  133. package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_client_initialization_async.py +0 -58
  134. package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_client_location_async.py +0 -82
  135. package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_deserialize_empty_string_as_null_async.py +0 -20
  136. package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_flatten_async.py +0 -115
  137. package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_hierrarchy_building_async.py +0 -53
  138. package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_next_link_verb_async.py +0 -28
  139. package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_override_async.py +0 -106
  140. package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_usage_async.py +0 -38
  141. package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_basic_async.py +0 -76
  142. package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_lro_rpc_async.py +0 -22
  143. package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_lro_standard_async.py +0 -39
  144. package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_model_async.py +0 -33
  145. package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_page_async.py +0 -80
  146. package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_scalar_async.py +0 -41
  147. package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_traits_async.py +0 -87
  148. package/generator/test/azure/mock_api_tests/asynctests/test_azure_encode_duration_async.py +0 -19
  149. package/generator/test/azure/mock_api_tests/asynctests/test_azure_example_basic_async.py +0 -30
  150. package/generator/test/azure/mock_api_tests/asynctests/test_azure_payload_pageable_async.py +0 -19
  151. package/generator/test/azure/mock_api_tests/asynctests/test_azure_resource_manager_method_subscription_id_async.py +0 -248
  152. package/generator/test/azure/mock_api_tests/asynctests/test_azure_resource_manager_multi_service_async.py +0 -110
  153. package/generator/test/azure/mock_api_tests/asynctests/test_azure_resource_manager_multi_service_shared_models_async.py +0 -132
  154. package/generator/test/azure/mock_api_tests/asynctests/test_azure_special_headers_client_request_id_async.py +0 -30
  155. package/generator/test/azure/mock_api_tests/asynctests/test_azure_versioning_previewversion_async.py +0 -53
  156. package/generator/test/azure/mock_api_tests/asynctests/test_client_namespace_async.py +0 -34
  157. package/generator/test/azure/mock_api_tests/asynctests/test_client_naming_async.py +0 -69
  158. package/generator/test/azure/mock_api_tests/asynctests/test_client_naming_enum_conflict_async.py +0 -37
  159. package/generator/test/azure/mock_api_tests/asynctests/test_client_overload_async.py +0 -27
  160. package/generator/test/azure/mock_api_tests/asynctests/test_client_structure_async.py +0 -64
  161. package/generator/test/azure/mock_api_tests/asynctests/test_client_structure_clientoperationgroup_async.py +0 -31
  162. package/generator/test/azure/mock_api_tests/asynctests/test_encode_duration_async.py +0 -63
  163. package/generator/test/azure/mock_api_tests/asynctests/test_encode_numeric_async.py +0 -35
  164. package/generator/test/azure/mock_api_tests/asynctests/test_parameters_basic_async.py +0 -24
  165. package/generator/test/azure/mock_api_tests/asynctests/test_parameters_spread_async.py +0 -76
  166. package/generator/test/azure/mock_api_tests/asynctests/test_payload_content_negotiation_async.py +0 -37
  167. package/generator/test/azure/mock_api_tests/asynctests/test_payload_multipart_async.py +0 -216
  168. package/generator/test/azure/mock_api_tests/asynctests/test_resiliency_srv_driven_async.py +0 -130
  169. package/generator/test/azure/mock_api_tests/asynctests/test_serialization_encoded_name_json_async.py +0 -24
  170. package/generator/test/azure/mock_api_tests/asynctests/test_service_multi_service_async.py +0 -31
  171. package/generator/test/azure/mock_api_tests/asynctests/test_special_words_async.py +0 -71
  172. package/generator/test/azure/mock_api_tests/conftest.py +0 -207
  173. package/generator/test/azure/mock_api_tests/data/image.jpg +0 -0
  174. package/generator/test/azure/mock_api_tests/data/image.png +0 -0
  175. package/generator/test/azure/mock_api_tests/test_azure_arm_commonproperties.py +0 -89
  176. package/generator/test/azure/mock_api_tests/test_azure_arm_largeheader.py +0 -27
  177. package/generator/test/azure/mock_api_tests/test_azure_arm_nonresource.py +0 -34
  178. package/generator/test/azure/mock_api_tests/test_azure_arm_operationtemplates.py +0 -180
  179. package/generator/test/azure/mock_api_tests/test_azure_arm_resource.py +0 -436
  180. package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_access.py +0 -92
  181. package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_api_version_header.py +0 -17
  182. package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_api_version_path.py +0 -17
  183. package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_api_version_query.py +0 -17
  184. package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_client_default_value.py +0 -42
  185. package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_client_initialization.py +0 -51
  186. package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_client_location.py +0 -70
  187. package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_deserialize_empty_string_as_null.py +0 -19
  188. package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_flatten.py +0 -104
  189. package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_hierrarchy_building.py +0 -45
  190. package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_next_link_verb.py +0 -27
  191. package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_override.py +0 -102
  192. package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_usage.py +0 -32
  193. package/generator/test/azure/mock_api_tests/test_azure_core_basic.py +0 -70
  194. package/generator/test/azure/mock_api_tests/test_azure_core_lro_rpc.py +0 -20
  195. package/generator/test/azure/mock_api_tests/test_azure_core_lro_standard.py +0 -32
  196. package/generator/test/azure/mock_api_tests/test_azure_core_model.py +0 -30
  197. package/generator/test/azure/mock_api_tests/test_azure_core_page.py +0 -71
  198. package/generator/test/azure/mock_api_tests/test_azure_core_scalar.py +0 -35
  199. package/generator/test/azure/mock_api_tests/test_azure_core_traits.py +0 -85
  200. package/generator/test/azure/mock_api_tests/test_azure_encode_duration.py +0 -18
  201. package/generator/test/azure/mock_api_tests/test_azure_example_basic.py +0 -29
  202. package/generator/test/azure/mock_api_tests/test_azure_payload_pageable.py +0 -18
  203. package/generator/test/azure/mock_api_tests/test_azure_resource_manager_method_subscription_id.py +0 -235
  204. package/generator/test/azure/mock_api_tests/test_azure_resource_manager_multi_service.py +0 -104
  205. package/generator/test/azure/mock_api_tests/test_azure_resource_manager_multi_service_shared_models.py +0 -128
  206. package/generator/test/azure/mock_api_tests/test_azure_special_headers_client_request_id.py +0 -29
  207. package/generator/test/azure/mock_api_tests/test_azure_versioning_previewversion.py +0 -50
  208. package/generator/test/azure/mock_api_tests/test_clear_output_folder.py +0 -23
  209. package/generator/test/azure/mock_api_tests/test_client_namespace.py +0 -32
  210. package/generator/test/azure/mock_api_tests/test_client_naming.py +0 -57
  211. package/generator/test/azure/mock_api_tests/test_client_naming_enum_conflict.py +0 -35
  212. package/generator/test/azure/mock_api_tests/test_client_overload.py +0 -25
  213. package/generator/test/azure/mock_api_tests/test_client_structure.py +0 -60
  214. package/generator/test/azure/mock_api_tests/test_client_structure_clientoperationgroup.py +0 -29
  215. package/generator/test/azure/mock_api_tests/test_encode_duration.py +0 -60
  216. package/generator/test/azure/mock_api_tests/test_encode_numeric.py +0 -31
  217. package/generator/test/azure/mock_api_tests/test_model_base_flatten_compatibility.py +0 -251
  218. package/generator/test/azure/mock_api_tests/test_parameters_basic.py +0 -22
  219. package/generator/test/azure/mock_api_tests/test_parameters_spread.py +0 -66
  220. package/generator/test/azure/mock_api_tests/test_payload_content_negotiation.py +0 -33
  221. package/generator/test/azure/mock_api_tests/test_payload_multipart.py +0 -198
  222. package/generator/test/azure/mock_api_tests/test_resiliency_srv_driven.py +0 -124
  223. package/generator/test/azure/mock_api_tests/test_serialization_encoded_name_json.py +0 -21
  224. package/generator/test/azure/mock_api_tests/test_service_multi_service.py +0 -29
  225. package/generator/test/azure/mock_api_tests/test_special_words.py +0 -63
  226. package/generator/test/azure/requirements.txt +0 -125
  227. package/generator/test/azure/tox.ini +0 -64
  228. package/generator/test/data/image.jpg +0 -0
  229. package/generator/test/data/image.png +0 -0
  230. package/generator/test/dev_requirements.txt +0 -8
  231. package/generator/test/generic_mock_api_tests/asynctests/test_authentication_async.py +0 -140
  232. package/generator/test/generic_mock_api_tests/asynctests/test_encode_array_async.py +0 -139
  233. package/generator/test/generic_mock_api_tests/asynctests/test_encode_bytes_async.py +0 -132
  234. package/generator/test/generic_mock_api_tests/asynctests/test_encode_datetime_async.py +0 -127
  235. package/generator/test/generic_mock_api_tests/asynctests/test_headasboolean_async.py +0 -35
  236. package/generator/test/generic_mock_api_tests/asynctests/test_parameters_body_optionality_async.py +0 -30
  237. package/generator/test/generic_mock_api_tests/asynctests/test_parameters_collection_format_async.py +0 -38
  238. package/generator/test/generic_mock_api_tests/asynctests/test_parameters_path_async.py +0 -24
  239. package/generator/test/generic_mock_api_tests/asynctests/test_parameters_query_async.py +0 -18
  240. package/generator/test/generic_mock_api_tests/asynctests/test_payload_json_merge_patch_async.py +0 -98
  241. package/generator/test/generic_mock_api_tests/asynctests/test_payload_media_type_async.py +0 -27
  242. package/generator/test/generic_mock_api_tests/asynctests/test_payload_pageable_async.py +0 -134
  243. package/generator/test/generic_mock_api_tests/asynctests/test_payload_xml_async.py +0 -150
  244. package/generator/test/generic_mock_api_tests/asynctests/test_response_status_code_range_async.py +0 -38
  245. package/generator/test/generic_mock_api_tests/asynctests/test_routes_async.py +0 -331
  246. package/generator/test/generic_mock_api_tests/asynctests/test_server_endpoint_not_defined_async.py +0 -18
  247. package/generator/test/generic_mock_api_tests/asynctests/test_server_path_multiple_async.py +0 -25
  248. package/generator/test/generic_mock_api_tests/asynctests/test_server_path_single_async.py +0 -18
  249. package/generator/test/generic_mock_api_tests/asynctests/test_server_versions_not_versioned_async.py +0 -28
  250. package/generator/test/generic_mock_api_tests/asynctests/test_server_versions_versioned_async.py +0 -34
  251. package/generator/test/generic_mock_api_tests/asynctests/test_special_headers_conditional_request_async.py +0 -38
  252. package/generator/test/generic_mock_api_tests/asynctests/test_special_headers_repeatability_async.py +0 -19
  253. package/generator/test/generic_mock_api_tests/asynctests/test_specs_documentation_async.py +0 -59
  254. package/generator/test/generic_mock_api_tests/asynctests/test_streaming_jsonl_async.py +0 -27
  255. package/generator/test/generic_mock_api_tests/asynctests/test_typetest_array_async.py +0 -127
  256. package/generator/test/generic_mock_api_tests/asynctests/test_typetest_dictionary_async.py +0 -98
  257. package/generator/test/generic_mock_api_tests/asynctests/test_typetest_enum_extensible_async.py +0 -25
  258. package/generator/test/generic_mock_api_tests/asynctests/test_typetest_enum_fixed_async.py +0 -27
  259. package/generator/test/generic_mock_api_tests/asynctests/test_typetest_file_async.py +0 -59
  260. package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_empty_async.py +0 -32
  261. package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_inheritance_enum_discriminator_async.py +0 -70
  262. package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_inheritance_nested_discriminator_async.py +0 -85
  263. package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_inheritance_not_discriminated_async.py +0 -34
  264. package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_inheritance_recursive_async.py +0 -34
  265. package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_inheritance_single_discriminator_async.py +0 -67
  266. package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_usage_async.py +0 -32
  267. package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_visibility_async.py +0 -47
  268. package/generator/test/generic_mock_api_tests/asynctests/test_typetest_property_additionalproperties_async.py +0 -353
  269. package/generator/test/generic_mock_api_tests/asynctests/test_typetest_property_nullable_async.py +0 -110
  270. package/generator/test/generic_mock_api_tests/asynctests/test_typetest_property_optional_async.py +0 -197
  271. package/generator/test/generic_mock_api_tests/asynctests/test_typetest_property_valuetypes_async.py +0 -315
  272. package/generator/test/generic_mock_api_tests/asynctests/test_typetest_scalar_async.py +0 -60
  273. package/generator/test/generic_mock_api_tests/asynctests/test_typetest_union_async.py +0 -90
  274. package/generator/test/generic_mock_api_tests/asynctests/test_versioning_added_async.py +0 -36
  275. package/generator/test/generic_mock_api_tests/asynctests/test_versioning_made_optional_async.py +0 -21
  276. package/generator/test/generic_mock_api_tests/asynctests/test_versioning_removed_async.py +0 -39
  277. package/generator/test/generic_mock_api_tests/asynctests/test_versioning_renamed_from_async.py +0 -29
  278. package/generator/test/generic_mock_api_tests/asynctests/test_versioning_return_type_changed_from_async.py +0 -18
  279. package/generator/test/generic_mock_api_tests/asynctests/test_versioning_type_changed_from_async.py +0 -22
  280. package/generator/test/generic_mock_api_tests/conftest.py +0 -75
  281. package/generator/test/generic_mock_api_tests/data/image.jpg +0 -0
  282. package/generator/test/generic_mock_api_tests/data/image.png +0 -0
  283. package/generator/test/generic_mock_api_tests/test_authentication.py +0 -130
  284. package/generator/test/generic_mock_api_tests/test_encode_array.py +0 -126
  285. package/generator/test/generic_mock_api_tests/test_encode_bytes.py +0 -128
  286. package/generator/test/generic_mock_api_tests/test_encode_datetime.py +0 -123
  287. package/generator/test/generic_mock_api_tests/test_headasboolean.py +0 -33
  288. package/generator/test/generic_mock_api_tests/test_parameters_body_optionality.py +0 -27
  289. package/generator/test/generic_mock_api_tests/test_parameters_collection_format.py +0 -33
  290. package/generator/test/generic_mock_api_tests/test_parameters_path.py +0 -22
  291. package/generator/test/generic_mock_api_tests/test_parameters_query.py +0 -17
  292. package/generator/test/generic_mock_api_tests/test_payload_json_merge_patch.py +0 -93
  293. package/generator/test/generic_mock_api_tests/test_payload_media_type.py +0 -25
  294. package/generator/test/generic_mock_api_tests/test_payload_pageable.py +0 -99
  295. package/generator/test/generic_mock_api_tests/test_payload_xml.py +0 -135
  296. package/generator/test/generic_mock_api_tests/test_response_status_code_range.py +0 -36
  297. package/generator/test/generic_mock_api_tests/test_routes.py +0 -285
  298. package/generator/test/generic_mock_api_tests/test_server_endpoint_not_defined.py +0 -17
  299. package/generator/test/generic_mock_api_tests/test_server_path_multiple.py +0 -21
  300. package/generator/test/generic_mock_api_tests/test_server_path_single.py +0 -17
  301. package/generator/test/generic_mock_api_tests/test_server_versions_not_versioned.py +0 -25
  302. package/generator/test/generic_mock_api_tests/test_server_versions_versioned.py +0 -30
  303. package/generator/test/generic_mock_api_tests/test_special_headers_conditional_request.py +0 -34
  304. package/generator/test/generic_mock_api_tests/test_special_headers_repeatability.py +0 -18
  305. package/generator/test/generic_mock_api_tests/test_specs_documentation.py +0 -51
  306. package/generator/test/generic_mock_api_tests/test_streaming_jsonl.py +0 -25
  307. package/generator/test/generic_mock_api_tests/test_typetest_array.py +0 -111
  308. package/generator/test/generic_mock_api_tests/test_typetest_dictionary.py +0 -86
  309. package/generator/test/generic_mock_api_tests/test_typetest_enum_extensible.py +0 -23
  310. package/generator/test/generic_mock_api_tests/test_typetest_enum_fixed.py +0 -25
  311. package/generator/test/generic_mock_api_tests/test_typetest_file.py +0 -52
  312. package/generator/test/generic_mock_api_tests/test_typetest_model_empty.py +0 -29
  313. package/generator/test/generic_mock_api_tests/test_typetest_model_inheritance_enum_discriminator.py +0 -58
  314. package/generator/test/generic_mock_api_tests/test_typetest_model_inheritance_nested_discriminator.py +0 -79
  315. package/generator/test/generic_mock_api_tests/test_typetest_model_inheritance_not_discriminated.py +0 -31
  316. package/generator/test/generic_mock_api_tests/test_typetest_model_inheritance_recursive.py +0 -32
  317. package/generator/test/generic_mock_api_tests/test_typetest_model_inheritance_single_discriminator.py +0 -60
  318. package/generator/test/generic_mock_api_tests/test_typetest_model_usage.py +0 -28
  319. package/generator/test/generic_mock_api_tests/test_typetest_model_visibility.py +0 -40
  320. package/generator/test/generic_mock_api_tests/test_typetest_property_additionalproperties.py +0 -314
  321. package/generator/test/generic_mock_api_tests/test_typetest_property_nullable.py +0 -102
  322. package/generator/test/generic_mock_api_tests/test_typetest_property_optional.py +0 -174
  323. package/generator/test/generic_mock_api_tests/test_typetest_property_valuetypes.py +0 -286
  324. package/generator/test/generic_mock_api_tests/test_typetest_scalar.py +0 -53
  325. package/generator/test/generic_mock_api_tests/test_typetest_union.py +0 -80
  326. package/generator/test/generic_mock_api_tests/test_typetest_union_discriminated.py +0 -290
  327. package/generator/test/generic_mock_api_tests/test_versioning_added.py +0 -33
  328. package/generator/test/generic_mock_api_tests/test_versioning_made_optional.py +0 -20
  329. package/generator/test/generic_mock_api_tests/test_versioning_removed.py +0 -37
  330. package/generator/test/generic_mock_api_tests/test_versioning_renamed_from.py +0 -27
  331. package/generator/test/generic_mock_api_tests/test_versioning_return_type_changed_from.py +0 -17
  332. package/generator/test/generic_mock_api_tests/test_versioning_type_changed_from.py +0 -21
  333. package/generator/test/unbranded/mock_api_tests/asynctests/test_auth_flow_async.py +0 -19
  334. package/generator/test/unbranded/mock_api_tests/asynctests/test_encode_duration_async.py +0 -63
  335. package/generator/test/unbranded/mock_api_tests/asynctests/test_encode_numeric_async.py +0 -35
  336. package/generator/test/unbranded/mock_api_tests/asynctests/test_parameters_basic_async.py +0 -24
  337. package/generator/test/unbranded/mock_api_tests/asynctests/test_parameters_spread_async.py +0 -76
  338. package/generator/test/unbranded/mock_api_tests/asynctests/test_payload_content_negotiation_async.py +0 -37
  339. package/generator/test/unbranded/mock_api_tests/asynctests/test_payload_multipart_async.py +0 -218
  340. package/generator/test/unbranded/mock_api_tests/asynctests/test_serialization_encoded_name_json_async.py +0 -24
  341. package/generator/test/unbranded/mock_api_tests/asynctests/test_special_words_async.py +0 -73
  342. package/generator/test/unbranded/mock_api_tests/asynctests/test_unbranded_async.py +0 -24
  343. package/generator/test/unbranded/mock_api_tests/conftest.py +0 -91
  344. package/generator/test/unbranded/mock_api_tests/data/image.jpg +0 -0
  345. package/generator/test/unbranded/mock_api_tests/data/image.png +0 -0
  346. package/generator/test/unbranded/mock_api_tests/test_auth_flow.py +0 -17
  347. package/generator/test/unbranded/mock_api_tests/test_encode_duration.py +0 -60
  348. package/generator/test/unbranded/mock_api_tests/test_encode_numeric.py +0 -32
  349. package/generator/test/unbranded/mock_api_tests/test_parameters_basic.py +0 -22
  350. package/generator/test/unbranded/mock_api_tests/test_parameters_spread.py +0 -66
  351. package/generator/test/unbranded/mock_api_tests/test_payload_content_negotiation.py +0 -33
  352. package/generator/test/unbranded/mock_api_tests/test_payload_multipart.py +0 -200
  353. package/generator/test/unbranded/mock_api_tests/test_serialization_encoded_name_json.py +0 -22
  354. package/generator/test/unbranded/mock_api_tests/test_special_words.py +0 -66
  355. package/generator/test/unbranded/mock_api_tests/test_unbranded.py +0 -65
  356. package/generator/test/unbranded/requirements.txt +0 -69
  357. package/generator/test/unbranded/tox.ini +0 -64
  358. package/generator/test/unittests/conftest.py +0 -15
  359. package/generator/test/unittests/requirements.txt +0 -3
  360. package/generator/test/unittests/test_enums.py +0 -89
  361. package/generator/test/unittests/test_model_base_serialization.py +0 -4906
  362. package/generator/test/unittests/test_model_base_xml_serialization.py +0 -1239
  363. package/generator/test/unittests/test_name_converter.py +0 -35
  364. package/generator/test/unittests/test_optional_return_type.py +0 -268
  365. package/generator/test/unittests/test_parameter_ordering.py +0 -104
  366. package/generator/test/unittests/test_sort_schema.py +0 -93
  367. package/generator/test/unittests/tox.ini +0 -5
  368. /package/eng/scripts/ci/{pyproject.toml → config/pyproject.toml} +0 -0
@@ -39,16 +39,6 @@ SPECIAL_HEADER_SERIALIZATION: dict[str, list[str]] = {
39
39
  "client-request-id": [],
40
40
  "x-ms-client-request-id": [],
41
41
  "return-client-request-id": [],
42
- "etag": [
43
- """if_match = prep_if_match(etag, match_condition)""",
44
- """if if_match is not None:""",
45
- """ _headers["If-Match"] = _SERIALIZER.header("if_match", if_match, "str")""",
46
- ],
47
- "match-condition": [
48
- """if_none_match = prep_if_none_match(etag, match_condition)""",
49
- """if if_none_match is not None:""",
50
- """ _headers["If-None-Match"] = _SERIALIZER.header("if_none_match", if_none_match, "str")""",
51
- ],
52
42
  }
53
43
 
54
44
 
@@ -157,6 +147,20 @@ class ParameterSerializer:
157
147
  ):
158
148
  return SPECIAL_HEADER_SERIALIZATION[param.wire_name.lower()]
159
149
 
150
+ if not is_legacy and param.location == ParameterLocation.HEADER and param.etag_role is not None:
151
+ header_name = param.wire_name
152
+ if param.etag_role == "ifMatch":
153
+ return [
154
+ """if_match = prep_if_match(etag, match_condition)""",
155
+ """if if_match is not None:""",
156
+ f""" _headers["{header_name}"] = _SERIALIZER.header("if_match", if_match, "str")""",
157
+ ]
158
+ return [
159
+ """if_none_match = prep_if_none_match(etag, match_condition)""",
160
+ """if if_none_match is not None:""",
161
+ f""" _headers["{header_name}"] = _SERIALIZER.header("if_none_match", if_none_match, "str")""",
162
+ ]
163
+
160
164
  set_parameter = "_{}['{}'] = {}".format(
161
165
  kwarg_name,
162
166
  param.wire_name,
@@ -202,11 +206,13 @@ class ParameterSerializer:
202
206
  if is_content_type_optional and not type_annotation.startswith("Optional[")
203
207
  else type_annotation
204
208
  )
205
- if kwarg.client_default_value is not None or kwarg.optional or kwarg.constant:
209
+ if kwarg.client_default_value is not None or kwarg.optional or kwarg.constant or kwarg.is_api_version:
206
210
  if check_client_input and kwarg.check_client_input:
207
211
  default_value = f"self._config.{kwarg.client_name}"
208
212
  elif kwarg.constant:
209
213
  default_value = kwarg.type.get_declaration(None)
214
+ elif kwarg.is_api_version and kwarg.client_default_value is None and kwarg.api_versions:
215
+ default_value = f'"{kwarg.api_versions[-1]}"'
210
216
  else:
211
217
  default_value = kwarg.client_default_value_declaration
212
218
  if check_kwarg_dict and (kwarg.location in [ParameterLocation.HEADER, ParameterLocation.QUERY]):
@@ -19,17 +19,22 @@ from datetime import datetime, date, time, timedelta, timezone
19
19
  from json import JSONEncoder
20
20
  import xml.etree.ElementTree as ET
21
21
  from collections.abc import MutableMapping
22
- from typing_extensions import Self
23
22
  import isodate
24
23
  from {{ code_model.core_library }}.exceptions import DeserializationError
25
24
  from {{ code_model.core_library }}{{ "" if code_model.is_azure_flavor else ".utils" }} import CaseInsensitiveEnumMeta
26
25
  from {{ code_model.core_library }}.{{ "" if code_model.is_azure_flavor else "runtime." }}pipeline import PipelineResponse
27
26
  from {{ code_model.core_library }}.serialization import _Null
27
+
28
28
  {% if code_model.has_external_type %}
29
29
  from {{ code_model.core_library }}.serialization import TypeHandlerRegistry
30
30
  {% endif %}
31
31
  from {{ code_model.core_library }}.rest import HttpResponse
32
32
 
33
+ if sys.version_info >= (3, 11):
34
+ from typing import Self
35
+ else:
36
+ from typing_extensions import Self
37
+
33
38
  _LOGGER = logging.getLogger(__name__)
34
39
 
35
40
  __all__ = ["SdkJSONEncoder", "Model", "rest_field", "rest_discriminator"]
@@ -617,62 +622,10 @@ class Model(_MyMutableMapping):
617
622
  class_name = self.__class__.__name__
618
623
  if len(args) > 1:
619
624
  raise TypeError(f"{class_name}.__init__() takes 2 positional arguments but {len(args) + 1} were given")
620
- dict_to_pass = {
621
- rest_field._rest_name: rest_field._default
622
- for rest_field in self._attr_to_rest_field.values()
623
- if rest_field._default is not _UNSET
624
- }
625
- if args: # pylint: disable=too-many-nested-blocks
625
+ dict_to_pass: dict[str, typing.Any] = {}
626
+ if args:
626
627
  if isinstance(args[0], ET.Element):
627
- existed_attr_keys = []
628
- model_meta = getattr(self, "_xml", {})
629
-
630
- for rf in self._attr_to_rest_field.values():
631
- prop_meta = getattr(rf, "_xml", {})
632
- xml_name = prop_meta.get("name", rf._rest_name)
633
- xml_ns = prop_meta.get("ns", model_meta.get("ns", None))
634
- if xml_ns:
635
- xml_name = "{" + xml_ns + "}" + xml_name
636
-
637
- # attribute
638
- if prop_meta.get("attribute", False) and args[0].get(xml_name) is not None:
639
- existed_attr_keys.append(xml_name)
640
- dict_to_pass[rf._rest_name] = _deserialize(rf._type, args[0].get(xml_name))
641
- continue
642
-
643
- # unwrapped element is array
644
- if prop_meta.get("unwrapped", False):
645
- # unwrapped array could either use prop items meta/prop meta
646
- if prop_meta.get("itemsName"):
647
- xml_name = prop_meta.get("itemsName")
648
- xml_ns = prop_meta.get("itemNs")
649
- if xml_ns:
650
- xml_name = "{" + xml_ns + "}" + xml_name
651
- items = args[0].findall(xml_name) # pyright: ignore
652
- if len(items) > 0:
653
- existed_attr_keys.append(xml_name)
654
- dict_to_pass[rf._rest_name] = _deserialize(rf._type, items)
655
- elif not rf._is_optional:
656
- existed_attr_keys.append(xml_name)
657
- dict_to_pass[rf._rest_name] = []
658
- continue
659
-
660
- # text element is primitive type
661
- if prop_meta.get("text", False):
662
- if args[0].text is not None:
663
- dict_to_pass[rf._rest_name] = _deserialize(rf._type, args[0].text)
664
- continue
665
-
666
- # wrapped element could be normal property or array, it should only have one element
667
- item = args[0].find(xml_name)
668
- if item is not None:
669
- existed_attr_keys.append(xml_name)
670
- dict_to_pass[rf._rest_name] = _deserialize(rf._type, item)
671
-
672
- # rest thing is additional properties
673
- for e in args[0]:
674
- if e.tag not in existed_attr_keys:
675
- dict_to_pass[e.tag] = _convert_element(e)
628
+ dict_to_pass.update(self._init_from_xml(args[0]))
676
629
  else:
677
630
  dict_to_pass.update(
678
631
  {k: _create_value(_get_rest_field(self._attr_to_rest_field, k), v) for k, v in args[0].items()}
@@ -689,8 +642,79 @@ class Model(_MyMutableMapping):
689
642
  if v is not None
690
643
  }
691
644
  )
645
+ # Apply client default values for fields the caller didn't set so that
646
+ # defaults are part of `_data` and therefore included during serialization.
647
+ for rf in self._attr_to_rest_field.values():
648
+ if rf._default is _UNSET:
649
+ continue
650
+ if rf._rest_name in dict_to_pass:
651
+ continue
652
+ dict_to_pass[rf._rest_name] = _create_value(rf, rf._default)
692
653
  super().__init__(dict_to_pass)
693
654
 
655
+ def _init_from_xml(self, element: ET.Element) -> dict[str, typing.Any]:
656
+ """Deserialize an XML element into a dict mapping rest field names to values.
657
+
658
+ :param ET.Element element: The XML element to deserialize from.
659
+ :returns: A dictionary of rest_name to deserialized value pairs.
660
+ :rtype: dict
661
+ """
662
+ result: dict[str, typing.Any] = {}
663
+ model_meta = getattr(self, "_xml", {})
664
+ existed_attr_keys: list[str] = []
665
+
666
+ for rf in self._attr_to_rest_field.values():
667
+ prop_meta = getattr(rf, "_xml", {})
668
+ xml_name = prop_meta.get("name", rf._rest_name)
669
+ xml_ns = _resolve_xml_ns(prop_meta, model_meta)
670
+ if xml_ns:
671
+ xml_name = "{" + xml_ns + "}" + xml_name
672
+
673
+ # attribute
674
+ if prop_meta.get("attribute", False) and element.get(xml_name) is not None:
675
+ existed_attr_keys.append(xml_name)
676
+ result[rf._rest_name] = _deserialize(rf._type, element.get(xml_name))
677
+ continue
678
+
679
+ # unwrapped element is array
680
+ if prop_meta.get("unwrapped", False):
681
+ # unwrapped array could either use prop items meta/prop meta
682
+ _items_name = prop_meta.get("itemsName")
683
+ if _items_name:
684
+ xml_name = _items_name
685
+ _items_ns = prop_meta.get("itemsNs")
686
+ if _items_ns is not None:
687
+ xml_ns = _items_ns
688
+ if xml_ns:
689
+ xml_name = "{" + xml_ns + "}" + xml_name
690
+ items = element.findall(xml_name) # pyright: ignore
691
+ if len(items) > 0:
692
+ existed_attr_keys.append(xml_name)
693
+ result[rf._rest_name] = _deserialize(rf._type, items)
694
+ elif not rf._is_optional:
695
+ existed_attr_keys.append(xml_name)
696
+ result[rf._rest_name] = []
697
+ continue
698
+
699
+ # text element is primitive type
700
+ if prop_meta.get("text", False):
701
+ if element.text is not None:
702
+ result[rf._rest_name] = _deserialize(rf._type, element.text)
703
+ continue
704
+
705
+ # wrapped element could be normal property or array, it should only have one element
706
+ item = element.find(xml_name)
707
+ if item is not None:
708
+ existed_attr_keys.append(xml_name)
709
+ result[rf._rest_name] = _deserialize(rf._type, item)
710
+
711
+ # rest thing is additional properties
712
+ for e in element:
713
+ if e.tag not in existed_attr_keys:
714
+ result[e.tag] = _convert_element(e)
715
+
716
+ return result
717
+
694
718
  def copy(self) -> "Model":
695
719
  return Model(self.__dict__)
696
720
 
@@ -761,7 +785,7 @@ class Model(_MyMutableMapping):
761
785
  model_meta = getattr(cls, "_xml", {})
762
786
  prop_meta = getattr(discriminator, "_xml", {})
763
787
  xml_name = prop_meta.get("name", discriminator._rest_name)
764
- xml_ns = prop_meta.get("ns", model_meta.get("ns", None))
788
+ xml_ns = _resolve_xml_ns(prop_meta, model_meta)
765
789
  if xml_ns:
766
790
  xml_name = "{" + xml_ns + "}" + xml_name
767
791
 
@@ -1145,7 +1169,10 @@ class _RestField:
1145
1169
  # by this point, type and rest_name will have a value bc we default
1146
1170
  # them in __new__ of the Model class
1147
1171
  # Use _data.get() directly to avoid triggering __getitem__ which clears the cache
1148
- item = obj._data.get(self._rest_name)
1172
+ item = obj._data.get(self._rest_name, _UNSET)
1173
+ if item is _UNSET:
1174
+ # Field not set by user; return the client default if one exists, otherwise None
1175
+ return self._default if self._default is not _UNSET else None
1149
1176
  if item is None:
1150
1177
  return item
1151
1178
  if self._is_model:
@@ -1243,6 +1270,58 @@ def serialize_xml(model: Model, exclude_readonly: bool = False) -> str:
1243
1270
  return ET.tostring(_get_element(model, exclude_readonly), encoding="unicode") # type: ignore
1244
1271
 
1245
1272
 
1273
+ def _get_xml_ns(meta: dict[str, typing.Any]) -> typing.Optional[str]:
1274
+ """Return the XML namespace from a metadata dict, checking both 'ns' (old-style) and 'namespace' (DPG) keys.
1275
+
1276
+ :param dict meta: The metadata dictionary to extract namespace from.
1277
+ :returns: The namespace string if 'ns' or 'namespace' key is present, None otherwise.
1278
+ :rtype: str or None
1279
+ """
1280
+ ns = meta.get("ns")
1281
+ if ns is None:
1282
+ ns = meta.get("namespace")
1283
+ return ns
1284
+
1285
+
1286
+ def _resolve_xml_ns(
1287
+ prop_meta: dict[str, typing.Any], model_meta: typing.Optional[dict[str, typing.Any]] = None
1288
+ ) -> typing.Optional[str]:
1289
+ """Resolve XML namespace for a property, falling back to model namespace when appropriate.
1290
+
1291
+ Checks the property metadata first; if no namespace is found and the model does not declare
1292
+ an explicit prefix, falls back to the model-level namespace.
1293
+
1294
+ :param dict prop_meta: The property metadata dictionary.
1295
+ :param dict model_meta: The model metadata dictionary, used as fallback.
1296
+ :returns: The resolved namespace string, or None.
1297
+ :rtype: str or None
1298
+ """
1299
+ ns = _get_xml_ns(prop_meta)
1300
+ if ns is None and model_meta is not None and not model_meta.get("prefix"):
1301
+ ns = _get_xml_ns(model_meta)
1302
+ return ns
1303
+
1304
+
1305
+ def _set_xml_attribute(
1306
+ element: ET.Element, name: str, value: typing.Any, prop_meta: dict[str, typing.Any]
1307
+ ) -> None:
1308
+ """Set an XML attribute on an element, handling namespace prefix registration.
1309
+
1310
+ :param ET.Element element: The element to set the attribute on.
1311
+ :param str name: The default attribute name (wire name).
1312
+ :param any value: The attribute value.
1313
+ :param dict prop_meta: The property metadata dictionary.
1314
+ """
1315
+ xml_name = prop_meta.get("name", name)
1316
+ _attr_ns = _get_xml_ns(prop_meta)
1317
+ if _attr_ns:
1318
+ _attr_prefix = prop_meta.get("prefix")
1319
+ if _attr_prefix:
1320
+ _safe_register_namespace(_attr_prefix, _attr_ns)
1321
+ xml_name = "{" + _attr_ns + "}" + xml_name
1322
+ element.set(xml_name, _get_primitive_type_value(value))
1323
+
1324
+
1246
1325
  def _get_element(
1247
1326
  o: typing.Any,
1248
1327
  exclude_readonly: bool = False,
@@ -1254,10 +1333,16 @@ def _get_element(
1254
1333
 
1255
1334
  # if prop is a model, then use the prop element directly, else generate a wrapper of model
1256
1335
  if wrapped_element is None:
1336
+ # When serializing as an array item (parent_meta is set), check if the parent has an
1337
+ # explicit itemsName. This ensures correct element names for unwrapped arrays (where
1338
+ # the element tag is the property/items name, not the model type name).
1339
+ _items_name = parent_meta.get("itemsName") if parent_meta is not None else None
1340
+ element_name = _items_name if _items_name else (model_meta.get("name") or o.__class__.__name__)
1341
+ _model_ns = _get_xml_ns(model_meta)
1257
1342
  wrapped_element = _create_xml_element(
1258
- model_meta.get("name", o.__class__.__name__),
1343
+ element_name,
1259
1344
  model_meta.get("prefix"),
1260
- model_meta.get("ns"),
1345
+ _model_ns,
1261
1346
  )
1262
1347
 
1263
1348
  readonly_props = []
@@ -1279,7 +1364,9 @@ def _get_element(
1279
1364
  # additional properties will not have rest field, use the wire name as xml name
1280
1365
  prop_meta = {"name": k}
1281
1366
 
1282
- # if no ns for prop, use model's
1367
+ # Propagate model namespace to properties only for old-style "ns"-keyed models.
1368
+ # DPG-generated models use the "namespace" key and explicitly declare namespace on
1369
+ # each property that needs it, so propagation is intentionally skipped for them.
1283
1370
  if prop_meta.get("ns") is None and model_meta.get("ns"):
1284
1371
  prop_meta["ns"] = model_meta.get("ns")
1285
1372
  prop_meta["prefix"] = model_meta.get("prefix")
@@ -1291,12 +1378,7 @@ def _get_element(
1291
1378
  # text could only set on primitive type
1292
1379
  wrapped_element.text = _get_primitive_type_value(v)
1293
1380
  elif prop_meta.get("attribute", False):
1294
- xml_name = prop_meta.get("name", k)
1295
- if prop_meta.get("ns"):
1296
- ET.register_namespace(prop_meta.get("prefix"), prop_meta.get("ns")) # pyright: ignore
1297
- xml_name = "{" + prop_meta.get("ns") + "}" + xml_name # pyright: ignore
1298
- # attribute should be primitive type
1299
- wrapped_element.set(xml_name, _get_primitive_type_value(v))
1381
+ _set_xml_attribute(wrapped_element, k, v, prop_meta)
1300
1382
  else:
1301
1383
  # other wrapped prop element
1302
1384
  wrapped_element.append(_get_wrapped_element(v, exclude_readonly, prop_meta))
@@ -1305,6 +1387,7 @@ def _get_element(
1305
1387
  return [_get_element(x, exclude_readonly, parent_meta) for x in o] # type: ignore
1306
1388
  if isinstance(o, dict):
1307
1389
  result = []
1390
+ _dict_ns = _get_xml_ns(parent_meta) if parent_meta else None
1308
1391
  for k, v in o.items():
1309
1392
  result.append(
1310
1393
  _get_wrapped_element(
@@ -1312,7 +1395,7 @@ def _get_element(
1312
1395
  exclude_readonly,
1313
1396
  {
1314
1397
  "name": k,
1315
- "ns": parent_meta.get("ns") if parent_meta else None,
1398
+ "ns": _dict_ns,
1316
1399
  "prefix": parent_meta.get("prefix") if parent_meta else None,
1317
1400
  },
1318
1401
  )
@@ -1321,13 +1404,16 @@ def _get_element(
1321
1404
 
1322
1405
  # primitive case need to create element based on parent_meta
1323
1406
  if parent_meta:
1407
+ _items_ns = parent_meta.get("itemsNs")
1408
+ if _items_ns is None:
1409
+ _items_ns = _get_xml_ns(parent_meta)
1324
1410
  return _get_wrapped_element(
1325
1411
  o,
1326
1412
  exclude_readonly,
1327
1413
  {
1328
1414
  "name": parent_meta.get("itemsName", parent_meta.get("name")),
1329
1415
  "prefix": parent_meta.get("itemsPrefix", parent_meta.get("prefix")),
1330
- "ns": parent_meta.get("itemsNs", parent_meta.get("ns")),
1416
+ "ns": _items_ns,
1331
1417
  },
1332
1418
  )
1333
1419
 
@@ -1339,8 +1425,9 @@ def _get_wrapped_element(
1339
1425
  exclude_readonly: bool,
1340
1426
  meta: typing.Optional[dict[str, typing.Any]],
1341
1427
  ) -> ET.Element:
1428
+ _meta_ns = _get_xml_ns(meta) if meta else None
1342
1429
  wrapped_element = _create_xml_element(
1343
- meta.get("name") if meta else None, meta.get("prefix") if meta else None, meta.get("ns") if meta else None
1430
+ meta.get("name") if meta else None, meta.get("prefix") if meta else None, _meta_ns
1344
1431
  )
1345
1432
  if isinstance(v, (dict, list)):
1346
1433
  wrapped_element.extend(_get_element(v, exclude_readonly, meta))
@@ -1361,11 +1448,29 @@ def _get_primitive_type_value(v) -> str:
1361
1448
  return str(v)
1362
1449
 
1363
1450
 
1451
+ def _safe_register_namespace(prefix: str, ns: str) -> None:
1452
+ """Register an XML namespace prefix, handling reserved prefix patterns.
1453
+
1454
+ Some prefixes (e.g. 'ns2') match Python's reserved 'ns\\d+' pattern used for
1455
+ auto-generated prefixes, causing register_namespace to raise ValueError.
1456
+ Falls back to directly registering in the internal namespace map.
1457
+
1458
+ :param str prefix: The namespace prefix to register.
1459
+ :param str ns: The namespace URI.
1460
+ """
1461
+ try:
1462
+ ET.register_namespace(prefix, ns)
1463
+ except ValueError:
1464
+ _ns_map = getattr(ET, "_namespace_map", None)
1465
+ if _ns_map is not None:
1466
+ _ns_map[ns] = prefix
1467
+
1468
+
1364
1469
  def _create_xml_element(
1365
1470
  tag: typing.Any, prefix: typing.Optional[str] = None, ns: typing.Optional[str] = None
1366
1471
  ) -> ET.Element:
1367
1472
  if prefix and ns:
1368
- ET.register_namespace(prefix, ns)
1473
+ _safe_register_namespace(prefix, ns)
1369
1474
  if ns:
1370
1475
  return ET.Element("{" + ns + "}" + tag)
1371
1476
  return ET.Element(tag)
@@ -3,7 +3,7 @@
3
3
  # Microsoft Azure SDK for Python
4
4
 
5
5
  This is the Microsoft {{options["package-pprint-name"]}} Client Library.
6
- This package has been tested with Python 3.9+.
6
+ This package has been tested with Python 3.10+.
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
@@ -14,6 +14,10 @@ For docs and references, see [Python SDK References](https://docs.microsoft.com/
14
14
  Code samples for this package can be found at [{{options["package-pprint-name"]}}](https://docs.microsoft.com/samples/browse/?languages=python&term=Getting%20started%20-%20Managing&terms=Getting%20started%20-%20Managing) on docs.microsoft.com.
15
15
  Additional code samples for different Azure services are available at [Samples Repo](https://aka.ms/azsdk/python/mgmt/samples)
16
16
 
17
+ # Use with AI tools
18
+
19
+ AI coding tools such as VS Code and GitHub Copilot can help you write and debug code that uses this library. See [Using the Azure SDK for Python with AI tools](https://aka.ms/azsdk/python/ai) for available integrations.
20
+
17
21
  # Provide Feedback
18
22
 
19
23
  If you encounter any bugs or have suggestions, please file an issue in the
@@ -36,10 +40,14 @@ python -m pip install {{ options["package-name"] }}
36
40
 
37
41
  #### Prequisites
38
42
 
39
- - Python 3.9 or later is required to use this package.
43
+ - Python 3.10 or later is required to use this package.
40
44
  - You need an [Azure subscription][azure_sub] to use this package.
41
45
  - An existing {{ options["package-pprint-name"] }} instance.
42
46
 
47
+ ### Use with AI tools
48
+
49
+ AI coding tools such as VS Code and GitHub Copilot can help you write and debug code that uses this library. See [Using the Azure SDK for Python with AI tools](https://aka.ms/azsdk/python/ai) for available integrations.
50
+
43
51
  {% if token_credential and client_name %}
44
52
  #### Create with an Azure Active Directory Credential
45
53
  To use an [Azure Active Directory (AAD) token credential][authenticate_with_token],
@@ -113,7 +121,7 @@ This package is generated by `@typespec/http-client-python` with Typespec.
113
121
 
114
122
  ### Prequisites
115
123
 
116
- - Python 3.9 or later is required to use this package.
124
+ - Python 3.10 or later is required to use this package.
117
125
 
118
126
  ### Install the package
119
127
 
@@ -57,7 +57,7 @@ dependencies = [
57
57
  {% endfor %}
58
58
  {% endif %}
59
59
  {% for dep in ADDITIONAL_DEPENDENCIES %}
60
- "{{ dep }}",
60
+ {{ dep }},
61
61
  {% endfor %}
62
62
  ]
63
63
  dynamic = [
@@ -35,11 +35,15 @@ except ImportError:
35
35
  import xml.etree.ElementTree as ET
36
36
 
37
37
  import isodate # type: ignore
38
- from typing_extensions import Self
39
38
 
40
39
  from {{ code_model.core_library }}.exceptions import DeserializationError, SerializationError
41
40
  from {{ code_model.core_library }}.serialization import NULL as CoreNull
42
41
 
42
+ if sys.version_info >= (3, 11):
43
+ from typing import Self
44
+ else:
45
+ from typing_extensions import Self
46
+
43
47
  _BOM = codecs.BOM_UTF8.decode(encoding="utf-8")
44
48
 
45
49
  JSON = MutableMapping[str, Any]
@@ -132,20 +132,18 @@ HEADERS_HIDE_IN_METHOD = (
132
132
  "client-request-id",
133
133
  "return-client-request-id",
134
134
  )
135
- HEADERS_CONVERT_IN_METHOD = {
136
- "if-match": {
137
- "clientName": "etag",
138
- "wireName": "etag",
139
- "description": "check if resource is changed. Set None to skip checking etag.",
140
- },
141
- "if-none-match": {
142
- "clientName": "match_condition",
143
- "wireName": "match-condition",
144
- "description": "The match condition to use upon the etag.",
145
- "type": {
146
- "type": "sdkcore",
147
- "name": "MatchConditions",
148
- },
135
+ ETAG_MATCH_DATA = {
136
+ "clientName": "etag",
137
+ "etagRole": "ifMatch",
138
+ "description": "check if resource is changed. Set None to skip checking etag.",
139
+ }
140
+ ETAG_NONE_MATCH_DATA = {
141
+ "clientName": "match_condition",
142
+ "etagRole": "ifNoneMatch",
143
+ "description": "The match condition to use upon the etag.",
144
+ "type": {
145
+ "type": "sdkcore",
146
+ "name": "MatchConditions",
149
147
  },
150
148
  }
151
149
  CLOUD_SETTING = {
@@ -166,6 +164,11 @@ def get_wire_name_lower(parameter: dict[str, Any]) -> str:
166
164
  return (parameter.get("wireName") or "").lower()
167
165
 
168
166
 
167
+ def _get_etag_role(parameter: dict[str, Any]) -> Optional[str]:
168
+ """Return 'ifMatch', 'ifNoneMatch', or None for this header parameter."""
169
+ return parameter.get("etagRole")
170
+
171
+
169
172
  def headers_convert(yaml_data: dict[str, Any], replace_data: Any) -> None:
170
173
  if isinstance(replace_data, dict):
171
174
  for k, v in replace_data.items():
@@ -281,9 +284,8 @@ class PreProcessPlugin(YamlUpdatePlugin):
281
284
  value["name"] = upper_name
282
285
 
283
286
  # add type for reference
284
- for v in HEADERS_CONVERT_IN_METHOD.values():
285
- if isinstance(v, dict) and "type" in v:
286
- yaml_data.append(v["type"])
287
+ if "type" in ETAG_NONE_MATCH_DATA:
288
+ yaml_data.append(ETAG_NONE_MATCH_DATA["type"])
287
289
  yaml_data.append(CLOUD_SETTING["type"]) # type: ignore
288
290
 
289
291
  def update_client(self, yaml_data: dict[str, Any]) -> None:
@@ -317,9 +319,10 @@ class PreProcessPlugin(YamlUpdatePlugin):
317
319
  if p["location"] == "header" and wire_name_lower == "client-request-id":
318
320
  yaml_data["requestIdHeaderName"] = wire_name_lower
319
321
  if self.version_tolerant and p["location"] == "header":
320
- if wire_name_lower == "if-match":
322
+ role = _get_etag_role(p)
323
+ if role == "ifMatch" and not property_if_match:
321
324
  property_if_match = p
322
- elif wire_name_lower == "if-none-match":
325
+ elif role == "ifNoneMatch" and not property_if_none_match:
323
326
  property_if_none_match = p
324
327
  # pylint: disable=line-too-long
325
328
  # some service(e.g. https://github.com/Azure/azure-rest-api-specs/blob/main/specification/cosmos-db/data-plane/Microsoft.Tables/preview/2019-02-02/table.json)
@@ -327,17 +330,19 @@ class PreProcessPlugin(YamlUpdatePlugin):
327
330
  if not property_if_match and property_if_none_match:
328
331
  property_if_match = property_if_none_match.copy()
329
332
  property_if_match["wireName"] = "if-match"
333
+ property_if_match["etagRole"] = "ifMatch"
330
334
  if not property_if_none_match and property_if_match:
331
335
  property_if_none_match = property_if_match.copy()
332
336
  property_if_none_match["wireName"] = "if-none-match"
337
+ property_if_none_match["etagRole"] = "ifNoneMatch"
333
338
 
334
339
  if property_if_match and property_if_none_match:
335
340
  # arrange if-match and if-none-match to the end of parameters
336
- o["parameters"] = [
337
- item
338
- for item in o["parameters"]
339
- if get_wire_name_lower(item) not in ("if-match", "if-none-match")
340
- ] + [property_if_match, property_if_none_match]
341
+ etag_params = {id(property_if_match), id(property_if_none_match)}
342
+ o["parameters"] = [item for item in o["parameters"] if id(item) not in etag_params] + [
343
+ property_if_match,
344
+ property_if_none_match,
345
+ ]
341
346
 
342
347
  o["hasEtag"] = True
343
348
  yaml_data["hasEtag"] = True
@@ -362,11 +367,9 @@ class PreProcessPlugin(YamlUpdatePlugin):
362
367
  yaml_data["clientName"].lower(), PadType.PARAMETER, yaml_data
363
368
  )
364
369
  if yaml_data.get("propertyToParameterName"):
365
- # need to create a new one with padded keys and values
370
+ # need to create a new one with padded values (but NOT keys, since keys are wire names)
366
371
  yaml_data["propertyToParameterName"] = {
367
- self.pad_reserved_words(prop, PadType.PROPERTY, yaml_data): self.pad_reserved_words(
368
- param_name, PadType.PARAMETER, yaml_data
369
- ).lower()
372
+ prop: self.pad_reserved_words(param_name, PadType.PARAMETER, yaml_data).lower()
370
373
  for prop, param_name in yaml_data["propertyToParameterName"].items()
371
374
  }
372
375
  wire_name_lower = (yaml_data.get("wireName") or "").lower()
@@ -374,8 +377,12 @@ class PreProcessPlugin(YamlUpdatePlugin):
374
377
  wire_name_lower in HEADERS_HIDE_IN_METHOD or yaml_data.get("clientDefaultValue") == "multipart/form-data"
375
378
  ):
376
379
  yaml_data["hideInMethod"] = True
377
- if self.version_tolerant and yaml_data["location"] == "header" and wire_name_lower in HEADERS_CONVERT_IN_METHOD:
378
- headers_convert(yaml_data, HEADERS_CONVERT_IN_METHOD[wire_name_lower])
380
+ if self.version_tolerant and yaml_data["location"] == "header":
381
+ role = _get_etag_role(yaml_data)
382
+ if role == "ifMatch":
383
+ headers_convert(yaml_data, ETAG_MATCH_DATA)
384
+ elif role == "ifNoneMatch":
385
+ headers_convert(yaml_data, ETAG_NONE_MATCH_DATA)
379
386
  if wire_name_lower in ["$host", "content-type", "accept"] and yaml_data["type"]["type"] == "constant":
380
387
  yaml_data["clientDefaultValue"] = yaml_data["type"]["value"]
381
388
 
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "version": "1",
3
- "pip_version": "26.0.1",
3
+ "pip_version": "26.1.1",
4
4
  "install": [
5
5
  {
6
6
  "download_info": {
7
7
  "url": "https://files.pythonhosted.org/packages/9d/76/f789f7a86709c6b087c5a2f52f911838cad707cc613162401badc665acfe/setuptools-82.0.1-py3-none-any.whl",
8
8
  "archive_info": {
9
- "hash": "sha256=a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb",
10
9
  "hashes": {
11
10
  "sha256": "a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb"
12
- }
11
+ },
12
+ "hash": "sha256=a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb"
13
13
  }
14
14
  },
15
15
  "is_direct": false,
@@ -122,13 +122,13 @@
122
122
  ],
123
123
  "environment": {
124
124
  "implementation_name": "cpython",
125
- "implementation_version": "3.11.14",
125
+ "implementation_version": "3.11.15",
126
126
  "os_name": "posix",
127
127
  "platform_machine": "x86_64",
128
- "platform_release": "6.11.0-1018-azure",
128
+ "platform_release": "6.17.0-1010-azure",
129
129
  "platform_system": "Linux",
130
- "platform_version": "#18~24.04.1-Ubuntu SMP Sat Jun 28 04:46:03 UTC 2025",
131
- "python_full_version": "3.11.14",
130
+ "platform_version": "#10~24.04.1-Ubuntu SMP Fri Mar 6 22:00:57 UTC 2026",
131
+ "python_full_version": "3.11.15",
132
132
  "platform_python_implementation": "CPython",
133
133
  "python_version": "3.11",
134
134
  "sys_platform": "linux"