diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py index 574d5018b..fde6cb49b 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py @@ -40,28 +40,28 @@ def _build_response(*, response: httpx.Response) -> Response[Union[None, HTTPVal def httpx_request( *, client: Client, - string_prop: Union[Unset, str] = "the default string", - datetime_prop: Union[Unset, datetime.datetime] = isoparse("1010-10-10T00:00:00"), - date_prop: Union[Unset, datetime.date] = isoparse("1010-10-10").date(), - float_prop: Union[Unset, float] = 3.14, - int_prop: Union[Unset, int] = 7, - boolean_prop: Union[Unset, bool] = False, - list_prop: Union[Unset, List[AnEnum]] = UNSET, - union_prop: Union[Unset, float, str] = "not a float", - union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, - enum_prop: Union[Unset, AnEnum] = UNSET, + string_prop: Union[Unset, None, str] = "the default string", + datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + date_prop: Union[Unset, None, datetime.date] = isoparse("1010-10-10").date(), + float_prop: Union[Unset, None, float] = 3.14, + int_prop: Union[Unset, None, int] = 7, + boolean_prop: Union[Unset, None, bool] = False, + list_prop: Union[Unset, None, List[AnEnum]] = None, + union_prop: Union[Unset, None, float, str] = "not a float", + union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, + enum_prop: Union[Unset, None, AnEnum] = None, ) -> Response[Union[None, HTTPValidationError]]: json_datetime_prop: Union[Unset, str] = UNSET - if not isinstance(datetime_prop, Unset): + if not isinstance(datetime_prop, Unset) and datetime_prop is not None: json_datetime_prop = datetime_prop.isoformat() json_date_prop: Union[Unset, str] = UNSET - if not isinstance(date_prop, Unset): + if not isinstance(date_prop, Unset) and date_prop is not None: json_date_prop = date_prop.isoformat() json_list_prop: Union[Unset, List[Any]] = UNSET - if not isinstance(list_prop, Unset): + if not isinstance(list_prop, Unset) and list_prop is not None: json_list_prop = [] for list_prop_item_data in list_prop: list_prop_item = list_prop_item_data.value @@ -69,13 +69,13 @@ def httpx_request( json_list_prop.append(list_prop_item) json_union_prop: Union[Unset, float, str] - if isinstance(union_prop, Unset): + if isinstance(union_prop, Unset) or union_prop is None: json_union_prop = UNSET else: json_union_prop = union_prop json_union_prop_with_ref: Union[Unset, float, AnEnum] - if isinstance(union_prop_with_ref, Unset): + if isinstance(union_prop_with_ref, Unset) or union_prop_with_ref is None: json_union_prop_with_ref = UNSET elif isinstance(union_prop_with_ref, AnEnum): json_union_prop_with_ref = UNSET @@ -86,29 +86,29 @@ def httpx_request( json_union_prop_with_ref = union_prop_with_ref json_enum_prop: Union[Unset, AnEnum] = UNSET - if not isinstance(enum_prop, Unset): + if not isinstance(enum_prop, Unset) and enum_prop is not None: json_enum_prop = enum_prop params: Dict[str, Any] = {} - if string_prop is not UNSET: + if string_prop is not UNSET and string_prop is not None: params["string_prop"] = string_prop - if datetime_prop is not UNSET: + if datetime_prop is not UNSET and datetime_prop is not None: params["datetime_prop"] = json_datetime_prop - if date_prop is not UNSET: + if date_prop is not UNSET and date_prop is not None: params["date_prop"] = json_date_prop - if float_prop is not UNSET: + if float_prop is not UNSET and float_prop is not None: params["float_prop"] = float_prop - if int_prop is not UNSET: + if int_prop is not UNSET and int_prop is not None: params["int_prop"] = int_prop - if boolean_prop is not UNSET: + if boolean_prop is not UNSET and boolean_prop is not None: params["boolean_prop"] = boolean_prop - if list_prop is not UNSET: + if list_prop is not UNSET and list_prop is not None: params["list_prop"] = json_list_prop - if union_prop is not UNSET: + if union_prop is not UNSET and union_prop is not None: params["union_prop"] = json_union_prop - if union_prop_with_ref is not UNSET: + if union_prop_with_ref is not UNSET and union_prop_with_ref is not None: params["union_prop_with_ref"] = json_union_prop_with_ref - if enum_prop is not UNSET: + if enum_prop is not UNSET and enum_prop is not None: params["enum_prop"] = json_enum_prop response = client.request( diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py index bff43cc10..7b821fca6 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py @@ -36,15 +36,15 @@ def _build_response(*, response: httpx.Response) -> Response[Union[None, HTTPVal def httpx_request( *, client: Client, - query_param: Union[Unset, List[str]] = UNSET, + query_param: Union[Unset, None, List[str]] = None, ) -> Response[Union[None, HTTPValidationError]]: json_query_param: Union[Unset, List[Any]] = UNSET - if not isinstance(query_param, Unset): + if not isinstance(query_param, Unset) and query_param is not None: json_query_param = query_param params: Dict[str, Any] = {} - if query_param is not UNSET: + if query_param is not UNSET and query_param is not None: params["query_param"] = json_query_param response = client.request( diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py index 47d65d90b..feb30878d 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/models/model_with_primitive_additional_properties.py @@ -12,7 +12,7 @@ class ModelWithPrimitiveAdditionalProperties: """ """ - a_date_holder: Union[ModelWithPrimitiveAdditionalPropertiesADateHolder, Unset] = UNSET + a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET additional_properties: Dict[str, str] = attr.ib(init=False, factory=dict) def to_dict(self) -> Dict[str, Any]: @@ -31,7 +31,7 @@ def to_dict(self) -> Dict[str, Any]: @staticmethod def from_dict(src_dict: Dict[str, Any]) -> "ModelWithPrimitiveAdditionalProperties": d = src_dict.copy() - a_date_holder: Union[ModelWithPrimitiveAdditionalPropertiesADateHolder, Unset] = UNSET + a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET _a_date_holder = d.pop("a_date_holder", UNSET) if _a_date_holder is not None and not isinstance(_a_date_holder, Unset): a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict( diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py index 9242cddaa..77ee6cce1 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py @@ -13,31 +13,31 @@ def _get_kwargs( *, client: Client, - string_prop: Union[Unset, str] = "the default string", - datetime_prop: Union[Unset, datetime.datetime] = isoparse("1010-10-10T00:00:00"), - date_prop: Union[Unset, datetime.date] = isoparse("1010-10-10").date(), - float_prop: Union[Unset, float] = 3.14, - int_prop: Union[Unset, int] = 7, - boolean_prop: Union[Unset, bool] = False, - list_prop: Union[Unset, List[AnEnum]] = UNSET, - union_prop: Union[Unset, float, str] = "not a float", - union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, - enum_prop: Union[Unset, AnEnum] = UNSET, + string_prop: Union[Unset, None, str] = "the default string", + datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + date_prop: Union[Unset, None, datetime.date] = isoparse("1010-10-10").date(), + float_prop: Union[Unset, None, float] = 3.14, + int_prop: Union[Unset, None, int] = 7, + boolean_prop: Union[Unset, None, bool] = False, + list_prop: Union[Unset, None, List[AnEnum]] = None, + union_prop: Union[Unset, None, float, str] = "not a float", + union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, + enum_prop: Union[Unset, None, AnEnum] = None, ) -> Dict[str, Any]: url = "{}/tests/defaults".format(client.base_url) headers: Dict[str, Any] = client.get_headers() json_datetime_prop: Union[Unset, str] = UNSET - if not isinstance(datetime_prop, Unset): + if not isinstance(datetime_prop, Unset) and datetime_prop is not None: json_datetime_prop = datetime_prop.isoformat() json_date_prop: Union[Unset, str] = UNSET - if not isinstance(date_prop, Unset): + if not isinstance(date_prop, Unset) and date_prop is not None: json_date_prop = date_prop.isoformat() json_list_prop: Union[Unset, List[Any]] = UNSET - if not isinstance(list_prop, Unset): + if not isinstance(list_prop, Unset) and list_prop is not None: json_list_prop = [] for list_prop_item_data in list_prop: list_prop_item = list_prop_item_data.value @@ -45,13 +45,13 @@ def _get_kwargs( json_list_prop.append(list_prop_item) json_union_prop: Union[Unset, float, str] - if isinstance(union_prop, Unset): + if isinstance(union_prop, Unset) or union_prop is None: json_union_prop = UNSET else: json_union_prop = union_prop json_union_prop_with_ref: Union[Unset, float, AnEnum] - if isinstance(union_prop_with_ref, Unset): + if isinstance(union_prop_with_ref, Unset) or union_prop_with_ref is None: json_union_prop_with_ref = UNSET elif isinstance(union_prop_with_ref, AnEnum): json_union_prop_with_ref = UNSET @@ -62,29 +62,29 @@ def _get_kwargs( json_union_prop_with_ref = union_prop_with_ref json_enum_prop: Union[Unset, AnEnum] = UNSET - if not isinstance(enum_prop, Unset): + if not isinstance(enum_prop, Unset) and enum_prop is not None: json_enum_prop = enum_prop params: Dict[str, Any] = {} - if string_prop is not UNSET: + if string_prop is not UNSET and string_prop is not None: params["string_prop"] = string_prop - if datetime_prop is not UNSET: + if datetime_prop is not UNSET and datetime_prop is not None: params["datetime_prop"] = json_datetime_prop - if date_prop is not UNSET: + if date_prop is not UNSET and date_prop is not None: params["date_prop"] = json_date_prop - if float_prop is not UNSET: + if float_prop is not UNSET and float_prop is not None: params["float_prop"] = float_prop - if int_prop is not UNSET: + if int_prop is not UNSET and int_prop is not None: params["int_prop"] = int_prop - if boolean_prop is not UNSET: + if boolean_prop is not UNSET and boolean_prop is not None: params["boolean_prop"] = boolean_prop - if list_prop is not UNSET: + if list_prop is not UNSET and list_prop is not None: params["list_prop"] = json_list_prop - if union_prop is not UNSET: + if union_prop is not UNSET and union_prop is not None: params["union_prop"] = json_union_prop - if union_prop_with_ref is not UNSET: + if union_prop_with_ref is not UNSET and union_prop_with_ref is not None: params["union_prop_with_ref"] = json_union_prop_with_ref - if enum_prop is not UNSET: + if enum_prop is not UNSET and enum_prop is not None: params["enum_prop"] = json_enum_prop return { @@ -120,16 +120,16 @@ def _build_response(*, response: httpx.Response) -> Response[Union[None, HTTPVal def sync_detailed( *, client: Client, - string_prop: Union[Unset, str] = "the default string", - datetime_prop: Union[Unset, datetime.datetime] = isoparse("1010-10-10T00:00:00"), - date_prop: Union[Unset, datetime.date] = isoparse("1010-10-10").date(), - float_prop: Union[Unset, float] = 3.14, - int_prop: Union[Unset, int] = 7, - boolean_prop: Union[Unset, bool] = False, - list_prop: Union[Unset, List[AnEnum]] = UNSET, - union_prop: Union[Unset, float, str] = "not a float", - union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, - enum_prop: Union[Unset, AnEnum] = UNSET, + string_prop: Union[Unset, None, str] = "the default string", + datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + date_prop: Union[Unset, None, datetime.date] = isoparse("1010-10-10").date(), + float_prop: Union[Unset, None, float] = 3.14, + int_prop: Union[Unset, None, int] = 7, + boolean_prop: Union[Unset, None, bool] = False, + list_prop: Union[Unset, None, List[AnEnum]] = None, + union_prop: Union[Unset, None, float, str] = "not a float", + union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, + enum_prop: Union[Unset, None, AnEnum] = None, ) -> Response[Union[None, HTTPValidationError]]: kwargs = _get_kwargs( client=client, @@ -155,16 +155,16 @@ def sync_detailed( def sync( *, client: Client, - string_prop: Union[Unset, str] = "the default string", - datetime_prop: Union[Unset, datetime.datetime] = isoparse("1010-10-10T00:00:00"), - date_prop: Union[Unset, datetime.date] = isoparse("1010-10-10").date(), - float_prop: Union[Unset, float] = 3.14, - int_prop: Union[Unset, int] = 7, - boolean_prop: Union[Unset, bool] = False, - list_prop: Union[Unset, List[AnEnum]] = UNSET, - union_prop: Union[Unset, float, str] = "not a float", - union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, - enum_prop: Union[Unset, AnEnum] = UNSET, + string_prop: Union[Unset, None, str] = "the default string", + datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + date_prop: Union[Unset, None, datetime.date] = isoparse("1010-10-10").date(), + float_prop: Union[Unset, None, float] = 3.14, + int_prop: Union[Unset, None, int] = 7, + boolean_prop: Union[Unset, None, bool] = False, + list_prop: Union[Unset, None, List[AnEnum]] = None, + union_prop: Union[Unset, None, float, str] = "not a float", + union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, + enum_prop: Union[Unset, None, AnEnum] = None, ) -> Optional[Union[None, HTTPValidationError]]: """ """ @@ -186,16 +186,16 @@ def sync( async def asyncio_detailed( *, client: Client, - string_prop: Union[Unset, str] = "the default string", - datetime_prop: Union[Unset, datetime.datetime] = isoparse("1010-10-10T00:00:00"), - date_prop: Union[Unset, datetime.date] = isoparse("1010-10-10").date(), - float_prop: Union[Unset, float] = 3.14, - int_prop: Union[Unset, int] = 7, - boolean_prop: Union[Unset, bool] = False, - list_prop: Union[Unset, List[AnEnum]] = UNSET, - union_prop: Union[Unset, float, str] = "not a float", - union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, - enum_prop: Union[Unset, AnEnum] = UNSET, + string_prop: Union[Unset, None, str] = "the default string", + datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + date_prop: Union[Unset, None, datetime.date] = isoparse("1010-10-10").date(), + float_prop: Union[Unset, None, float] = 3.14, + int_prop: Union[Unset, None, int] = 7, + boolean_prop: Union[Unset, None, bool] = False, + list_prop: Union[Unset, None, List[AnEnum]] = None, + union_prop: Union[Unset, None, float, str] = "not a float", + union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, + enum_prop: Union[Unset, None, AnEnum] = None, ) -> Response[Union[None, HTTPValidationError]]: kwargs = _get_kwargs( client=client, @@ -220,16 +220,16 @@ async def asyncio_detailed( async def asyncio( *, client: Client, - string_prop: Union[Unset, str] = "the default string", - datetime_prop: Union[Unset, datetime.datetime] = isoparse("1010-10-10T00:00:00"), - date_prop: Union[Unset, datetime.date] = isoparse("1010-10-10").date(), - float_prop: Union[Unset, float] = 3.14, - int_prop: Union[Unset, int] = 7, - boolean_prop: Union[Unset, bool] = False, - list_prop: Union[Unset, List[AnEnum]] = UNSET, - union_prop: Union[Unset, float, str] = "not a float", - union_prop_with_ref: Union[Unset, float, AnEnum] = 0.6, - enum_prop: Union[Unset, AnEnum] = UNSET, + string_prop: Union[Unset, None, str] = "the default string", + datetime_prop: Union[Unset, None, datetime.datetime] = isoparse("1010-10-10T00:00:00"), + date_prop: Union[Unset, None, datetime.date] = isoparse("1010-10-10").date(), + float_prop: Union[Unset, None, float] = 3.14, + int_prop: Union[Unset, None, int] = 7, + boolean_prop: Union[Unset, None, bool] = False, + list_prop: Union[Unset, None, List[AnEnum]] = None, + union_prop: Union[Unset, None, float, str] = "not a float", + union_prop_with_ref: Union[Unset, None, float, AnEnum] = 0.6, + enum_prop: Union[Unset, None, AnEnum] = None, ) -> Optional[Union[None, HTTPValidationError]]: """ """ diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py index 751f48e03..8058acb43 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py @@ -10,18 +10,18 @@ def _get_kwargs( *, client: Client, - query_param: Union[Unset, List[str]] = UNSET, + query_param: Union[Unset, None, List[str]] = None, ) -> Dict[str, Any]: url = "{}/tests/optional_query_param/".format(client.base_url) headers: Dict[str, Any] = client.get_headers() json_query_param: Union[Unset, List[Any]] = UNSET - if not isinstance(query_param, Unset): + if not isinstance(query_param, Unset) and query_param is not None: json_query_param = query_param params: Dict[str, Any] = {} - if query_param is not UNSET: + if query_param is not UNSET and query_param is not None: params["query_param"] = json_query_param return { @@ -57,7 +57,7 @@ def _build_response(*, response: httpx.Response) -> Response[Union[None, HTTPVal def sync_detailed( *, client: Client, - query_param: Union[Unset, List[str]] = UNSET, + query_param: Union[Unset, None, List[str]] = None, ) -> Response[Union[None, HTTPValidationError]]: kwargs = _get_kwargs( client=client, @@ -74,7 +74,7 @@ def sync_detailed( def sync( *, client: Client, - query_param: Union[Unset, List[str]] = UNSET, + query_param: Union[Unset, None, List[str]] = None, ) -> Optional[Union[None, HTTPValidationError]]: """ Test optional query parameters """ @@ -87,7 +87,7 @@ def sync( async def asyncio_detailed( *, client: Client, - query_param: Union[Unset, List[str]] = UNSET, + query_param: Union[Unset, None, List[str]] = None, ) -> Response[Union[None, HTTPValidationError]]: kwargs = _get_kwargs( client=client, @@ -103,7 +103,7 @@ async def asyncio_detailed( async def asyncio( *, client: Client, - query_param: Union[Unset, List[str]] = UNSET, + query_param: Union[Unset, None, List[str]] = None, ) -> Optional[Union[None, HTTPValidationError]]: """ Test optional query parameters """ diff --git a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py index 47d65d90b..feb30878d 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py +++ b/end_to_end_tests/golden-record/my_test_api_client/models/model_with_primitive_additional_properties.py @@ -12,7 +12,7 @@ class ModelWithPrimitiveAdditionalProperties: """ """ - a_date_holder: Union[ModelWithPrimitiveAdditionalPropertiesADateHolder, Unset] = UNSET + a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET additional_properties: Dict[str, str] = attr.ib(init=False, factory=dict) def to_dict(self) -> Dict[str, Any]: @@ -31,7 +31,7 @@ def to_dict(self) -> Dict[str, Any]: @staticmethod def from_dict(src_dict: Dict[str, Any]) -> "ModelWithPrimitiveAdditionalProperties": d = src_dict.copy() - a_date_holder: Union[ModelWithPrimitiveAdditionalPropertiesADateHolder, Unset] = UNSET + a_date_holder: Union[Unset, ModelWithPrimitiveAdditionalPropertiesADateHolder] = UNSET _a_date_holder = d.pop("a_date_holder", UNSET) if _a_date_holder is not None and not isinstance(_a_date_holder, Unset): a_date_holder = ModelWithPrimitiveAdditionalPropertiesADateHolder.from_dict( diff --git a/openapi_python_client/parser/properties/__init__.py b/openapi_python_client/parser/properties/__init__.py index 487f5b464..4669769c8 100644 --- a/openapi_python_client/parser/properties/__init__.py +++ b/openapi_python_client/parser/properties/__init__.py @@ -124,16 +124,8 @@ class ListProperty(Property, Generic[InnerProp]): inner_property: InnerProp template: ClassVar[str] = "list_property.pyi" - def get_type_string(self, no_optional: bool = False) -> str: - """ Get a string representation of type that should be used when declaring this property """ - type_string = f"List[{self.inner_property.get_type_string()}]" - if no_optional: - return type_string - if self.nullable: - type_string = f"Optional[{type_string}]" - if not self.required: - type_string = f"Union[Unset, {type_string}]" - return type_string + def get_base_type_string(self) -> str: + return f"List[{self.inner_property.get_type_string()}]" def get_instance_type_string(self) -> str: """Get a string representation of runtime type that should be used for `isinstance` checks""" @@ -167,17 +159,26 @@ def __attrs_post_init__(self) -> None: self, "has_properties_without_templates", any(prop.template is None for prop in self.inner_properties) ) - def get_type_string(self, no_optional: bool = False) -> str: - """ Get a string representation of type that should be used when declaring this property """ + def _get_inner_prop_string(self) -> List[str]: inner_types = [p.get_type_string(no_optional=True) for p in self.inner_properties] - inner_prop_string = ", ".join(inner_types) - type_string = f"Union[{inner_prop_string}]" + return ", ".join(inner_types) + + def get_base_type_string(self) -> str: + return f"Union[{self._get_inner_prop_string()}]" + + def get_type_string(self, no_optional: bool = False, query_parameter: bool = False) -> str: + """ Get a string representation of type that should be used when declaring this property """ + type_string = self.get_base_type_string() if no_optional: return type_string - if not self.required: - type_string = f"Union[Unset, {inner_prop_string}]" if self.nullable: type_string = f"Optional[{type_string}]" + if not self.required: + if query_parameter: + # For query parameters, None has the same meaning as Unset + type_string = f"Union[Unset, None, {self._get_inner_prop_string()}]" + else: + type_string = f"Union[Unset, {self._get_inner_prop_string()}]" return type_string def get_imports(self, *, prefix: str) -> Set[str]: diff --git a/openapi_python_client/parser/properties/enum_property.py b/openapi_python_client/parser/properties/enum_property.py index 1217f23ee..08fce294d 100644 --- a/openapi_python_client/parser/properties/enum_property.py +++ b/openapi_python_client/parser/properties/enum_property.py @@ -22,17 +22,8 @@ class EnumProperty(Property): template: ClassVar[str] = "enum_property.pyi" - def get_type_string(self, no_optional: bool = False) -> str: - """ Get a string representation of type that should be used when declaring this property """ - - type_string = self.reference.class_name - if no_optional: - return type_string - if self.nullable: - type_string = f"Optional[{type_string}]" - if not self.required: - type_string = f"Union[Unset, {type_string}]" - return type_string + def get_base_type_string(self) -> str: + return self.reference.class_name def get_imports(self, *, prefix: str) -> Set[str]: """ diff --git a/openapi_python_client/parser/properties/model_property.py b/openapi_python_client/parser/properties/model_property.py index 40d1f930b..7ebc804b2 100644 --- a/openapi_python_client/parser/properties/model_property.py +++ b/openapi_python_client/parser/properties/model_property.py @@ -71,16 +71,8 @@ def resolve_references( return schemas - def get_type_string(self, no_optional: bool = False) -> str: - """ Get a string representation of type that should be used when declaring this property """ - type_string = self.reference.class_name - if no_optional: - return type_string - if self.nullable: - type_string = f"Optional[{type_string}]" - if not self.required: - type_string = f"Union[{type_string}, Unset]" - return type_string + def get_base_type_string(self) -> str: + return self.reference.class_name def get_imports(self, *, prefix: str) -> Set[str]: """ diff --git a/openapi_python_client/parser/properties/property.py b/openapi_python_client/parser/properties/property.py index 0b7047551..a75fc481f 100644 --- a/openapi_python_client/parser/properties/property.py +++ b/openapi_python_client/parser/properties/property.py @@ -31,21 +31,29 @@ class Property: def __attrs_post_init__(self) -> None: object.__setattr__(self, "python_name", utils.to_valid_python_identifier(utils.snake_case(self.name))) + + def get_base_type_string(self) -> str: + return self._type_string - def get_type_string(self, no_optional: bool = False) -> str: + def get_type_string(self, no_optional: bool = False, query_parameter: 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) + query_parameter: True if the property's type is being used for a query parameter """ - type_string = self._type_string + type_string = self.get_base_type_string() if no_optional: - return self._type_string + return type_string if self.nullable: type_string = f"Optional[{type_string}]" if not self.required: - type_string = f"Union[Unset, {type_string}]" + if query_parameter: + # For query parameters, None has the same meaning as Unset + type_string = f"Union[Unset, None, {type_string}]" + else: + type_string = f"Union[Unset, {type_string}]" return type_string def get_instance_type_string(self) -> str: @@ -69,17 +77,25 @@ def get_imports(self, *, prefix: str) -> Set[str]: imports.add(f"from {prefix}types import UNSET, Unset") return imports - def to_string(self) -> str: - """ How this should be declared in a dataclass """ + def to_string(self, query_parameter: bool = False) -> str: + """ + How this should be declared in a dataclass + + Args: + query_parameter: True if the property's type is being used for a query parameter + """ default: Optional[str] if self.default is not None: default = self.default elif not self.required: - default = "UNSET" + if query_parameter: + default = "None" + else: + 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(query_parameter=query_parameter)} = {default}" else: - return f"{self.python_name}: {self.get_type_string()}" + return f"{self.python_name}: {self.get_type_string(query_parameter=query_parameter)}" diff --git a/openapi_python_client/templates/endpoint_macros.pyi b/openapi_python_client/templates/endpoint_macros.pyi index 5819714d8..3e527b017 100644 --- a/openapi_python_client/templates/endpoint_macros.pyi +++ b/openapi_python_client/templates/endpoint_macros.pyi @@ -17,7 +17,7 @@ if {{ parameter.python_name }} is not UNSET: {% set destination = "json_" + property.python_name %} {% if property.template %} {% from "property_templates/" + property.template import transform %} -{{ transform(property, property.python_name, destination) }} +{{ transform(property, property.python_name, destination, query_parameter=True) }} {% endif %} {% endfor %} params: Dict[str, Any] = { @@ -33,7 +33,7 @@ params: Dict[str, Any] = { } {% for property in endpoint.query_parameters %} {% if not property.required %} -if {{ property.python_name }} is not UNSET: +if {{ property.python_name }} is not UNSET and {{ property.python_name }} is not None: {% if property.template %} params["{{ property.name }}"] = {{ "json_" + property.python_name }} {% else %} @@ -96,7 +96,7 @@ json_body: {{ endpoint.json_body.get_type_string() }}, {% endif %} {# query parameters #} {% for parameter in endpoint.query_parameters %} -{{ parameter.to_string() }}, +{{ parameter.to_string(query_parameter=True) }}, {% endfor %} {% for parameter in endpoint.header_parameters %} {{ parameter.to_string() }}, diff --git a/openapi_python_client/templates/property_templates/date_property.pyi b/openapi_python_client/templates/property_templates/date_property.pyi index a3a980c8f..18fbf7735 100644 --- a/openapi_python_client/templates/property_templates/date_property.pyi +++ b/openapi_python_client/templates/property_templates/date_property.pyi @@ -9,12 +9,12 @@ if _{{ property.python_name }} is not None: {% endif %} {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} {{ destination }} = {{ source }}.isoformat() {% if property.nullable %}if {{ source }} else None {%endif%} {% else %} {{ destination }}{% if declare_type %}: Union[Unset, str]{% endif %} = UNSET -if not isinstance({{ source }}, Unset): +if not isinstance({{ source }}, Unset){%if query_parameter %} and {{ source }} is not None{% endif %}: {% if property.nullable %} {{ destination }} = {{ source }}.isoformat() if {{ source }} else None {% else %} diff --git a/openapi_python_client/templates/property_templates/datetime_property.pyi b/openapi_python_client/templates/property_templates/datetime_property.pyi index b8e1b8ff0..073db6822 100644 --- a/openapi_python_client/templates/property_templates/datetime_property.pyi +++ b/openapi_python_client/templates/property_templates/datetime_property.pyi @@ -14,7 +14,7 @@ if _{{ property.python_name }} is not None: {% endif %} {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} {% if property.nullable %} {{ destination }} = {{ source }}.isoformat() if {{ source }} else None @@ -23,7 +23,7 @@ if _{{ property.python_name }} is not None: {% endif %} {% else %} {{ destination }}{% if declare_type %}: Union[Unset, str]{% endif %} = UNSET -if not isinstance({{ source }}, Unset): +if not isinstance({{ source }}, Unset){%if query_parameter %} and {{ source }} is not None{% endif %}: {% if property.nullable %} {{ destination }} = {{ source }}.isoformat() if {{ source }} else None {% else %} diff --git a/openapi_python_client/templates/property_templates/enum_property.pyi b/openapi_python_client/templates/property_templates/enum_property.pyi index 4765a6fd5..a5f07a8e4 100644 --- a/openapi_python_client/templates/property_templates/enum_property.pyi +++ b/openapi_python_client/templates/property_templates/enum_property.pyi @@ -9,7 +9,7 @@ if _{{ property.python_name }} is not None: {% endif %} {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} {% if property.nullable %} {{ destination }} = {{ source }}.value if {{ source }} else None @@ -18,7 +18,7 @@ if _{{ property.python_name }} is not None: {% endif %} {% else %} {{ destination }}{% if declare_type %}: {{ property.get_type_string() }}{% endif %} = UNSET -if not isinstance({{ source }}, Unset): +if not isinstance({{ source }}, Unset){%if query_parameter %} and {{ source }} is not None{% endif %}: {% if property.nullable %} {{ destination }} = {{ source }} if {{ source }} else None {% else %} diff --git a/openapi_python_client/templates/property_templates/file_property.pyi b/openapi_python_client/templates/property_templates/file_property.pyi index ffa3c20d9..3833a93ea 100644 --- a/openapi_python_client/templates/property_templates/file_property.pyi +++ b/openapi_python_client/templates/property_templates/file_property.pyi @@ -4,7 +4,7 @@ ) {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} {% if property.nullable %} {{ destination }} = {{ source }}.to_tuple() if {{ source }} else None @@ -13,7 +13,7 @@ {% endif %} {% else %} {{ destination }}{% if declare_type %}: {{ property.get_type_string() }}{% endif %} = UNSET -if not isinstance({{ source }}, Unset): +if not isinstance({{ source }}, Unset){%if query_parameter %} and {{ source }} is not None{% endif %}: {% if property.nullable %} {{ destination }} = {{ source }}.to_tuple() if {{ source }} else None {% else %} diff --git a/openapi_python_client/templates/property_templates/list_property.pyi b/openapi_python_client/templates/property_templates/list_property.pyi index d05a13960..317bb19e8 100644 --- a/openapi_python_client/templates/property_templates/list_property.pyi +++ b/openapi_python_client/templates/property_templates/list_property.pyi @@ -32,7 +32,7 @@ for {{ inner_source }} in {{ source }}: {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% set inner_property = property.inner_property %} {% if property.required %} {% if property.nullable %} @@ -45,7 +45,7 @@ else: {% endif %} {% else %} {{ destination }}{% if declare_type %}: Union[Unset, List[Any]]{% endif %} = UNSET -if not isinstance({{ source }}, Unset): +if not isinstance({{ source }}, Unset){%if query_parameter %} and {{ source }} is not None{% endif %}: {% if property.nullable %} if {{ source }} is None: {{ destination }} = None diff --git a/openapi_python_client/templates/property_templates/model_property.pyi b/openapi_python_client/templates/property_templates/model_property.pyi index e6746cb24..0ad78c991 100644 --- a/openapi_python_client/templates/property_templates/model_property.pyi +++ b/openapi_python_client/templates/property_templates/model_property.pyi @@ -15,7 +15,7 @@ if _{{ property.python_name }} is not None and not isinstance(_{{ property.pytho {% endif %} {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if property.required %} {% if property.nullable %} {{ destination }} = {{ source }}.to_dict() if {{ source }} else None @@ -24,7 +24,7 @@ if _{{ property.python_name }} is not None and not isinstance(_{{ property.pytho {% endif %} {% else %} {{ destination }}{% if declare_type %}: Union[{% if property.nullable %}None, {% endif %}Unset, Dict[str, Any]]{% endif %} = UNSET -if not isinstance({{ source }}, Unset): +if not isinstance({{ source }}, Unset){%if query_parameter %} and {{ source }} is not None{% endif %}: {% if property.nullable %} {{ destination }} = {{ source }}.to_dict() if {{ source }} else None {% else %} diff --git a/openapi_python_client/templates/property_templates/union_property.pyi b/openapi_python_client/templates/property_templates/union_property.pyi index 4c632c60a..fadef57e5 100644 --- a/openapi_python_client/templates/property_templates/union_property.pyi +++ b/openapi_python_client/templates/property_templates/union_property.pyi @@ -24,11 +24,11 @@ def _parse_{{ property.python_name }}(data: Any) -> {{ property.get_type_string( {{ property.python_name }} = _parse_{{ property.python_name }}({{ source }}) {% endmacro %} -{% macro transform(property, source, destination, declare_type=True) %} +{% macro transform(property, source, destination, declare_type=True, query_parameter=False) %} {% if not property.required %} {{ destination }}{% if declare_type %}: {{ property.get_type_string() }}{% endif %} -if isinstance({{ source }}, Unset): +if isinstance({{ source }}, Unset){%if query_parameter %} or {{ source }} is None{% endif %}: {{ destination }} = UNSET {% endif %} {% if property.nullable %}