3333from typing_extensions import Literal
3434
3535from iwf .iwf_api .models import EncodedObject
36- from iwf .iwf_api .types import Unset
36+ from iwf .iwf_api .types import UNSET , Unset
3737
3838# StrEnum is available in 3.11+
3939if sys .version_info >= (3 , 11 ):
@@ -50,14 +50,15 @@ class PayloadConverter(ABC):
5050 def to_payload (
5151 self ,
5252 value : Any ,
53- ) -> EncodedObject :
53+ ) -> Union [ EncodedObject , Unset ] :
5454 """Encode values into payloads.
5555
5656 Args:
5757 value: value to be converted
5858
5959 Returns:
60- Converted payload.
60+ A boolean to indicate if the payload was converted and the converted value
61+ or Unset
6162
6263 Raises:
6364 Exception: Any issue during conversion.
@@ -90,19 +91,20 @@ class EncodingPayloadConverter(ABC):
9091
9192 @property
9293 @abstractmethod
93- def encoding (self ) -> str :
94+ def encoding (self ) -> Union [ str , Unset ] :
9495 """Encoding for the payload this converter works with."""
9596 raise NotImplementedError
9697
9798 @abstractmethod
98- def to_payload (self , value : Any ) -> Optional [ EncodedObject ]:
99+ def to_payload (self , value : Any ) -> tuple [ bool , Union [ EncodedObject , Unset ] ]:
99100 """Encode a single value to a payload or None.
100101
101102 Args:
102103 value: Value to be converted.
103104
104105 Returns:
105- Payload of the value or None if unable to convert.
106+ A boolean to indicate if the payload was converted and the converted value
107+ or Unset
106108
107109 Raises:
108110 TypeError: Value is not the expected type.
@@ -145,7 +147,7 @@ class CompositePayloadConverter(PayloadConverter):
145147 converters: List of payload converters to delegate to, in order.
146148 """
147149
148- converters : Mapping [str , EncodingPayloadConverter ]
150+ converters : Mapping [Union [ str , Unset ] , EncodingPayloadConverter ]
149151
150152 def __init__ (self , * converters : EncodingPayloadConverter ) -> None :
151153 """Initializes the data converter.
@@ -159,7 +161,7 @@ def __init__(self, *converters: EncodingPayloadConverter) -> None:
159161 def to_payload (
160162 self ,
161163 value : Any ,
162- ) -> EncodedObject :
164+ ) -> Union [ EncodedObject , Unset ] :
163165 """Encode values trying each converter.
164166
165167 See base class. Always returns the same number of payloads as values.
@@ -169,12 +171,13 @@ def to_payload(
169171 """
170172 # We intentionally attempt these serially just in case a stateful
171173 # converter may rely on the previous values
172- payload = None
174+ payload : Union [EncodedObject , Unset ] = Unset ()
175+ is_encoded = False
173176 for converter in self .converters .values ():
174- payload = converter .to_payload (value )
175- if payload is not None :
177+ is_encoded , payload = converter .to_payload (value )
178+ if is_encoded :
176179 break
177- if payload is None :
180+ if not is_encoded :
178181 raise RuntimeError (
179182 f"Value of type { type (value )} has no known converter" ,
180183 )
@@ -194,7 +197,7 @@ def from_payload(
194197 RuntimeError: Error during decode
195198 """
196199 encoding = payload .encoding
197- assert isinstance (encoding , str )
200+ assert isinstance (encoding , ( str , Unset ) )
198201 converter = self .converters .get (encoding )
199202 if converter is None :
200203 raise KeyError (f"Unknown payload encoding { encoding } " )
@@ -229,17 +232,15 @@ class BinaryNullPayloadConverter(EncodingPayloadConverter):
229232 """Converter for 'binary/null' payloads supporting None values."""
230233
231234 @property
232- def encoding (self ) -> str :
235+ def encoding (self ) -> Union [ str , Unset ] :
233236 """See base class."""
234- return "binary/null"
237+ return UNSET
235238
236- def to_payload (self , value : Any ) -> Optional [ EncodedObject ]:
239+ def to_payload (self , value : Any ) -> tuple [ bool , Union [ EncodedObject , Unset ] ]:
237240 """See base class."""
238241 if value is None :
239- return EncodedObject (
240- encoding = self .encoding ,
241- )
242- return None
242+ return (True , UNSET )
243+ return (False , UNSET )
243244
244245 def from_payload (
245246 self ,
@@ -256,18 +257,21 @@ class BinaryPlainPayloadConverter(EncodingPayloadConverter):
256257 """Converter for 'binary/plain' payloads supporting bytes values."""
257258
258259 @property
259- def encoding (self ) -> str :
260+ def encoding (self ) -> Union [ str , Unset ] :
260261 """See base class."""
261262 return "binary/plain"
262263
263- def to_payload (self , value : Any ) -> Optional [ EncodedObject ]:
264+ def to_payload (self , value : Any ) -> tuple [ bool , Union [ EncodedObject , Unset ] ]:
264265 """See base class."""
265266 if isinstance (value , bytes ):
266- return EncodedObject (
267- encoding = self .encoding ,
268- data = str (value ),
267+ return (
268+ True ,
269+ EncodedObject (
270+ encoding = self .encoding ,
271+ data = str (value ),
272+ ),
269273 )
270- return None
274+ return ( False , UNSET )
271275
272276 def from_payload (
273277 self ,
@@ -345,11 +349,11 @@ def __init__(
345349 self ._custom_type_converters = custom_type_converters
346350
347351 @property
348- def encoding (self ) -> str :
352+ def encoding (self ) -> Union [ str , Unset ] :
349353 """See base class."""
350354 return self ._encoding
351355
352- def to_payload (self , value : Any ) -> Optional [ EncodedObject ]:
356+ def to_payload (self , value : Any ) -> tuple [ bool , Union [ EncodedObject , Unset ] ]:
353357 """See base class."""
354358 # Check for pydantic then send warning
355359 if hasattr (value , "parse_obj" ):
@@ -358,13 +362,16 @@ def to_payload(self, value: Any) -> Optional[EncodedObject]:
358362 "https://github.com/temporalio/samples-python/tree/main/pydantic_converter for better support" ,
359363 )
360364 # We let JSON conversion errors be thrown to caller
361- return EncodedObject (
362- encoding = self .encoding ,
363- data = json .dumps (
364- value ,
365- cls = self ._encoder ,
366- separators = ("," , ":" ),
367- sort_keys = True ,
365+ return (
366+ True ,
367+ EncodedObject (
368+ encoding = self .encoding ,
369+ data = json .dumps (
370+ value ,
371+ cls = self ._encoder ,
372+ separators = ("," , ":" ),
373+ sort_keys = True ,
374+ ),
368375 ),
369376 )
370377
@@ -428,7 +435,7 @@ class PayloadCodec(ABC):
428435 @abstractmethod
429436 def encode (
430437 self ,
431- payload : EncodedObject ,
438+ payload : Union [ EncodedObject , Unset ] ,
432439 ) -> EncodedObject :
433440 """Encode the given payloads.
434441
@@ -486,7 +493,7 @@ def __post_init__(self) -> None: # noqa: D105
486493 def encode (
487494 self ,
488495 value : Any ,
489- ) -> EncodedObject :
496+ ) -> Union [ EncodedObject , Unset ] :
490497 """Encode values into payloads.
491498
492499 First converts values to payload then encodes payload using codec.
0 commit comments