Skip to content

Commit b1c2abd

Browse files
authored
chore: Refactor Value to store raw values (#1118)
Co-authored-by: Dylan Anthony <[email protected]>
1 parent 0bdd8ba commit b1c2abd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+291
-226
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
default: patch
3+
---
4+
5+
# Allow default values for properties of `Any` type

end_to_end_tests/baseline_openapi_3.0.json

+26-6
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,16 @@
596596
"name": "float_prop",
597597
"in": "query"
598598
},
599+
{
600+
"required": true,
601+
"schema": {
602+
"title": "Float with int default",
603+
"type": "number",
604+
"default": 3
605+
},
606+
"name": "float_with_int",
607+
"in": "query"
608+
},
599609
{
600610
"required": true,
601611
"schema": {
@@ -1674,15 +1684,20 @@
16741684
"an_required_field"
16751685
]
16761686
},
1677-
"Aliased":{
1687+
"Aliased": {
16781688
"allOf": [
1679-
{"$ref": "#/components/schemas/AModel"}
1689+
{
1690+
"$ref": "#/components/schemas/AModel"
1691+
}
16801692
]
16811693
},
16821694
"Extended": {
16831695
"allOf": [
1684-
{"$ref": "#/components/schemas/Aliased"},
1685-
{"type": "object",
1696+
{
1697+
"$ref": "#/components/schemas/Aliased"
1698+
},
1699+
{
1700+
"type": "object",
16861701
"properties": {
16871702
"fromExtended": {
16881703
"type": "string"
@@ -1708,7 +1723,9 @@
17081723
],
17091724
"type": "object",
17101725
"properties": {
1711-
"any_value": {},
1726+
"any_value": {
1727+
"default": "default"
1728+
},
17121729
"an_enum_value": {
17131730
"$ref": "#/components/schemas/AnEnum"
17141731
},
@@ -2185,7 +2202,10 @@
21852202
},
21862203
"stringToEnum": {
21872204
"type": "string",
2188-
"enum": ["a", "b"]
2205+
"enum": [
2206+
"a",
2207+
"b"
2208+
]
21892209
},
21902210
"stringToDate": {
21912211
"type": "string",

end_to_end_tests/baseline_openapi_3.1.yaml

+17-5
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,16 @@ info:
592592
"name": "float_prop",
593593
"in": "query"
594594
},
595+
{
596+
"required": true,
597+
"schema": {
598+
"title": "Float with int default",
599+
"type": "number",
600+
"default": 3
601+
},
602+
"name": "float_with_int",
603+
"in": "query"
604+
},
595605
{
596606
"required": true,
597607
"schema": {
@@ -1698,7 +1708,9 @@ info:
16981708
],
16991709
"type": "object",
17001710
"properties": {
1701-
"any_value": { },
1711+
"any_value": {
1712+
"default": "default",
1713+
},
17021714
"an_enum_value": {
17031715
"$ref": "#/components/schemas/AnEnum"
17041716
},
@@ -1972,7 +1984,7 @@ info:
19721984
"title": "Some Integer Array",
19731985
"type": "array",
19741986
"items": {
1975-
"type": ["integer", "null"]
1987+
"type": [ "integer", "null" ]
19761988
}
19771989
},
19781990
"some_array": {
@@ -2166,7 +2178,7 @@ info:
21662178
"numberToInt": {
21672179
"type": "number"
21682180
},
2169-
"anyToString": {}
2181+
"anyToString": { }
21702182
}
21712183
},
21722184
{
@@ -2179,7 +2191,7 @@ info:
21792191
},
21802192
"stringToEnum": {
21812193
"type": "string",
2182-
"enum": ["a", "b"]
2194+
"enum": [ "a", "b" ]
21832195
},
21842196
"stringToDate": {
21852197
"type": "string",
@@ -2265,7 +2277,7 @@ info:
22652277
},
22662278
"ModelWithNoProperties": {
22672279
"type": "object",
2268-
"properties": {},
2280+
"properties": { },
22692281
"additionalProperties": false
22702282
},
22712283
"AllOfSubModel": {

end_to_end_tests/golden-record/my_test_api_client/api/defaults/defaults_tests_defaults_post.py

+15
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def _get_kwargs(
1919
string_with_num: str = "1",
2020
date_prop: datetime.date = isoparse("1010-10-10").date(),
2121
float_prop: float = 3.14,
22+
float_with_int: float = 3.0,
2223
int_prop: int = 7,
2324
boolean_prop: bool = False,
2425
list_prop: List[AnEnum],
@@ -39,6 +40,8 @@ def _get_kwargs(
3940

4041
params["float_prop"] = float_prop
4142

43+
params["float_with_int"] = float_with_int
44+
4245
params["int_prop"] = int_prop
4346

4447
params["boolean_prop"] = boolean_prop
@@ -117,6 +120,7 @@ def sync_detailed(
117120
string_with_num: str = "1",
118121
date_prop: datetime.date = isoparse("1010-10-10").date(),
119122
float_prop: float = 3.14,
123+
float_with_int: float = 3.0,
120124
int_prop: int = 7,
121125
boolean_prop: bool = False,
122126
list_prop: List[AnEnum],
@@ -133,6 +137,7 @@ def sync_detailed(
133137
string_with_num (str): Default: '1'.
134138
date_prop (datetime.date): Default: isoparse('1010-10-10').date().
135139
float_prop (float): Default: 3.14.
140+
float_with_int (float): Default: 3.0.
136141
int_prop (int): Default: 7.
137142
boolean_prop (bool): Default: False.
138143
list_prop (List[AnEnum]):
@@ -155,6 +160,7 @@ def sync_detailed(
155160
string_with_num=string_with_num,
156161
date_prop=date_prop,
157162
float_prop=float_prop,
163+
float_with_int=float_with_int,
158164
int_prop=int_prop,
159165
boolean_prop=boolean_prop,
160166
list_prop=list_prop,
@@ -179,6 +185,7 @@ def sync(
179185
string_with_num: str = "1",
180186
date_prop: datetime.date = isoparse("1010-10-10").date(),
181187
float_prop: float = 3.14,
188+
float_with_int: float = 3.0,
182189
int_prop: int = 7,
183190
boolean_prop: bool = False,
184191
list_prop: List[AnEnum],
@@ -195,6 +202,7 @@ def sync(
195202
string_with_num (str): Default: '1'.
196203
date_prop (datetime.date): Default: isoparse('1010-10-10').date().
197204
float_prop (float): Default: 3.14.
205+
float_with_int (float): Default: 3.0.
198206
int_prop (int): Default: 7.
199207
boolean_prop (bool): Default: False.
200208
list_prop (List[AnEnum]):
@@ -218,6 +226,7 @@ def sync(
218226
string_with_num=string_with_num,
219227
date_prop=date_prop,
220228
float_prop=float_prop,
229+
float_with_int=float_with_int,
221230
int_prop=int_prop,
222231
boolean_prop=boolean_prop,
223232
list_prop=list_prop,
@@ -236,6 +245,7 @@ async def asyncio_detailed(
236245
string_with_num: str = "1",
237246
date_prop: datetime.date = isoparse("1010-10-10").date(),
238247
float_prop: float = 3.14,
248+
float_with_int: float = 3.0,
239249
int_prop: int = 7,
240250
boolean_prop: bool = False,
241251
list_prop: List[AnEnum],
@@ -252,6 +262,7 @@ async def asyncio_detailed(
252262
string_with_num (str): Default: '1'.
253263
date_prop (datetime.date): Default: isoparse('1010-10-10').date().
254264
float_prop (float): Default: 3.14.
265+
float_with_int (float): Default: 3.0.
255266
int_prop (int): Default: 7.
256267
boolean_prop (bool): Default: False.
257268
list_prop (List[AnEnum]):
@@ -274,6 +285,7 @@ async def asyncio_detailed(
274285
string_with_num=string_with_num,
275286
date_prop=date_prop,
276287
float_prop=float_prop,
288+
float_with_int=float_with_int,
277289
int_prop=int_prop,
278290
boolean_prop=boolean_prop,
279291
list_prop=list_prop,
@@ -296,6 +308,7 @@ async def asyncio(
296308
string_with_num: str = "1",
297309
date_prop: datetime.date = isoparse("1010-10-10").date(),
298310
float_prop: float = 3.14,
311+
float_with_int: float = 3.0,
299312
int_prop: int = 7,
300313
boolean_prop: bool = False,
301314
list_prop: List[AnEnum],
@@ -312,6 +325,7 @@ async def asyncio(
312325
string_with_num (str): Default: '1'.
313326
date_prop (datetime.date): Default: isoparse('1010-10-10').date().
314327
float_prop (float): Default: 3.14.
328+
float_with_int (float): Default: 3.0.
315329
int_prop (int): Default: 7.
316330
boolean_prop (bool): Default: False.
317331
list_prop (List[AnEnum]):
@@ -336,6 +350,7 @@ async def asyncio(
336350
string_with_num=string_with_num,
337351
date_prop=date_prop,
338352
float_prop=float_prop,
353+
float_with_int=float_with_int,
339354
int_prop=int_prop,
340355
boolean_prop=boolean_prop,
341356
list_prop=list_prop,

end_to_end_tests/golden-record/my_test_api_client/models/a_model.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class AModel:
3333
nullable_one_of_models (Union['FreeFormModel', 'ModelWithUnionProperty', None]):
3434
model (ModelWithUnionProperty):
3535
nullable_model (Union['ModelWithUnionProperty', None]):
36-
any_value (Union[Unset, Any]):
36+
any_value (Union[Unset, Any]): Default: 'default'.
3737
an_optional_allof_enum (Union[Unset, AnAllOfEnum]):
3838
nested_list_of_enums (Union[Unset, List[List[DifferentEnum]]]):
3939
a_not_required_date (Union[Unset, datetime.date]):
@@ -58,7 +58,7 @@ class AModel:
5858
model: "ModelWithUnionProperty"
5959
nullable_model: Union["ModelWithUnionProperty", None]
6060
an_allof_enum_with_overridden_default: AnAllOfEnum = AnAllOfEnum.OVERRIDDEN_DEFAULT
61-
any_value: Union[Unset, Any] = UNSET
61+
any_value: Union[Unset, Any] = "default"
6262
an_optional_allof_enum: Union[Unset, AnAllOfEnum] = UNSET
6363
nested_list_of_enums: Union[Unset, List[List[DifferentEnum]]] = UNSET
6464
a_not_required_date: Union[Unset, datetime.date] = UNSET

end_to_end_tests/golden-record/my_test_api_client/models/extended.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class Extended:
3333
nullable_one_of_models (Union['FreeFormModel', 'ModelWithUnionProperty', None]):
3434
model (ModelWithUnionProperty):
3535
nullable_model (Union['ModelWithUnionProperty', None]):
36-
any_value (Union[Unset, Any]):
36+
any_value (Union[Unset, Any]): Default: 'default'.
3737
an_optional_allof_enum (Union[Unset, AnAllOfEnum]):
3838
nested_list_of_enums (Union[Unset, List[List[DifferentEnum]]]):
3939
a_not_required_date (Union[Unset, datetime.date]):
@@ -59,7 +59,7 @@ class Extended:
5959
model: "ModelWithUnionProperty"
6060
nullable_model: Union["ModelWithUnionProperty", None]
6161
an_allof_enum_with_overridden_default: AnAllOfEnum = AnAllOfEnum.OVERRIDDEN_DEFAULT
62-
any_value: Union[Unset, Any] = UNSET
62+
any_value: Union[Unset, Any] = "default"
6363
an_optional_allof_enum: Union[Unset, AnAllOfEnum] = UNSET
6464
nested_list_of_enums: Union[Unset, List[List[DifferentEnum]]] = UNSET
6565
a_not_required_date: Union[Unset, datetime.date] = UNSET

openapi_python_client/parser/properties/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ def property_from_data( # noqa: PLR0911, PLR0912
280280
AnyProperty.build(
281281
name=name,
282282
required=required,
283-
default=None,
283+
default=data.default,
284284
python_name=utils.PythonIdentifier(value=name, prefix=config.field_prefix),
285285
description=data.description,
286286
example=data.example,

openapi_python_client/parser/properties/any.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,13 @@ def build(
3333

3434
@classmethod
3535
def convert_value(cls, value: Any) -> Value | None:
36-
if value is None or isinstance(value, Value):
36+
from .string import StringProperty
37+
38+
if value is None:
3739
return value
38-
return Value(str(value))
40+
if isinstance(value, str):
41+
return StringProperty.convert_value(value)
42+
return Value(python_code=str(value), raw_value=value)
3943

4044
name: str
4145
required: bool

openapi_python_client/parser/properties/boolean.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ def convert_value(cls, value: Any) -> Value | None | PropertyError:
5959
return value
6060
if isinstance(value, str):
6161
if value.lower() == "true":
62-
return Value("True")
62+
return Value(python_code="True", raw_value=value)
6363
elif value.lower() == "false":
64-
return Value("False")
64+
return Value(python_code="False", raw_value=value)
6565
if isinstance(value, bool):
66-
return Value(str(value))
66+
return Value(python_code=str(value), raw_value=value)
6767
return PropertyError(f"Invalid boolean value: {value}")

openapi_python_client/parser/properties/const.py

+5-7
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ def build(
6363
return prop
6464

6565
def convert_value(self, value: Any) -> Value | None | PropertyError:
66-
if isinstance(value, Value):
67-
return value
6866
value = self._convert_value(value)
6967
if value is None:
7068
return value
7169
if value != self.value:
72-
return PropertyError(detail=f"Invalid value for const {self.name}; {value} != {self.value}")
70+
return PropertyError(
71+
detail=f"Invalid value for const {self.name}; {value.raw_value} != {self.value.raw_value}"
72+
)
7373
return value
7474

7575
@staticmethod
@@ -85,11 +85,9 @@ def _convert_value(value: Any) -> Value: ... # pragma: no cover
8585
def _convert_value(value: Any) -> Value | None:
8686
if value is None or isinstance(value, Value):
8787
return value
88-
if isinstance(value, Value):
89-
return value # pragma: no cover
9088
if isinstance(value, str):
9189
return StringProperty.convert_value(value)
92-
return Value(str(value))
90+
return Value(python_code=str(value), raw_value=value)
9391

9492
def get_type_string(
9593
self,
@@ -99,7 +97,7 @@ def get_type_string(
9997
multipart: bool = False,
10098
quoted: bool = False,
10199
) -> str:
102-
lit = f"Literal[{self.value}]"
100+
lit = f"Literal[{self.value.python_code}]"
103101
if not no_optional and not self.required:
104102
return f"Union[{lit}, Unset]"
105103
return lit

openapi_python_client/parser/properties/date.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def convert_value(cls, value: Any) -> Value | None | PropertyError:
5757
isoparse(value).date() # make sure it's a valid value
5858
except ValueError as e:
5959
return PropertyError(f"Invalid date: {e}")
60-
return Value(f"isoparse({value!r}).date()")
60+
return Value(python_code=f"isoparse({value!r}).date()", raw_value=value)
6161
return PropertyError(f"Cannot convert {value} to a date")
6262

6363
def get_imports(self, *, prefix: str) -> set[str]:

openapi_python_client/parser/properties/datetime.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def convert_value(cls, value: Any) -> Value | None | PropertyError:
5959
isoparse(value) # make sure it's a valid value
6060
except ValueError as e:
6161
return PropertyError(f"Invalid datetime: {e}")
62-
return Value(f"isoparse({value!r})")
62+
return Value(python_code=f"isoparse({value!r})", raw_value=value)
6363
return PropertyError(f"Cannot convert {value} to a datetime")
6464

6565
def get_imports(self, *, prefix: str) -> set[str]:

openapi_python_client/parser/properties/enum_property.py

+1-7
Original file line numberDiff line numberDiff line change
@@ -159,17 +159,11 @@ def convert_value(self, value: Any) -> Value | PropertyError | None:
159159
if isinstance(value, self.value_type):
160160
inverse_values = {v: k for k, v in self.values.items()}
161161
try:
162-
return Value(f"{self.class_info.name}.{inverse_values[value]}")
162+
return Value(python_code=f"{self.class_info.name}.{inverse_values[value]}", raw_value=value)
163163
except KeyError:
164164
return PropertyError(detail=f"Value {value} is not valid for enum {self.name}")
165165
return PropertyError(detail=f"Cannot convert {value} to enum {self.name} of type {self.value_type}")
166166

167-
def default_to_raw(self) -> ValueType | None:
168-
if self.default is None:
169-
return None
170-
key = self.default.split(".")[1]
171-
return self.values[key]
172-
173167
def get_base_type_string(self, *, quoted: bool = False) -> str:
174168
return self.class_info.name
175169

0 commit comments

Comments
 (0)