@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.
- package/dist/emitter/code-model.d.ts.map +1 -1
- package/dist/emitter/code-model.js +7 -6
- package/dist/emitter/code-model.js.map +1 -1
- package/dist/emitter/constants.d.ts +6 -0
- package/dist/emitter/constants.d.ts.map +1 -0
- package/dist/emitter/constants.js +27 -0
- package/dist/emitter/constants.js.map +1 -0
- package/dist/emitter/emitter.d.ts.map +1 -1
- package/dist/emitter/emitter.js +193 -119
- package/dist/emitter/emitter.js.map +1 -1
- package/dist/emitter/http.d.ts.map +1 -1
- package/dist/emitter/http.js +33 -1
- package/dist/emitter/http.js.map +1 -1
- package/dist/emitter/lib.d.ts +37 -3
- package/dist/emitter/lib.d.ts.map +1 -1
- package/dist/emitter/lib.js +17 -0
- package/dist/emitter/lib.js.map +1 -1
- package/dist/emitter/run-python3.js +1 -1
- package/dist/emitter/run-python3.js.map +1 -1
- package/dist/emitter/system-requirements.js +6 -4
- package/dist/emitter/system-requirements.js.map +1 -1
- package/dist/emitter/types.d.ts +2 -5
- package/dist/emitter/types.d.ts.map +1 -1
- package/dist/emitter/types.js +86 -63
- package/dist/emitter/types.js.map +1 -1
- package/dist/emitter/utils.d.ts.map +1 -1
- package/dist/emitter/utils.js +16 -17
- package/dist/emitter/utils.js.map +1 -1
- package/emitter/src/code-model.ts +7 -13
- package/emitter/src/constants.ts +27 -0
- package/emitter/src/emitter.ts +241 -123
- package/emitter/src/http.ts +29 -1
- package/emitter/src/lib.ts +24 -0
- package/emitter/src/run-python3.ts +1 -1
- package/emitter/src/system-requirements.ts +4 -4
- package/emitter/src/types.ts +102 -62
- package/emitter/src/utils.ts +16 -18
- package/emitter/temp/tsconfig.tsbuildinfo +1 -1
- package/emitter/test/utils.test.ts +3 -0
- package/emitter/tsconfig.build.json +2 -1
- package/emitter/tsconfig.json +2 -1
- package/eng/scripts/Build-Packages.ps1 +62 -37
- package/eng/scripts/Check-GitChanges.ps1 +30 -3
- package/eng/scripts/Functions.ps1 +54 -15
- package/eng/scripts/Generate.ps1 +42 -8
- package/eng/scripts/Generation.psm1 +44 -15
- package/eng/scripts/Initialize-Repository.ps1 +29 -11
- package/eng/scripts/Test-Packages.ps1 +47 -31
- package/eng/scripts/ci/config/eslint-ci.config.mjs +64 -0
- package/eng/scripts/ci/{mypy.ini → config/mypy.ini} +1 -1
- package/eng/scripts/ci/{pylintrc → config/pylintrc} +1 -1
- package/eng/scripts/ci/{pyrightconfig.json → config/pyrightconfig.json} +1 -1
- package/eng/scripts/ci/dev_requirements.txt +2 -1
- package/eng/scripts/ci/format.ts +232 -2
- package/eng/scripts/ci/lint.ts +223 -20
- package/eng/scripts/ci/regenerate-common.ts +411 -136
- package/eng/scripts/ci/regenerate.ts +247 -101
- package/eng/scripts/ci/run-tests.ts +507 -0
- package/eng/scripts/ci/run_apiview.py +22 -16
- package/eng/scripts/ci/run_mypy.py +34 -23
- package/eng/scripts/ci/run_pylint.py +27 -19
- package/eng/scripts/ci/run_pyright.py +9 -5
- package/eng/scripts/ci/run_sphinx_build.py +24 -9
- package/eng/scripts/ci/typecheck.ts +225 -0
- package/eng/scripts/ci/util.py +61 -25
- package/eng/scripts/ci/utils.ts +5 -5
- package/eng/scripts/setup/__pycache__/package_manager.cpython-311.pyc +0 -0
- package/eng/scripts/setup/__pycache__/venvtools.cpython-311.pyc +0 -0
- package/eng/scripts/setup/build.ts +1 -1
- package/eng/scripts/setup/build_pygen_wheel.py +4 -3
- package/eng/scripts/setup/install.py +4 -3
- package/eng/scripts/setup/install.ts +1 -1
- package/eng/scripts/setup/prepare.py +3 -2
- package/eng/scripts/setup/prepare.ts +1 -1
- package/eng/scripts/setup/run-python3.ts +1 -1
- package/eng/scripts/setup/run_batch.py +197 -0
- package/eng/scripts/setup/run_tsp.py +3 -3
- package/eng/scripts/setup/system-requirements.ts +8 -4
- package/eng/scripts/setup/venvtools.py +1 -1
- package/generator/build/lib/pygen/__init__.py +1 -3
- package/generator/build/lib/pygen/codegen/__init__.py +0 -1
- package/generator/build/lib/pygen/codegen/models/base.py +0 -1
- package/generator/build/lib/pygen/codegen/models/client.py +2 -1
- package/generator/build/lib/pygen/codegen/models/code_model.py +1 -0
- package/generator/build/lib/pygen/codegen/models/enum_type.py +0 -1
- package/generator/build/lib/pygen/codegen/models/model_type.py +1 -7
- package/generator/build/lib/pygen/codegen/models/parameter.py +16 -14
- package/generator/build/lib/pygen/codegen/serializers/__init__.py +27 -12
- package/generator/build/lib/pygen/codegen/serializers/builder_serializer.py +12 -3
- package/generator/build/lib/pygen/codegen/serializers/general_serializer.py +6 -2
- package/generator/build/lib/pygen/codegen/serializers/import_serializer.py +17 -4
- package/generator/build/lib/pygen/codegen/serializers/parameter_serializer.py +17 -11
- package/generator/build/lib/pygen/codegen/templates/model_base.py.jinja2 +176 -71
- package/generator/build/lib/pygen/codegen/templates/packaging_templates/README.md.jinja2 +11 -3
- package/generator/build/lib/pygen/codegen/templates/packaging_templates/pyproject.toml.jinja2 +1 -1
- package/generator/build/lib/pygen/codegen/templates/serialization.py.jinja2 +5 -1
- package/generator/build/lib/pygen/preprocess/__init__.py +37 -30
- package/generator/component-detection-pip-report.json +7 -7
- package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
- package/generator/pygen/__init__.py +1 -3
- package/generator/pygen/codegen/__init__.py +0 -1
- package/generator/pygen/codegen/models/base.py +0 -1
- package/generator/pygen/codegen/models/client.py +2 -1
- package/generator/pygen/codegen/models/code_model.py +1 -0
- package/generator/pygen/codegen/models/enum_type.py +0 -1
- package/generator/pygen/codegen/models/model_type.py +1 -7
- package/generator/pygen/codegen/models/parameter.py +16 -14
- package/generator/pygen/codegen/serializers/__init__.py +27 -12
- package/generator/pygen/codegen/serializers/builder_serializer.py +12 -3
- package/generator/pygen/codegen/serializers/general_serializer.py +6 -2
- package/generator/pygen/codegen/serializers/import_serializer.py +17 -4
- package/generator/pygen/codegen/serializers/parameter_serializer.py +17 -11
- package/generator/pygen/codegen/templates/model_base.py.jinja2 +176 -71
- package/generator/pygen/codegen/templates/packaging_templates/README.md.jinja2 +11 -3
- package/generator/pygen/codegen/templates/packaging_templates/pyproject.toml.jinja2 +1 -1
- package/generator/pygen/codegen/templates/serialization.py.jinja2 +5 -1
- package/generator/pygen/preprocess/__init__.py +37 -30
- package/generator/pygen.egg-info/PKG-INFO +1 -2
- package/generator/pygen.egg-info/requires.txt +1 -1
- package/generator/setup.py +1 -2
- package/package.json +63 -42
- package/eng/scripts/ci/run-ci.ts +0 -89
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_commonproperties_async.py +0 -94
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_largeheader_async.py +0 -30
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_nonresource_async.py +0 -36
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_operationtemplates_async.py +0 -205
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_arm_resource_async.py +0 -478
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_access_async.py +0 -101
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_api_version_header_async.py +0 -18
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_api_version_path_async.py +0 -18
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_api_version_query_async.py +0 -18
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_client_default_value_async.py +0 -46
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_client_initialization_async.py +0 -58
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_client_location_async.py +0 -82
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_deserialize_empty_string_as_null_async.py +0 -20
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_flatten_async.py +0 -115
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_hierrarchy_building_async.py +0 -53
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_next_link_verb_async.py +0 -28
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_override_async.py +0 -106
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_client_generator_core_usage_async.py +0 -38
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_basic_async.py +0 -76
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_lro_rpc_async.py +0 -22
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_lro_standard_async.py +0 -39
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_model_async.py +0 -33
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_page_async.py +0 -80
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_scalar_async.py +0 -41
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_core_traits_async.py +0 -87
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_encode_duration_async.py +0 -19
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_example_basic_async.py +0 -30
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_payload_pageable_async.py +0 -19
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_resource_manager_method_subscription_id_async.py +0 -248
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_resource_manager_multi_service_async.py +0 -110
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_resource_manager_multi_service_shared_models_async.py +0 -132
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_special_headers_client_request_id_async.py +0 -30
- package/generator/test/azure/mock_api_tests/asynctests/test_azure_versioning_previewversion_async.py +0 -53
- package/generator/test/azure/mock_api_tests/asynctests/test_client_namespace_async.py +0 -34
- package/generator/test/azure/mock_api_tests/asynctests/test_client_naming_async.py +0 -69
- package/generator/test/azure/mock_api_tests/asynctests/test_client_naming_enum_conflict_async.py +0 -37
- package/generator/test/azure/mock_api_tests/asynctests/test_client_overload_async.py +0 -27
- package/generator/test/azure/mock_api_tests/asynctests/test_client_structure_async.py +0 -64
- package/generator/test/azure/mock_api_tests/asynctests/test_client_structure_clientoperationgroup_async.py +0 -31
- package/generator/test/azure/mock_api_tests/asynctests/test_encode_duration_async.py +0 -63
- package/generator/test/azure/mock_api_tests/asynctests/test_encode_numeric_async.py +0 -35
- package/generator/test/azure/mock_api_tests/asynctests/test_parameters_basic_async.py +0 -24
- package/generator/test/azure/mock_api_tests/asynctests/test_parameters_spread_async.py +0 -76
- package/generator/test/azure/mock_api_tests/asynctests/test_payload_content_negotiation_async.py +0 -37
- package/generator/test/azure/mock_api_tests/asynctests/test_payload_multipart_async.py +0 -216
- package/generator/test/azure/mock_api_tests/asynctests/test_resiliency_srv_driven_async.py +0 -130
- package/generator/test/azure/mock_api_tests/asynctests/test_serialization_encoded_name_json_async.py +0 -24
- package/generator/test/azure/mock_api_tests/asynctests/test_service_multi_service_async.py +0 -31
- package/generator/test/azure/mock_api_tests/asynctests/test_special_words_async.py +0 -71
- package/generator/test/azure/mock_api_tests/conftest.py +0 -207
- package/generator/test/azure/mock_api_tests/data/image.jpg +0 -0
- package/generator/test/azure/mock_api_tests/data/image.png +0 -0
- package/generator/test/azure/mock_api_tests/test_azure_arm_commonproperties.py +0 -89
- package/generator/test/azure/mock_api_tests/test_azure_arm_largeheader.py +0 -27
- package/generator/test/azure/mock_api_tests/test_azure_arm_nonresource.py +0 -34
- package/generator/test/azure/mock_api_tests/test_azure_arm_operationtemplates.py +0 -180
- package/generator/test/azure/mock_api_tests/test_azure_arm_resource.py +0 -436
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_access.py +0 -92
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_api_version_header.py +0 -17
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_api_version_path.py +0 -17
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_api_version_query.py +0 -17
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_client_default_value.py +0 -42
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_client_initialization.py +0 -51
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_client_location.py +0 -70
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_deserialize_empty_string_as_null.py +0 -19
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_flatten.py +0 -104
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_hierrarchy_building.py +0 -45
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_next_link_verb.py +0 -27
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_override.py +0 -102
- package/generator/test/azure/mock_api_tests/test_azure_client_generator_core_usage.py +0 -32
- package/generator/test/azure/mock_api_tests/test_azure_core_basic.py +0 -70
- package/generator/test/azure/mock_api_tests/test_azure_core_lro_rpc.py +0 -20
- package/generator/test/azure/mock_api_tests/test_azure_core_lro_standard.py +0 -32
- package/generator/test/azure/mock_api_tests/test_azure_core_model.py +0 -30
- package/generator/test/azure/mock_api_tests/test_azure_core_page.py +0 -71
- package/generator/test/azure/mock_api_tests/test_azure_core_scalar.py +0 -35
- package/generator/test/azure/mock_api_tests/test_azure_core_traits.py +0 -85
- package/generator/test/azure/mock_api_tests/test_azure_encode_duration.py +0 -18
- package/generator/test/azure/mock_api_tests/test_azure_example_basic.py +0 -29
- package/generator/test/azure/mock_api_tests/test_azure_payload_pageable.py +0 -18
- package/generator/test/azure/mock_api_tests/test_azure_resource_manager_method_subscription_id.py +0 -235
- package/generator/test/azure/mock_api_tests/test_azure_resource_manager_multi_service.py +0 -104
- package/generator/test/azure/mock_api_tests/test_azure_resource_manager_multi_service_shared_models.py +0 -128
- package/generator/test/azure/mock_api_tests/test_azure_special_headers_client_request_id.py +0 -29
- package/generator/test/azure/mock_api_tests/test_azure_versioning_previewversion.py +0 -50
- package/generator/test/azure/mock_api_tests/test_clear_output_folder.py +0 -23
- package/generator/test/azure/mock_api_tests/test_client_namespace.py +0 -32
- package/generator/test/azure/mock_api_tests/test_client_naming.py +0 -57
- package/generator/test/azure/mock_api_tests/test_client_naming_enum_conflict.py +0 -35
- package/generator/test/azure/mock_api_tests/test_client_overload.py +0 -25
- package/generator/test/azure/mock_api_tests/test_client_structure.py +0 -60
- package/generator/test/azure/mock_api_tests/test_client_structure_clientoperationgroup.py +0 -29
- package/generator/test/azure/mock_api_tests/test_encode_duration.py +0 -60
- package/generator/test/azure/mock_api_tests/test_encode_numeric.py +0 -31
- package/generator/test/azure/mock_api_tests/test_model_base_flatten_compatibility.py +0 -251
- package/generator/test/azure/mock_api_tests/test_parameters_basic.py +0 -22
- package/generator/test/azure/mock_api_tests/test_parameters_spread.py +0 -66
- package/generator/test/azure/mock_api_tests/test_payload_content_negotiation.py +0 -33
- package/generator/test/azure/mock_api_tests/test_payload_multipart.py +0 -198
- package/generator/test/azure/mock_api_tests/test_resiliency_srv_driven.py +0 -124
- package/generator/test/azure/mock_api_tests/test_serialization_encoded_name_json.py +0 -21
- package/generator/test/azure/mock_api_tests/test_service_multi_service.py +0 -29
- package/generator/test/azure/mock_api_tests/test_special_words.py +0 -63
- package/generator/test/azure/requirements.txt +0 -125
- package/generator/test/azure/tox.ini +0 -64
- package/generator/test/data/image.jpg +0 -0
- package/generator/test/data/image.png +0 -0
- package/generator/test/dev_requirements.txt +0 -8
- package/generator/test/generic_mock_api_tests/asynctests/test_authentication_async.py +0 -140
- package/generator/test/generic_mock_api_tests/asynctests/test_encode_array_async.py +0 -139
- package/generator/test/generic_mock_api_tests/asynctests/test_encode_bytes_async.py +0 -132
- package/generator/test/generic_mock_api_tests/asynctests/test_encode_datetime_async.py +0 -127
- package/generator/test/generic_mock_api_tests/asynctests/test_headasboolean_async.py +0 -35
- package/generator/test/generic_mock_api_tests/asynctests/test_parameters_body_optionality_async.py +0 -30
- package/generator/test/generic_mock_api_tests/asynctests/test_parameters_collection_format_async.py +0 -38
- package/generator/test/generic_mock_api_tests/asynctests/test_parameters_path_async.py +0 -24
- package/generator/test/generic_mock_api_tests/asynctests/test_parameters_query_async.py +0 -18
- package/generator/test/generic_mock_api_tests/asynctests/test_payload_json_merge_patch_async.py +0 -98
- package/generator/test/generic_mock_api_tests/asynctests/test_payload_media_type_async.py +0 -27
- package/generator/test/generic_mock_api_tests/asynctests/test_payload_pageable_async.py +0 -134
- package/generator/test/generic_mock_api_tests/asynctests/test_payload_xml_async.py +0 -150
- package/generator/test/generic_mock_api_tests/asynctests/test_response_status_code_range_async.py +0 -38
- package/generator/test/generic_mock_api_tests/asynctests/test_routes_async.py +0 -331
- package/generator/test/generic_mock_api_tests/asynctests/test_server_endpoint_not_defined_async.py +0 -18
- package/generator/test/generic_mock_api_tests/asynctests/test_server_path_multiple_async.py +0 -25
- package/generator/test/generic_mock_api_tests/asynctests/test_server_path_single_async.py +0 -18
- package/generator/test/generic_mock_api_tests/asynctests/test_server_versions_not_versioned_async.py +0 -28
- package/generator/test/generic_mock_api_tests/asynctests/test_server_versions_versioned_async.py +0 -34
- package/generator/test/generic_mock_api_tests/asynctests/test_special_headers_conditional_request_async.py +0 -38
- package/generator/test/generic_mock_api_tests/asynctests/test_special_headers_repeatability_async.py +0 -19
- package/generator/test/generic_mock_api_tests/asynctests/test_specs_documentation_async.py +0 -59
- package/generator/test/generic_mock_api_tests/asynctests/test_streaming_jsonl_async.py +0 -27
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_array_async.py +0 -127
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_dictionary_async.py +0 -98
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_enum_extensible_async.py +0 -25
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_enum_fixed_async.py +0 -27
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_file_async.py +0 -59
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_empty_async.py +0 -32
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_inheritance_enum_discriminator_async.py +0 -70
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_inheritance_nested_discriminator_async.py +0 -85
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_inheritance_not_discriminated_async.py +0 -34
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_inheritance_recursive_async.py +0 -34
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_inheritance_single_discriminator_async.py +0 -67
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_usage_async.py +0 -32
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_model_visibility_async.py +0 -47
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_property_additionalproperties_async.py +0 -353
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_property_nullable_async.py +0 -110
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_property_optional_async.py +0 -197
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_property_valuetypes_async.py +0 -315
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_scalar_async.py +0 -60
- package/generator/test/generic_mock_api_tests/asynctests/test_typetest_union_async.py +0 -90
- package/generator/test/generic_mock_api_tests/asynctests/test_versioning_added_async.py +0 -36
- package/generator/test/generic_mock_api_tests/asynctests/test_versioning_made_optional_async.py +0 -21
- package/generator/test/generic_mock_api_tests/asynctests/test_versioning_removed_async.py +0 -39
- package/generator/test/generic_mock_api_tests/asynctests/test_versioning_renamed_from_async.py +0 -29
- package/generator/test/generic_mock_api_tests/asynctests/test_versioning_return_type_changed_from_async.py +0 -18
- package/generator/test/generic_mock_api_tests/asynctests/test_versioning_type_changed_from_async.py +0 -22
- package/generator/test/generic_mock_api_tests/conftest.py +0 -75
- package/generator/test/generic_mock_api_tests/data/image.jpg +0 -0
- package/generator/test/generic_mock_api_tests/data/image.png +0 -0
- package/generator/test/generic_mock_api_tests/test_authentication.py +0 -130
- package/generator/test/generic_mock_api_tests/test_encode_array.py +0 -126
- package/generator/test/generic_mock_api_tests/test_encode_bytes.py +0 -128
- package/generator/test/generic_mock_api_tests/test_encode_datetime.py +0 -123
- package/generator/test/generic_mock_api_tests/test_headasboolean.py +0 -33
- package/generator/test/generic_mock_api_tests/test_parameters_body_optionality.py +0 -27
- package/generator/test/generic_mock_api_tests/test_parameters_collection_format.py +0 -33
- package/generator/test/generic_mock_api_tests/test_parameters_path.py +0 -22
- package/generator/test/generic_mock_api_tests/test_parameters_query.py +0 -17
- package/generator/test/generic_mock_api_tests/test_payload_json_merge_patch.py +0 -93
- package/generator/test/generic_mock_api_tests/test_payload_media_type.py +0 -25
- package/generator/test/generic_mock_api_tests/test_payload_pageable.py +0 -99
- package/generator/test/generic_mock_api_tests/test_payload_xml.py +0 -135
- package/generator/test/generic_mock_api_tests/test_response_status_code_range.py +0 -36
- package/generator/test/generic_mock_api_tests/test_routes.py +0 -285
- package/generator/test/generic_mock_api_tests/test_server_endpoint_not_defined.py +0 -17
- package/generator/test/generic_mock_api_tests/test_server_path_multiple.py +0 -21
- package/generator/test/generic_mock_api_tests/test_server_path_single.py +0 -17
- package/generator/test/generic_mock_api_tests/test_server_versions_not_versioned.py +0 -25
- package/generator/test/generic_mock_api_tests/test_server_versions_versioned.py +0 -30
- package/generator/test/generic_mock_api_tests/test_special_headers_conditional_request.py +0 -34
- package/generator/test/generic_mock_api_tests/test_special_headers_repeatability.py +0 -18
- package/generator/test/generic_mock_api_tests/test_specs_documentation.py +0 -51
- package/generator/test/generic_mock_api_tests/test_streaming_jsonl.py +0 -25
- package/generator/test/generic_mock_api_tests/test_typetest_array.py +0 -111
- package/generator/test/generic_mock_api_tests/test_typetest_dictionary.py +0 -86
- package/generator/test/generic_mock_api_tests/test_typetest_enum_extensible.py +0 -23
- package/generator/test/generic_mock_api_tests/test_typetest_enum_fixed.py +0 -25
- package/generator/test/generic_mock_api_tests/test_typetest_file.py +0 -52
- package/generator/test/generic_mock_api_tests/test_typetest_model_empty.py +0 -29
- package/generator/test/generic_mock_api_tests/test_typetest_model_inheritance_enum_discriminator.py +0 -58
- package/generator/test/generic_mock_api_tests/test_typetest_model_inheritance_nested_discriminator.py +0 -79
- package/generator/test/generic_mock_api_tests/test_typetest_model_inheritance_not_discriminated.py +0 -31
- package/generator/test/generic_mock_api_tests/test_typetest_model_inheritance_recursive.py +0 -32
- package/generator/test/generic_mock_api_tests/test_typetest_model_inheritance_single_discriminator.py +0 -60
- package/generator/test/generic_mock_api_tests/test_typetest_model_usage.py +0 -28
- package/generator/test/generic_mock_api_tests/test_typetest_model_visibility.py +0 -40
- package/generator/test/generic_mock_api_tests/test_typetest_property_additionalproperties.py +0 -314
- package/generator/test/generic_mock_api_tests/test_typetest_property_nullable.py +0 -102
- package/generator/test/generic_mock_api_tests/test_typetest_property_optional.py +0 -174
- package/generator/test/generic_mock_api_tests/test_typetest_property_valuetypes.py +0 -286
- package/generator/test/generic_mock_api_tests/test_typetest_scalar.py +0 -53
- package/generator/test/generic_mock_api_tests/test_typetest_union.py +0 -80
- package/generator/test/generic_mock_api_tests/test_typetest_union_discriminated.py +0 -290
- package/generator/test/generic_mock_api_tests/test_versioning_added.py +0 -33
- package/generator/test/generic_mock_api_tests/test_versioning_made_optional.py +0 -20
- package/generator/test/generic_mock_api_tests/test_versioning_removed.py +0 -37
- package/generator/test/generic_mock_api_tests/test_versioning_renamed_from.py +0 -27
- package/generator/test/generic_mock_api_tests/test_versioning_return_type_changed_from.py +0 -17
- package/generator/test/generic_mock_api_tests/test_versioning_type_changed_from.py +0 -21
- package/generator/test/unbranded/mock_api_tests/asynctests/test_auth_flow_async.py +0 -19
- package/generator/test/unbranded/mock_api_tests/asynctests/test_encode_duration_async.py +0 -63
- package/generator/test/unbranded/mock_api_tests/asynctests/test_encode_numeric_async.py +0 -35
- package/generator/test/unbranded/mock_api_tests/asynctests/test_parameters_basic_async.py +0 -24
- package/generator/test/unbranded/mock_api_tests/asynctests/test_parameters_spread_async.py +0 -76
- package/generator/test/unbranded/mock_api_tests/asynctests/test_payload_content_negotiation_async.py +0 -37
- package/generator/test/unbranded/mock_api_tests/asynctests/test_payload_multipart_async.py +0 -218
- package/generator/test/unbranded/mock_api_tests/asynctests/test_serialization_encoded_name_json_async.py +0 -24
- package/generator/test/unbranded/mock_api_tests/asynctests/test_special_words_async.py +0 -73
- package/generator/test/unbranded/mock_api_tests/asynctests/test_unbranded_async.py +0 -24
- package/generator/test/unbranded/mock_api_tests/conftest.py +0 -91
- package/generator/test/unbranded/mock_api_tests/data/image.jpg +0 -0
- package/generator/test/unbranded/mock_api_tests/data/image.png +0 -0
- package/generator/test/unbranded/mock_api_tests/test_auth_flow.py +0 -17
- package/generator/test/unbranded/mock_api_tests/test_encode_duration.py +0 -60
- package/generator/test/unbranded/mock_api_tests/test_encode_numeric.py +0 -32
- package/generator/test/unbranded/mock_api_tests/test_parameters_basic.py +0 -22
- package/generator/test/unbranded/mock_api_tests/test_parameters_spread.py +0 -66
- package/generator/test/unbranded/mock_api_tests/test_payload_content_negotiation.py +0 -33
- package/generator/test/unbranded/mock_api_tests/test_payload_multipart.py +0 -200
- package/generator/test/unbranded/mock_api_tests/test_serialization_encoded_name_json.py +0 -22
- package/generator/test/unbranded/mock_api_tests/test_special_words.py +0 -66
- package/generator/test/unbranded/mock_api_tests/test_unbranded.py +0 -65
- package/generator/test/unbranded/requirements.txt +0 -69
- package/generator/test/unbranded/tox.ini +0 -64
- package/generator/test/unittests/conftest.py +0 -15
- package/generator/test/unittests/requirements.txt +0 -3
- package/generator/test/unittests/test_enums.py +0 -89
- package/generator/test/unittests/test_model_base_serialization.py +0 -4906
- package/generator/test/unittests/test_model_base_xml_serialization.py +0 -1239
- package/generator/test/unittests/test_name_converter.py +0 -35
- package/generator/test/unittests/test_optional_return_type.py +0 -268
- package/generator/test/unittests/test_parameter_ordering.py +0 -104
- package/generator/test/unittests/test_sort_schema.py +0 -93
- package/generator/test/unittests/tox.ini +0 -5
- /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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
1343
|
+
element_name,
|
|
1259
1344
|
model_meta.get("prefix"),
|
|
1260
|
-
|
|
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
|
-
#
|
|
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
|
-
|
|
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":
|
|
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":
|
|
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,
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
124
|
+
- Python 3.10 or later is required to use this package.
|
|
117
125
|
|
|
118
126
|
### Install the package
|
|
119
127
|
|
|
@@ -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
|
-
|
|
136
|
-
"
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
"
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
"type":
|
|
146
|
-
|
|
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
|
-
|
|
285
|
-
|
|
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
|
-
|
|
322
|
+
role = _get_etag_role(p)
|
|
323
|
+
if role == "ifMatch" and not property_if_match:
|
|
321
324
|
property_if_match = p
|
|
322
|
-
elif
|
|
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
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
]
|
|
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
|
|
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(
|
|
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"
|
|
378
|
-
|
|
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.
|
|
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.
|
|
125
|
+
"implementation_version": "3.11.15",
|
|
126
126
|
"os_name": "posix",
|
|
127
127
|
"platform_machine": "x86_64",
|
|
128
|
-
"platform_release": "6.
|
|
128
|
+
"platform_release": "6.17.0-1010-azure",
|
|
129
129
|
"platform_system": "Linux",
|
|
130
|
-
"platform_version": "#
|
|
131
|
-
"python_full_version": "3.11.
|
|
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"
|
|
Binary file
|