Skip to content

Commit

Permalink
fix defualt (#161)
Browse files Browse the repository at this point in the history
* fix defualt

* remove typed_defult
  • Loading branch information
koxudaxi authored Jun 20, 2020
1 parent ef6f682 commit 01e9e58
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 59 deletions.
6 changes: 5 additions & 1 deletion datamodel_code_generator/model/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from collections import defaultdict
from functools import wraps
from pathlib import Path
from typing import Any, Callable, DefaultDict, Dict, List, Optional, Set
from typing import Any, Callable, DefaultDict, Dict, List, Optional, Set, Union

from jinja2 import Environment, FileSystemLoader, Template
from pydantic import BaseModel, root_validator
Expand Down Expand Up @@ -108,6 +108,10 @@ def __init__(self, **values: Any) -> None:
self.imports.extend(data_type.imports_)
self.type_hint = self._get_type_hint()

@property
def represented_default(self) -> str:
return repr(self.default)


class TemplateBase(ABC):
def __init__(self, template_file_path: Path) -> None:
Expand Down
18 changes: 2 additions & 16 deletions datamodel_code_generator/model/pydantic/base_model.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
from pathlib import Path
from typing import Any, DefaultDict, Dict, List, Optional, Set, Union

from jinja2 import Environment, FileSystemLoader, Template

from datamodel_code_generator.imports import Import
from datamodel_code_generator.model import DataModel, DataModelFieldBase
from datamodel_code_generator.model.pydantic.types import get_data_type
Expand All @@ -12,18 +10,6 @@
class DataModelField(DataModelFieldBase):
_FIELDS_KEYS: Set[str] = {'alias', 'example', 'examples', 'description', 'title'}

def get_valid_argument(self, value: Any) -> Union[str, List[Any], Dict[Any, Any]]:
if isinstance(value, str):
return repr(value)
elif isinstance(value, list):
return [self.get_valid_argument(i) for i in value]
elif isinstance(value, dict):
return {
self.get_valid_argument(k): self.get_valid_argument(v)
for k, v in value.items()
}
return value

def __init__(self, **values: Any) -> None:
super().__init__(**values)

Expand Down Expand Up @@ -52,14 +38,14 @@ def field(self) -> Optional[str]:

def __str__(self) -> str:
field_arguments = [
f"{k}={self.get_valid_argument(v)}"
f"{k}={repr(v)}"
for k, v in self.dict(include=self._FIELDS_KEYS).items()
if v is not None
]
if not field_arguments:
return ""

value_arg = "..." if self.required else self.get_valid_argument(self.default)
value_arg = "..." if self.required else repr(self.default)
kwargs = ",".join(field_arguments)
return f'Field({value_arg}, {kwargs})'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class {{ class_name }}({{ base_class }}):
{%- elif field.required %}
{{ field.name }}: {{ field.type_hint }}
{%- else %}
{{ field.name }}: {{ field.type_hint }} = {{ field.default }}
{{ field.name }}: {{ field.type_hint }} = {{ field.represented_default }}
{%- endif %}
{%- for method in methods -%}
{{ method }}
Expand Down
29 changes: 3 additions & 26 deletions datamodel_code_generator/parser/jsonschema.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,29 +120,6 @@ def validate_items(cls, values: Any) -> Any:
return None
return values

@property
def typed_default(self) -> Union[str, bool, Dict[Any, Any], None]:
if self.default is not None and self.type:
type_ = self.type[0] if isinstance(self.type, list) else self.type
return self._get_typed_default(type_, self.default)
return None

@classmethod
def _get_typed_default(
cls, type_: str, default_value: Any
) -> Union[str, bool, Dict[Any, Any], None]:
if type_ == 'integer' or type_ == 'number':
return default_value
elif type_ == 'boolean':
if default_value == 'true':
return True
return False
elif type_ == 'object' and isinstance(default_value, dict):
return default_value
elif type_ == 'null':
return None
return f"'{default_value}'"


JsonSchemaObject.update_forward_refs()

Expand Down Expand Up @@ -371,7 +348,7 @@ def parse_object_fields(self, obj: JsonSchemaObject) -> List[DataModelFieldBase]
name=field_name,
example=field.examples,
description=field.description,
default=field.typed_default,
default=field.default,
title=field.title,
data_types=field_types,
required=required,
Expand Down Expand Up @@ -441,7 +418,7 @@ def parse_array_fields(
field = self.data_model_field_type(
data_types=item_obj_data_types,
example=obj.examples,
default=obj.typed_default,
default=obj.default,
description=obj.description,
title=obj.title,
required=True,
Expand Down Expand Up @@ -486,7 +463,7 @@ def parse_root_type(self, name: str, obj: JsonSchemaObject) -> None:
data_types=types,
description=obj.description,
example=obj.examples,
default=obj.typed_default,
default=obj.default,
required=not obj.nullable,
)
],
Expand Down
6 changes: 3 additions & 3 deletions tests/model/pydantic/test_base_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def test_base_model():

def test_base_model_optional():
field = DataModelField(
name='a', data_types=[DataType(type='str')], default="'abc'", required=False
name='a', data_types=[DataType(type='str')], default='abc', required=False
)

base_model = BaseModel(name='test_model', fields=[field])
Expand All @@ -33,7 +33,7 @@ def test_base_model_optional():

def test_base_model_decorator():
field = DataModelField(
name='a', data_types=[DataType(type='str')], default="'abc'", required=False
name='a', data_types=[DataType(type='str')], default='abc', required=False
)

base_model = BaseModel(
Expand Down Expand Up @@ -121,7 +121,7 @@ def test_base_model_reserved_name():
({'examples': [1, 2, 3]}, "Field(None, examples=[1, 2, 3])"),
(
{'examples': {'name': 'dog', 'age': 1}},
'Field(None, examples={"\'name\'": "\'dog\'", "\'age\'": 1})',
'Field(None, examples={\'name\': \'dog\', \'age\': 1})',
),
({'default': 'abc', 'title': 'title'}, 'Field(\'abc\', title=\'title\')'),
({'default': 123, 'title': 'title'}, 'Field(123, title=\'title\')'),
Expand Down
52 changes: 40 additions & 12 deletions tests/parser/test_jsonschema.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import pytest

from datamodel_code_generator import DataModelField
from datamodel_code_generator.model import DataModelFieldBase
from datamodel_code_generator.model.pydantic import BaseModel, CustomRootType
from datamodel_code_generator.parser.base import dump_templates
from datamodel_code_generator.parser.jsonschema import (
Expand Down Expand Up @@ -189,17 +188,46 @@ def test_parse_one_of_object(source_obj, generated_classes):


@pytest.mark.parametrize(
'type_,default,expected',
'source_obj,generated_classes',
[
('string', 'abc', "'abc'"),
('string', '', "''"),
('number', 123, 123),
('number', 0, 0),
('boolean', 'true', True),
('boolean', 'false', False),
('null', 'null', None),
('object', {'abc': 123, 'efg': 'hij'}, {'abc': 123, 'efg': 'hij'}),
(
{
"$id": "https://example.com/person.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "defaults",
"type": "object",
"properties": {
"string": {"type": "string", "default": "default string",},
"string_on_field": {
"type": "string",
"default": "default string",
"description": "description",
},
"number": {"type": "number", "default": 123},
"number_on_field": {
"type": "number",
"default": 123,
"description": "description",
},
"number_array": {"type": "array", "default": [1, 2, 3]},
"string_array": {"type": "array", "default": ["a", "b", "c"]},
"object": {"type": "object", "default": {"key": "value"}},
},
},
"""class Defaults(BaseModel):
string: Optional[str] = 'default string'
string_on_field: Optional[str] = Field('default string', description='description')
number: Optional[float] = 123
number_on_field: Optional[float] = Field(123, description='description')
number_array: Optional[List] = [1, 2, 3]
string_array: Optional[List] = ['a', 'b', 'c']
object: Optional[Dict[str, Any]] = {'key': 'value'}""",
)
],
)
def test_typed_default(type_, default, expected):
assert JsonSchemaObject(type=type_, default=default).typed_default == expected
def test_parse_default(source_obj, generated_classes):
parser = JsonSchemaParser(
BaseModel, CustomRootType, data_model_field_type=DataModelField
)
parser.parse_raw_obj('Defaults', source_obj)
assert dump_templates(list(parser.results)) == generated_classes

0 comments on commit 01e9e58

Please sign in to comment.