Skip to content

Commit

Permalink
fix: do not force pascalcase for enum names. Closes #544 (#571)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcosschroh committed Mar 15, 2024
1 parent c324f60 commit 9106035
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 9 deletions.
15 changes: 10 additions & 5 deletions dataclasses_avroschema/model_generator/lang/python/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,8 +391,7 @@ def parse_enum(self, field: JsonDict) -> str:
"""
self.imports.add("import enum")

field_name: str = field["name"]
enum_name = casefy.pascalcase(field_name)
enum_name: str = field["name"]

symbols_map = {}
symbols: typing.List[str] = field["symbols"]
Expand Down Expand Up @@ -532,12 +531,18 @@ def get_field_default(
default_repr += inner_default_repr
elif default is dataclasses.MISSING:
pass
elif field_type in (field_utils.STRING, field_utils.UUID,):
elif field_type in (
field_utils.STRING,
field_utils.UUID,
):
default_repr = f'"{default}"'
elif field_type in (field_utils.BYTES, field_utils.FIXED,):
elif field_type in (
field_utils.BYTES,
field_utils.FIXED,
):
default_repr = f'b"{default}"'
elif field_type == field_utils.ENUM:
default_repr = f"{casefy.pascalcase(name)}.{casefy.uppercase(default)}"
default_repr = f"{name}.{casefy.uppercase(default)}"
elif isinstance(field_type, list):
# union type
default_repr = self.get_field_default(field_type=field_type[0], default=default, name=name)
Expand Down
3 changes: 3 additions & 0 deletions docs/complex_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ User.avro_schema()
}'
```

!!! info
There are not restriction about `enum` names but is is highly recommended to use `pascalcase`

### Repeated Enums

Sometimes we have cases where an `Enum` is used more than once with a particular class, for those cases the same `type` is used in order to generate a valid schema.
Expand Down
36 changes: 34 additions & 2 deletions tests/model_generator/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ def schema_with_fixed_types() -> Dict:
"namespace": "md5",
"aliases": ["md5", "hash"],
},
"default": "u00ffffffffffffx"
"default": "u00ffffffffffffx",
},
],
}
Expand Down Expand Up @@ -236,7 +236,7 @@ def schema_with_enum_types() -> Dict:
"null",
{
"type": "enum",
"name": "cars",
"name": "Cars",
"symbols": ["bmw", "ferrary", "duna"],
},
],
Expand Down Expand Up @@ -264,6 +264,38 @@ def schema_with_enum_types_case_sensitivity() -> Dict:
}


@pytest.fixture
def schema_with_enum_types_no_pascal_case() -> Dict:
return {
"type": "record",
"name": "User",
"fields": [
{
"name": "favorite_color",
"type": {
"type": "enum",
"name": "my_favorite_color",
"symbols": ["Blue", "Yellow", "Green"],
"doc": "A favorite color",
"namespace": "some.name.space",
"aliases": ["Color", "My favorite color"],
},
},
{"name": "primaty_color", "type": "some.name.space.my_favorite_color"},
{
"name": "superheros",
"type": {"type": "enum", "name": "super_heros", "symbols": ["batman", "superman", "spiderman"]},
"default": "batman",
},
{
"name": "my_cars",
"type": ["null", {"type": "enum", "name": "cars", "symbols": ["bmw", "ferrary", "duna"]}],
"default": None,
},
],
}


@pytest.fixture
def schema_with_custom_inner_names() -> Dict:
return {
Expand Down
49 changes: 47 additions & 2 deletions tests/model_generator/test_model_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,21 +250,66 @@ def test_schema_with_enum_types_case_sensitivity(
import enum
class UnitMultiPlayer(enum.Enum):
class unit_multi_player(enum.Enum):
q = "q"
Q = "Q"
@dataclasses.dataclass
class User(AvroModel):
unit_multi_player: UnitMultiPlayer
unit_multi_player: unit_multi_player
"""
model_generator = ModelGenerator()
result = model_generator.render(schema=schema_with_enum_types_case_sensitivity)
assert result.strip() == expected_result.strip()


def test_enum_types_with_no_pascal_case(schema_with_enum_types_no_pascal_case) -> None:
expected_result = '''
from dataclasses_avroschema import AvroModel
import dataclasses
import enum
import typing
class my_favorite_color(enum.Enum):
"""
A favorite color
"""
BLUE = "Blue"
YELLOW = "Yellow"
GREEN = "Green"
class Meta:
namespace = "some.name.space"
aliases = ['Color', 'My favorite color']
class super_heros(enum.Enum):
BATMAN = "batman"
SUPERMAN = "superman"
SPIDERMAN = "spiderman"
class cars(enum.Enum):
BMW = "bmw"
FERRARY = "ferrary"
DUNA = "duna"
@dataclasses.dataclass
class User(AvroModel):
favorite_color: my_favorite_color
primaty_color: my_favorite_color
superheros: super_heros = super_heros.BATMAN
my_cars: typing.Optional[cars] = None
'''
model_generator = ModelGenerator()
result = model_generator.render(schema=schema_with_enum_types_no_pascal_case)
assert result.strip() == expected_result.strip()


def test_schema_one_to_one_relationship(
schema_one_to_one_relationship: types.JsonDict,
) -> None:
Expand Down
42 changes: 42 additions & 0 deletions tests/schemas/avro/enums_with_customer_names.avsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"type": "record",
"name": "User",
"fields": [
{
"name": "favorite_color",
"type": {
"type": "enum",
"name": "my_favorite_color",
"symbols": ["Blue", "Yellow", "Green"],
"doc": "A favorite color",
"namespace": "some.name.space",
"aliases": ["Color", "My favorite color"]
}
},
{
"name": "primaty_color",
"type": "some.name.space.my_favorite_color"
},
{
"name": "superheros",
"type": {
"type": "enum",
"name": "super_heros",
"symbols": ["batman", "superman", "spiderman"]
},
"default": "batman"
},
{
"name": "my_cars",
"type": [
"null",
{
"type": "enum",
"name": "cars",
"symbols": ["bmw", "ferrary", "duna"]
}
],
"default": null
}
]
}

0 comments on commit 9106035

Please sign in to comment.