diff --git a/.changeset/avoid_duplicating_user_defined_enum_property_names.md b/.changeset/avoid_duplicating_user_defined_enum_property_names.md new file mode 100644 index 000000000..e254d97dc --- /dev/null +++ b/.changeset/avoid_duplicating_user_defined_enum_property_names.md @@ -0,0 +1,11 @@ +--- +default: major +--- + +# Avoid duplicating user-defined enum property names + +#1168 by @wileykestner + +The generator will now create names for properties gauranteed to avoid colliding with the names of other existing, user-defined types. + +Resolves #1167 diff --git a/openapi_python_client/parser/properties/enum_property.py b/openapi_python_client/parser/properties/enum_property.py index fc7f20bd9..2f88999c3 100644 --- a/openapi_python_client/parser/properties/enum_property.py +++ b/openapi_python_client/parser/properties/enum_property.py @@ -120,6 +120,11 @@ def build( # noqa: PLR0911 class_name = data.title or name if parent_name: class_name = f"{utils.pascal_case(parent_name)}{utils.pascal_case(class_name)}" + original_class_name = class_name + name_index = 0 + while class_name in schemas.classes_by_name: + name_index += 1 + class_name = f"{original_class_name}PropertyEnum_{name_index}" class_info = Class.from_string(string=class_name, config=config) values = EnumProperty.values_from_list(value_list, class_info) diff --git a/openapi_python_client/parser/properties/literal_enum_property.py b/openapi_python_client/parser/properties/literal_enum_property.py index 669b62f58..d80d831f4 100644 --- a/openapi_python_client/parser/properties/literal_enum_property.py +++ b/openapi_python_client/parser/properties/literal_enum_property.py @@ -119,6 +119,11 @@ def build( # noqa: PLR0911 class_name = data.title or name if parent_name: class_name = f"{utils.pascal_case(parent_name)}{utils.pascal_case(class_name)}" + original_class_name = class_name + name_index = 0 + while class_name in schemas.classes_by_name: + name_index += 1 + class_name = f"{original_class_name}PropertyEnum_{name_index}" class_info = Class.from_string(string=class_name, config=config) values: set[str | int] = set(value_list) diff --git a/tests/test_parser/test_properties/test_enum_property.py b/tests/test_parser/test_properties/test_enum_property.py index 282298aaf..60e26f277 100644 --- a/tests/test_parser/test_properties/test_enum_property.py +++ b/tests/test_parser/test_properties/test_enum_property.py @@ -35,6 +35,34 @@ def test_conflict(config: Config, property_class: PropertyClass) -> None: assert err.detail == "Found conflicting enums named Existing with incompatible values." +def test_avoids_false_conflict(config: Config, property_class: PropertyClass) -> None: + schemas = Schemas() + + _, schemas = property_class.build( + data=oai.Schema(enum=["a"]), name="Friend", required=True, schemas=schemas, parent_name="", config=config + ) + _, schemas = property_class.build( + data=oai.Schema(enum=["a", "b"]), + name="FriendShips", + required=True, + schemas=schemas, + parent_name="", + config=config, + ) + prop, new_schemas = property_class.build( + data=oai.Schema(enum=["c"]), + name="ships", + required=True, + schemas=schemas, + parent_name="Friend", + config=config, + ) + + assert sorted([n for n in schemas.classes_by_name]) == ["Friend", "FriendShips"] + assert sorted([n for n in new_schemas.classes_by_name]) == ["Friend", "FriendShips", "FriendShipsPropertyEnum1"] + assert prop.name == "ships" + + def test_bad_default_value(config: Config, property_class: PropertyClass) -> None: data = oai.Schema(default="B", enum=["A"]) schemas = Schemas()