diff --git a/datamodel_code_generator/model/pydantic/types.py b/datamodel_code_generator/model/pydantic/types.py index a5e82f05f..1e115ee2e 100644 --- a/datamodel_code_generator/model/pydantic/types.py +++ b/datamodel_code_generator/model/pydantic/types.py @@ -1,4 +1,4 @@ -from typing import Any, Dict +from typing import Any, Dict, Set from datamodel_code_generator.imports import ( IMPORT_CONFLOAT, @@ -66,24 +66,44 @@ ), } +kwargs_schema_to_model = { + 'exclusiveMinimum': 'gt', + 'minimum': 'ge', + 'exclusiveMaximum': 'lt', + 'maximum': 'le', + 'multipleOf': 'multiple_of', + 'minItems': 'min_items', + 'maxItems': 'max_items', + 'minLength': 'min_length', + 'maxLength': 'max_length', + 'pattern': 'regex', +} + +number_kwargs = { + 'exclusiveMinimum', + 'minimum', + 'exclusiveMaximum', + 'maximum', + 'multipleOf', +} + +string_kwargs = {'minItems', 'maxItems', 'minLength', 'maxLength', 'pattern'} -def get_data_int_type(types: Types, **kwargs: Any) -> DataType: - data_type_kwargs: Dict[str, str] = {} - if kwargs.get('maximum') is not None: - data_type_kwargs['gt'] = kwargs['maximum'] - if kwargs.get('exclusiveMaximum') is not None: - data_type_kwargs['ge'] = kwargs['exclusiveMaximum'] - if kwargs.get('minimum') is not None: - data_type_kwargs['lt'] = kwargs['minimum'] - if kwargs.get('exclusiveMinimum') is not None: - data_type_kwargs['le'] = kwargs['exclusiveMinimum'] - if kwargs.get('multipleOf') is not None: - data_type_kwargs['multiple_of'] = kwargs['multipleOf'] +def transform_kwargs(kwargs: Dict[str, Any], filter: Set[str]) -> Dict[str, str]: + return { + kwargs_schema_to_model.get(k, k): v + for (k, v) in kwargs.items() + if v is not None and k in filter + } + + +def get_data_int_type(types: Types, **kwargs: Any) -> DataType: + data_type_kwargs = transform_kwargs(kwargs, number_kwargs) if data_type_kwargs: - if len(data_type_kwargs) == 1 and data_type_kwargs.get('le') == 0: + if data_type_kwargs == {'gt': 0}: return DataType(type='PositiveInt') - if len(data_type_kwargs) == 1 and data_type_kwargs.get('ge') == 0: + if data_type_kwargs == {'lt': 0}: return DataType(type='NegativeInt') return DataType( type='conint', @@ -95,22 +115,11 @@ def get_data_int_type(types: Types, **kwargs: Any) -> DataType: def get_data_float_type(types: Types, **kwargs: Any) -> DataType: - data_type_kwargs: Dict[str, str] = {} - if kwargs.get('maximum') is not None: - data_type_kwargs['gt'] = kwargs['maximum'] - if kwargs.get('exclusiveMaximum') is not None: - data_type_kwargs['ge'] = kwargs['exclusiveMaximum'] - if kwargs.get('minimum') is not None: - data_type_kwargs['lt'] = kwargs['minimum'] - if kwargs.get('exclusiveMinimum') is not None: - data_type_kwargs['le'] = kwargs['exclusiveMinimum'] - if kwargs.get('multipleOf') is not None: - data_type_kwargs['multiple_of'] = kwargs['multipleOf'] - + data_type_kwargs = transform_kwargs(kwargs, number_kwargs) if data_type_kwargs: - if len(data_type_kwargs) == 1 and data_type_kwargs.get('le') == 0: + if data_type_kwargs == {'gt': 0}: return DataType(type='PositiveFloat') - if len(data_type_kwargs) == 1 and data_type_kwargs.get('ge') == 0: + if data_type_kwargs == {'lt': 0}: return DataType(type='NegativeFloat') return DataType( type='confloat', @@ -122,13 +131,7 @@ def get_data_float_type(types: Types, **kwargs: Any) -> DataType: def get_data_str_type(types: Types, **kwargs: Any) -> DataType: - data_type_kwargs: Dict[str, str] = {} - if kwargs.get('pattern') is not None: - data_type_kwargs['regex'] = kwargs['pattern'] - if kwargs.get('minLength') is not None: - data_type_kwargs['min_length'] = kwargs['minLength'] - if kwargs.get('maxLength') is not None: - data_type_kwargs['max_length'] = kwargs['maxLength'] + data_type_kwargs = transform_kwargs(kwargs, string_kwargs) if data_type_kwargs: return DataType( type='constr', diff --git a/tests/model/pydantic/test_types.py b/tests/model/pydantic/test_types.py index 6824ed755..6559a1bb7 100644 --- a/tests/model/pydantic/test_types.py +++ b/tests/model/pydantic/test_types.py @@ -21,28 +21,28 @@ Types.integer, {'maximum': 10}, DataType( - type='conint', is_func=True, kwargs={'gt': 10}, imports_=[IMPORT_CONINT] + type='conint', is_func=True, kwargs={'le': 10}, imports_=[IMPORT_CONINT] ), ), ( Types.integer, {'exclusiveMaximum': 10}, DataType( - type='conint', is_func=True, kwargs={'ge': 10}, imports_=[IMPORT_CONINT] + type='conint', is_func=True, kwargs={'lt': 10}, imports_=[IMPORT_CONINT] ), ), ( Types.integer, {'minimum': 10}, DataType( - type='conint', is_func=True, kwargs={'lt': 10}, imports_=[IMPORT_CONINT] + type='conint', is_func=True, kwargs={'ge': 10}, imports_=[IMPORT_CONINT] ), ), ( Types.integer, {'exclusiveMinimum': 10}, DataType( - type='conint', is_func=True, kwargs={'le': 10}, imports_=[IMPORT_CONINT] + type='conint', is_func=True, kwargs={'gt': 10}, imports_=[IMPORT_CONINT] ), ), ( @@ -73,7 +73,7 @@ def test_get_data_int_type(types, params, data_type): DataType( type='confloat', is_func=True, - kwargs={'gt': 10}, + kwargs={'le': 10}, imports_=[IMPORT_CONFLOAT], ), ), @@ -83,7 +83,7 @@ def test_get_data_int_type(types, params, data_type): DataType( type='confloat', is_func=True, - kwargs={'ge': 10}, + kwargs={'lt': 10}, imports_=[IMPORT_CONFLOAT], ), ), @@ -93,7 +93,7 @@ def test_get_data_int_type(types, params, data_type): DataType( type='confloat', is_func=True, - kwargs={'lt': 10}, + kwargs={'ge': 10}, imports_=[IMPORT_CONFLOAT], ), ), @@ -103,7 +103,7 @@ def test_get_data_int_type(types, params, data_type): DataType( type='confloat', is_func=True, - kwargs={'le': 10}, + kwargs={'gt': 10}, imports_=[IMPORT_CONFLOAT], ), ), diff --git a/tests/parser/test_jsonschema.py b/tests/parser/test_jsonschema.py index 3100cb267..b13e11584 100644 --- a/tests/parser/test_jsonschema.py +++ b/tests/parser/test_jsonschema.py @@ -86,7 +86,7 @@ def test_json_schema_object_ref_url(): """class Pets(BaseModel): firstName: Optional[str] = None lastName: Optional[str] = None - age: Optional[conint(lt=0.0)] = None""", + age: Optional[conint(ge=0.0)] = None""", ) ], ) diff --git a/tests/parser/test_openapi.py b/tests/parser/test_openapi.py index 0ff0a2137..ea5d75b31 100644 --- a/tests/parser/test_openapi.py +++ b/tests/parser/test_openapi.py @@ -863,7 +863,7 @@ class AllOfobj(BaseModel): class AllOfCombine(Pet): birthdate: Optional[date] = None - size: Optional[conint(lt=1.0)] = None + size: Optional[conint(ge=1.0)] = None class AnyOfCombine(Pet, Car): diff --git a/tests/test_main.py b/tests/test_main.py index 07fcf2fcd..0bf53ac04 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -301,7 +301,7 @@ def test_main_autodetect(): class Person(BaseModel): firstName: Optional[str] = None lastName: Optional[str] = None - age: Optional[conint(lt=0.0)] = None + age: Optional[conint(ge=0.0)] = None ''' ) @@ -364,7 +364,7 @@ def test_main_jsonschema(): class Person(BaseModel): firstName: Optional[str] = None lastName: Optional[str] = None - age: Optional[conint(lt=0.0)] = None + age: Optional[conint(ge=0.0)] = None ''' )