From 54ddf3945ff7fc9ba9114696132e0add4fd448ea Mon Sep 17 00:00:00 2001 From: Jebin Date: Wed, 6 Dec 2023 21:58:44 -0600 Subject: [PATCH] Fix `to_snake` conversion Fixes a case for `to_snake` conversion for sequence of uppercase letters followed by a lowercase letter --- pydantic/alias_generators.py | 10 ++++++++-- tests/test_utils.py | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pydantic/alias_generators.py b/pydantic/alias_generators.py index bbdaaaf121..155e66e0c4 100644 --- a/pydantic/alias_generators.py +++ b/pydantic/alias_generators.py @@ -39,6 +39,12 @@ def to_snake(camel: str) -> str: Returns: The converted string in snake_case. """ - snake = re.sub(r'([a-zA-Z])([0-9])', lambda m: f'{m.group(1)}_{m.group(2)}', camel) - snake = re.sub(r'([a-z0-9])([A-Z])', lambda m: f'{m.group(1)}_{m.group(2)}', snake) + # Handle the sequence of uppercase letters followed by a lowercase letter + snake = re.sub(r'([A-Z]+)([A-Z][a-z])', lambda m: f'{m.group(1)}_{m.group(2)}', camel) + # Insert an underscore between a lowercase letter and an uppercase letter + snake = re.sub(r'([a-z])([A-Z])', lambda m: f'{m.group(1)}_{m.group(2)}', snake) + # Insert an underscore between a digit and an uppercase letter + snake = re.sub(r'([0-9])([A-Z])', lambda m: f'{m.group(1)}_{m.group(2)}', snake) + # Insert an underscore between a lowercase letter and a digit + snake = re.sub(r'([a-z])([0-9])', lambda m: f'{m.group(1)}_{m.group(2)}', snake) return snake.lower() diff --git a/tests/test_utils.py b/tests/test_utils.py index ccbc956a00..dff54caac0 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -529,6 +529,7 @@ def test_snake2camel(value: str, result: str) -> None: ('Camel2Snake', 'camel_2_snake'), ('_CamelToSnake', '_camel_to_snake'), ('CamelToSnake_', 'camel_to_snake_'), + ('CAMELToSnake', 'camel_to_snake'), ('__CamelToSnake__', '__camel_to_snake__'), ('Camel2', 'camel_2'), ('Camel2_', 'camel_2_'),