@@ -112,6 +112,7 @@ def _report_progress(_stats, progress_logger, duration):
112112 'encodings' ,
113113 'ignore_encoding_errors' ,
114114 'default_timezone' ,
115+ 'custom_operators' ,
115116)
116117
117118
@@ -130,6 +131,7 @@ def __init__(self,
130131 custom_operators : Optional [List [Any ]] = None ,
131132 cutoff_distance_for_pairs : float = CUTOFF_DISTANCE_FOR_PAIRS_DEFAULT ,
132133 cutoff_intersection_for_pairs : float = CUTOFF_INTERSECTION_FOR_PAIRS_DEFAULT ,
134+ default_timezone :Union [datetime .timezone , datetime .timezone , pytz .tzinfo .BaseTzInfo ]= datetime .timezone .utc ,
133135 encodings : Optional [List [str ]]= None ,
134136 exclude_obj_callback : Optional [Callable ]= None ,
135137 exclude_obj_callback_strict : Optional [Callable ]= None ,
@@ -156,6 +158,8 @@ def __init__(self,
156158 include_paths : Union [str , List [str ], None ]= None ,
157159 iterable_compare_func : Optional [Callable ]= None ,
158160 log_frequency_in_sec : int = 0 ,
161+ log_scale_similarity_threshold : float = 0.1 ,
162+ log_stacktrace : bool = False ,
159163 math_epsilon : Optional [float ]= None ,
160164 max_diffs : Optional [int ]= None ,
161165 max_passes : int = 10000000 ,
@@ -164,15 +168,13 @@ def __init__(self,
164168 progress_logger : Callable = logger .info ,
165169 report_repetition : bool = False ,
166170 significant_digits : Optional [int ]= None ,
167- use_log_scale : bool = False ,
168- log_scale_similarity_threshold : float = 0.1 ,
169171 threshold_to_diff_deeper : float = 0.33 ,
170172 truncate_datetime : Optional [str ]= None ,
171173 use_enum_value : bool = False ,
174+ use_log_scale : bool = False ,
172175 verbose_level : int = 1 ,
173176 view : str = TEXT_VIEW ,
174177 zip_ordered_iterables : bool = False ,
175- default_timezone :Union [datetime .timezone , datetime .timezone , pytz .tzinfo .BaseTzInfo ]= datetime .timezone .utc ,
176178 _parameters = None ,
177179 _shared_parameters = None ,
178180 ** kwargs ):
@@ -186,7 +188,7 @@ def __init__(self,
186188 "ignore_private_variables, ignore_nan_inequality, number_to_string_func, verbose_level, "
187189 "view, hasher, hashes, max_passes, max_diffs, zip_ordered_iterables, "
188190 "cutoff_distance_for_pairs, cutoff_intersection_for_pairs, log_frequency_in_sec, cache_size, "
189- "cache_tuning_sample_size, get_deep_distance, group_by, group_by_sort_key, cache_purge_level, "
191+ "cache_tuning_sample_size, get_deep_distance, group_by, group_by_sort_key, cache_purge_level, log_stacktrace, "
190192 "math_epsilon, iterable_compare_func, use_enum_value, _original_type, threshold_to_diff_deeper, default_timezone "
191193 "ignore_order_func, custom_operators, encodings, ignore_encoding_errors, use_log_scale, log_scale_similarity_threshold "
192194 "_parameters and _shared_parameters." ) % ', ' .join (kwargs .keys ()))
@@ -209,6 +211,7 @@ def __init__(self,
209211 self .log_scale_similarity_threshold = log_scale_similarity_threshold
210212 self .use_log_scale = use_log_scale
211213 self .default_timezone = default_timezone
214+ self .log_stacktrace = log_stacktrace
212215 self .threshold_to_diff_deeper = threshold_to_diff_deeper
213216 self .ignore_string_type_changes = ignore_string_type_changes
214217 self .ignore_type_in_groups = self .get_ignore_types_in_groups (
@@ -276,6 +279,10 @@ def _group_by_sort_key(x):
276279 self .cache_size = cache_size
277280 _parameters = self .__dict__ .copy ()
278281 _parameters ['group_by' ] = None # overwriting since these parameters will be passed on to other passes.
282+ if log_stacktrace :
283+ self .log_err = logger .exception
284+ else :
285+ self .log_err = logger .error
279286
280287 # Non-Root
281288 if _shared_parameters :
@@ -736,7 +743,7 @@ def _compare_in_order(
736743 self , level ,
737744 t1_from_index = None , t1_to_index = None ,
738745 t2_from_index = None , t2_to_index = None
739- ):
746+ ) -> List [ Tuple [ Tuple [ int , int ], Tuple [ Any , Any ]]] :
740747 """
741748 Default compare if `iterable_compare_func` is not provided.
742749 This will compare in sequence order.
@@ -756,7 +763,7 @@ def _get_matching_pairs(
756763 self , level ,
757764 t1_from_index = None , t1_to_index = None ,
758765 t2_from_index = None , t2_to_index = None
759- ):
766+ ) -> List [ Tuple [ Tuple [ int , int ], Tuple [ Any , Any ]]] :
760767 """
761768 Given a level get matching pairs. This returns list of two tuples in the form:
762769 [
@@ -1088,44 +1095,48 @@ def _create_hashtable(self, level, t):
10881095 # It only includes the ones needed when comparing iterables.
10891096 # The self.hashes dictionary gets shared between different runs of DeepHash
10901097 # So that any object that is already calculated to have a hash is not re-calculated.
1091- deep_hash = DeepHash (item ,
1092- hashes = self .hashes ,
1093- parent = parent ,
1094- apply_hash = True ,
1095- ** self .deephash_parameters ,
1096- )
1098+ deep_hash = DeepHash (
1099+ item ,
1100+ hashes = self .hashes ,
1101+ parent = parent ,
1102+ apply_hash = True ,
1103+ ** self .deephash_parameters ,
1104+ )
10971105 except UnicodeDecodeError as err :
10981106 err .reason = f"Can not produce a hash for { level .path ()} : { err .reason } "
10991107 raise
1100- except Exception as e : # pragma: no cover
1101- logger .error ("Can not produce a hash for %s."
1102- "Not counting this object.\n %s" %
1103- (level .path (), e ))
1108+ except NotImplementedError :
1109+ raise
1110+ # except Exception as e: # pragma: no cover
1111+ # logger.error("Can not produce a hash for %s."
1112+ # "Not counting this object.\n %s" %
1113+ # (level.path(), e))
11041114 else :
11051115 try :
11061116 item_hash = deep_hash [item ]
11071117 except KeyError :
11081118 pass
11091119 else :
11101120 if item_hash is unprocessed : # pragma: no cover
1111- logger . warning ("Item %s was not processed while hashing "
1121+ self . log_err ("Item %s was not processed while hashing "
11121122 "thus not counting this object." %
11131123 level .path ())
11141124 else :
11151125 self ._add_hash (hashes = local_hashes , item_hash = item_hash , item = item , i = i )
11161126
11171127 # Also we hash the iterables themselves too so that we can later create cache keys from those hashes.
1118- try :
1119- DeepHash (
1120- obj ,
1121- hashes = self .hashes ,
1122- parent = level .path (),
1123- apply_hash = True ,
1124- ** self .deephash_parameters ,
1125- )
1126- except Exception as e : # pragma: no cover
1127- logger .error ("Can not produce a hash for iterable %s. %s" %
1128- (level .path (), e ))
1128+ DeepHash (
1129+ obj ,
1130+ hashes = self .hashes ,
1131+ parent = level .path (),
1132+ apply_hash = True ,
1133+ ** self .deephash_parameters ,
1134+ )
1135+ # try:
1136+ # except Exception as e: # pragma: no cover
1137+ # import pytest; pytest.set_trace()
1138+ # self.log_err("Can not produce a hash for iterable %s. %s" %
1139+ # (level.path(), e))
11291140 return local_hashes
11301141
11311142 @staticmethod
0 commit comments