forked from openapi-generators/openapi-python-client
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathproperty.py
More file actions
109 lines (87 loc) · 4.09 KB
/
Copy pathproperty.py
File metadata and controls
109 lines (87 loc) · 4.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
__all__ = ["Property"]
from typing import ClassVar, Optional, Set
import attr
from ... import Config
from ...utils import PythonIdentifier
@attr.s(auto_attribs=True, frozen=True)
class Property:
"""
Describes a single property for a schema
Attributes:
template: Name of the template file (if any) to use for this property. Must be stored in
templates/property_templates and must contain two macros: construct and transform. Construct will be used to
build this property from JSON data (a response from an API). Transform will be used to convert this property
to JSON data (when sending a request to the API).
Raises:
ValidationError: Raised when the default value fails to be converted to the expected type
"""
name: str
required: bool
nullable: bool
_type_string: ClassVar[str] = ""
_json_type_string: ClassVar[str] = "" # Type of the property after JSON serialization
default: Optional[str] = attr.ib()
python_name: PythonIdentifier
template: ClassVar[Optional[str]] = None
json_is_dict: ClassVar[bool] = False
def set_python_name(self, new_name: str, config: Config) -> None:
"""Mutates this Property to set a new python_name.
Required to mutate due to how Properties are stored and the difficulty of updating them in-dict.
`new_name` will be validated before it is set, so `python_name` is not guaranteed to equal `new_name` after
calling this.
"""
object.__setattr__(self, "python_name", PythonIdentifier(value=new_name, prefix=config.field_prefix))
def get_base_type_string(self) -> str:
"""Get the string describing the Python type of this property."""
return self._type_string
def get_base_json_type_string(self) -> str:
"""Get the string describing the JSON type of this property."""
return self._json_type_string
def get_type_string(self, no_optional: bool = False, json: bool = False) -> str:
"""
Get a string representation of type that should be used when declaring this property
Args:
no_optional: Do not include Optional or Unset even if the value is optional (needed for isinstance checks)
json: True if the type refers to the property after JSON serialization
"""
if json:
type_string = self.get_base_json_type_string()
else:
type_string = self.get_base_type_string()
if no_optional or (self.required and not self.nullable):
return type_string
if self.required and self.nullable:
return f"Optional[{type_string}]"
if not self.required and self.nullable:
return f"Union[Unset, None, {type_string}]"
return f"Union[Unset, {type_string}]"
def get_instance_type_string(self) -> str:
"""Get a string representation of runtime type that should be used for `isinstance` checks"""
return self.get_type_string(no_optional=True)
# noinspection PyUnusedLocal
def get_imports(self, *, prefix: str) -> Set[str]:
"""
Get a set of import strings that should be included when this property is used somewhere
Args:
prefix: A prefix to put before any relative (local) module names. This should be the number of . to get
back to the root of the generated client.
"""
imports = set()
if self.nullable:
imports.add("from typing import Optional")
if not self.required:
imports.add("from typing import Union")
imports.add(f"from {prefix}types import UNSET, Unset")
return imports
def to_string(self) -> str:
"""How this should be declared in a dataclass"""
default: Optional[str]
if self.default is not None:
default = self.default
elif not self.required:
default = "UNSET"
else:
default = None
if default is not None:
return f"{self.python_name}: {self.get_type_string()} = {default}"
return f"{self.python_name}: {self.get_type_string()}"