From 04e22d71f4fec9e72d14335e6b40ff4bf0071339 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Thu, 23 Jul 2026 13:58:25 -0400 Subject: [PATCH 1/2] python: replace third-party lazy imports with the standard library --- .../resources/python/__init__api.mustache | 31 +- .../resources/python/__init__model.mustache | 31 +- .../resources/python/__init__package.mustache | 40 +- .../main/resources/python/pyproject.mustache | 6 - .../resources/python/requirements.mustache | 3 - .../src/main/resources/python/setup.mustache | 3 - .../petstore_api/__init__.py | 292 +++++++------- .../petstore_api/api/__init__.py | 51 ++- .../petstore_api/models/__init__.py | 369 ++++++++++++------ .../python-lazyImports/pyproject.toml | 1 - .../python-lazyImports/requirements.txt | 1 - .../petstore/python-lazyImports/setup.py | 1 - .../tests/test_lazy_imports.py | 60 +++ 13 files changed, 553 insertions(+), 336 deletions(-) create mode 100644 samples/openapi3/client/petstore/python-lazyImports/tests/test_lazy_imports.py diff --git a/modules/openapi-generator/src/main/resources/python/__init__api.mustache b/modules/openapi-generator/src/main/resources/python/__init__api.mustache index dff26fb1fce3..7f0e3a5dae0c 100644 --- a/modules/openapi-generator/src/main/resources/python/__init__api.mustache +++ b/modules/openapi-generator/src/main/resources/python/__init__api.mustache @@ -3,17 +3,28 @@ {{^lazyImports}} {{>exports_api}} {{/lazyImports}} -{{#lazyImports}}if __import__("typing").TYPE_CHECKING: +{{#lazyImports}}__all__ = [ +{{#apiInfo}}{{#apis}} "{{classname}}", +{{/apis}}{{/apiInfo}}] + +if __import__("typing").TYPE_CHECKING: {{>exports_api}} else: - from lazy_imports import LazyModule, as_package, load + from importlib import import_module + + _exports = { +{{#apiInfo}}{{#apis}} "{{classname}}": ".{{classFilename}}", +{{/apis}}{{/apiInfo}} } + + def __getattr__(name: str) -> object: + try: + module_name = _exports[name] + except KeyError: + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") from None + value = getattr(import_module(module_name, __name__), name) + globals()[name] = value + return value - load( - LazyModule( - *as_package(__file__), - """{{>exports_api}}""", - name=__name__, - doc=__doc__, - ) - ) + def __dir__() -> list[str]: + return sorted(globals().keys() | _exports.keys()) {{/lazyImports}} diff --git a/modules/openapi-generator/src/main/resources/python/__init__model.mustache b/modules/openapi-generator/src/main/resources/python/__init__model.mustache index 117f69132c40..cb405426bf51 100644 --- a/modules/openapi-generator/src/main/resources/python/__init__model.mustache +++ b/modules/openapi-generator/src/main/resources/python/__init__model.mustache @@ -6,17 +6,28 @@ {{^lazyImports}} {{>exports_model}} {{/lazyImports}} -{{#lazyImports}}if __import__("typing").TYPE_CHECKING: +{{#lazyImports}}__all__ = [ +{{#models}}{{#model}} "{{classname}}", +{{/model}}{{/models}}] + +if __import__("typing").TYPE_CHECKING: {{>exports_model}} else: - from lazy_imports import LazyModule, as_package, load + from importlib import import_module + + _exports = { +{{#models}}{{#model}} "{{classname}}": ".{{classFilename}}", +{{/model}}{{/models}} } + + def __getattr__(name: str) -> object: + try: + module_name = _exports[name] + except KeyError: + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") from None + value = getattr(import_module(module_name, __name__), name) + globals()[name] = value + return value - load( - LazyModule( - *as_package(__file__), - """{{>exports_model}}""", - name=__name__, - doc=__doc__, - ) - ) + def __dir__() -> list[str]: + return sorted(globals().keys() | _exports.keys()) {{/lazyImports}} diff --git a/modules/openapi-generator/src/main/resources/python/__init__package.mustache b/modules/openapi-generator/src/main/resources/python/__init__package.mustache index 73f0adf0d473..febad8e59e62 100644 --- a/modules/openapi-generator/src/main/resources/python/__init__package.mustache +++ b/modules/openapi-generator/src/main/resources/python/__init__package.mustache @@ -30,18 +30,34 @@ __all__ = [ {{#lazyImports}}if __import__("typing").TYPE_CHECKING: {{>exports_package}} else: - from lazy_imports import LazyModule, as_package, load - - load( - LazyModule( - *as_package(__file__), - ("__version__", __version__), - ("__all__", __all__), - """{{>exports_package}}""", - name=__name__, - doc=__doc__, - ) - ) + from importlib import import_module + + _exports = { +{{#apiInfo}}{{#apis}} "{{classname}}": ".api.{{classFilename}}", +{{/apis}}{{/apiInfo}} "ApiResponse": ".api_response", + "ApiClient": ".api_client", + "Configuration": ".configuration", + "OpenApiException": ".exceptions", + "ApiTypeError": ".exceptions", + "ApiValueError": ".exceptions", + "ApiKeyError": ".exceptions", + "ApiAttributeError": ".exceptions", + "ApiException": ".exceptions", +{{#hasHttpSignatureMethods}} "HttpSigningConfiguration": ".signing", +{{/hasHttpSignatureMethods}}{{#models}}{{#model}} "{{classname}}": ".models.{{classFilename}}", +{{/model}}{{/models}} } + + def __getattr__(name: str) -> object: + try: + module_name = _exports[name] + except KeyError: + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") from None + value = getattr(import_module(module_name, __name__), name) + globals()[name] = value + return value + + def __dir__() -> list[str]: + return sorted(globals().keys() | _exports.keys()) {{/lazyImports}} {{#recursionLimit}} diff --git a/modules/openapi-generator/src/main/resources/python/pyproject.mustache b/modules/openapi-generator/src/main/resources/python/pyproject.mustache index 560ccfbf89b1..3088e6df9843 100644 --- a/modules/openapi-generator/src/main/resources/python/pyproject.mustache +++ b/modules/openapi-generator/src/main/resources/python/pyproject.mustache @@ -53,9 +53,6 @@ pycryptodome = ">= 3.9.0" {{/hasHttpSignatureMethods}} pydantic = ">= 2.11" typing-extensions = ">= 4.7.1" -{{#lazyImports}} -lazy-imports = ">= 1, < 2" -{{/lazyImports}} {{/poetry1}} {{^poetry1}} requires-python = ">=3.10" @@ -81,9 +78,6 @@ dependencies = [ {{/hasHttpSignatureMethods}} "pydantic (>=2.11)", "typing-extensions (>=4.7.1)", -{{#lazyImports}} - "lazy-imports (>=1,<2)" -{{/lazyImports}} ] [project.urls] diff --git a/modules/openapi-generator/src/main/resources/python/requirements.mustache b/modules/openapi-generator/src/main/resources/python/requirements.mustache index 2746ec9325a6..78efc3b2e306 100644 --- a/modules/openapi-generator/src/main/resources/python/requirements.mustache +++ b/modules/openapi-generator/src/main/resources/python/requirements.mustache @@ -18,6 +18,3 @@ pycryptodome >= 3.9.0 {{/hasHttpSignatureMethods}} pydantic >= 2.11 typing-extensions >= 4.7.1 -{{#lazyImports}} -lazy-imports >= 1, < 2 -{{/lazyImports}} diff --git a/modules/openapi-generator/src/main/resources/python/setup.mustache b/modules/openapi-generator/src/main/resources/python/setup.mustache index 57e58ded1e66..70068a880b6c 100644 --- a/modules/openapi-generator/src/main/resources/python/setup.mustache +++ b/modules/openapi-generator/src/main/resources/python/setup.mustache @@ -32,9 +32,6 @@ REQUIRES = [ {{/hasHttpSignatureMethods}} "pydantic >= 2.11", "typing-extensions >= 4.7.1", -{{#lazyImports}} - "lazy-imports >= 1, < 2", -{{/lazyImports}} ] setup( diff --git a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/__init__.py b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/__init__.py index 64ad7b567d1a..7028a8a17b84 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/__init__.py +++ b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/__init__.py @@ -292,153 +292,151 @@ from petstore_api.models.with_nested_one_of import WithNestedOneOf as WithNestedOneOf else: - from lazy_imports import LazyModule, as_package, load + from importlib import import_module - load( - LazyModule( - *as_package(__file__), - ("__version__", __version__), - ("__all__", __all__), - """# import apis into sdk package -from petstore_api.api.another_fake_api import AnotherFakeApi as AnotherFakeApi -from petstore_api.api.default_api import DefaultApi as DefaultApi -from petstore_api.api.fake_api import FakeApi as FakeApi -from petstore_api.api.fake_classname_tags123_api import FakeClassnameTags123Api as FakeClassnameTags123Api -from petstore_api.api.import_test_datetime_api import ImportTestDatetimeApi as ImportTestDatetimeApi -from petstore_api.api.pet_api import PetApi as PetApi -from petstore_api.api.store_api import StoreApi as StoreApi -from petstore_api.api.user_api import UserApi as UserApi + _exports = { + "AnotherFakeApi": ".api.another_fake_api", + "DefaultApi": ".api.default_api", + "FakeApi": ".api.fake_api", + "FakeClassnameTags123Api": ".api.fake_classname_tags123_api", + "ImportTestDatetimeApi": ".api.import_test_datetime_api", + "PetApi": ".api.pet_api", + "StoreApi": ".api.store_api", + "UserApi": ".api.user_api", + "ApiResponse": ".api_response", + "ApiClient": ".api_client", + "Configuration": ".configuration", + "OpenApiException": ".exceptions", + "ApiTypeError": ".exceptions", + "ApiValueError": ".exceptions", + "ApiKeyError": ".exceptions", + "ApiAttributeError": ".exceptions", + "ApiException": ".exceptions", + "HttpSigningConfiguration": ".signing", + "AdditionalPropertiesAnyType": ".models.additional_properties_any_type", + "AdditionalPropertiesClass": ".models.additional_properties_class", + "AdditionalPropertiesObject": ".models.additional_properties_object", + "AdditionalPropertiesWithDescriptionOnly": ".models.additional_properties_with_description_only", + "AllOfSuperModel": ".models.all_of_super_model", + "AllOfWithSingleRef": ".models.all_of_with_single_ref", + "Animal": ".models.animal", + "AnyOfColor": ".models.any_of_color", + "AnyOfPig": ".models.any_of_pig", + "ArrayOfArrayOfModel": ".models.array_of_array_of_model", + "ArrayOfArrayOfNumberOnly": ".models.array_of_array_of_number_only", + "ArrayOfMapModel": ".models.array_of_map_model", + "ArrayOfNumberOnly": ".models.array_of_number_only", + "ArrayTest": ".models.array_test", + "BaseDiscriminator": ".models.base_discriminator", + "BasquePig": ".models.basque_pig", + "Bathing": ".models.bathing", + "Capitalization": ".models.capitalization", + "Cat": ".models.cat", + "Category": ".models.category", + "CircularAllOfRef": ".models.circular_all_of_ref", + "CircularReferenceModel": ".models.circular_reference_model", + "ClassModel": ".models.class_model", + "Client": ".models.client", + "Color": ".models.color", + "Creature": ".models.creature", + "CreatureInfo": ".models.creature_info", + "DanishPig": ".models.danish_pig", + "DataOutputFormat": ".models.data_output_format", + "DeprecatedObject": ".models.deprecated_object", + "DiscriminatorAllOfSub": ".models.discriminator_all_of_sub", + "DiscriminatorAllOfSuper": ".models.discriminator_all_of_super", + "Dog": ".models.dog", + "DummyModel": ".models.dummy_model", + "EnumArrays": ".models.enum_arrays", + "EnumClass": ".models.enum_class", + "EnumNumberVendorExt": ".models.enum_number_vendor_ext", + "EnumRefWithDefaultValue": ".models.enum_ref_with_default_value", + "EnumString1": ".models.enum_string1", + "EnumString2": ".models.enum_string2", + "EnumStringVendorExt": ".models.enum_string_vendor_ext", + "EnumTest": ".models.enum_test", + "Feeding": ".models.feeding", + "File": ".models.file", + "FileSchemaTestClass": ".models.file_schema_test_class", + "FirstRef": ".models.first_ref", + "Foo": ".models.foo", + "FooGetDefaultResponse": ".models.foo_get_default_response", + "FormatTest": ".models.format_test", + "HasOnlyReadOnly": ".models.has_only_read_only", + "HealthCheckResult": ".models.health_check_result", + "HuntingDog": ".models.hunting_dog", + "Info": ".models.info", + "InnerDictWithProperty": ".models.inner_dict_with_property", + "InputAllOf": ".models.input_all_of", + "IntOrString": ".models.int_or_string", + "ListClass": ".models.list_class", + "MapOfArrayOfModel": ".models.map_of_array_of_model", + "MapTest": ".models.map_test", + "MixedPropertiesAndAdditionalPropertiesClass": ".models.mixed_properties_and_additional_properties_class", + "Model200Response": ".models.model200_response", + "ModelApiResponse": ".models.model_api_response", + "ModelField": ".models.model_field", + "ModelReturn": ".models.model_return", + "MultiArrays": ".models.multi_arrays", + "Name": ".models.name", + "NullableClass": ".models.nullable_class", + "NullableProperty": ".models.nullable_property", + "NumberOnly": ".models.number_only", + "ObjectToTestAdditionalProperties": ".models.object_to_test_additional_properties", + "ObjectWithDeprecatedFields": ".models.object_with_deprecated_fields", + "OneOfEnumString": ".models.one_of_enum_string", + "Order": ".models.order", + "OuterComposite": ".models.outer_composite", + "OuterEnum": ".models.outer_enum", + "OuterEnumDefaultValue": ".models.outer_enum_default_value", + "OuterEnumInteger": ".models.outer_enum_integer", + "OuterEnumIntegerDefaultValue": ".models.outer_enum_integer_default_value", + "OuterObjectWithEnumProperty": ".models.outer_object_with_enum_property", + "Parent": ".models.parent", + "ParentWithOptionalDict": ".models.parent_with_optional_dict", + "Pet": ".models.pet", + "Pig": ".models.pig", + "PonySizes": ".models.pony_sizes", + "PoopCleaning": ".models.poop_cleaning", + "PrimitiveString": ".models.primitive_string", + "PropertyMap": ".models.property_map", + "PropertyNameCollision": ".models.property_name_collision", + "ReadOnlyFirst": ".models.read_only_first", + "SecondCircularAllOfRef": ".models.second_circular_all_of_ref", + "SecondRef": ".models.second_ref", + "SelfReferenceModel": ".models.self_reference_model", + "SingleRefType": ".models.single_ref_type", + "SpecialCharacterEnum": ".models.special_character_enum", + "SpecialModelName": ".models.special_model_name", + "SpecialName": ".models.special_name", + "Tag": ".models.tag", + "Task": ".models.task", + "TaskActivity": ".models.task_activity", + "TestEnum": ".models.test_enum", + "TestEnumWithDefault": ".models.test_enum_with_default", + "TestErrorResponsesWithModel400Response": ".models.test_error_responses_with_model400_response", + "TestErrorResponsesWithModel404Response": ".models.test_error_responses_with_model404_response", + "TestInlineFreeformAdditionalPropertiesRequest": ".models.test_inline_freeform_additional_properties_request", + "TestModelWithEnumDefault": ".models.test_model_with_enum_default", + "TestObjectForMultipartRequestsRequestMarker": ".models.test_object_for_multipart_requests_request_marker", + "Tiger": ".models.tiger", + "Type": ".models.type", + "UnnamedDictWithAdditionalModelListProperties": ".models.unnamed_dict_with_additional_model_list_properties", + "UnnamedDictWithAdditionalStringListProperties": ".models.unnamed_dict_with_additional_string_list_properties", + "UploadFileWithAdditionalPropertiesRequestObject": ".models.upload_file_with_additional_properties_request_object", + "User": ".models.user", + "UuidWithPattern": ".models.uuid_with_pattern", + "WithNestedOneOf": ".models.with_nested_one_of", + } -# import ApiClient -from petstore_api.api_response import ApiResponse as ApiResponse -from petstore_api.api_client import ApiClient as ApiClient -from petstore_api.configuration import Configuration as Configuration -from petstore_api.exceptions import OpenApiException as OpenApiException -from petstore_api.exceptions import ApiTypeError as ApiTypeError -from petstore_api.exceptions import ApiValueError as ApiValueError -from petstore_api.exceptions import ApiKeyError as ApiKeyError -from petstore_api.exceptions import ApiAttributeError as ApiAttributeError -from petstore_api.exceptions import ApiException as ApiException -from petstore_api.signing import HttpSigningConfiguration as HttpSigningConfiguration + def __getattr__(name: str) -> object: + try: + module_name = _exports[name] + except KeyError: + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") from None + value = getattr(import_module(module_name, __name__), name) + globals()[name] = value + return value -# import models into sdk package -from petstore_api.models.additional_properties_any_type import AdditionalPropertiesAnyType as AdditionalPropertiesAnyType -from petstore_api.models.additional_properties_class import AdditionalPropertiesClass as AdditionalPropertiesClass -from petstore_api.models.additional_properties_object import AdditionalPropertiesObject as AdditionalPropertiesObject -from petstore_api.models.additional_properties_with_description_only import AdditionalPropertiesWithDescriptionOnly as AdditionalPropertiesWithDescriptionOnly -from petstore_api.models.all_of_super_model import AllOfSuperModel as AllOfSuperModel -from petstore_api.models.all_of_with_single_ref import AllOfWithSingleRef as AllOfWithSingleRef -from petstore_api.models.animal import Animal as Animal -from petstore_api.models.any_of_color import AnyOfColor as AnyOfColor -from petstore_api.models.any_of_pig import AnyOfPig as AnyOfPig -from petstore_api.models.array_of_array_of_model import ArrayOfArrayOfModel as ArrayOfArrayOfModel -from petstore_api.models.array_of_array_of_number_only import ArrayOfArrayOfNumberOnly as ArrayOfArrayOfNumberOnly -from petstore_api.models.array_of_map_model import ArrayOfMapModel as ArrayOfMapModel -from petstore_api.models.array_of_number_only import ArrayOfNumberOnly as ArrayOfNumberOnly -from petstore_api.models.array_test import ArrayTest as ArrayTest -from petstore_api.models.base_discriminator import BaseDiscriminator as BaseDiscriminator -from petstore_api.models.basque_pig import BasquePig as BasquePig -from petstore_api.models.bathing import Bathing as Bathing -from petstore_api.models.capitalization import Capitalization as Capitalization -from petstore_api.models.cat import Cat as Cat -from petstore_api.models.category import Category as Category -from petstore_api.models.circular_all_of_ref import CircularAllOfRef as CircularAllOfRef -from petstore_api.models.circular_reference_model import CircularReferenceModel as CircularReferenceModel -from petstore_api.models.class_model import ClassModel as ClassModel -from petstore_api.models.client import Client as Client -from petstore_api.models.color import Color as Color -from petstore_api.models.creature import Creature as Creature -from petstore_api.models.creature_info import CreatureInfo as CreatureInfo -from petstore_api.models.danish_pig import DanishPig as DanishPig -from petstore_api.models.data_output_format import DataOutputFormat as DataOutputFormat -from petstore_api.models.deprecated_object import DeprecatedObject as DeprecatedObject -from petstore_api.models.discriminator_all_of_sub import DiscriminatorAllOfSub as DiscriminatorAllOfSub -from petstore_api.models.discriminator_all_of_super import DiscriminatorAllOfSuper as DiscriminatorAllOfSuper -from petstore_api.models.dog import Dog as Dog -from petstore_api.models.dummy_model import DummyModel as DummyModel -from petstore_api.models.enum_arrays import EnumArrays as EnumArrays -from petstore_api.models.enum_class import EnumClass as EnumClass -from petstore_api.models.enum_number_vendor_ext import EnumNumberVendorExt as EnumNumberVendorExt -from petstore_api.models.enum_ref_with_default_value import EnumRefWithDefaultValue as EnumRefWithDefaultValue -from petstore_api.models.enum_string1 import EnumString1 as EnumString1 -from petstore_api.models.enum_string2 import EnumString2 as EnumString2 -from petstore_api.models.enum_string_vendor_ext import EnumStringVendorExt as EnumStringVendorExt -from petstore_api.models.enum_test import EnumTest as EnumTest -from petstore_api.models.feeding import Feeding as Feeding -from petstore_api.models.file import File as File -from petstore_api.models.file_schema_test_class import FileSchemaTestClass as FileSchemaTestClass -from petstore_api.models.first_ref import FirstRef as FirstRef -from petstore_api.models.foo import Foo as Foo -from petstore_api.models.foo_get_default_response import FooGetDefaultResponse as FooGetDefaultResponse -from petstore_api.models.format_test import FormatTest as FormatTest -from petstore_api.models.has_only_read_only import HasOnlyReadOnly as HasOnlyReadOnly -from petstore_api.models.health_check_result import HealthCheckResult as HealthCheckResult -from petstore_api.models.hunting_dog import HuntingDog as HuntingDog -from petstore_api.models.info import Info as Info -from petstore_api.models.inner_dict_with_property import InnerDictWithProperty as InnerDictWithProperty -from petstore_api.models.input_all_of import InputAllOf as InputAllOf -from petstore_api.models.int_or_string import IntOrString as IntOrString -from petstore_api.models.list_class import ListClass as ListClass -from petstore_api.models.map_of_array_of_model import MapOfArrayOfModel as MapOfArrayOfModel -from petstore_api.models.map_test import MapTest as MapTest -from petstore_api.models.mixed_properties_and_additional_properties_class import MixedPropertiesAndAdditionalPropertiesClass as MixedPropertiesAndAdditionalPropertiesClass -from petstore_api.models.model200_response import Model200Response as Model200Response -from petstore_api.models.model_api_response import ModelApiResponse as ModelApiResponse -from petstore_api.models.model_field import ModelField as ModelField -from petstore_api.models.model_return import ModelReturn as ModelReturn -from petstore_api.models.multi_arrays import MultiArrays as MultiArrays -from petstore_api.models.name import Name as Name -from petstore_api.models.nullable_class import NullableClass as NullableClass -from petstore_api.models.nullable_property import NullableProperty as NullableProperty -from petstore_api.models.number_only import NumberOnly as NumberOnly -from petstore_api.models.object_to_test_additional_properties import ObjectToTestAdditionalProperties as ObjectToTestAdditionalProperties -from petstore_api.models.object_with_deprecated_fields import ObjectWithDeprecatedFields as ObjectWithDeprecatedFields -from petstore_api.models.one_of_enum_string import OneOfEnumString as OneOfEnumString -from petstore_api.models.order import Order as Order -from petstore_api.models.outer_composite import OuterComposite as OuterComposite -from petstore_api.models.outer_enum import OuterEnum as OuterEnum -from petstore_api.models.outer_enum_default_value import OuterEnumDefaultValue as OuterEnumDefaultValue -from petstore_api.models.outer_enum_integer import OuterEnumInteger as OuterEnumInteger -from petstore_api.models.outer_enum_integer_default_value import OuterEnumIntegerDefaultValue as OuterEnumIntegerDefaultValue -from petstore_api.models.outer_object_with_enum_property import OuterObjectWithEnumProperty as OuterObjectWithEnumProperty -from petstore_api.models.parent import Parent as Parent -from petstore_api.models.parent_with_optional_dict import ParentWithOptionalDict as ParentWithOptionalDict -from petstore_api.models.pet import Pet as Pet -from petstore_api.models.pig import Pig as Pig -from petstore_api.models.pony_sizes import PonySizes as PonySizes -from petstore_api.models.poop_cleaning import PoopCleaning as PoopCleaning -from petstore_api.models.primitive_string import PrimitiveString as PrimitiveString -from petstore_api.models.property_map import PropertyMap as PropertyMap -from petstore_api.models.property_name_collision import PropertyNameCollision as PropertyNameCollision -from petstore_api.models.read_only_first import ReadOnlyFirst as ReadOnlyFirst -from petstore_api.models.second_circular_all_of_ref import SecondCircularAllOfRef as SecondCircularAllOfRef -from petstore_api.models.second_ref import SecondRef as SecondRef -from petstore_api.models.self_reference_model import SelfReferenceModel as SelfReferenceModel -from petstore_api.models.single_ref_type import SingleRefType as SingleRefType -from petstore_api.models.special_character_enum import SpecialCharacterEnum as SpecialCharacterEnum -from petstore_api.models.special_model_name import SpecialModelName as SpecialModelName -from petstore_api.models.special_name import SpecialName as SpecialName -from petstore_api.models.tag import Tag as Tag -from petstore_api.models.task import Task as Task -from petstore_api.models.task_activity import TaskActivity as TaskActivity -from petstore_api.models.test_enum import TestEnum as TestEnum -from petstore_api.models.test_enum_with_default import TestEnumWithDefault as TestEnumWithDefault -from petstore_api.models.test_error_responses_with_model400_response import TestErrorResponsesWithModel400Response as TestErrorResponsesWithModel400Response -from petstore_api.models.test_error_responses_with_model404_response import TestErrorResponsesWithModel404Response as TestErrorResponsesWithModel404Response -from petstore_api.models.test_inline_freeform_additional_properties_request import TestInlineFreeformAdditionalPropertiesRequest as TestInlineFreeformAdditionalPropertiesRequest -from petstore_api.models.test_model_with_enum_default import TestModelWithEnumDefault as TestModelWithEnumDefault -from petstore_api.models.test_object_for_multipart_requests_request_marker import TestObjectForMultipartRequestsRequestMarker as TestObjectForMultipartRequestsRequestMarker -from petstore_api.models.tiger import Tiger as Tiger -from petstore_api.models.type import Type as Type -from petstore_api.models.unnamed_dict_with_additional_model_list_properties import UnnamedDictWithAdditionalModelListProperties as UnnamedDictWithAdditionalModelListProperties -from petstore_api.models.unnamed_dict_with_additional_string_list_properties import UnnamedDictWithAdditionalStringListProperties as UnnamedDictWithAdditionalStringListProperties -from petstore_api.models.upload_file_with_additional_properties_request_object import UploadFileWithAdditionalPropertiesRequestObject as UploadFileWithAdditionalPropertiesRequestObject -from petstore_api.models.user import User as User -from petstore_api.models.uuid_with_pattern import UuidWithPattern as UuidWithPattern -from petstore_api.models.with_nested_one_of import WithNestedOneOf as WithNestedOneOf - -""", - name=__name__, - doc=__doc__, - ) - ) + def __dir__() -> list[str]: + return sorted(globals().keys() | _exports.keys()) diff --git a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/__init__.py b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/__init__.py index e77aed00eb57..22074e1a95bb 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/__init__.py +++ b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/__init__.py @@ -1,5 +1,16 @@ # flake8: noqa +__all__ = [ + "AnotherFakeApi", + "DefaultApi", + "FakeApi", + "FakeClassnameTags123Api", + "ImportTestDatetimeApi", + "PetApi", + "StoreApi", + "UserApi", +] + if __import__("typing").TYPE_CHECKING: # import apis into api package from petstore_api.api.another_fake_api import AnotherFakeApi @@ -12,23 +23,27 @@ from petstore_api.api.user_api import UserApi else: - from lazy_imports import LazyModule, as_package, load + from importlib import import_module + + _exports = { + "AnotherFakeApi": ".another_fake_api", + "DefaultApi": ".default_api", + "FakeApi": ".fake_api", + "FakeClassnameTags123Api": ".fake_classname_tags123_api", + "ImportTestDatetimeApi": ".import_test_datetime_api", + "PetApi": ".pet_api", + "StoreApi": ".store_api", + "UserApi": ".user_api", + } - load( - LazyModule( - *as_package(__file__), - """# import apis into api package -from petstore_api.api.another_fake_api import AnotherFakeApi -from petstore_api.api.default_api import DefaultApi -from petstore_api.api.fake_api import FakeApi -from petstore_api.api.fake_classname_tags123_api import FakeClassnameTags123Api -from petstore_api.api.import_test_datetime_api import ImportTestDatetimeApi -from petstore_api.api.pet_api import PetApi -from petstore_api.api.store_api import StoreApi -from petstore_api.api.user_api import UserApi + def __getattr__(name: str) -> object: + try: + module_name = _exports[name] + except KeyError: + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") from None + value = getattr(import_module(module_name, __name__), name) + globals()[name] = value + return value -""", - name=__name__, - doc=__doc__, - ) - ) + def __dir__() -> list[str]: + return sorted(globals().keys() | _exports.keys()) diff --git a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/models/__init__.py b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/models/__init__.py index 9f052c816cb7..c40b976996bc 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/models/__init__.py +++ b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/models/__init__.py @@ -12,6 +12,123 @@ Do not edit the class manually. """ # noqa: E501 +__all__ = [ + "AdditionalPropertiesAnyType", + "AdditionalPropertiesClass", + "AdditionalPropertiesObject", + "AdditionalPropertiesWithDescriptionOnly", + "AllOfSuperModel", + "AllOfWithSingleRef", + "Animal", + "AnyOfColor", + "AnyOfPig", + "ArrayOfArrayOfModel", + "ArrayOfArrayOfNumberOnly", + "ArrayOfMapModel", + "ArrayOfNumberOnly", + "ArrayTest", + "BaseDiscriminator", + "BasquePig", + "Bathing", + "Capitalization", + "Cat", + "Category", + "CircularAllOfRef", + "CircularReferenceModel", + "ClassModel", + "Client", + "Color", + "Creature", + "CreatureInfo", + "DanishPig", + "DataOutputFormat", + "DeprecatedObject", + "DiscriminatorAllOfSub", + "DiscriminatorAllOfSuper", + "Dog", + "DummyModel", + "EnumArrays", + "EnumClass", + "EnumNumberVendorExt", + "EnumRefWithDefaultValue", + "EnumString1", + "EnumString2", + "EnumStringVendorExt", + "EnumTest", + "Feeding", + "File", + "FileSchemaTestClass", + "FirstRef", + "Foo", + "FooGetDefaultResponse", + "FormatTest", + "HasOnlyReadOnly", + "HealthCheckResult", + "HuntingDog", + "Info", + "InnerDictWithProperty", + "InputAllOf", + "IntOrString", + "ListClass", + "MapOfArrayOfModel", + "MapTest", + "MixedPropertiesAndAdditionalPropertiesClass", + "Model200Response", + "ModelApiResponse", + "ModelField", + "ModelReturn", + "MultiArrays", + "Name", + "NullableClass", + "NullableProperty", + "NumberOnly", + "ObjectToTestAdditionalProperties", + "ObjectWithDeprecatedFields", + "OneOfEnumString", + "Order", + "OuterComposite", + "OuterEnum", + "OuterEnumDefaultValue", + "OuterEnumInteger", + "OuterEnumIntegerDefaultValue", + "OuterObjectWithEnumProperty", + "Parent", + "ParentWithOptionalDict", + "Pet", + "Pig", + "PonySizes", + "PoopCleaning", + "PrimitiveString", + "PropertyMap", + "PropertyNameCollision", + "ReadOnlyFirst", + "SecondCircularAllOfRef", + "SecondRef", + "SelfReferenceModel", + "SingleRefType", + "SpecialCharacterEnum", + "SpecialModelName", + "SpecialName", + "Tag", + "Task", + "TaskActivity", + "TestEnum", + "TestEnumWithDefault", + "TestErrorResponsesWithModel400Response", + "TestErrorResponsesWithModel404Response", + "TestInlineFreeformAdditionalPropertiesRequest", + "TestModelWithEnumDefault", + "TestObjectForMultipartRequestsRequestMarker", + "Tiger", + "Type", + "UnnamedDictWithAdditionalModelListProperties", + "UnnamedDictWithAdditionalStringListProperties", + "UploadFileWithAdditionalPropertiesRequestObject", + "User", + "UuidWithPattern", + "WithNestedOneOf", +] + if __import__("typing").TYPE_CHECKING: # import models into model package from petstore_api.models.additional_properties_any_type import AdditionalPropertiesAnyType @@ -130,129 +247,133 @@ from petstore_api.models.with_nested_one_of import WithNestedOneOf else: - from lazy_imports import LazyModule, as_package, load + from importlib import import_module + + _exports = { + "AdditionalPropertiesAnyType": ".additional_properties_any_type", + "AdditionalPropertiesClass": ".additional_properties_class", + "AdditionalPropertiesObject": ".additional_properties_object", + "AdditionalPropertiesWithDescriptionOnly": ".additional_properties_with_description_only", + "AllOfSuperModel": ".all_of_super_model", + "AllOfWithSingleRef": ".all_of_with_single_ref", + "Animal": ".animal", + "AnyOfColor": ".any_of_color", + "AnyOfPig": ".any_of_pig", + "ArrayOfArrayOfModel": ".array_of_array_of_model", + "ArrayOfArrayOfNumberOnly": ".array_of_array_of_number_only", + "ArrayOfMapModel": ".array_of_map_model", + "ArrayOfNumberOnly": ".array_of_number_only", + "ArrayTest": ".array_test", + "BaseDiscriminator": ".base_discriminator", + "BasquePig": ".basque_pig", + "Bathing": ".bathing", + "Capitalization": ".capitalization", + "Cat": ".cat", + "Category": ".category", + "CircularAllOfRef": ".circular_all_of_ref", + "CircularReferenceModel": ".circular_reference_model", + "ClassModel": ".class_model", + "Client": ".client", + "Color": ".color", + "Creature": ".creature", + "CreatureInfo": ".creature_info", + "DanishPig": ".danish_pig", + "DataOutputFormat": ".data_output_format", + "DeprecatedObject": ".deprecated_object", + "DiscriminatorAllOfSub": ".discriminator_all_of_sub", + "DiscriminatorAllOfSuper": ".discriminator_all_of_super", + "Dog": ".dog", + "DummyModel": ".dummy_model", + "EnumArrays": ".enum_arrays", + "EnumClass": ".enum_class", + "EnumNumberVendorExt": ".enum_number_vendor_ext", + "EnumRefWithDefaultValue": ".enum_ref_with_default_value", + "EnumString1": ".enum_string1", + "EnumString2": ".enum_string2", + "EnumStringVendorExt": ".enum_string_vendor_ext", + "EnumTest": ".enum_test", + "Feeding": ".feeding", + "File": ".file", + "FileSchemaTestClass": ".file_schema_test_class", + "FirstRef": ".first_ref", + "Foo": ".foo", + "FooGetDefaultResponse": ".foo_get_default_response", + "FormatTest": ".format_test", + "HasOnlyReadOnly": ".has_only_read_only", + "HealthCheckResult": ".health_check_result", + "HuntingDog": ".hunting_dog", + "Info": ".info", + "InnerDictWithProperty": ".inner_dict_with_property", + "InputAllOf": ".input_all_of", + "IntOrString": ".int_or_string", + "ListClass": ".list_class", + "MapOfArrayOfModel": ".map_of_array_of_model", + "MapTest": ".map_test", + "MixedPropertiesAndAdditionalPropertiesClass": ".mixed_properties_and_additional_properties_class", + "Model200Response": ".model200_response", + "ModelApiResponse": ".model_api_response", + "ModelField": ".model_field", + "ModelReturn": ".model_return", + "MultiArrays": ".multi_arrays", + "Name": ".name", + "NullableClass": ".nullable_class", + "NullableProperty": ".nullable_property", + "NumberOnly": ".number_only", + "ObjectToTestAdditionalProperties": ".object_to_test_additional_properties", + "ObjectWithDeprecatedFields": ".object_with_deprecated_fields", + "OneOfEnumString": ".one_of_enum_string", + "Order": ".order", + "OuterComposite": ".outer_composite", + "OuterEnum": ".outer_enum", + "OuterEnumDefaultValue": ".outer_enum_default_value", + "OuterEnumInteger": ".outer_enum_integer", + "OuterEnumIntegerDefaultValue": ".outer_enum_integer_default_value", + "OuterObjectWithEnumProperty": ".outer_object_with_enum_property", + "Parent": ".parent", + "ParentWithOptionalDict": ".parent_with_optional_dict", + "Pet": ".pet", + "Pig": ".pig", + "PonySizes": ".pony_sizes", + "PoopCleaning": ".poop_cleaning", + "PrimitiveString": ".primitive_string", + "PropertyMap": ".property_map", + "PropertyNameCollision": ".property_name_collision", + "ReadOnlyFirst": ".read_only_first", + "SecondCircularAllOfRef": ".second_circular_all_of_ref", + "SecondRef": ".second_ref", + "SelfReferenceModel": ".self_reference_model", + "SingleRefType": ".single_ref_type", + "SpecialCharacterEnum": ".special_character_enum", + "SpecialModelName": ".special_model_name", + "SpecialName": ".special_name", + "Tag": ".tag", + "Task": ".task", + "TaskActivity": ".task_activity", + "TestEnum": ".test_enum", + "TestEnumWithDefault": ".test_enum_with_default", + "TestErrorResponsesWithModel400Response": ".test_error_responses_with_model400_response", + "TestErrorResponsesWithModel404Response": ".test_error_responses_with_model404_response", + "TestInlineFreeformAdditionalPropertiesRequest": ".test_inline_freeform_additional_properties_request", + "TestModelWithEnumDefault": ".test_model_with_enum_default", + "TestObjectForMultipartRequestsRequestMarker": ".test_object_for_multipart_requests_request_marker", + "Tiger": ".tiger", + "Type": ".type", + "UnnamedDictWithAdditionalModelListProperties": ".unnamed_dict_with_additional_model_list_properties", + "UnnamedDictWithAdditionalStringListProperties": ".unnamed_dict_with_additional_string_list_properties", + "UploadFileWithAdditionalPropertiesRequestObject": ".upload_file_with_additional_properties_request_object", + "User": ".user", + "UuidWithPattern": ".uuid_with_pattern", + "WithNestedOneOf": ".with_nested_one_of", + } - load( - LazyModule( - *as_package(__file__), - """# import models into model package -from petstore_api.models.additional_properties_any_type import AdditionalPropertiesAnyType -from petstore_api.models.additional_properties_class import AdditionalPropertiesClass -from petstore_api.models.additional_properties_object import AdditionalPropertiesObject -from petstore_api.models.additional_properties_with_description_only import AdditionalPropertiesWithDescriptionOnly -from petstore_api.models.all_of_super_model import AllOfSuperModel -from petstore_api.models.all_of_with_single_ref import AllOfWithSingleRef -from petstore_api.models.animal import Animal -from petstore_api.models.any_of_color import AnyOfColor -from petstore_api.models.any_of_pig import AnyOfPig -from petstore_api.models.array_of_array_of_model import ArrayOfArrayOfModel -from petstore_api.models.array_of_array_of_number_only import ArrayOfArrayOfNumberOnly -from petstore_api.models.array_of_map_model import ArrayOfMapModel -from petstore_api.models.array_of_number_only import ArrayOfNumberOnly -from petstore_api.models.array_test import ArrayTest -from petstore_api.models.base_discriminator import BaseDiscriminator -from petstore_api.models.basque_pig import BasquePig -from petstore_api.models.bathing import Bathing -from petstore_api.models.capitalization import Capitalization -from petstore_api.models.cat import Cat -from petstore_api.models.category import Category -from petstore_api.models.circular_all_of_ref import CircularAllOfRef -from petstore_api.models.circular_reference_model import CircularReferenceModel -from petstore_api.models.class_model import ClassModel -from petstore_api.models.client import Client -from petstore_api.models.color import Color -from petstore_api.models.creature import Creature -from petstore_api.models.creature_info import CreatureInfo -from petstore_api.models.danish_pig import DanishPig -from petstore_api.models.data_output_format import DataOutputFormat -from petstore_api.models.deprecated_object import DeprecatedObject -from petstore_api.models.discriminator_all_of_sub import DiscriminatorAllOfSub -from petstore_api.models.discriminator_all_of_super import DiscriminatorAllOfSuper -from petstore_api.models.dog import Dog -from petstore_api.models.dummy_model import DummyModel -from petstore_api.models.enum_arrays import EnumArrays -from petstore_api.models.enum_class import EnumClass -from petstore_api.models.enum_number_vendor_ext import EnumNumberVendorExt -from petstore_api.models.enum_ref_with_default_value import EnumRefWithDefaultValue -from petstore_api.models.enum_string1 import EnumString1 -from petstore_api.models.enum_string2 import EnumString2 -from petstore_api.models.enum_string_vendor_ext import EnumStringVendorExt -from petstore_api.models.enum_test import EnumTest -from petstore_api.models.feeding import Feeding -from petstore_api.models.file import File -from petstore_api.models.file_schema_test_class import FileSchemaTestClass -from petstore_api.models.first_ref import FirstRef -from petstore_api.models.foo import Foo -from petstore_api.models.foo_get_default_response import FooGetDefaultResponse -from petstore_api.models.format_test import FormatTest -from petstore_api.models.has_only_read_only import HasOnlyReadOnly -from petstore_api.models.health_check_result import HealthCheckResult -from petstore_api.models.hunting_dog import HuntingDog -from petstore_api.models.info import Info -from petstore_api.models.inner_dict_with_property import InnerDictWithProperty -from petstore_api.models.input_all_of import InputAllOf -from petstore_api.models.int_or_string import IntOrString -from petstore_api.models.list_class import ListClass -from petstore_api.models.map_of_array_of_model import MapOfArrayOfModel -from petstore_api.models.map_test import MapTest -from petstore_api.models.mixed_properties_and_additional_properties_class import MixedPropertiesAndAdditionalPropertiesClass -from petstore_api.models.model200_response import Model200Response -from petstore_api.models.model_api_response import ModelApiResponse -from petstore_api.models.model_field import ModelField -from petstore_api.models.model_return import ModelReturn -from petstore_api.models.multi_arrays import MultiArrays -from petstore_api.models.name import Name -from petstore_api.models.nullable_class import NullableClass -from petstore_api.models.nullable_property import NullableProperty -from petstore_api.models.number_only import NumberOnly -from petstore_api.models.object_to_test_additional_properties import ObjectToTestAdditionalProperties -from petstore_api.models.object_with_deprecated_fields import ObjectWithDeprecatedFields -from petstore_api.models.one_of_enum_string import OneOfEnumString -from petstore_api.models.order import Order -from petstore_api.models.outer_composite import OuterComposite -from petstore_api.models.outer_enum import OuterEnum -from petstore_api.models.outer_enum_default_value import OuterEnumDefaultValue -from petstore_api.models.outer_enum_integer import OuterEnumInteger -from petstore_api.models.outer_enum_integer_default_value import OuterEnumIntegerDefaultValue -from petstore_api.models.outer_object_with_enum_property import OuterObjectWithEnumProperty -from petstore_api.models.parent import Parent -from petstore_api.models.parent_with_optional_dict import ParentWithOptionalDict -from petstore_api.models.pet import Pet -from petstore_api.models.pig import Pig -from petstore_api.models.pony_sizes import PonySizes -from petstore_api.models.poop_cleaning import PoopCleaning -from petstore_api.models.primitive_string import PrimitiveString -from petstore_api.models.property_map import PropertyMap -from petstore_api.models.property_name_collision import PropertyNameCollision -from petstore_api.models.read_only_first import ReadOnlyFirst -from petstore_api.models.second_circular_all_of_ref import SecondCircularAllOfRef -from petstore_api.models.second_ref import SecondRef -from petstore_api.models.self_reference_model import SelfReferenceModel -from petstore_api.models.single_ref_type import SingleRefType -from petstore_api.models.special_character_enum import SpecialCharacterEnum -from petstore_api.models.special_model_name import SpecialModelName -from petstore_api.models.special_name import SpecialName -from petstore_api.models.tag import Tag -from petstore_api.models.task import Task -from petstore_api.models.task_activity import TaskActivity -from petstore_api.models.test_enum import TestEnum -from petstore_api.models.test_enum_with_default import TestEnumWithDefault -from petstore_api.models.test_error_responses_with_model400_response import TestErrorResponsesWithModel400Response -from petstore_api.models.test_error_responses_with_model404_response import TestErrorResponsesWithModel404Response -from petstore_api.models.test_inline_freeform_additional_properties_request import TestInlineFreeformAdditionalPropertiesRequest -from petstore_api.models.test_model_with_enum_default import TestModelWithEnumDefault -from petstore_api.models.test_object_for_multipart_requests_request_marker import TestObjectForMultipartRequestsRequestMarker -from petstore_api.models.tiger import Tiger -from petstore_api.models.type import Type -from petstore_api.models.unnamed_dict_with_additional_model_list_properties import UnnamedDictWithAdditionalModelListProperties -from petstore_api.models.unnamed_dict_with_additional_string_list_properties import UnnamedDictWithAdditionalStringListProperties -from petstore_api.models.upload_file_with_additional_properties_request_object import UploadFileWithAdditionalPropertiesRequestObject -from petstore_api.models.user import User -from petstore_api.models.uuid_with_pattern import UuidWithPattern -from petstore_api.models.with_nested_one_of import WithNestedOneOf + def __getattr__(name: str) -> object: + try: + module_name = _exports[name] + except KeyError: + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") from None + value = getattr(import_module(module_name, __name__), name) + globals()[name] = value + return value -""", - name=__name__, - doc=__doc__, - ) - ) + def __dir__() -> list[str]: + return sorted(globals().keys() | _exports.keys()) diff --git a/samples/openapi3/client/petstore/python-lazyImports/pyproject.toml b/samples/openapi3/client/petstore/python-lazyImports/pyproject.toml index c581cbd91241..fd828c3cfe54 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/pyproject.toml +++ b/samples/openapi3/client/petstore/python-lazyImports/pyproject.toml @@ -17,7 +17,6 @@ dependencies = [ "pycryptodome (>=3.9.0)", "pydantic (>=2.11)", "typing-extensions (>=4.7.1)", - "lazy-imports (>=1,<2)" ] [project.urls] diff --git a/samples/openapi3/client/petstore/python-lazyImports/requirements.txt b/samples/openapi3/client/petstore/python-lazyImports/requirements.txt index 7c1400939f47..05db0e110efc 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/requirements.txt +++ b/samples/openapi3/client/petstore/python-lazyImports/requirements.txt @@ -4,4 +4,3 @@ pem >= 19.3.0 pycryptodome >= 3.9.0 pydantic >= 2.11 typing-extensions >= 4.7.1 -lazy-imports >= 1, < 2 diff --git a/samples/openapi3/client/petstore/python-lazyImports/setup.py b/samples/openapi3/client/petstore/python-lazyImports/setup.py index 9e33575a0954..f07225fced95 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/setup.py +++ b/samples/openapi3/client/petstore/python-lazyImports/setup.py @@ -28,7 +28,6 @@ "pycryptodome >= 3.9.0", "pydantic >= 2.11", "typing-extensions >= 4.7.1", - "lazy-imports >= 1, < 2", ] setup( diff --git a/samples/openapi3/client/petstore/python-lazyImports/tests/test_lazy_imports.py b/samples/openapi3/client/petstore/python-lazyImports/tests/test_lazy_imports.py new file mode 100644 index 000000000000..892ca0504b4b --- /dev/null +++ b/samples/openapi3/client/petstore/python-lazyImports/tests/test_lazy_imports.py @@ -0,0 +1,60 @@ +import subprocess +import sys +from pathlib import Path +from textwrap import dedent + + +def test_lazy_imports_use_standard_library() -> None: + subprocess.run( + [ + sys.executable, + "-c", + dedent( + """\ + import importlib.util + import sys + from types import ModuleType + + import petstore_api + + assert type(petstore_api) is ModuleType + assert petstore_api.__spec__ is not None + assert "lazy_imports" not in sys.modules + assert not any(name.startswith("petstore_api.models.") for name in sys.modules) + assert not any(name.startswith("petstore_api.api.") for name in sys.modules) + + import petstore_api.api + import petstore_api.models + + assert importlib.util.find_spec("petstore_api.api") is not None + assert importlib.util.find_spec("petstore_api.models") is not None + assert "Pet" in petstore_api.__all__ + assert "ApiClient" in petstore_api.__all__ + assert "HttpSigningConfiguration" in petstore_api.__all__ + assert "Pet" in petstore_api.models.__all__ + assert "Pet" in dir(petstore_api.models) + assert "DefaultApi" in petstore_api.api.__all__ + assert "DefaultApi" in dir(petstore_api.api) + + from petstore_api import Pet + + assert Pet is petstore_api.Pet + assert Pet is petstore_api.models.Pet + assert Pet is petstore_api.__dict__["Pet"] + assert Pet is petstore_api.models.__dict__["Pet"] + assert petstore_api.CircularReferenceModel is petstore_api.models.CircularReferenceModel + + try: + petstore_api.missing_export + except AttributeError as error: + assert "missing_export" in str(error) + else: + raise AssertionError("unknown export did not raise AttributeError") + + assert "lazy_imports" not in sys.modules + """ + ), + ], + check=True, + cwd=Path(__file__).resolve().parents[1], + ) From f7325bcd0ca21ee8aa18bdd82458df573472259c Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Thu, 23 Jul 2026 14:39:41 -0400 Subject: [PATCH 2/2] python: verify lazy namespace and API imports --- .../python-lazyImports/tests/test_lazy_imports.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/samples/openapi3/client/petstore/python-lazyImports/tests/test_lazy_imports.py b/samples/openapi3/client/petstore/python-lazyImports/tests/test_lazy_imports.py index 892ca0504b4b..d3c2eed66a5d 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/tests/test_lazy_imports.py +++ b/samples/openapi3/client/petstore/python-lazyImports/tests/test_lazy_imports.py @@ -26,6 +26,9 @@ def test_lazy_imports_use_standard_library() -> None: import petstore_api.api import petstore_api.models + assert not any(name.startswith("petstore_api.models.") for name in sys.modules) + assert not any(name.startswith("petstore_api.api.") for name in sys.modules) + assert importlib.util.find_spec("petstore_api.api") is not None assert importlib.util.find_spec("petstore_api.models") is not None assert "Pet" in petstore_api.__all__ @@ -36,6 +39,13 @@ def test_lazy_imports_use_standard_library() -> None: assert "DefaultApi" in petstore_api.api.__all__ assert "DefaultApi" in dir(petstore_api.api) + from petstore_api.api import DefaultApi + + assert DefaultApi is petstore_api.api.DefaultApi + assert DefaultApi is petstore_api.DefaultApi + assert "petstore_api.api.default_api" in sys.modules + assert "petstore_api.api.pet_api" not in sys.modules + from petstore_api import Pet assert Pet is petstore_api.Pet