@@ -112,6 +112,7 @@ def _report_progress(_stats, progress_logger, duration):
112
112
'encodings' ,
113
113
'ignore_encoding_errors' ,
114
114
'default_timezone' ,
115
+ 'custom_operators' ,
115
116
)
116
117
117
118
@@ -130,6 +131,7 @@ def __init__(self,
130
131
custom_operators : Optional [List [Any ]] = None ,
131
132
cutoff_distance_for_pairs : float = CUTOFF_DISTANCE_FOR_PAIRS_DEFAULT ,
132
133
cutoff_intersection_for_pairs : float = CUTOFF_INTERSECTION_FOR_PAIRS_DEFAULT ,
134
+ default_timezone :Union [datetime .timezone , datetime .timezone , pytz .tzinfo .BaseTzInfo ]= datetime .timezone .utc ,
133
135
encodings : Optional [List [str ]]= None ,
134
136
exclude_obj_callback : Optional [Callable ]= None ,
135
137
exclude_obj_callback_strict : Optional [Callable ]= None ,
@@ -156,6 +158,8 @@ def __init__(self,
156
158
include_paths : Union [str , List [str ], None ]= None ,
157
159
iterable_compare_func : Optional [Callable ]= None ,
158
160
log_frequency_in_sec : int = 0 ,
161
+ log_scale_similarity_threshold : float = 0.1 ,
162
+ log_stacktrace : bool = False ,
159
163
math_epsilon : Optional [float ]= None ,
160
164
max_diffs : Optional [int ]= None ,
161
165
max_passes : int = 10000000 ,
@@ -164,15 +168,13 @@ def __init__(self,
164
168
progress_logger : Callable = logger .info ,
165
169
report_repetition : bool = False ,
166
170
significant_digits : Optional [int ]= None ,
167
- use_log_scale : bool = False ,
168
- log_scale_similarity_threshold : float = 0.1 ,
169
171
threshold_to_diff_deeper : float = 0.33 ,
170
172
truncate_datetime : Optional [str ]= None ,
171
173
use_enum_value : bool = False ,
174
+ use_log_scale : bool = False ,
172
175
verbose_level : int = 1 ,
173
176
view : str = TEXT_VIEW ,
174
177
zip_ordered_iterables : bool = False ,
175
- default_timezone :Union [datetime .timezone , datetime .timezone , pytz .tzinfo .BaseTzInfo ]= datetime .timezone .utc ,
176
178
_parameters = None ,
177
179
_shared_parameters = None ,
178
180
** kwargs ):
@@ -186,7 +188,7 @@ def __init__(self,
186
188
"ignore_private_variables, ignore_nan_inequality, number_to_string_func, verbose_level, "
187
189
"view, hasher, hashes, max_passes, max_diffs, zip_ordered_iterables, "
188
190
"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, "
190
192
"math_epsilon, iterable_compare_func, use_enum_value, _original_type, threshold_to_diff_deeper, default_timezone "
191
193
"ignore_order_func, custom_operators, encodings, ignore_encoding_errors, use_log_scale, log_scale_similarity_threshold "
192
194
"_parameters and _shared_parameters." ) % ', ' .join (kwargs .keys ()))
@@ -209,6 +211,7 @@ def __init__(self,
209
211
self .log_scale_similarity_threshold = log_scale_similarity_threshold
210
212
self .use_log_scale = use_log_scale
211
213
self .default_timezone = default_timezone
214
+ self .log_stacktrace = log_stacktrace
212
215
self .threshold_to_diff_deeper = threshold_to_diff_deeper
213
216
self .ignore_string_type_changes = ignore_string_type_changes
214
217
self .ignore_type_in_groups = self .get_ignore_types_in_groups (
@@ -276,6 +279,10 @@ def _group_by_sort_key(x):
276
279
self .cache_size = cache_size
277
280
_parameters = self .__dict__ .copy ()
278
281
_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
279
286
280
287
# Non-Root
281
288
if _shared_parameters :
@@ -736,7 +743,7 @@ def _compare_in_order(
736
743
self , level ,
737
744
t1_from_index = None , t1_to_index = None ,
738
745
t2_from_index = None , t2_to_index = None
739
- ):
746
+ ) -> List [ Tuple [ Tuple [ int , int ], Tuple [ Any , Any ]]] :
740
747
"""
741
748
Default compare if `iterable_compare_func` is not provided.
742
749
This will compare in sequence order.
@@ -756,7 +763,7 @@ def _get_matching_pairs(
756
763
self , level ,
757
764
t1_from_index = None , t1_to_index = None ,
758
765
t2_from_index = None , t2_to_index = None
759
- ):
766
+ ) -> List [ Tuple [ Tuple [ int , int ], Tuple [ Any , Any ]]] :
760
767
"""
761
768
Given a level get matching pairs. This returns list of two tuples in the form:
762
769
[
@@ -1088,44 +1095,48 @@ def _create_hashtable(self, level, t):
1088
1095
# It only includes the ones needed when comparing iterables.
1089
1096
# The self.hashes dictionary gets shared between different runs of DeepHash
1090
1097
# 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
+ )
1097
1105
except UnicodeDecodeError as err :
1098
1106
err .reason = f"Can not produce a hash for { level .path ()} : { err .reason } "
1099
1107
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))
1104
1114
else :
1105
1115
try :
1106
1116
item_hash = deep_hash [item ]
1107
1117
except KeyError :
1108
1118
pass
1109
1119
else :
1110
1120
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 "
1112
1122
"thus not counting this object." %
1113
1123
level .path ())
1114
1124
else :
1115
1125
self ._add_hash (hashes = local_hashes , item_hash = item_hash , item = item , i = i )
1116
1126
1117
1127
# 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))
1129
1140
return local_hashes
1130
1141
1131
1142
@staticmethod
0 commit comments