forked from openapi-generators/openapi-python-client
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconst.py
120 lines (104 loc) · 3.75 KB
/
const.py
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
110
111
112
113
114
115
116
117
118
119
120
from __future__ import annotations
from typing import Any, ClassVar, overload
from attr import define
from ...utils import PythonIdentifier
from ..errors import PropertyError
from .protocol import PropertyProtocol, Value
from .string import StringProperty
@define
class ConstProperty(PropertyProtocol):
"""A property representing a const value"""
name: str
required: bool
value: Value
default: Value | None
python_name: PythonIdentifier
description: str | None
example: None
template: ClassVar[str] = "const_property.py.jinja"
@classmethod
def build(
cls,
*,
const: str | int | float | bool,
default: Any,
name: str,
python_name: PythonIdentifier,
required: bool,
description: str | None,
) -> ConstProperty | PropertyError:
"""
Create a `ConstProperty` the right way.
Args:
const: The `const` value of the schema, indicating the literal value this represents
default: The default value of this property, if any. Must be equal to `const` if set.
name: The name of the property where it appears in the OpenAPI document.
required: Whether this property is required where it's being used.
python_name: The name used to represent this variable/property in generated Python code
description: The description of this property, used for docstrings
"""
value = cls._convert_value(const)
prop = cls(
value=value,
python_name=python_name,
name=name,
required=required,
default=None,
description=description,
example=None,
)
converted_default = prop.convert_value(default)
if isinstance(converted_default, PropertyError):
return converted_default
prop.default = converted_default
return prop
def convert_value(self, value: Any) -> Value | None | PropertyError:
if isinstance(value, Value):
return value
value = self._convert_value(value)
if value is None:
return value
if value != self.value:
return PropertyError(detail=f"Invalid value for const {self.name}; {value} != {self.value}")
return value
@staticmethod
@overload
def _convert_value(value: None) -> None: # type: ignore[misc]
... # pragma: no cover
@staticmethod
@overload
def _convert_value(value: Any) -> Value: ... # pragma: no cover
@staticmethod
def _convert_value(value: Any) -> Value | None:
if value is None or isinstance(value, Value):
return value
if isinstance(value, Value):
return value # pragma: no cover
if isinstance(value, str):
return StringProperty.convert_value(value)
return Value(str(value))
def get_type_string(
self,
no_optional: bool = False,
json: bool = False,
*,
multipart: bool = False,
quoted: bool = False,
) -> str:
lit = f"Literal[{self.value}]"
if not no_optional and not self.required:
return f"Union[{lit}, Unset]"
return lit
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.
"""
if self.required:
return {"from typing import Literal"}
return {
"from typing import Literal, Union",
f"from {prefix}types import UNSET, Unset",
}