openapi-python-client 0.21.4__tar.gz → 0.21.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/PKG-INFO +1 -1
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/openapi.py +2 -2
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/properties/__init__.py +1 -2
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/properties/any.py +6 -2
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/properties/boolean.py +3 -3
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/properties/const.py +5 -7
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/properties/date.py +1 -1
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/properties/datetime.py +1 -1
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/properties/enum_property.py +2 -2
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/properties/float.py +3 -3
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/properties/int.py +10 -6
- openapi_python_client-0.21.5/openapi_python_client/parser/properties/merge_properties.py +168 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/properties/model_property.py +14 -67
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/properties/none.py +1 -1
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/properties/protocol.py +12 -4
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/properties/string.py +1 -5
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/model.py.jinja +2 -0
- openapi_python_client-0.21.5/openapi_python_client/templates/property_templates/const_property.py.jinja +5 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/pyproject.toml +2 -2
- openapi_python_client-0.21.4/openapi_python_client/templates/property_templates/const_property.py.jinja +0 -5
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/.gitignore +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/LICENSE +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/README.md +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/__init__.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/__main__.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/cli.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/config.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/__init__.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/bodies.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/errors.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/properties/file.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/properties/list_property.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/properties/property.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/properties/schemas.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/properties/union.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/responses.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/py.typed +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/3.0.3.md +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/3.1.0.md +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/__init__.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/data_type.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/LICENSE +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/README.md +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/__init__.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/callback.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/components.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/contact.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/discriminator.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/encoding.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/example.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/external_documentation.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/header.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/info.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/license.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/link.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/media_type.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/oauth_flow.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/oauth_flows.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/open_api.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/operation.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/parameter.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/path_item.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/paths.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/reference.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/request_body.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/response.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/responses.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/schema.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/security_requirement.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/security_scheme.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/server.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/server_variable.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/tag.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/openapi_schema_pydantic/xml.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/parameter_location.py +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/.gitignore.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/README.md.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/api_init.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/client.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/endpoint_init.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/endpoint_macros.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/endpoint_module.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/errors.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/helpers.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/int_enum.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/models_init.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/package_init.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/property_templates/any_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/property_templates/boolean_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/property_templates/date_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/property_templates/datetime_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/property_templates/enum_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/property_templates/file_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/property_templates/float_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/property_templates/helpers.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/property_templates/int_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/property_templates/list_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/property_templates/model_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/property_templates/property_macros.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/property_templates/union_property.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/pyproject.toml.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/pyproject_ruff.toml.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/setup.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/str_enum.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/templates/types.py.jinja +0 -0
- {openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: openapi-python-client
|
|
3
|
-
Version: 0.21.
|
|
3
|
+
Version: 0.21.5
|
|
4
4
|
Summary: Generate modern Python clients from OpenAPI
|
|
5
5
|
Project-URL: repository, https://github.com/openapi-generators/openapi-python-client
|
|
6
6
|
Author-email: Dylan Anthony <contact@dylananthony.com>
|
|
@@ -155,7 +155,7 @@ class Endpoint:
|
|
|
155
155
|
ParseError(
|
|
156
156
|
detail=(
|
|
157
157
|
f"Invalid response status code {code} (not a valid HTTP "
|
|
158
|
-
f"status code), response will be
|
|
158
|
+
f"status code), response will be omitted from generated "
|
|
159
159
|
f"client"
|
|
160
160
|
)
|
|
161
161
|
)
|
|
@@ -175,7 +175,7 @@ class Endpoint:
|
|
|
175
175
|
ParseError(
|
|
176
176
|
detail=(
|
|
177
177
|
f"Cannot parse response for status code {status_code}{detail_suffix}, "
|
|
178
|
-
f"response will be
|
|
178
|
+
f"response will be omitted from generated client"
|
|
179
179
|
),
|
|
180
180
|
data=response.data,
|
|
181
181
|
)
|
|
@@ -83,7 +83,6 @@ def _string_based_property(
|
|
|
83
83
|
name=name,
|
|
84
84
|
default=data.default,
|
|
85
85
|
required=required,
|
|
86
|
-
pattern=data.pattern,
|
|
87
86
|
python_name=python_name,
|
|
88
87
|
description=data.description,
|
|
89
88
|
example=data.example,
|
|
@@ -281,7 +280,7 @@ def property_from_data( # noqa: PLR0911, PLR0912
|
|
|
281
280
|
AnyProperty.build(
|
|
282
281
|
name=name,
|
|
283
282
|
required=required,
|
|
284
|
-
default=
|
|
283
|
+
default=data.default,
|
|
285
284
|
python_name=utils.PythonIdentifier(value=name, prefix=config.field_prefix),
|
|
286
285
|
description=data.description,
|
|
287
286
|
example=data.example,
|
|
@@ -33,9 +33,13 @@ class AnyProperty(PropertyProtocol):
|
|
|
33
33
|
|
|
34
34
|
@classmethod
|
|
35
35
|
def convert_value(cls, value: Any) -> Value | None:
|
|
36
|
-
|
|
36
|
+
from .string import StringProperty
|
|
37
|
+
|
|
38
|
+
if value is None:
|
|
37
39
|
return value
|
|
38
|
-
|
|
40
|
+
if isinstance(value, str):
|
|
41
|
+
return StringProperty.convert_value(value)
|
|
42
|
+
return Value(python_code=str(value), raw_value=value)
|
|
39
43
|
|
|
40
44
|
name: str
|
|
41
45
|
required: bool
|
|
@@ -59,9 +59,9 @@ class BooleanProperty(PropertyProtocol):
|
|
|
59
59
|
return value
|
|
60
60
|
if isinstance(value, str):
|
|
61
61
|
if value.lower() == "true":
|
|
62
|
-
return Value("True")
|
|
62
|
+
return Value(python_code="True", raw_value=value)
|
|
63
63
|
elif value.lower() == "false":
|
|
64
|
-
return Value("False")
|
|
64
|
+
return Value(python_code="False", raw_value=value)
|
|
65
65
|
if isinstance(value, bool):
|
|
66
|
-
return Value(str(value))
|
|
66
|
+
return Value(python_code=str(value), raw_value=value)
|
|
67
67
|
return PropertyError(f"Invalid boolean value: {value}")
|
|
@@ -63,13 +63,13 @@ class ConstProperty(PropertyProtocol):
|
|
|
63
63
|
return prop
|
|
64
64
|
|
|
65
65
|
def convert_value(self, value: Any) -> Value | None | PropertyError:
|
|
66
|
-
if isinstance(value, Value):
|
|
67
|
-
return value
|
|
68
66
|
value = self._convert_value(value)
|
|
69
67
|
if value is None:
|
|
70
68
|
return value
|
|
71
69
|
if value != self.value:
|
|
72
|
-
return PropertyError(
|
|
70
|
+
return PropertyError(
|
|
71
|
+
detail=f"Invalid value for const {self.name}; {value.raw_value} != {self.value.raw_value}"
|
|
72
|
+
)
|
|
73
73
|
return value
|
|
74
74
|
|
|
75
75
|
@staticmethod
|
|
@@ -85,11 +85,9 @@ class ConstProperty(PropertyProtocol):
|
|
|
85
85
|
def _convert_value(value: Any) -> Value | None:
|
|
86
86
|
if value is None or isinstance(value, Value):
|
|
87
87
|
return value
|
|
88
|
-
if isinstance(value, Value):
|
|
89
|
-
return value # pragma: no cover
|
|
90
88
|
if isinstance(value, str):
|
|
91
89
|
return StringProperty.convert_value(value)
|
|
92
|
-
return Value(str(value))
|
|
90
|
+
return Value(python_code=str(value), raw_value=value)
|
|
93
91
|
|
|
94
92
|
def get_type_string(
|
|
95
93
|
self,
|
|
@@ -99,7 +97,7 @@ class ConstProperty(PropertyProtocol):
|
|
|
99
97
|
multipart: bool = False,
|
|
100
98
|
quoted: bool = False,
|
|
101
99
|
) -> str:
|
|
102
|
-
lit = f"Literal[{self.value}]"
|
|
100
|
+
lit = f"Literal[{self.value.python_code}]"
|
|
103
101
|
if not no_optional and not self.required:
|
|
104
102
|
return f"Union[{lit}, Unset]"
|
|
105
103
|
return lit
|
|
@@ -57,7 +57,7 @@ class DateProperty(PropertyProtocol):
|
|
|
57
57
|
isoparse(value).date() # make sure it's a valid value
|
|
58
58
|
except ValueError as e:
|
|
59
59
|
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)
|
|
61
61
|
return PropertyError(f"Cannot convert {value} to a date")
|
|
62
62
|
|
|
63
63
|
def get_imports(self, *, prefix: str) -> set[str]:
|
|
@@ -59,7 +59,7 @@ class DateTimeProperty(PropertyProtocol):
|
|
|
59
59
|
isoparse(value) # make sure it's a valid value
|
|
60
60
|
except ValueError as e:
|
|
61
61
|
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)
|
|
63
63
|
return PropertyError(f"Cannot convert {value} to a datetime")
|
|
64
64
|
|
|
65
65
|
def get_imports(self, *, prefix: str) -> set[str]:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
__all__ = ["EnumProperty"]
|
|
3
|
+
__all__ = ["EnumProperty", "ValueType"]
|
|
4
4
|
|
|
5
5
|
from typing import Any, ClassVar, List, Union, cast
|
|
6
6
|
|
|
@@ -159,7 +159,7 @@ class EnumProperty(PropertyProtocol):
|
|
|
159
159
|
if isinstance(value, self.value_type):
|
|
160
160
|
inverse_values = {v: k for k, v in self.values.items()}
|
|
161
161
|
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)
|
|
163
163
|
except KeyError:
|
|
164
164
|
return PropertyError(detail=f"Value {value} is not valid for enum {self.name}")
|
|
165
165
|
return PropertyError(detail=f"Cannot convert {value} to enum {self.name} of type {self.value_type}")
|
|
@@ -61,11 +61,11 @@ class FloatProperty(PropertyProtocol):
|
|
|
61
61
|
if isinstance(value, str):
|
|
62
62
|
try:
|
|
63
63
|
parsed = float(value)
|
|
64
|
-
return Value(str(parsed))
|
|
64
|
+
return Value(python_code=str(parsed), raw_value=value)
|
|
65
65
|
except ValueError:
|
|
66
66
|
return PropertyError(f"Invalid float value: {value}")
|
|
67
67
|
if isinstance(value, float):
|
|
68
|
-
return Value(str(value))
|
|
68
|
+
return Value(python_code=str(value), raw_value=value)
|
|
69
69
|
if isinstance(value, int) and not isinstance(value, bool):
|
|
70
|
-
return Value(str(float(value)))
|
|
70
|
+
return Value(python_code=str(float(value)), raw_value=value)
|
|
71
71
|
return PropertyError(f"Cannot convert {value} to a float")
|
|
@@ -58,12 +58,16 @@ class IntProperty(PropertyProtocol):
|
|
|
58
58
|
def convert_value(cls, value: Any) -> Value | None | PropertyError:
|
|
59
59
|
if value is None or isinstance(value, Value):
|
|
60
60
|
return value
|
|
61
|
-
|
|
61
|
+
converted = value
|
|
62
|
+
if isinstance(converted, str):
|
|
62
63
|
try:
|
|
63
|
-
|
|
64
|
+
converted = float(converted)
|
|
64
65
|
except ValueError:
|
|
65
|
-
return PropertyError(f"Invalid int value: {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
return PropertyError(f"Invalid int value: {converted}")
|
|
67
|
+
if isinstance(converted, float):
|
|
68
|
+
as_int = int(converted)
|
|
69
|
+
if converted == as_int:
|
|
70
|
+
converted = as_int
|
|
71
|
+
if isinstance(converted, int) and not isinstance(converted, bool):
|
|
72
|
+
return Value(python_code=str(converted), raw_value=value)
|
|
69
73
|
return PropertyError(f"Invalid int value: {value}")
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from openapi_python_client.parser.properties.date import DateProperty
|
|
4
|
+
from openapi_python_client.parser.properties.datetime import DateTimeProperty
|
|
5
|
+
from openapi_python_client.parser.properties.file import FileProperty
|
|
6
|
+
|
|
7
|
+
__all__ = ["merge_properties"]
|
|
8
|
+
|
|
9
|
+
from typing import TypeVar, cast
|
|
10
|
+
|
|
11
|
+
from attr import evolve
|
|
12
|
+
|
|
13
|
+
from ..errors import PropertyError
|
|
14
|
+
from . import FloatProperty
|
|
15
|
+
from .any import AnyProperty
|
|
16
|
+
from .enum_property import EnumProperty
|
|
17
|
+
from .int import IntProperty
|
|
18
|
+
from .list_property import ListProperty
|
|
19
|
+
from .property import Property
|
|
20
|
+
from .protocol import PropertyProtocol
|
|
21
|
+
from .string import StringProperty
|
|
22
|
+
|
|
23
|
+
PropertyT = TypeVar("PropertyT", bound=PropertyProtocol)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
STRING_WITH_FORMAT_TYPES = (DateProperty, DateTimeProperty, FileProperty)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def merge_properties(prop1: Property, prop2: Property) -> Property | PropertyError: # noqa: PLR0911
|
|
30
|
+
"""Attempt to create a new property that incorporates the behavior of both.
|
|
31
|
+
|
|
32
|
+
This is used when merging schemas with allOf, when two schemas define a property with the same name.
|
|
33
|
+
|
|
34
|
+
OpenAPI defines allOf in terms of validation behavior: the input must pass the validation rules
|
|
35
|
+
defined in all the listed schemas. Our task here is slightly more difficult, since we must end
|
|
36
|
+
up with a single Property object that will be used to generate a single class property in the
|
|
37
|
+
generated code. Due to limitations of our internal model, this may not be possible for some
|
|
38
|
+
combinations of property attributes that OpenAPI supports (for instance, we have no way to represent
|
|
39
|
+
a string property that must match two different regexes).
|
|
40
|
+
|
|
41
|
+
Properties can also have attributes that do not represent validation rules, such as "description"
|
|
42
|
+
and "example". OpenAPI does not define any overriding/aggregation rules for these in allOf. The
|
|
43
|
+
implementation here is, assuming prop1 and prop2 are in the same order that the schemas were in the
|
|
44
|
+
allOf, any such attributes that prop2 specifies will override the ones from prop1.
|
|
45
|
+
"""
|
|
46
|
+
if isinstance(prop2, AnyProperty):
|
|
47
|
+
return _merge_common_attributes(prop1, prop2)
|
|
48
|
+
|
|
49
|
+
if isinstance(prop1, AnyProperty):
|
|
50
|
+
# Use the base type of `prop2`, but keep the override order
|
|
51
|
+
return _merge_common_attributes(prop2, prop1, prop2)
|
|
52
|
+
|
|
53
|
+
if isinstance(prop1, EnumProperty) or isinstance(prop2, EnumProperty):
|
|
54
|
+
return _merge_with_enum(prop1, prop2)
|
|
55
|
+
|
|
56
|
+
if (merged := _merge_same_type(prop1, prop2)) is not None:
|
|
57
|
+
return merged
|
|
58
|
+
|
|
59
|
+
if (merged := _merge_numeric(prop1, prop2)) is not None:
|
|
60
|
+
return merged
|
|
61
|
+
|
|
62
|
+
if (merged := _merge_string_with_format(prop1, prop2)) is not None:
|
|
63
|
+
return merged
|
|
64
|
+
|
|
65
|
+
return PropertyError(
|
|
66
|
+
detail=f"{prop1.get_type_string(no_optional=True)} can't be merged with {prop2.get_type_string(no_optional=True)}"
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _merge_same_type(prop1: Property, prop2: Property) -> Property | None | PropertyError:
|
|
71
|
+
if type(prop1) is not type(prop2):
|
|
72
|
+
return None
|
|
73
|
+
|
|
74
|
+
if prop1 == prop2:
|
|
75
|
+
# It's always OK to redefine a property with everything exactly the same
|
|
76
|
+
return prop1
|
|
77
|
+
|
|
78
|
+
if isinstance(prop1, ListProperty) and isinstance(prop2, ListProperty):
|
|
79
|
+
inner_property = merge_properties(prop1.inner_property, prop2.inner_property) # type: ignore
|
|
80
|
+
if isinstance(inner_property, PropertyError):
|
|
81
|
+
return PropertyError(detail=f"can't merge list properties: {inner_property.detail}")
|
|
82
|
+
prop1.inner_property = inner_property
|
|
83
|
+
|
|
84
|
+
# For all other property types, there aren't any special attributes that affect validation, so just
|
|
85
|
+
# apply the rules for common attributes like "description".
|
|
86
|
+
return _merge_common_attributes(prop1, prop2)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _merge_string_with_format(prop1: Property, prop2: Property) -> Property | None | PropertyError:
|
|
90
|
+
"""Merge a string that has no format with a string that has a format"""
|
|
91
|
+
# Here we need to use the DateProperty/DateTimeProperty/FileProperty as the base so that we preserve
|
|
92
|
+
# its class, but keep the correct override order for merging the attributes.
|
|
93
|
+
if isinstance(prop1, StringProperty) and isinstance(prop2, STRING_WITH_FORMAT_TYPES):
|
|
94
|
+
# Use the more specific class as a base, but keep the correct override order
|
|
95
|
+
return _merge_common_attributes(prop2, prop1, prop2)
|
|
96
|
+
elif isinstance(prop2, StringProperty) and isinstance(prop1, STRING_WITH_FORMAT_TYPES):
|
|
97
|
+
return _merge_common_attributes(prop1, prop2)
|
|
98
|
+
else:
|
|
99
|
+
return None
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _merge_numeric(prop1: Property, prop2: Property) -> IntProperty | None | PropertyError:
|
|
103
|
+
"""Merge IntProperty with FloatProperty"""
|
|
104
|
+
if isinstance(prop1, IntProperty) and isinstance(prop2, (IntProperty, FloatProperty)):
|
|
105
|
+
return _merge_common_attributes(prop1, prop2)
|
|
106
|
+
elif isinstance(prop2, IntProperty) and isinstance(prop1, (IntProperty, FloatProperty)):
|
|
107
|
+
# Use the IntProperty as a base since it's more restrictive, but keep the correct override order
|
|
108
|
+
return _merge_common_attributes(prop2, prop1, prop2)
|
|
109
|
+
else:
|
|
110
|
+
return None
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _merge_with_enum(prop1: PropertyProtocol, prop2: PropertyProtocol) -> EnumProperty | PropertyError:
|
|
114
|
+
if isinstance(prop1, EnumProperty) and isinstance(prop2, EnumProperty):
|
|
115
|
+
# We want the narrowest validation rules that fit both, so use whichever values list is a
|
|
116
|
+
# subset of the other.
|
|
117
|
+
if _values_are_subset(prop1, prop2):
|
|
118
|
+
values = prop1.values
|
|
119
|
+
class_info = prop1.class_info
|
|
120
|
+
elif _values_are_subset(prop2, prop1):
|
|
121
|
+
values = prop2.values
|
|
122
|
+
class_info = prop2.class_info
|
|
123
|
+
else:
|
|
124
|
+
return PropertyError(detail="can't redefine an enum property with incompatible lists of values")
|
|
125
|
+
return _merge_common_attributes(evolve(prop1, values=values, class_info=class_info), prop2)
|
|
126
|
+
|
|
127
|
+
# If enum values were specified for just one of the properties, use those.
|
|
128
|
+
enum_prop = prop1 if isinstance(prop1, EnumProperty) else cast(EnumProperty, prop2)
|
|
129
|
+
non_enum_prop = prop2 if isinstance(prop1, EnumProperty) else prop1
|
|
130
|
+
if (isinstance(non_enum_prop, IntProperty) and enum_prop.value_type is int) or (
|
|
131
|
+
isinstance(non_enum_prop, StringProperty) and enum_prop.value_type is str
|
|
132
|
+
):
|
|
133
|
+
return _merge_common_attributes(enum_prop, prop1, prop2)
|
|
134
|
+
return PropertyError(
|
|
135
|
+
detail=f"can't combine enum of type {enum_prop.value_type} with {non_enum_prop.get_type_string(no_optional=True)}"
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def _merge_common_attributes(base: PropertyT, *extend_with: PropertyProtocol) -> PropertyT | PropertyError:
|
|
140
|
+
"""Create a new instance based on base, overriding basic attributes with values from extend_with, in order.
|
|
141
|
+
|
|
142
|
+
For "default", "description", and "example", a non-None value overrides any value from a previously
|
|
143
|
+
specified property. The behavior is similar to using the spread operator with dictionaries, except
|
|
144
|
+
that None means "not specified".
|
|
145
|
+
|
|
146
|
+
For "required", any True value overrides all other values (a property that was previously required
|
|
147
|
+
cannot become optional).
|
|
148
|
+
"""
|
|
149
|
+
current = base
|
|
150
|
+
for override in extend_with:
|
|
151
|
+
if override.default is not None:
|
|
152
|
+
override_default = current.convert_value(override.default.raw_value)
|
|
153
|
+
else:
|
|
154
|
+
override_default = None
|
|
155
|
+
if isinstance(override_default, PropertyError):
|
|
156
|
+
return override_default
|
|
157
|
+
current = evolve(
|
|
158
|
+
current, # type: ignore # can't prove that every property type is an attrs class, but it is
|
|
159
|
+
required=current.required or override.required,
|
|
160
|
+
default=override_default or current.default,
|
|
161
|
+
description=override.description or current.description,
|
|
162
|
+
example=override.example or current.example,
|
|
163
|
+
)
|
|
164
|
+
return current
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _values_are_subset(prop1: EnumProperty, prop2: EnumProperty) -> bool:
|
|
168
|
+
return set(prop1.values.items()) <= set(prop2.values.items())
|
|
@@ -10,7 +10,6 @@ from ... import schema as oai
|
|
|
10
10
|
from ...utils import PythonIdentifier
|
|
11
11
|
from ..errors import ParseError, PropertyError
|
|
12
12
|
from .any import AnyProperty
|
|
13
|
-
from .enum_property import EnumProperty
|
|
14
13
|
from .protocol import PropertyProtocol, Value
|
|
15
14
|
from .schemas import Class, ReferencePath, Schemas, parse_reference_path
|
|
16
15
|
|
|
@@ -220,59 +219,6 @@ class ModelProperty(PropertyProtocol):
|
|
|
220
219
|
from .property import Property # noqa: E402
|
|
221
220
|
|
|
222
221
|
|
|
223
|
-
def _values_are_subset(first: EnumProperty, second: EnumProperty) -> bool:
|
|
224
|
-
return set(first.values.items()) <= set(second.values.items())
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
def _types_are_subset(first: EnumProperty, second: Property) -> bool:
|
|
228
|
-
from . import IntProperty, StringProperty
|
|
229
|
-
|
|
230
|
-
if first.value_type is int and isinstance(second, IntProperty):
|
|
231
|
-
return True
|
|
232
|
-
if first.value_type is str and isinstance(second, StringProperty):
|
|
233
|
-
return True
|
|
234
|
-
return False
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
def _enum_subset(first: Property, second: Property) -> EnumProperty | None:
|
|
238
|
-
"""Return the EnumProperty that is the subset of the other, if possible."""
|
|
239
|
-
|
|
240
|
-
if isinstance(first, EnumProperty):
|
|
241
|
-
if isinstance(second, EnumProperty):
|
|
242
|
-
if _values_are_subset(first, second):
|
|
243
|
-
return first
|
|
244
|
-
if _values_are_subset(second, first):
|
|
245
|
-
return second
|
|
246
|
-
return None
|
|
247
|
-
return first if _types_are_subset(first, second) else None
|
|
248
|
-
|
|
249
|
-
if isinstance(second, EnumProperty) and _types_are_subset(second, first):
|
|
250
|
-
return second
|
|
251
|
-
return None
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
def _merge_properties(first: Property, second: Property) -> Property | PropertyError:
|
|
255
|
-
required = first.required or second.required
|
|
256
|
-
|
|
257
|
-
err = None
|
|
258
|
-
|
|
259
|
-
if first.__class__ == second.__class__:
|
|
260
|
-
first = evolve(first, required=required)
|
|
261
|
-
second = evolve(second, required=required)
|
|
262
|
-
if first == second:
|
|
263
|
-
return first
|
|
264
|
-
err = PropertyError(header="Cannot merge properties", detail="Properties has conflicting values")
|
|
265
|
-
|
|
266
|
-
enum_subset = _enum_subset(first, second)
|
|
267
|
-
if enum_subset is not None:
|
|
268
|
-
return evolve(enum_subset, required=required)
|
|
269
|
-
|
|
270
|
-
return err or PropertyError(
|
|
271
|
-
header="Cannot merge properties",
|
|
272
|
-
detail=f"{first.__class__}, {second.__class__}Properties have incompatible types",
|
|
273
|
-
)
|
|
274
|
-
|
|
275
|
-
|
|
276
222
|
def _resolve_naming_conflict(first: Property, second: Property, config: Config) -> PropertyError | None:
|
|
277
223
|
first.set_python_name(first.name, config=config, skip_snake_case=True)
|
|
278
224
|
second.set_python_name(second.name, config=config, skip_snake_case=True)
|
|
@@ -301,6 +247,7 @@ def _process_properties( # noqa: PLR0912, PLR0911
|
|
|
301
247
|
roots: set[ReferencePath | utils.ClassName],
|
|
302
248
|
) -> _PropertyData | PropertyError:
|
|
303
249
|
from . import property_from_data
|
|
250
|
+
from .merge_properties import merge_properties
|
|
304
251
|
|
|
305
252
|
properties: dict[str, Property] = {}
|
|
306
253
|
relative_imports: set[str] = set()
|
|
@@ -311,26 +258,26 @@ def _process_properties( # noqa: PLR0912, PLR0911
|
|
|
311
258
|
nonlocal properties
|
|
312
259
|
|
|
313
260
|
name_conflict = properties.get(new_prop.name)
|
|
314
|
-
|
|
315
|
-
if isinstance(
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
)
|
|
319
|
-
return merged_prop_or_error
|
|
261
|
+
merged_prop = merge_properties(name_conflict, new_prop) if name_conflict else new_prop
|
|
262
|
+
if isinstance(merged_prop, PropertyError):
|
|
263
|
+
merged_prop.header = f"Found conflicting properties named {new_prop.name} when creating {class_name}"
|
|
264
|
+
return merged_prop
|
|
320
265
|
|
|
321
266
|
for other_prop in properties.values():
|
|
322
|
-
if other_prop.name ==
|
|
267
|
+
if other_prop.name == merged_prop.name:
|
|
323
268
|
continue # Same property, probably just got merged
|
|
324
|
-
if other_prop.python_name !=
|
|
269
|
+
if other_prop.python_name != merged_prop.python_name:
|
|
325
270
|
continue
|
|
326
|
-
naming_error = _resolve_naming_conflict(
|
|
271
|
+
naming_error = _resolve_naming_conflict(merged_prop, other_prop, config)
|
|
327
272
|
if naming_error is not None:
|
|
328
273
|
return naming_error
|
|
329
274
|
|
|
330
|
-
properties[
|
|
275
|
+
properties[merged_prop.name] = merged_prop
|
|
331
276
|
return None
|
|
332
277
|
|
|
333
|
-
unprocessed_props
|
|
278
|
+
unprocessed_props: list[tuple[str, oai.Reference | oai.Schema]] = (
|
|
279
|
+
list(data.properties.items()) if data.properties else []
|
|
280
|
+
)
|
|
334
281
|
for sub_prop in data.allOf:
|
|
335
282
|
if isinstance(sub_prop, oai.Reference):
|
|
336
283
|
ref_path = parse_reference_path(sub_prop.ref)
|
|
@@ -352,10 +299,10 @@ def _process_properties( # noqa: PLR0912, PLR0911
|
|
|
352
299
|
return err
|
|
353
300
|
schemas.add_dependencies(ref_path=ref_path, roots=roots)
|
|
354
301
|
else:
|
|
355
|
-
unprocessed_props.
|
|
302
|
+
unprocessed_props.extend(sub_prop.properties.items() if sub_prop.properties else [])
|
|
356
303
|
required_set.update(sub_prop.required or [])
|
|
357
304
|
|
|
358
|
-
for key, value in unprocessed_props
|
|
305
|
+
for key, value in unprocessed_props:
|
|
359
306
|
prop_required = key in required_set
|
|
360
307
|
prop_or_error: Property | (PropertyError | None)
|
|
361
308
|
prop_or_error, schemas = property_from_data(
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
__all__ = ["PropertyProtocol", "Value"]
|
|
4
4
|
|
|
5
5
|
from abc import abstractmethod
|
|
6
|
+
from dataclasses import dataclass
|
|
6
7
|
from typing import TYPE_CHECKING, Any, ClassVar, Protocol, TypeVar
|
|
7
8
|
|
|
8
9
|
from ... import Config
|
|
@@ -16,8 +17,15 @@ else:
|
|
|
16
17
|
ModelProperty = "ModelProperty"
|
|
17
18
|
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
@dataclass
|
|
21
|
+
class Value:
|
|
22
|
+
"""
|
|
23
|
+
Some literal values in OpenAPI documents (like defaults) have to be converted into Python code safely
|
|
24
|
+
(with string escaping, for example). We still keep the `raw_value` around for merging `allOf`.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
python_code: str
|
|
28
|
+
raw_value: Any
|
|
21
29
|
|
|
22
30
|
|
|
23
31
|
PropertyType = TypeVar("PropertyType", bound="PropertyProtocol")
|
|
@@ -148,7 +156,7 @@ class PropertyProtocol(Protocol):
|
|
|
148
156
|
"""How this should be declared in a dataclass"""
|
|
149
157
|
default: str | None
|
|
150
158
|
if self.default is not None:
|
|
151
|
-
default = self.default
|
|
159
|
+
default = self.default.python_code
|
|
152
160
|
elif not self.required:
|
|
153
161
|
default = "UNSET"
|
|
154
162
|
else:
|
|
@@ -162,7 +170,7 @@ class PropertyProtocol(Protocol):
|
|
|
162
170
|
"""Returns property docstring"""
|
|
163
171
|
doc = f"{self.python_name} ({self.get_type_string()}): {self.description or ''}"
|
|
164
172
|
if self.default:
|
|
165
|
-
doc += f" Default: {self.default}."
|
|
173
|
+
doc += f" Default: {self.default.python_code}."
|
|
166
174
|
if self.example:
|
|
167
175
|
doc += f" Example: {self.example}."
|
|
168
176
|
return doc
|
|
@@ -21,8 +21,6 @@ class StringProperty(PropertyProtocol):
|
|
|
21
21
|
python_name: PythonIdentifier
|
|
22
22
|
description: str | None
|
|
23
23
|
example: str | None
|
|
24
|
-
max_length: int | None = None
|
|
25
|
-
pattern: str | None = None
|
|
26
24
|
_type_string: ClassVar[str] = "str"
|
|
27
25
|
_json_type_string: ClassVar[str] = "str"
|
|
28
26
|
_allowed_locations: ClassVar[set[oai.ParameterLocation]] = {
|
|
@@ -41,7 +39,6 @@ class StringProperty(PropertyProtocol):
|
|
|
41
39
|
python_name: PythonIdentifier,
|
|
42
40
|
description: str | None,
|
|
43
41
|
example: str | None,
|
|
44
|
-
pattern: str | None = None,
|
|
45
42
|
) -> StringProperty | PropertyError:
|
|
46
43
|
checked_default = cls.convert_value(default)
|
|
47
44
|
return cls(
|
|
@@ -51,7 +48,6 @@ class StringProperty(PropertyProtocol):
|
|
|
51
48
|
python_name=python_name,
|
|
52
49
|
description=description,
|
|
53
50
|
example=example,
|
|
54
|
-
pattern=pattern,
|
|
55
51
|
)
|
|
56
52
|
|
|
57
53
|
@classmethod
|
|
@@ -69,4 +65,4 @@ class StringProperty(PropertyProtocol):
|
|
|
69
65
|
return value
|
|
70
66
|
if not isinstance(value, str):
|
|
71
67
|
value = str(value)
|
|
72
|
-
return Value(repr(utils.remove_string_escapes(value)))
|
|
68
|
+
return Value(python_code=repr(utils.remove_string_escapes(value)), raw_value=value)
|
|
@@ -138,6 +138,7 @@ return field_dict
|
|
|
138
138
|
{% for lazy_import in model.lazy_imports %}
|
|
139
139
|
{{ lazy_import }}
|
|
140
140
|
{% endfor %}
|
|
141
|
+
{% if (model.required_properties or model.optional_properties or model.additional_properties) %}
|
|
141
142
|
d = src_dict.copy()
|
|
142
143
|
{% for property in model.required_properties + model.optional_properties %}
|
|
143
144
|
{% if property.required %}
|
|
@@ -153,6 +154,7 @@ return field_dict
|
|
|
153
154
|
{% endif %}
|
|
154
155
|
|
|
155
156
|
{% endfor %}
|
|
157
|
+
{% endif %}
|
|
156
158
|
{{ module_name }} = cls(
|
|
157
159
|
{% for property in model.required_properties + model.optional_properties %}
|
|
158
160
|
{{ property.python_name }}={{ property.python_name }},
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{% macro construct(property, source) %}
|
|
2
|
+
{{ property.python_name }} = cast({{ property.get_type_string() }} , {{ source }})
|
|
3
|
+
if {{ property.python_name }} != {{ property.value.python_code }}{% if not property.required %}and not isinstance({{ property.python_name }}, Unset){% endif %}:
|
|
4
|
+
raise ValueError(f"{{ property.name }} must match const {{ property.value.python_code }}, got '{{'{' + property.python_name + '}' }}'")
|
|
5
|
+
{%- endmacro %}
|
|
@@ -18,7 +18,7 @@ dependencies = [
|
|
|
18
18
|
"typing-extensions>=4.8.0,<5.0.0",
|
|
19
19
|
]
|
|
20
20
|
name = "openapi-python-client"
|
|
21
|
-
version = "0.21.
|
|
21
|
+
version = "0.21.5"
|
|
22
22
|
description = "Generate modern Python clients from OpenAPI"
|
|
23
23
|
keywords = [
|
|
24
24
|
"OpenAPI",
|
|
@@ -66,7 +66,7 @@ ignore = ["E501", "PLR0913"]
|
|
|
66
66
|
"tests/*" = ["PLR2004"]
|
|
67
67
|
|
|
68
68
|
[tool.coverage.run]
|
|
69
|
-
omit = ["openapi_python_client/templates/*"]
|
|
69
|
+
omit = ["openapi_python_client/__main__.py", "openapi_python_client/templates/*"]
|
|
70
70
|
|
|
71
71
|
[tool.mypy]
|
|
72
72
|
plugins = ["pydantic.mypy"]
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
{% macro construct(property, source) %}
|
|
2
|
-
{{ property.python_name }} = cast({{ property.get_type_string() }} , {{ source }})
|
|
3
|
-
if {{ property.python_name }} != {{ property.value }}{% if not property.required %}and not isinstance({{ property.python_name }}, Unset){% endif %}:
|
|
4
|
-
raise ValueError(f"{{ property.name }} must match const {{ property.value }}, got '{{'{' + property.python_name + '}' }}'")
|
|
5
|
-
{%- endmacro %}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/__init__.py
RENAMED
|
File without changes
|
{openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/__main__.py
RENAMED
|
File without changes
|
|
File without changes
|
{openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/config.py
RENAMED
|
File without changes
|
|
File without changes
|
{openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/bodies.py
RENAMED
|
File without changes
|
{openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/parser/errors.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/py.typed
RENAMED
|
File without changes
|
{openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/3.0.3.md
RENAMED
|
File without changes
|
{openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/schema/3.1.0.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openapi_python_client-0.21.4 → openapi_python_client-0.21.5}/openapi_python_client/utils.py
RENAMED
|
File without changes
|