2323import enum
2424import logging
2525import math
26+ import os
2627import pickle
2728import subprocess
2829import sys
@@ -248,12 +249,21 @@ def test_memoizing_pickle_coder(self):
248249 @parameterized .expand ([
249250 param (compat_version = None ),
250251 param (compat_version = "2.67.0" ),
252+ param (compat_version = "2.68.0" ),
251253 ])
252254 def test_deterministic_coder (self , compat_version ):
255+ """ Test in process determinism for all special deterministic types
256+
257+ - In SDK version <= 2.67.0 dill is used to encode "special types"
258+ - In SDK version 2.68.0 cloudpickle is used to encode "special types" with
259+ absolute filepaths in code objects and dynamic functions.
260+ - In SDK version >=2.69.0 cloudpickle is used to encode "special types"
261+ with relative filepaths in code objects and dynamic functions.
262+ """
253263
254264 typecoders .registry .update_compatibility_version = compat_version
255265 coder = coders .FastPrimitivesCoder ()
256- if not dill and compat_version :
266+ if not dill and compat_version == "2.67.0" :
257267 with self .assertRaises (RuntimeError ):
258268 coder .as_deterministic_coder (step_label = "step" )
259269 self .skipTest ('Dill not installed' )
@@ -283,7 +293,7 @@ def test_deterministic_coder(self, compat_version):
283293 # Skip this test during cloudpickle. Dill monkey patches the __reduce__
284294 # method for anonymous named tuples (MyNamedTuple) which is not pickleable.
285295 # Since the test is parameterized the type gets colbbered.
286- if compat_version :
296+ if compat_version == "2.67.0" :
287297 self .check_coder (
288298 deterministic_coder , [MyNamedTuple (1 , 2 ), MyTypedNamedTuple (1 , 'a' )])
289299
@@ -324,8 +334,18 @@ def test_deterministic_coder(self, compat_version):
324334 @parameterized .expand ([
325335 param (compat_version = None ),
326336 param (compat_version = "2.67.0" ),
337+ param (compat_version = "2.68.0" ),
327338 ])
328339 def test_deterministic_map_coder_is_update_compatible (self , compat_version ):
340+ """ Test in process determinism for map coder including when a component
341+ coder uses DeterministicFastPrimitivesCoder for "special types".
342+
343+ - In SDK version <= 2.67.0 dill is used to encode "special types"
344+ - In SDK version 2.68.0 cloudpickle is used to encode "special types" with
345+ absolute filepaths in code objects and dynamic functions.
346+ - In SDK version >=2.69.0 cloudpickle is used to encode "special types"
347+ with relative file.
348+ """
329349 typecoders .registry .update_compatibility_version = compat_version
330350 values = [{
331351 MyTypedNamedTuple (i , 'a' ): MyTypedNamedTuple ('a' , i )
@@ -335,7 +355,7 @@ def test_deterministic_map_coder_is_update_compatible(self, compat_version):
335355 coder = coders .MapCoder (
336356 coders .FastPrimitivesCoder (), coders .FastPrimitivesCoder ())
337357
338- if not dill and compat_version :
358+ if not dill and compat_version == "2.67.0" :
339359 with self .assertRaises (RuntimeError ):
340360 coder .as_deterministic_coder (step_label = "step" )
341361 self .skipTest ('Dill not installed' )
@@ -344,8 +364,8 @@ def test_deterministic_map_coder_is_update_compatible(self, compat_version):
344364
345365 assert isinstance (
346366 deterministic_coder ._key_coder ,
347- coders .DeterministicFastPrimitivesCoderV2
348- if not compat_version else coders .DeterministicFastPrimitivesCoder )
367+ coders .DeterministicFastPrimitivesCoderV2 if compat_version
368+ in ( None , "2.68.0" ) else coders .DeterministicFastPrimitivesCoder )
349369
350370 self .check_coder (deterministic_coder , * values )
351371
@@ -681,11 +701,20 @@ def test_param_windowed_value_coder(self):
681701 @parameterized .expand ([
682702 param (compat_version = None ),
683703 param (compat_version = "2.67.0" ),
704+ param (compat_version = "2.68.0" ),
684705 ])
685706 def test_cross_process_encoding_of_special_types_is_deterministic (
686707 self , compat_version ):
687- """Test cross-process determinism for all special deterministic types"""
688- if compat_version :
708+ """Test cross-process determinism for all special deterministic types
709+
710+ - In SDK version <= 2.67.0 dill is used to encode "special types"
711+ - In SDK version 2.68.0 cloudpickle is used to encode "special types" with
712+ absolute filepaths in code objects and dynamic functions.
713+ - In SDK version 2.69.0 cloudpickle is used to encode "special types" with
714+ relative filepaths in code objects and dynamic functions.
715+ """
716+ is_using_dill = compat_version == "2.67.0"
717+ if is_using_dill :
689718 pytest .importorskip ("dill" )
690719
691720 if sys .executable is None :
@@ -785,6 +814,7 @@ def run_subprocess():
785814 deterministic_coder = coder .as_deterministic_coder ("step" )
786815
787816 for test_name in results1 :
817+
788818 data1 = results1 [test_name ]
789819 data2 = results2 [test_name ]
790820
@@ -799,6 +829,19 @@ def run_subprocess():
799829 logging .warning ("Could not decode %s data due to %s" , test_name , e )
800830 continue
801831
832+ if test_name == "named_tuple_simple" and not is_using_dill :
833+ # The absense of a compat_version means we are using the most recent
834+ # implementation of the coder, which uses relative paths.
835+ should_have_relative_path = not compat_version
836+ named_tuple_type = type (decoded1 )
837+ self .assertEqual (
838+ os .path .isabs (named_tuple_type ._make .__code__ .co_filename ),
839+ not should_have_relative_path )
840+ self .assertEqual (
841+ os .path .isabs (
842+ named_tuple_type .__getnewargs__ .__globals__ ['__file__' ]),
843+ not should_have_relative_path )
844+
802845 self .assertEqual (
803846 decoded1 , decoded2 , f"Cross-process decoding differs for { test_name } " )
804847 self .assertIsInstance (
0 commit comments