@typespec/http-client-python 0.28.2 → 0.28.3
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 +6 -6
- package/dist/emitter/code-model.js.map +1 -1
- package/dist/emitter/emitter.d.ts.map +1 -1
- package/dist/emitter/emitter.js +27 -28
- package/dist/emitter/emitter.js.map +1 -1
- package/dist/emitter/lib.d.ts +4 -1
- package/dist/emitter/lib.d.ts.map +1 -1
- package/dist/emitter/lib.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 +55 -58
- 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 +6 -13
- package/emitter/src/emitter.ts +29 -31
- package/emitter/src/lib.ts +4 -0
- package/emitter/src/system-requirements.ts +4 -4
- package/emitter/src/types.ts +67 -57
- package/emitter/src/utils.ts +16 -18
- package/emitter/temp/tsconfig.tsbuildinfo +1 -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 +54 -0
- package/eng/scripts/ci/dev_requirements.txt +1 -0
- package/eng/scripts/ci/format.ts +232 -2
- package/eng/scripts/ci/lint.ts +216 -20
- package/eng/scripts/ci/regenerate-common.ts +18 -14
- package/eng/scripts/ci/regenerate.ts +305 -68
- package/eng/scripts/ci/run-tests.ts +402 -0
- package/eng/scripts/ci/run_mypy.py +4 -3
- package/eng/scripts/ci/run_pylint.py +4 -3
- package/eng/scripts/ci/run_pyright.py +4 -3
- package/eng/scripts/ci/typecheck.ts +225 -0
- package/eng/scripts/ci/util.py +1 -1
- 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 +1 -0
- package/eng/scripts/setup/install.py +1 -0
- package/eng/scripts/setup/prepare.py +1 -0
- package/eng/scripts/setup/prepare.ts +1 -1
- 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 -0
- package/generator/build/lib/pygen/codegen/templates/model_base.py.jinja2 +157 -64
- package/generator/dist/pygen-0.1.0-py3-none-any.whl +0 -0
- package/generator/pygen/codegen/templates/model_base.py.jinja2 +157 -64
- package/package.json +48 -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/{mypy.ini → config/mypy.ini} +0 -0
- /package/eng/scripts/ci/{pylintrc → config/pylintrc} +0 -0
- /package/eng/scripts/ci/{pyproject.toml → config/pyproject.toml} +0 -0
- /package/eng/scripts/ci/{pyrightconfig.json → config/pyrightconfig.json} +0 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import { ChildProcess, spawn } from "child_process";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import { cpus } from "os";
|
|
5
|
+
import { dirname, join } from "path";
|
|
6
|
+
import pc from "picocolors";
|
|
7
|
+
import { fileURLToPath } from "url";
|
|
8
|
+
import { parseArgs } from "util";
|
|
9
|
+
|
|
10
|
+
const root = join(dirname(fileURLToPath(import.meta.url)), "../../../");
|
|
11
|
+
const monorepoRoot = join(root, "../../");
|
|
12
|
+
const testsDir = join(root, "tests");
|
|
13
|
+
|
|
14
|
+
const argv = parseArgs({
|
|
15
|
+
args: process.argv.slice(2),
|
|
16
|
+
options: {
|
|
17
|
+
emitter: { type: "boolean", short: "e" },
|
|
18
|
+
generator: { type: "boolean", short: "g" },
|
|
19
|
+
flavor: { type: "string", short: "f", default: "all" },
|
|
20
|
+
env: { type: "string" },
|
|
21
|
+
jobs: { type: "string", short: "j" },
|
|
22
|
+
name: { type: "string", short: "n" },
|
|
23
|
+
quiet: { type: "boolean", short: "q", default: false },
|
|
24
|
+
help: { type: "boolean", short: "h", default: false },
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
if (argv.values.help) {
|
|
29
|
+
console.log(`
|
|
30
|
+
Usage: run-tests.ts [options]
|
|
31
|
+
|
|
32
|
+
Options:
|
|
33
|
+
-e, --emitter Run TypeScript emitter tests (vitest)
|
|
34
|
+
-g, --generator Run Python generator tests (tox)
|
|
35
|
+
-f, --flavor <azure|unbranded> SDK flavor to test (only applies to --generator)
|
|
36
|
+
If not specified, tests both flavors
|
|
37
|
+
--env <env1,env2,...> Specific tox environments to run
|
|
38
|
+
Available: test, lint, mypy, pyright, docs, ci, unittest
|
|
39
|
+
-j, --jobs <n> Number of parallel jobs (default: CPU cores - 2)
|
|
40
|
+
-n, --name <pattern> Filter tests by name pattern
|
|
41
|
+
-q, --quiet Suppress test output (only show pass/fail summary)
|
|
42
|
+
-h, --help Show this help message
|
|
43
|
+
|
|
44
|
+
Environments (for --generator):
|
|
45
|
+
test Run pytest tests for generated packages
|
|
46
|
+
lint Run pylint on generated packages
|
|
47
|
+
mypy Run mypy type checking on generated packages
|
|
48
|
+
pyright Run pyright type checking on generated packages
|
|
49
|
+
docs Run documentation validation (apiview, sphinx)
|
|
50
|
+
ci Run all checks (test + lint + mypy + pyright)
|
|
51
|
+
unittest Run unit tests for pygen internals
|
|
52
|
+
|
|
53
|
+
Examples:
|
|
54
|
+
run-tests.ts # Run all tests (emitter + generator)
|
|
55
|
+
run-tests.ts --emitter # Run only emitter tests
|
|
56
|
+
run-tests.ts --generator # Run generator tests for all flavors
|
|
57
|
+
run-tests.ts --generator --flavor=azure # Run generator tests for azure only
|
|
58
|
+
run-tests.ts -g -f azure --env=test # Run pytest for azure only
|
|
59
|
+
run-tests.ts -g --env=mypy # Run mypy for all flavors
|
|
60
|
+
run-tests.ts -g -f unbranded --env=lint # Run pylint for unbranded only
|
|
61
|
+
`);
|
|
62
|
+
process.exit(0);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Get Python venv path
|
|
66
|
+
function getVenvPython(): string {
|
|
67
|
+
const venvPath = join(root, "venv");
|
|
68
|
+
if (fs.existsSync(join(venvPath, "bin"))) {
|
|
69
|
+
return join(venvPath, "bin", "python");
|
|
70
|
+
} else if (fs.existsSync(join(venvPath, "Scripts"))) {
|
|
71
|
+
return join(venvPath, "Scripts", "python.exe");
|
|
72
|
+
}
|
|
73
|
+
throw new Error("Virtual environment not found. Run 'npm run install' first.");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
interface ToxResult {
|
|
77
|
+
env: string;
|
|
78
|
+
success: boolean;
|
|
79
|
+
duration: number;
|
|
80
|
+
error?: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function runToxEnv(env: string, pythonPath: string, name?: string): Promise<ToxResult> {
|
|
84
|
+
const startTime = Date.now();
|
|
85
|
+
const toxIniPath = join(testsDir, "tox.ini");
|
|
86
|
+
|
|
87
|
+
// Build command
|
|
88
|
+
const args = ["-m", "tox", "-c", toxIniPath, "-e", env];
|
|
89
|
+
if (name) {
|
|
90
|
+
args.push("--", "-k", name);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
console.log(`${pc.blue("[START]")} ${env}`);
|
|
94
|
+
|
|
95
|
+
return new Promise((resolve) => {
|
|
96
|
+
const proc: ChildProcess = spawn(pythonPath, args, {
|
|
97
|
+
cwd: testsDir,
|
|
98
|
+
stdio: !argv.values.quiet ? "inherit" : "pipe",
|
|
99
|
+
env: { ...process.env, FOLDER: env.split("-")[1] || "azure" },
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
let stderr = "";
|
|
103
|
+
if (argv.values.quiet && proc.stderr) {
|
|
104
|
+
proc.stderr.on("data", (data) => {
|
|
105
|
+
stderr += data.toString();
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
proc.on("close", (code) => {
|
|
110
|
+
const duration = (Date.now() - startTime) / 1000;
|
|
111
|
+
const success = code === 0;
|
|
112
|
+
|
|
113
|
+
if (success) {
|
|
114
|
+
console.log(`${pc.green("[PASS]")} ${env} (${duration.toFixed(1)}s)`);
|
|
115
|
+
} else {
|
|
116
|
+
console.log(`${pc.red("[FAIL]")} ${env} (${duration.toFixed(1)}s)`);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
resolve({
|
|
120
|
+
env,
|
|
121
|
+
success,
|
|
122
|
+
duration,
|
|
123
|
+
error: success ? undefined : stderr || `Exit code: ${code}`,
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
proc.on("error", (err) => {
|
|
128
|
+
const duration = (Date.now() - startTime) / 1000;
|
|
129
|
+
console.log(`${pc.red("[ERROR]")} ${env}: ${err.message}`);
|
|
130
|
+
resolve({
|
|
131
|
+
env,
|
|
132
|
+
success: false,
|
|
133
|
+
duration,
|
|
134
|
+
error: err.message,
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async function runParallel(
|
|
141
|
+
envs: string[],
|
|
142
|
+
pythonPath: string,
|
|
143
|
+
maxJobs: number,
|
|
144
|
+
name?: string,
|
|
145
|
+
): Promise<ToxResult[]> {
|
|
146
|
+
const results: ToxResult[] = [];
|
|
147
|
+
const running: Map<string, Promise<ToxResult>> = new Map();
|
|
148
|
+
|
|
149
|
+
for (const env of envs) {
|
|
150
|
+
// Wait if we're at max capacity
|
|
151
|
+
if (running.size >= maxJobs) {
|
|
152
|
+
const completed = await Promise.race(running.values());
|
|
153
|
+
results.push(completed);
|
|
154
|
+
running.delete(completed.env);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Start new task
|
|
158
|
+
const task = runToxEnv(env, pythonPath, name);
|
|
159
|
+
running.set(env, task);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Wait for remaining tasks
|
|
163
|
+
const remaining = await Promise.all(running.values());
|
|
164
|
+
results.push(...remaining);
|
|
165
|
+
|
|
166
|
+
return results;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async function _runSequential(
|
|
170
|
+
envs: string[],
|
|
171
|
+
pythonPath: string,
|
|
172
|
+
name?: string,
|
|
173
|
+
): Promise<ToxResult[]> {
|
|
174
|
+
const results: ToxResult[] = [];
|
|
175
|
+
for (const env of envs) {
|
|
176
|
+
const result = await runToxEnv(env, pythonPath, name);
|
|
177
|
+
results.push(result);
|
|
178
|
+
}
|
|
179
|
+
return results;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function printSummary(results: ToxResult[]): void {
|
|
183
|
+
console.log("\n" + pc.bold("═".repeat(60)));
|
|
184
|
+
console.log(pc.bold(" Test Results Summary"));
|
|
185
|
+
console.log(pc.bold("═".repeat(60)) + "\n");
|
|
186
|
+
|
|
187
|
+
const passed = results.filter((r) => r.success);
|
|
188
|
+
const failed = results.filter((r) => !r.success);
|
|
189
|
+
const totalDuration = results.reduce((sum, r) => sum + r.duration, 0);
|
|
190
|
+
|
|
191
|
+
for (const result of results) {
|
|
192
|
+
const status = result.success ? pc.green("PASS") : pc.red("FAIL");
|
|
193
|
+
console.log(` ${status} ${result.env} (${result.duration.toFixed(1)}s)`);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
console.log("\n" + "─".repeat(60));
|
|
197
|
+
console.log(
|
|
198
|
+
` ${pc.green(`Passed: ${passed.length}`)} ` +
|
|
199
|
+
`${pc.red(`Failed: ${failed.length}`)} ` +
|
|
200
|
+
`Total: ${results.length} ` +
|
|
201
|
+
`Duration: ${totalDuration.toFixed(1)}s`,
|
|
202
|
+
);
|
|
203
|
+
console.log("─".repeat(60) + "\n");
|
|
204
|
+
|
|
205
|
+
if (failed.length > 0) {
|
|
206
|
+
console.log(pc.red("Failed environments:"));
|
|
207
|
+
for (const result of failed) {
|
|
208
|
+
console.log(` - ${result.env}`);
|
|
209
|
+
if (result.error && !argv.values.quiet) {
|
|
210
|
+
console.log(` ${result.error.split("\n").slice(0, 5).join("\n ")}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
console.log();
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
async function runEmitterTests(): Promise<ToxResult> {
|
|
218
|
+
const startTime = Date.now();
|
|
219
|
+
console.log(`${pc.blue("[START]")} emitter (vitest)`);
|
|
220
|
+
|
|
221
|
+
// Add node_modules/.bin directories to PATH so vitest can be found
|
|
222
|
+
const pathSep = process.platform === "win32" ? ";" : ":";
|
|
223
|
+
const binPaths = [
|
|
224
|
+
join(root, "node_modules", ".bin"),
|
|
225
|
+
join(monorepoRoot, "node_modules", ".bin"),
|
|
226
|
+
].join(pathSep);
|
|
227
|
+
const env = {
|
|
228
|
+
...process.env,
|
|
229
|
+
PATH: `${binPaths}${pathSep}${process.env.PATH}`,
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
return new Promise((resolve) => {
|
|
233
|
+
const proc: ChildProcess = spawn("vitest", ["run", "-c", "./emitter/vitest.config.ts"], {
|
|
234
|
+
cwd: root,
|
|
235
|
+
stdio: !argv.values.quiet ? "inherit" : "pipe",
|
|
236
|
+
shell: true,
|
|
237
|
+
env,
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
let stderr = "";
|
|
241
|
+
if (argv.values.quiet && proc.stderr) {
|
|
242
|
+
proc.stderr.on("data", (data) => {
|
|
243
|
+
stderr += data.toString();
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
proc.on("close", (code) => {
|
|
248
|
+
const duration = (Date.now() - startTime) / 1000;
|
|
249
|
+
const success = code === 0;
|
|
250
|
+
|
|
251
|
+
if (success) {
|
|
252
|
+
console.log(`${pc.green("[PASS]")} emitter (vitest) (${duration.toFixed(1)}s)`);
|
|
253
|
+
} else {
|
|
254
|
+
console.log(`${pc.red("[FAIL]")} emitter (vitest) (${duration.toFixed(1)}s)`);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
resolve({
|
|
258
|
+
env: "emitter (vitest)",
|
|
259
|
+
success,
|
|
260
|
+
duration,
|
|
261
|
+
error: success ? undefined : stderr || `Exit code: ${code}`,
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
proc.on("error", (err) => {
|
|
266
|
+
const duration = (Date.now() - startTime) / 1000;
|
|
267
|
+
console.log(`${pc.red("[ERROR]")} emitter (vitest): ${err.message}`);
|
|
268
|
+
resolve({
|
|
269
|
+
env: "emitter (vitest)",
|
|
270
|
+
success: false,
|
|
271
|
+
duration,
|
|
272
|
+
error: err.message,
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
async function main(): Promise<void> {
|
|
279
|
+
const startTime = Date.now();
|
|
280
|
+
|
|
281
|
+
const runEmitter = argv.values.emitter;
|
|
282
|
+
const runGenerator = argv.values.generator;
|
|
283
|
+
const runBoth = !runEmitter && !runGenerator;
|
|
284
|
+
|
|
285
|
+
const allResults: ToxResult[] = [];
|
|
286
|
+
|
|
287
|
+
// Header
|
|
288
|
+
console.log(pc.cyan("\n╔══════════════════════════════════════════════════════════╗"));
|
|
289
|
+
console.log(
|
|
290
|
+
pc.cyan("║") +
|
|
291
|
+
pc.bold(" TypeSpec Python SDK Generator Tests ") +
|
|
292
|
+
pc.cyan("║"),
|
|
293
|
+
);
|
|
294
|
+
console.log(pc.cyan("╚══════════════════════════════════════════════════════════╝") + "\n");
|
|
295
|
+
|
|
296
|
+
// Run emitter tests if requested
|
|
297
|
+
if (runEmitter || runBoth) {
|
|
298
|
+
console.log(`${pc.bold("=== Emitter Tests (TypeScript) ===")}\n`);
|
|
299
|
+
const emitterResult = await runEmitterTests();
|
|
300
|
+
allResults.push(emitterResult);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Run generator tests if requested
|
|
304
|
+
if (runGenerator || runBoth) {
|
|
305
|
+
console.log(`\n${pc.bold("=== Generator Tests (Python) ===")}\n`);
|
|
306
|
+
|
|
307
|
+
// Determine flavors
|
|
308
|
+
const flavors = argv.values.flavor === "all" ? ["azure", "unbranded"] : [argv.values.flavor!];
|
|
309
|
+
|
|
310
|
+
// Determine environments
|
|
311
|
+
let baseEnvs: string[];
|
|
312
|
+
if (argv.values.env) {
|
|
313
|
+
baseEnvs = argv.values.env.split(",").map((e) => e.trim());
|
|
314
|
+
} else {
|
|
315
|
+
// Default: run test environments
|
|
316
|
+
baseEnvs = ["test"];
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Expand 'ci' into its component environments for parallel execution
|
|
320
|
+
const expandedEnvs: string[] = [];
|
|
321
|
+
for (const env of baseEnvs) {
|
|
322
|
+
if (env === "ci") {
|
|
323
|
+
// Run test first (sequential), then lint/mypy/pyright/docs in parallel
|
|
324
|
+
expandedEnvs.push("test", "lint", "mypy", "pyright", "docs");
|
|
325
|
+
} else {
|
|
326
|
+
expandedEnvs.push(env);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Build full environment list
|
|
331
|
+
const envs: string[] = [];
|
|
332
|
+
for (const env of expandedEnvs) {
|
|
333
|
+
if (env === "unittest") {
|
|
334
|
+
envs.push("unittest");
|
|
335
|
+
} else {
|
|
336
|
+
for (const flavor of flavors) {
|
|
337
|
+
envs.push(`${env}-${flavor}`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Get Python path
|
|
343
|
+
let pythonPath: string;
|
|
344
|
+
try {
|
|
345
|
+
pythonPath = getVenvPython();
|
|
346
|
+
} catch (error) {
|
|
347
|
+
console.error(pc.red((error as Error).message));
|
|
348
|
+
process.exit(1);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// Separate test environments from other environments
|
|
352
|
+
// Test environments must run sequentially (they share port 3000)
|
|
353
|
+
// Other environments (lint, mypy, pyright, docs) can run in parallel
|
|
354
|
+
const testEnvs = envs.filter((e) => e.startsWith("test-") || e === "unittest");
|
|
355
|
+
const otherEnvs = envs.filter((e) => !e.startsWith("test-") && e !== "unittest");
|
|
356
|
+
|
|
357
|
+
const maxJobs = argv.values.jobs
|
|
358
|
+
? parseInt(argv.values.jobs, 10)
|
|
359
|
+
: Math.max(2, cpus().length - 2);
|
|
360
|
+
|
|
361
|
+
console.log(` Flavors: ${flavors.join(", ")}`);
|
|
362
|
+
console.log(` Environments: ${envs.join(", ")}`);
|
|
363
|
+
console.log(` Jobs: ${maxJobs} (test envs run sequentially, others in parallel)`);
|
|
364
|
+
if (argv.values.name) {
|
|
365
|
+
console.log(` Filter: ${argv.values.name}`);
|
|
366
|
+
}
|
|
367
|
+
console.log();
|
|
368
|
+
|
|
369
|
+
// Run test environments first (sequentially)
|
|
370
|
+
let results: ToxResult[] = [];
|
|
371
|
+
if (testEnvs.length > 0) {
|
|
372
|
+
console.log(pc.cyan("Running test environments (sequential)..."));
|
|
373
|
+
results = await runParallel(testEnvs, pythonPath, 1, argv.values.name);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Run other environments in parallel
|
|
377
|
+
if (otherEnvs.length > 0) {
|
|
378
|
+
console.log(pc.cyan("\nRunning lint/typecheck environments (parallel)..."));
|
|
379
|
+
const otherResults = await runParallel(otherEnvs, pythonPath, maxJobs, argv.values.name);
|
|
380
|
+
results = results.concat(otherResults);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
allResults.push(...results);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// Print summary
|
|
387
|
+
printSummary(allResults);
|
|
388
|
+
|
|
389
|
+
const totalDuration = (Date.now() - startTime) / 1000;
|
|
390
|
+
console.log(`Total execution time: ${totalDuration.toFixed(1)}s\n`);
|
|
391
|
+
|
|
392
|
+
// Exit with appropriate code
|
|
393
|
+
const failed = allResults.filter((r) => !r.success);
|
|
394
|
+
if (failed.length > 0) {
|
|
395
|
+
process.exit(1);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
main().catch((error) => {
|
|
400
|
+
console.error(`${pc.red("Unexpected error:")}`, error);
|
|
401
|
+
process.exit(1);
|
|
402
|
+
});
|
|
@@ -18,11 +18,12 @@ logging.getLogger().setLevel(logging.INFO)
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
def get_config_file_location():
|
|
21
|
-
|
|
21
|
+
# When running from tests/ directory via tox
|
|
22
|
+
mypy_ini_path = os.path.join(os.getcwd(), "../eng/scripts/ci/config/mypy.ini")
|
|
22
23
|
if os.path.exists(mypy_ini_path):
|
|
23
24
|
return mypy_ini_path
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
# Fallback for running from different directories
|
|
26
|
+
return os.path.join(os.path.dirname(__file__), "config/mypy.ini")
|
|
26
27
|
|
|
27
28
|
|
|
28
29
|
def _single_dir_mypy(mod):
|
|
@@ -18,11 +18,12 @@ logging.getLogger().setLevel(logging.INFO)
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
def get_rfc_file_location():
|
|
21
|
-
|
|
21
|
+
# When running from tests/ directory via tox
|
|
22
|
+
rfc_file_location = os.path.join(os.getcwd(), "../eng/scripts/ci/config/pylintrc")
|
|
22
23
|
if os.path.exists(rfc_file_location):
|
|
23
24
|
return rfc_file_location
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
# Fallback for running from different directories
|
|
26
|
+
return os.path.join(os.path.dirname(__file__), "config/pylintrc")
|
|
26
27
|
|
|
27
28
|
|
|
28
29
|
def _single_dir_pylint(mod):
|
|
@@ -19,11 +19,12 @@ logging.getLogger().setLevel(logging.INFO)
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
def get_pyright_config_file_location():
|
|
22
|
-
|
|
22
|
+
# When running from tests/ directory via tox
|
|
23
|
+
pyright_config = os.path.join(os.getcwd(), "../eng/scripts/ci/config/pyrightconfig.json")
|
|
23
24
|
if os.path.exists(pyright_config):
|
|
24
25
|
return pyright_config
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
# Fallback for running from different directories
|
|
27
|
+
return os.path.join(os.path.dirname(__file__), "config/pyrightconfig.json")
|
|
27
28
|
|
|
28
29
|
|
|
29
30
|
def _single_dir_pyright(mod):
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import { spawn } from "child_process";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import { dirname, join } from "path";
|
|
5
|
+
import pc from "picocolors";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
import { parseArgs } from "util";
|
|
8
|
+
|
|
9
|
+
const root = join(dirname(fileURLToPath(import.meta.url)), "../../../");
|
|
10
|
+
const testsDir = join(root, "tests");
|
|
11
|
+
|
|
12
|
+
// Get Python venv path
|
|
13
|
+
function getVenvPython(): string {
|
|
14
|
+
const venvPath = join(root, "venv");
|
|
15
|
+
if (fs.existsSync(join(venvPath, "bin"))) {
|
|
16
|
+
return join(venvPath, "bin", "python");
|
|
17
|
+
} else if (fs.existsSync(join(venvPath, "Scripts"))) {
|
|
18
|
+
return join(venvPath, "Scripts", "python.exe");
|
|
19
|
+
}
|
|
20
|
+
throw new Error("Virtual environment not found. Run 'npm run install' first.");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const argv = parseArgs({
|
|
24
|
+
args: process.argv.slice(2),
|
|
25
|
+
options: {
|
|
26
|
+
generated: { type: "boolean" },
|
|
27
|
+
flavor: { type: "string", short: "f" },
|
|
28
|
+
mypy: { type: "boolean" },
|
|
29
|
+
pyright: { type: "boolean" },
|
|
30
|
+
help: { type: "boolean", short: "h" },
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if (argv.values.help) {
|
|
35
|
+
console.log(`
|
|
36
|
+
${pc.bold("Usage:")} tsx typecheck.ts [options]
|
|
37
|
+
|
|
38
|
+
${pc.bold("Description:")}
|
|
39
|
+
Run type checking (mypy + pyright) on Python code.
|
|
40
|
+
|
|
41
|
+
${pc.bold("Options:")}
|
|
42
|
+
${pc.cyan("--generated")}
|
|
43
|
+
Run type checking on generated SDK packages (via tox).
|
|
44
|
+
Use with --flavor to specify azure or unbranded.
|
|
45
|
+
|
|
46
|
+
${pc.cyan("-f, --flavor <azure|unbranded>")}
|
|
47
|
+
SDK flavor to check (only applies to --generated).
|
|
48
|
+
If not specified, checks both flavors.
|
|
49
|
+
|
|
50
|
+
${pc.cyan("--mypy")}
|
|
51
|
+
Run only mypy (skip pyright).
|
|
52
|
+
|
|
53
|
+
${pc.cyan("--pyright")}
|
|
54
|
+
Run only pyright (skip mypy).
|
|
55
|
+
|
|
56
|
+
${pc.cyan("-h, --help")}
|
|
57
|
+
Show this help message.
|
|
58
|
+
|
|
59
|
+
${pc.bold("Examples:")}
|
|
60
|
+
${pc.dim("# Type check pygen source (default - runs both mypy and pyright)")}
|
|
61
|
+
tsx typecheck.ts
|
|
62
|
+
|
|
63
|
+
${pc.dim("# Run only mypy on pygen source")}
|
|
64
|
+
tsx typecheck.ts --mypy
|
|
65
|
+
|
|
66
|
+
${pc.dim("# Run only pyright on pygen source")}
|
|
67
|
+
tsx typecheck.ts --pyright
|
|
68
|
+
|
|
69
|
+
${pc.dim("# Type check generated SDK packages")}
|
|
70
|
+
tsx typecheck.ts --generated
|
|
71
|
+
|
|
72
|
+
${pc.dim("# Type check generated SDK packages for azure only")}
|
|
73
|
+
tsx typecheck.ts --generated --flavor=azure
|
|
74
|
+
`);
|
|
75
|
+
process.exit(0);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function runCommand(command: string, args: string[], cwd?: string): Promise<boolean> {
|
|
79
|
+
return new Promise((resolve) => {
|
|
80
|
+
console.log(`${pc.cyan("[RUN]")} ${command} ${args.join(" ")}`);
|
|
81
|
+
const proc = spawn(command, args, {
|
|
82
|
+
cwd: cwd || root,
|
|
83
|
+
stdio: "inherit",
|
|
84
|
+
shell: true,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
proc.on("close", (code) => {
|
|
88
|
+
if (code === 0) {
|
|
89
|
+
console.log(`${pc.green("[PASS]")} ${command} completed successfully`);
|
|
90
|
+
resolve(true);
|
|
91
|
+
} else {
|
|
92
|
+
console.log(`${pc.red("[FAIL]")} ${command} failed with code ${code}`);
|
|
93
|
+
resolve(false);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
proc.on("error", (err) => {
|
|
98
|
+
console.log(`${pc.red("[ERROR]")} ${command}: ${err.message}`);
|
|
99
|
+
resolve(false);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async function runMypyOnPygen(): Promise<boolean> {
|
|
105
|
+
console.log(`\n${pc.bold("=== Running mypy on pygen ===")}\n`);
|
|
106
|
+
|
|
107
|
+
let pythonPath: string;
|
|
108
|
+
try {
|
|
109
|
+
pythonPath = getVenvPython();
|
|
110
|
+
} catch (error) {
|
|
111
|
+
console.error(pc.red((error as Error).message));
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return runCommand(pythonPath, [
|
|
116
|
+
"-m",
|
|
117
|
+
"mypy",
|
|
118
|
+
"generator/pygen",
|
|
119
|
+
"--config-file=eng/scripts/ci/config/mypy.ini",
|
|
120
|
+
"--ignore-missing",
|
|
121
|
+
]);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function runPyrightOnPygen(): Promise<boolean> {
|
|
125
|
+
console.log(`\n${pc.bold("=== Running pyright on pygen ===")}\n`);
|
|
126
|
+
|
|
127
|
+
let pythonPath: string;
|
|
128
|
+
try {
|
|
129
|
+
pythonPath = getVenvPython();
|
|
130
|
+
} catch (error) {
|
|
131
|
+
console.error(pc.red((error as Error).message));
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return runCommand(pythonPath, [
|
|
136
|
+
"-m",
|
|
137
|
+
"pyright",
|
|
138
|
+
"-p",
|
|
139
|
+
"eng/scripts/ci/config/pyrightconfig.json",
|
|
140
|
+
"generator/pygen",
|
|
141
|
+
]);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async function runTypecheckOnGenerated(
|
|
145
|
+
flavor?: string,
|
|
146
|
+
mypyOnly?: boolean,
|
|
147
|
+
pyrightOnly?: boolean,
|
|
148
|
+
): Promise<boolean> {
|
|
149
|
+
const flavors = flavor ? [flavor] : ["azure", "unbranded"];
|
|
150
|
+
console.log(
|
|
151
|
+
`\n${pc.bold(`=== Type Checking Generated SDK Packages (${flavors.join(", ")}) ===`)}\n`,
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
let pythonPath: string;
|
|
155
|
+
try {
|
|
156
|
+
pythonPath = getVenvPython();
|
|
157
|
+
} catch (error) {
|
|
158
|
+
console.error(pc.red((error as Error).message));
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
let success = true;
|
|
163
|
+
|
|
164
|
+
for (const f of flavors) {
|
|
165
|
+
if (!pyrightOnly) {
|
|
166
|
+
const mypyEnv = `mypy-${f}`;
|
|
167
|
+
const result = await runCommand(
|
|
168
|
+
pythonPath,
|
|
169
|
+
["-m", "tox", "-c", "tox.ini", "-e", mypyEnv],
|
|
170
|
+
testsDir,
|
|
171
|
+
);
|
|
172
|
+
if (!result) success = false;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (!mypyOnly) {
|
|
176
|
+
const pyrightEnv = `pyright-${f}`;
|
|
177
|
+
const result = await runCommand(
|
|
178
|
+
pythonPath,
|
|
179
|
+
["-m", "tox", "-c", "tox.ini", "-e", pyrightEnv],
|
|
180
|
+
testsDir,
|
|
181
|
+
);
|
|
182
|
+
if (!result) success = false;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return success;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async function main(): Promise<void> {
|
|
190
|
+
const runGenerated = argv.values.generated;
|
|
191
|
+
const mypyOnly = argv.values.mypy && !argv.values.pyright;
|
|
192
|
+
const pyrightOnly = argv.values.pyright && !argv.values.mypy;
|
|
193
|
+
|
|
194
|
+
// If --generated is specified, type check generated packages
|
|
195
|
+
if (runGenerated) {
|
|
196
|
+
const result = await runTypecheckOnGenerated(argv.values.flavor, mypyOnly, pyrightOnly);
|
|
197
|
+
if (!result) process.exit(1);
|
|
198
|
+
console.log(`\n${pc.green(pc.bold("Generated SDK type checking complete!"))}\n`);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Default: type check pygen source
|
|
203
|
+
let success = true;
|
|
204
|
+
|
|
205
|
+
if (!pyrightOnly) {
|
|
206
|
+
const mypyResult = await runMypyOnPygen();
|
|
207
|
+
if (!mypyResult) success = false;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (!mypyOnly) {
|
|
211
|
+
const pyrightResult = await runPyrightOnPygen();
|
|
212
|
+
if (!pyrightResult) success = false;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (!success) {
|
|
216
|
+
process.exit(1);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
console.log(`\n${pc.green(pc.bold("All type checks passed!"))}\n`);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
main().catch((error) => {
|
|
223
|
+
console.error(`${pc.red("Unexpected error:")}`, error);
|
|
224
|
+
process.exit(1);
|
|
225
|
+
});
|
package/eng/scripts/ci/util.py
CHANGED
|
@@ -12,7 +12,7 @@ from multiprocessing import Pool
|
|
|
12
12
|
|
|
13
13
|
logging.getLogger().setLevel(logging.INFO)
|
|
14
14
|
|
|
15
|
-
ROOT_FOLDER = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..", "..", "
|
|
15
|
+
ROOT_FOLDER = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..", "..", "generator"))
|
|
16
16
|
|
|
17
17
|
IGNORE_FOLDER = []
|
|
18
18
|
|