From 10f5bdb724d3e1dbe6ba03387003585029064ae3 Mon Sep 17 00:00:00 2001 From: Benjamin Lowry Date: Fri, 6 Jun 2025 16:27:29 -0400 Subject: [PATCH 1/4] handle optional binary and aliases --- .../python/client/ClientGenerator.java | 21 ++- .../python/poet/PythonEndpointDefinition.java | 19 ++- .../services/expected/package_name/_impl.py | 149 +++++++++++++++++- .../expected/package_name/product/__init__.py | 4 + .../test/resources/types/example-service.yml | 30 ++++ .../types/expected/package_name/_impl.py | 149 +++++++++++++++++- .../expected/package_name/product/__init__.py | 4 + 7 files changed, 351 insertions(+), 25 deletions(-) diff --git a/conjure-python-core/src/main/java/com/palantir/conjure/python/client/ClientGenerator.java b/conjure-python-core/src/main/java/com/palantir/conjure/python/client/ClientGenerator.java index c053a26f2..dcfbfe348 100644 --- a/conjure-python-core/src/main/java/com/palantir/conjure/python/client/ClientGenerator.java +++ b/conjure-python-core/src/main/java/com/palantir/conjure/python/client/ClientGenerator.java @@ -31,7 +31,6 @@ import com.palantir.conjure.python.types.MyPyTypeNameVisitor; import com.palantir.conjure.python.types.PythonTypeNameVisitor; import com.palantir.conjure.spec.EndpointDefinition; -import com.palantir.conjure.spec.PrimitiveType; import com.palantir.conjure.spec.ServiceDefinition; import com.palantir.conjure.spec.Type; import com.palantir.conjure.visitor.DealiasingTypeVisitor; @@ -127,12 +126,24 @@ private PythonEndpointDefinition generateEndpoint( .myPyReturnType(endpointDef.getReturns().map(type -> type.accept(myPyTypeNameVisitor))) .isRequestBinary(endpointDef.getArgs().stream() .anyMatch(argumentDef -> argumentDef.getParamType().accept(ParameterTypeVisitor.IS_BODY) - && argumentDef.getType().accept(TypeVisitor.IS_BINARY))) + && dealiasingTypeVisitor + .dealias(argumentDef.getType()) + .fold(_typeDefinition -> false, type -> type.accept(TypeVisitor.IS_BINARY)))) .isResponseBinary(endpointDef .getReturns() - // We do not need to handle alias of binary since they are treated differently over the wire - .map(rt -> rt.accept(TypeVisitor.IS_PRIMITIVE) - && rt.accept(TypeVisitor.PRIMITIVE).get() == PrimitiveType.Value.BINARY) + .map(rt -> dealiasingTypeVisitor + .dealias(rt) + .fold( + _typeDefinition -> false, + type -> type.accept(TypeVisitor.IS_BINARY) + || (type.accept(TypeVisitor.IS_OPTIONAL) + && dealiasingTypeVisitor + .dealias(type.accept(TypeVisitor.OPTIONAL) + .getItemType()) + .fold( + _typeDefinition -> false, + itemType -> itemType.accept( + TypeVisitor.IS_BINARY))))) .orElse(false)) .isOptionalReturnType(endpointDef .getReturns() diff --git a/conjure-python-core/src/main/java/com/palantir/conjure/python/poet/PythonEndpointDefinition.java b/conjure-python-core/src/main/java/com/palantir/conjure/python/poet/PythonEndpointDefinition.java index 36da98025..1425fb491 100644 --- a/conjure-python-core/src/main/java/com/palantir/conjure/python/poet/PythonEndpointDefinition.java +++ b/conjure-python-core/src/main/java/com/palantir/conjure/python/poet/PythonEndpointDefinition.java @@ -225,22 +225,21 @@ default void emit(PythonPoetWriter poetWriter) { poetWriter.decreaseIndent(); poetWriter.writeLine(); + if (isOptionalReturnType()) { + poetWriter.writeIndentedLine("if _response.status_code == 204:"); + poetWriter.increaseIndent(); + poetWriter.writeIndentedLine("return None"); + poetWriter.decreaseIndent(); + } if (isResponseBinary()) { poetWriter.writeIndentedLine("_raw = _response.raw"); poetWriter.writeIndentedLine("_raw.decode_content = True"); poetWriter.writeIndentedLine("return _raw"); } else if (pythonReturnType().isPresent()) { poetWriter.writeIndentedLine("_decoder = ConjureDecoder()"); - if (isOptionalReturnType()) { - poetWriter.writeIndentedLine( - "return None if _response.status_code == 204 else _decoder.decode(_response.json()" - + ", %s, self._return_none_for_unknown_union_types)", - pythonReturnType().get()); - } else { - poetWriter.writeIndentedLine( - "return _decoder.decode(_response.json(), %s, self._return_none_for_unknown_union_types)", - pythonReturnType().get()); - } + poetWriter.writeIndentedLine( + "return _decoder.decode(_response.json(), %s, self._return_none_for_unknown_union_types)", + pythonReturnType().get()); } else { poetWriter.writeIndentedLine("return"); } diff --git a/conjure-python-core/src/test/resources/services/expected/package_name/_impl.py b/conjure-python-core/src/test/resources/services/expected/package_name/_impl.py index 7bfef9025..f65d636b5 100644 --- a/conjure-python-core/src/test/resources/services/expected/package_name/_impl.py +++ b/conjure-python-core/src/test/resources/services/expected/package_name/_impl.py @@ -126,8 +126,10 @@ def get_dataset(self, auth_header: str, dataset_rid: str) -> Optional["product_d headers=_headers, json=_json) + if _response.status_code == 204: + return None _decoder = ConjureDecoder() - return None if _response.status_code == 204 else _decoder.decode(_response.json(), OptionalTypeWrapper[product_datasets_Dataset], self._return_none_for_unknown_union_types) + return _decoder.decode(_response.json(), OptionalTypeWrapper[product_datasets_Dataset], self._return_none_for_unknown_union_types) def get_raw_data(self, auth_header: str, dataset_rid: str) -> Any: _conjure_encoder = ConjureEncoder() @@ -161,11 +163,42 @@ def get_raw_data(self, auth_header: str, dataset_rid: str) -> Any: _raw.decode_content = True return _raw + def get_aliased_raw_data(self, auth_header: str) -> Any: + _conjure_encoder = ConjureEncoder() + + _headers: Dict[str, Any] = { + 'Accept': 'application/octet-stream', + 'Authorization': auth_header, + } + + _params: Dict[str, Any] = { + } + + _path_params: Dict[str, str] = { + } + + _json: Any = None + + _path = '/catalog/get-aliased-raw' + _path = _path.format(**_path_params) + + _response: Response = self._request( + 'GET', + self._uri + _path, + params=_params, + headers=_headers, + stream=True, + json=_json) + + _raw = _response.raw + _raw.decode_content = True + return _raw + def maybe_get_raw_data(self, auth_header: str, dataset_rid: str) -> Optional[Any]: _conjure_encoder = ConjureEncoder() _headers: Dict[str, Any] = { - 'Accept': 'application/json', + 'Accept': 'application/octet-stream', 'Authorization': auth_header, } @@ -186,10 +219,79 @@ def maybe_get_raw_data(self, auth_header: str, dataset_rid: str) -> Optional[Any self._uri + _path, params=_params, headers=_headers, + stream=True, json=_json) + if _response.status_code == 204: + return None + _raw = _response.raw + _raw.decode_content = True + return _raw + + def maybe_get_aliased_raw_data(self, auth_header: str, dataset_rid: str) -> Optional[Any]: + _conjure_encoder = ConjureEncoder() + + _headers: Dict[str, Any] = { + 'Accept': 'application/octet-stream', + 'Authorization': auth_header, + } + + _params: Dict[str, Any] = { + } + + _path_params: Dict[str, str] = { + 'datasetRid': quote(str(_conjure_encoder.default(dataset_rid)), safe=''), + } + + _json: Any = None + + _path = '/catalog/datasets/{datasetRid}/raw-maybe-alias' + _path = _path.format(**_path_params) + + _response: Response = self._request( + 'GET', + self._uri + _path, + params=_params, + headers=_headers, + stream=True, + json=_json) + + if _response.status_code == 204: + return None + _raw = _response.raw + _raw.decode_content = True + return _raw + + def get_aliased_return(self, auth_header: str) -> Optional[str]: + _conjure_encoder = ConjureEncoder() + + _headers: Dict[str, Any] = { + 'Accept': 'application/json', + 'Authorization': auth_header, + } + + _params: Dict[str, Any] = { + } + + _path_params: Dict[str, str] = { + } + + _json: Any = None + + _path = '/catalog/aliased-return' + _path = _path.format(**_path_params) + + _response: Response = self._request( + 'GET', + self._uri + _path, + params=_params, + headers=_headers, + json=_json) + + if _response.status_code == 204: + return None _decoder = ConjureDecoder() - return None if _response.status_code == 204 else _decoder.decode(_response.json(), OptionalTypeWrapper[BinaryType], self._return_none_for_unknown_union_types) + return _decoder.decode(_response.json(), product_OptionalStringAlias, self._return_none_for_unknown_union_types) def upload_raw_data(self, auth_header: str, input: Any) -> None: _conjure_encoder = ConjureEncoder() @@ -220,6 +322,35 @@ def upload_raw_data(self, auth_header: str, input: Any) -> None: return + def upload_aliased_raw_data(self, auth_header: str, input: Any) -> None: + _conjure_encoder = ConjureEncoder() + + _headers: Dict[str, Any] = { + 'Accept': 'application/json', + 'Content-Type': 'application/octet-stream', + 'Authorization': auth_header, + } + + _params: Dict[str, Any] = { + } + + _path_params: Dict[str, str] = { + } + + _data: Any = input + + _path = '/catalog/datasets/upload-raw-alias' + _path = _path.format(**_path_params) + + _response: Response = self._request( + 'POST', + self._uri + _path, + params=_params, + headers=_headers, + data=_data) + + return + def upload_python_package(self, auth_header: str, upload_type: "product_UploadType", upload_type_header: "product_UploadType", upload_types_query: List["product_UploadType"] = None, upload_type_body: Optional["product_UploadType"] = None) -> None: upload_types_query = upload_types_query if upload_types_query is not None else [] _conjure_encoder = ConjureEncoder() @@ -345,8 +476,10 @@ def resolve_branch(self, auth_header: str, branch: str, dataset_rid: str) -> Opt headers=_headers, json=_json) + if _response.status_code == 204: + return None _decoder = ConjureDecoder() - return None if _response.status_code == 204 else _decoder.decode(_response.json(), OptionalTypeWrapper[str], self._return_none_for_unknown_union_types) + return _decoder.decode(_response.json(), OptionalTypeWrapper[str], self._return_none_for_unknown_union_types) def test_param(self, auth_header: str, dataset_rid: str) -> Optional[str]: _conjure_encoder = ConjureEncoder() @@ -375,8 +508,10 @@ def test_param(self, auth_header: str, dataset_rid: str) -> Optional[str]: headers=_headers, json=_json) + if _response.status_code == 204: + return None _decoder = ConjureDecoder() - return None if _response.status_code == 204 else _decoder.decode(_response.json(), OptionalTypeWrapper[str], self._return_none_for_unknown_union_types) + return _decoder.decode(_response.json(), OptionalTypeWrapper[str], self._return_none_for_unknown_union_types) def test_query_params(self, auth_header: str, implicit: str, nonlocal_: int, something: str, list: List[int] = None, set: List[int] = None) -> int: list = list if list is not None else [] @@ -624,3 +759,7 @@ def rid(self) -> str: package_name_TypeInPackageWithTheSameNameAsRootPackage = str +product_OptionalStringAlias = OptionalTypeWrapper[str] + +product_BinaryAlias = BinaryType + diff --git a/conjure-python-core/src/test/resources/services/expected/package_name/product/__init__.py b/conjure-python-core/src/test/resources/services/expected/package_name/product/__init__.py index 6bf45bf60..5326e64d2 100644 --- a/conjure-python-core/src/test/resources/services/expected/package_name/product/__init__.py +++ b/conjure-python-core/src/test/resources/services/expected/package_name/product/__init__.py @@ -1,11 +1,15 @@ # coding=utf-8 from .._impl import ( + product_BinaryAlias as BinaryAlias, product_CreateDatasetRequest as CreateDatasetRequest, + product_OptionalStringAlias as OptionalStringAlias, product_UploadType as UploadType, ) __all__ = [ + 'BinaryAlias', 'CreateDatasetRequest', + 'OptionalStringAlias', 'UploadType', ] diff --git a/conjure-python-core/src/test/resources/types/example-service.yml b/conjure-python-core/src/test/resources/types/example-service.yml index f5a33abd1..5582bd3c3 100644 --- a/conjure-python-core/src/test/resources/types/example-service.yml +++ b/conjure-python-core/src/test/resources/types/example-service.yml @@ -52,6 +52,12 @@ types: - value: PYPI - value: CONDA + BinaryAlias: + alias: binary + + OptionalStringAlias: + alias: optional + services: TestService: name: Test Service @@ -98,6 +104,10 @@ services: - Safe returns: binary + getAliasedRawData: + http: GET /get-aliased-raw + returns: BinaryAlias + maybeGetRawData: http: GET /datasets/{datasetRid}/raw-maybe args: @@ -107,6 +117,19 @@ services: - Safe returns: optional + maybeGetAliasedRawData: + http: GET /datasets/{datasetRid}/raw-maybe-alias + args: + datasetRid: + type: rid + markers: + - Safe + returns: optional + + getAliasedReturn: + http: GET /aliased-return + returns: OptionalStringAlias + uploadRawData: http: POST /datasets/upload-raw args: @@ -114,6 +137,13 @@ services: type: binary param-type: body + uploadAliasedRawData: + http: POST /datasets/upload-raw-alias + args: + input: + type: BinaryAlias + param-type: body + uploadPythonPackage: http: POST /data/python/{uploadType} args: diff --git a/conjure-python-core/src/test/resources/types/expected/package_name/_impl.py b/conjure-python-core/src/test/resources/types/expected/package_name/_impl.py index fc23bdf1f..6ec1180fb 100644 --- a/conjure-python-core/src/test/resources/types/expected/package_name/_impl.py +++ b/conjure-python-core/src/test/resources/types/expected/package_name/_impl.py @@ -130,8 +130,10 @@ def get_dataset(self, auth_header: str, dataset_rid: str) -> Optional["product_d headers=_headers, json=_json) + if _response.status_code == 204: + return None _decoder = ConjureDecoder() - return None if _response.status_code == 204 else _decoder.decode(_response.json(), OptionalTypeWrapper[product_datasets_Dataset], self._return_none_for_unknown_union_types) + return _decoder.decode(_response.json(), OptionalTypeWrapper[product_datasets_Dataset], self._return_none_for_unknown_union_types) def get_raw_data(self, auth_header: str, dataset_rid: str) -> Any: _conjure_encoder = ConjureEncoder() @@ -165,11 +167,42 @@ def get_raw_data(self, auth_header: str, dataset_rid: str) -> Any: _raw.decode_content = True return _raw + def get_aliased_raw_data(self, auth_header: str) -> Any: + _conjure_encoder = ConjureEncoder() + + _headers: Dict[str, Any] = { + 'Accept': 'application/octet-stream', + 'Authorization': auth_header, + } + + _params: Dict[str, Any] = { + } + + _path_params: Dict[str, str] = { + } + + _json: Any = None + + _path = '/catalog/get-aliased-raw' + _path = _path.format(**_path_params) + + _response: Response = self._request( + 'GET', + self._uri + _path, + params=_params, + headers=_headers, + stream=True, + json=_json) + + _raw = _response.raw + _raw.decode_content = True + return _raw + def maybe_get_raw_data(self, auth_header: str, dataset_rid: str) -> Optional[Any]: _conjure_encoder = ConjureEncoder() _headers: Dict[str, Any] = { - 'Accept': 'application/json', + 'Accept': 'application/octet-stream', 'Authorization': auth_header, } @@ -190,10 +223,79 @@ def maybe_get_raw_data(self, auth_header: str, dataset_rid: str) -> Optional[Any self._uri + _path, params=_params, headers=_headers, + stream=True, json=_json) + if _response.status_code == 204: + return None + _raw = _response.raw + _raw.decode_content = True + return _raw + + def maybe_get_aliased_raw_data(self, auth_header: str, dataset_rid: str) -> Optional[Any]: + _conjure_encoder = ConjureEncoder() + + _headers: Dict[str, Any] = { + 'Accept': 'application/octet-stream', + 'Authorization': auth_header, + } + + _params: Dict[str, Any] = { + } + + _path_params: Dict[str, str] = { + 'datasetRid': quote(str(_conjure_encoder.default(dataset_rid)), safe=''), + } + + _json: Any = None + + _path = '/catalog/datasets/{datasetRid}/raw-maybe-alias' + _path = _path.format(**_path_params) + + _response: Response = self._request( + 'GET', + self._uri + _path, + params=_params, + headers=_headers, + stream=True, + json=_json) + + if _response.status_code == 204: + return None + _raw = _response.raw + _raw.decode_content = True + return _raw + + def get_aliased_return(self, auth_header: str) -> Optional[str]: + _conjure_encoder = ConjureEncoder() + + _headers: Dict[str, Any] = { + 'Accept': 'application/json', + 'Authorization': auth_header, + } + + _params: Dict[str, Any] = { + } + + _path_params: Dict[str, str] = { + } + + _json: Any = None + + _path = '/catalog/aliased-return' + _path = _path.format(**_path_params) + + _response: Response = self._request( + 'GET', + self._uri + _path, + params=_params, + headers=_headers, + json=_json) + + if _response.status_code == 204: + return None _decoder = ConjureDecoder() - return None if _response.status_code == 204 else _decoder.decode(_response.json(), OptionalTypeWrapper[BinaryType], self._return_none_for_unknown_union_types) + return _decoder.decode(_response.json(), product_OptionalStringAlias, self._return_none_for_unknown_union_types) def upload_raw_data(self, auth_header: str, input: Any) -> None: _conjure_encoder = ConjureEncoder() @@ -224,6 +326,35 @@ def upload_raw_data(self, auth_header: str, input: Any) -> None: return + def upload_aliased_raw_data(self, auth_header: str, input: Any) -> None: + _conjure_encoder = ConjureEncoder() + + _headers: Dict[str, Any] = { + 'Accept': 'application/json', + 'Content-Type': 'application/octet-stream', + 'Authorization': auth_header, + } + + _params: Dict[str, Any] = { + } + + _path_params: Dict[str, str] = { + } + + _data: Any = input + + _path = '/catalog/datasets/upload-raw-alias' + _path = _path.format(**_path_params) + + _response: Response = self._request( + 'POST', + self._uri + _path, + params=_params, + headers=_headers, + data=_data) + + return + def upload_python_package(self, auth_header: str, upload_type: "product_UploadType", upload_type_header: "product_UploadType", upload_types_query: List["product_UploadType"] = None, upload_type_body: Optional["product_UploadType"] = None) -> None: upload_types_query = upload_types_query if upload_types_query is not None else [] _conjure_encoder = ConjureEncoder() @@ -349,8 +480,10 @@ def resolve_branch(self, auth_header: str, branch: str, dataset_rid: str) -> Opt headers=_headers, json=_json) + if _response.status_code == 204: + return None _decoder = ConjureDecoder() - return None if _response.status_code == 204 else _decoder.decode(_response.json(), OptionalTypeWrapper[str], self._return_none_for_unknown_union_types) + return _decoder.decode(_response.json(), OptionalTypeWrapper[str], self._return_none_for_unknown_union_types) def test_param(self, auth_header: str, dataset_rid: str) -> Optional[str]: _conjure_encoder = ConjureEncoder() @@ -379,8 +512,10 @@ def test_param(self, auth_header: str, dataset_rid: str) -> Optional[str]: headers=_headers, json=_json) + if _response.status_code == 204: + return None _decoder = ConjureDecoder() - return None if _response.status_code == 204 else _decoder.decode(_response.json(), OptionalTypeWrapper[str], self._return_none_for_unknown_union_types) + return _decoder.decode(_response.json(), OptionalTypeWrapper[str], self._return_none_for_unknown_union_types) def test_query_params(self, auth_header: str, implicit: str, nonlocal_: int, something: str, list: List[int] = None, set: List[int] = None) -> int: list = list if list is not None else [] @@ -2050,12 +2185,16 @@ def _imported(self, imported: "product_AnyMapExample") -> Any: product_UuidAliasExample = str +product_OptionalStringAlias = OptionalTypeWrapper[str] + product_StringAliasExample = str with_imports_AliasImportedPrimitiveAlias = product_StringAliasExample with_imports_AliasImportedReferenceAlias = product_ReferenceAliasExample +product_BinaryAlias = BinaryType + product_DoubleAliasExample = float product_RecursiveObjectAlias = product_RecursiveObjectExample diff --git a/conjure-python-core/src/test/resources/types/expected/package_name/product/__init__.py b/conjure-python-core/src/test/resources/types/expected/package_name/product/__init__.py index 15929a225..85f33b95d 100644 --- a/conjure-python-core/src/test/resources/types/expected/package_name/product/__init__.py +++ b/conjure-python-core/src/test/resources/types/expected/package_name/product/__init__.py @@ -5,6 +5,7 @@ product_AnyMapExample as AnyMapExample, product_BearerTokenAliasExample as BearerTokenAliasExample, product_BearerTokenExample as BearerTokenExample, + product_BinaryAlias as BinaryAlias, product_BinaryAliasExample as BinaryAliasExample, product_BinaryExample as BinaryExample, product_BooleanAliasExample as BooleanAliasExample, @@ -27,6 +28,7 @@ product_MapExample as MapExample, product_NestedAliasExample as NestedAliasExample, product_OptionalExample as OptionalExample, + product_OptionalStringAlias as OptionalStringAlias, product_OptionsUnion as OptionsUnion, product_OptionsUnionVisitor as OptionsUnionVisitor, product_PrimitiveOptionalsExample as PrimitiveOptionalsExample, @@ -57,6 +59,7 @@ 'AnyMapExample', 'BearerTokenAliasExample', 'BearerTokenExample', + 'BinaryAlias', 'BinaryAliasExample', 'BinaryExample', 'BooleanAliasExample', @@ -79,6 +82,7 @@ 'MapExample', 'NestedAliasExample', 'OptionalExample', + 'OptionalStringAlias', 'OptionsUnion', 'OptionsUnionVisitor', 'PrimitiveOptionalsExample', From d8ba14cf1443c686023498f1ceb03c51befb49d0 Mon Sep 17 00:00:00 2001 From: Benjamin Lowry Date: Fri, 6 Jun 2025 16:30:27 -0400 Subject: [PATCH 2/4] comment --- .../com/palantir/conjure/python/client/ClientGenerator.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/conjure-python-core/src/main/java/com/palantir/conjure/python/client/ClientGenerator.java b/conjure-python-core/src/main/java/com/palantir/conjure/python/client/ClientGenerator.java index dcfbfe348..a1746ca6c 100644 --- a/conjure-python-core/src/main/java/com/palantir/conjure/python/client/ClientGenerator.java +++ b/conjure-python-core/src/main/java/com/palantir/conjure/python/client/ClientGenerator.java @@ -124,11 +124,13 @@ private PythonEndpointDefinition generateEndpoint( .params(params) .pythonReturnType(endpointDef.getReturns().map(type -> type.accept(pythonTypeNameVisitor))) .myPyReturnType(endpointDef.getReturns().map(type -> type.accept(myPyTypeNameVisitor))) + // Set to true iff the de-aliased type is binary. .isRequestBinary(endpointDef.getArgs().stream() .anyMatch(argumentDef -> argumentDef.getParamType().accept(ParameterTypeVisitor.IS_BODY) && dealiasingTypeVisitor .dealias(argumentDef.getType()) .fold(_typeDefinition -> false, type -> type.accept(TypeVisitor.IS_BINARY)))) + // Set to true iff 1) the de-aliased type is binary or 2) the de-aliased type is optional (both outer and inner type de-aliased). .isResponseBinary(endpointDef .getReturns() .map(rt -> dealiasingTypeVisitor From dbecb01a6fb7f4655ec42d78a151232f27449880 Mon Sep 17 00:00:00 2001 From: Benjamin Lowry Date: Fri, 6 Jun 2025 16:33:54 -0400 Subject: [PATCH 3/4] spotless --- .../com/palantir/conjure/python/client/ClientGenerator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/conjure-python-core/src/main/java/com/palantir/conjure/python/client/ClientGenerator.java b/conjure-python-core/src/main/java/com/palantir/conjure/python/client/ClientGenerator.java index a1746ca6c..b52c3d193 100644 --- a/conjure-python-core/src/main/java/com/palantir/conjure/python/client/ClientGenerator.java +++ b/conjure-python-core/src/main/java/com/palantir/conjure/python/client/ClientGenerator.java @@ -130,7 +130,8 @@ private PythonEndpointDefinition generateEndpoint( && dealiasingTypeVisitor .dealias(argumentDef.getType()) .fold(_typeDefinition -> false, type -> type.accept(TypeVisitor.IS_BINARY)))) - // Set to true iff 1) the de-aliased type is binary or 2) the de-aliased type is optional (both outer and inner type de-aliased). + // Set to true iff 1) the de-aliased type is binary or 2) the de-aliased type is optional (both + // outer and inner type de-aliased). .isResponseBinary(endpointDef .getReturns() .map(rt -> dealiasingTypeVisitor From cd2d71680e24e0abed78c1dcd3e885afad05d8ab Mon Sep 17 00:00:00 2001 From: svc-changelog Date: Fri, 6 Jun 2025 20:47:08 +0000 Subject: [PATCH 4/4] Add generated changelog entries --- changelog/@unreleased/pr-1052.v2.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 changelog/@unreleased/pr-1052.v2.yml diff --git a/changelog/@unreleased/pr-1052.v2.yml b/changelog/@unreleased/pr-1052.v2.yml new file mode 100644 index 000000000..24a15c3a9 --- /dev/null +++ b/changelog/@unreleased/pr-1052.v2.yml @@ -0,0 +1,6 @@ +type: fix +fix: + description: Properly handle optional endpoint return type and binary-related + aliases + links: + - https://github.com/palantir/conjure-python/pull/1052