From 4f34fe2dae62c455a2ec7425772e7f1af88ca4c6 Mon Sep 17 00:00:00 2001 From: Sep Dehpour Date: Wed, 5 Mar 2025 13:27:22 -0800 Subject: [PATCH] adding mypy.ini but there are still way too many mypy errors --- deepdiff/__init__.py | 10 ++++----- deepdiff/deephash.py | 26 +++++++++++------------ deepdiff/delta.py | 46 ++++++++++++++++++++--------------------- deepdiff/lfucache.py | 36 ++++++++++++++++---------------- docs/faq.rst | 1 + mypy.ini | 2 ++ requirements-dev.txt | 1 + tests/test_operators.py | 10 +++++---- 8 files changed, 69 insertions(+), 63 deletions(-) create mode 100644 mypy.ini diff --git a/deepdiff/__init__.py b/deepdiff/__init__.py index 587ea86..eb6f272 100644 --- a/deepdiff/__init__.py +++ b/deepdiff/__init__.py @@ -7,8 +7,8 @@ logging.basicConfig(format='%(asctime)s %(levelname)8s %(message)s') -from .diff import DeepDiff -from .search import DeepSearch, grep -from .deephash import DeepHash -from .delta import Delta -from .path import extract, parse_path +from .diff import DeepDiff as DeepDiff +from .search import DeepSearch as DeepSearch, grep as grep +from .deephash import DeepHash as DeepHash +from .delta import Delta as Delta +from .path import extract as extract, parse_path as parse_path diff --git a/deepdiff/deephash.py b/deepdiff/deephash.py index 18c90bd..98ff7d0 100644 --- a/deepdiff/deephash.py +++ b/deepdiff/deephash.py @@ -107,8 +107,8 @@ def prepare_string_for_hashing( break except UnicodeDecodeError as er: err = er - if not encoded: - obj_decoded = obj.decode('utf-8', errors='ignore') + if not encoded and err is not None: + obj_decoded = obj.decode('utf-8', errors='ignore') # type: ignore start = max(err.start - 20, 0) start_prefix = '' if start > 0: @@ -379,7 +379,7 @@ def _skip_this(self, obj, parent): skip = False break elif self.exclude_regex_paths and any( - [exclude_regex_path.search(parent) for exclude_regex_path in self.exclude_regex_paths]): + [exclude_regex_path.search(parent) for exclude_regex_path in self.exclude_regex_paths]): # type: ignore skip = True elif self.exclude_types_tuple and isinstance(obj, self.exclude_types_tuple): skip = True @@ -540,7 +540,7 @@ def _hash(self, obj, parent, parents_ids=EMPTY_FROZENSET): elif isinstance(obj, datetime.date): result = self._prep_date(obj) - elif isinstance(obj, numbers): + elif isinstance(obj, numbers): # type: ignore result = self._prep_number(obj) elif isinstance(obj, MutableMapping): @@ -549,17 +549,17 @@ def _hash(self, obj, parent, parents_ids=EMPTY_FROZENSET): elif isinstance(obj, tuple): result, counts = self._prep_tuple(obj=obj, parent=parent, parents_ids=parents_ids) - elif (pandas and isinstance(obj, pandas.DataFrame)): - def gen(): - yield ('dtype', obj.dtypes) - yield ('index', obj.index) - yield from obj.items() # which contains (column name, series tuples) + elif (pandas and isinstance(obj, pandas.DataFrame)): # type: ignore + def gen(): # type: ignore + yield ('dtype', obj.dtypes) # type: ignore + yield ('index', obj.index) # type: ignore + yield from obj.items() # type: ignore # which contains (column name, series tuples) result, counts = self._prep_iterable(obj=gen(), parent=parent, parents_ids=parents_ids) - elif (polars and isinstance(obj, polars.DataFrame)): + elif (polars and isinstance(obj, polars.DataFrame)): # type: ignore def gen(): - yield from obj.columns - yield from list(obj.schema.items()) - yield from obj.rows() + yield from obj.columns # type: ignore + yield from list(obj.schema.items()) # type: ignore + yield from obj.rows() # type: ignore result, counts = self._prep_iterable(obj=gen(), parent=parent, parents_ids=parents_ids) elif isinstance(obj, Iterable): diff --git a/deepdiff/delta.py b/deepdiff/delta.py index 63fea81..a76593c 100644 --- a/deepdiff/delta.py +++ b/deepdiff/delta.py @@ -171,7 +171,7 @@ def reset(self): self.post_process_paths_to_convert = dict_() def __add__(self, other): - if isinstance(other, numbers) and self._numpy_paths: + if isinstance(other, numbers) and self._numpy_paths: # type: ignore raise DeltaNumpyOperatorOverrideError(DELTA_NUMPY_OPERATOR_OVERRIDE_MSG) if self.mutate: self.root = other @@ -240,7 +240,7 @@ def _get_elem_and_compare_to_old_value( if action == GET: current_old_value = obj[elem] elif action == GETATTR: - current_old_value = getattr(obj, elem) + current_old_value = getattr(obj, elem) # type: ignore else: raise DeltaError(INVALID_ACTION_WHEN_CALLING_GET_ELEM.format(action)) except (KeyError, IndexError, AttributeError, TypeError) as e: @@ -261,7 +261,7 @@ def _get_elem_and_compare_to_old_value( else: obj[elem] = _forced_old_value elif action == GETATTR: - setattr(obj, elem, _forced_old_value) + setattr(obj, elem, _forced_old_value) # type: ignore return _forced_old_value current_old_value = not_found if isinstance(path_for_err_reporting, (list, tuple)): @@ -289,7 +289,7 @@ def _simple_set_elem_value(self, obj, path_for_err_reporting, elem=None, value=N else: self._raise_or_log(ELEM_NOT_FOUND_TO_ADD_MSG.format(elem, path_for_err_reporting)) elif action == GETATTR: - setattr(obj, elem, value) + setattr(obj, elem, value) # type: ignore else: raise DeltaError(INVALID_ACTION_WHEN_CALLING_SIMPLE_SET_ELEM.format(action)) except (KeyError, IndexError, AttributeError, TypeError) as e: @@ -457,8 +457,8 @@ def _do_item_added(self, items, sort=True, insert=False): continue # pragma: no cover. Due to cPython peephole optimizer, this line doesn't get covered. https://github.com/nedbat/coveragepy/issues/198 # Insert is only true for iterables, make sure it is a valid index. - if(insert and elem < len(obj)): - obj.insert(elem, None) + if(insert and elem < len(obj)): # type: ignore + obj.insert(elem, None) # type: ignore self._set_new_value(parent, parent_to_obj_elem, parent_to_obj_action, obj, elements, path, elem, action, new_value) @@ -482,7 +482,7 @@ def _do_post_process(self): def _do_pre_process(self): if self._numpy_paths and ('iterable_item_added' in self.diff or 'iterable_item_removed' in self.diff): preprocess_paths = dict_() - for path, type_ in self._numpy_paths.items(): + for path, type_ in self._numpy_paths.items(): # type: ignore preprocess_paths[path] = {'old_type': np_ndarray, 'new_type': list} try: type_ = numpy_dtype_string_to_type(type_) @@ -507,7 +507,7 @@ def _get_elements_and_details(self, path): parent_to_obj_elem, parent_to_obj_action = elements[-2] obj = self._get_elem_and_compare_to_old_value( obj=parent, path_for_err_reporting=path, expected_old_value=None, - elem=parent_to_obj_elem, action=parent_to_obj_action, next_element=next2_element) + elem=parent_to_obj_elem, action=parent_to_obj_action, next_element=next2_element) # type: ignore else: # parent = self # obj = self.root @@ -516,7 +516,7 @@ def _get_elements_and_details(self, path): parent = parent_to_obj_elem = parent_to_obj_action = None obj = self # obj = self.get_nested_obj(obj=self, elements=elements[:-1]) - elem, action = elements[-1] + elem, action = elements[-1] # type: ignore except Exception as e: self._raise_or_log(UNABLE_TO_GET_ITEM_MSG.format(path, e)) return None @@ -550,7 +550,7 @@ def _do_values_or_type_changed(self, changes, is_type_change=False, verify_chang else: new_value = new_type(current_old_value) except Exception as e: - self._raise_or_log(TYPE_CHANGE_FAIL_MSG.format(obj[elem], value.get('new_type', 'unknown'), e)) + self._raise_or_log(TYPE_CHANGE_FAIL_MSG.format(obj[elem], value.get('new_type', 'unknown'), e)) # type: ignore continue else: new_value = value['new_value'] @@ -582,7 +582,7 @@ def _do_item_removed(self, items): current_old_value = not_found try: if action == GET: - current_old_value = obj[elem] + current_old_value = obj[elem] # type: ignore elif action == GETATTR: current_old_value = getattr(obj, elem) look_for_expected_old_value = current_old_value != expected_old_value @@ -644,15 +644,15 @@ def _do_iterable_opcodes(self): transformed.extend(opcode.new_values) elif opcode.tag == 'equal': # Items are the same in both lists, so we add them to the result - transformed.extend(obj[opcode.t1_from_index:opcode.t1_to_index]) + transformed.extend(obj[opcode.t1_from_index:opcode.t1_to_index]) # type: ignore if is_obj_tuple: - obj = tuple(obj) + obj = tuple(obj) # type: ignore # Making sure that the object is re-instated inside the parent especially if it was immutable # and we had to turn it into a mutable one. In such cases the object has a new id. self._simple_set_elem_value(obj=parent, path_for_err_reporting=path, elem=parent_to_obj_elem, value=obj, action=parent_to_obj_action) else: - obj[:] = transformed + obj[:] = transformed # type: ignore @@ -745,7 +745,7 @@ def _do_ignore_order(self): fixed_indexes = self.diff.get('iterable_items_added_at_indexes', dict_()) remove_indexes = self.diff.get('iterable_items_removed_at_indexes', dict_()) paths = SetOrdered(fixed_indexes.keys()) | SetOrdered(remove_indexes.keys()) - for path in paths: + for path in paths: # type: ignore # In the case of ignore_order reports, we are pointing to the container object. # Thus we add a [0] to the elements so we can get the required objects and discard what we don't need. elem_and_details = self._get_elements_and_details("{}[0]".format(path)) @@ -1021,7 +1021,7 @@ def _from_flat_dicts(flat_dict_list): result['_iterable_opcodes'][path_str] = [] result['_iterable_opcodes'][path_str].append( Opcode( - tag=FLAT_DATA_ACTION_TO_OPCODE_TAG[action], + tag=FLAT_DATA_ACTION_TO_OPCODE_TAG[action], # type: ignore t1_from_index=flat_dict.get('t1_from_index'), t1_to_index=flat_dict.get('t1_to_index'), t2_from_index=flat_dict.get('t2_from_index'), @@ -1091,7 +1091,7 @@ def to_flat_dicts(self, include_action_in_path=False, report_type_changes=True) """ return [ i._asdict() for i in self.to_flat_rows(include_action_in_path=False, report_type_changes=True) - ] + ] # type: ignore def to_flat_rows(self, include_action_in_path=False, report_type_changes=True) -> List[FlatDeltaRow]: """ @@ -1141,13 +1141,13 @@ def to_flat_rows(self, include_action_in_path=False, report_type_changes=True) - for index, value in index_to_value.items(): path2 = path.copy() if include_action_in_path: - path2.append((index, 'GET')) + path2.append((index, 'GET')) # type: ignore else: path2.append(index) if report_type_changes: - row = FlatDeltaRow(path=path2, value=value, action=new_action, type=type(value)) + row = FlatDeltaRow(path=path2, value=value, action=new_action, type=type(value)) # type: ignore else: - row = FlatDeltaRow(path=path2, value=value, action=new_action) + row = FlatDeltaRow(path=path2, value=value, action=new_action) # type: ignore result.append(row) elif action in {'set_item_added', 'set_item_removed'}: for path, values in info.items(): @@ -1167,15 +1167,15 @@ def to_flat_rows(self, include_action_in_path=False, report_type_changes=True) - value = value[new_key] elif isinstance(value, (list, tuple)) and len(value) == 1: value = value[0] - path.append(0) + path.append(0) # type: ignore action = 'iterable_item_added' elif isinstance(value, set) and len(value) == 1: value = value.pop() action = 'set_item_added' if report_type_changes: - row = FlatDeltaRow(path=path, value=value, action=action, type=type(value)) + row = FlatDeltaRow(path=path, value=value, action=action, type=type(value)) # type: ignore else: - row = FlatDeltaRow(path=path, value=value, action=action) + row = FlatDeltaRow(path=path, value=value, action=action) # type: ignore result.append(row) elif action in { 'dictionary_item_removed', 'iterable_item_added', diff --git a/deepdiff/lfucache.py b/deepdiff/lfucache.py index 3aa168a..75d1708 100644 --- a/deepdiff/lfucache.py +++ b/deepdiff/lfucache.py @@ -23,17 +23,17 @@ def __init__(self, key, report_type, value, freq_node, pre, nxt): self.nxt = nxt # next CacheNode def free_myself(self): - if self.freq_node.cache_head == self.freq_node.cache_tail: - self.freq_node.cache_head = self.freq_node.cache_tail = None - elif self.freq_node.cache_head == self: - self.nxt.pre = None - self.freq_node.cache_head = self.nxt - elif self.freq_node.cache_tail == self: - self.pre.nxt = None - self.freq_node.cache_tail = self.pre + if self.freq_node.cache_head == self.freq_node.cache_tail: # type: ignore + self.freq_node.cache_head = self.freq_node.cache_tail = None # type: ignore + elif self.freq_node.cache_head == self: # type: ignore + self.nxt.pre = None # type: ignore + self.freq_node.cache_head = self.nxt # type: ignore + elif self.freq_node.cache_tail == self: # type: ignore + self.pre.nxt = None # type: ignore + self.freq_node.cache_tail = self.pre # type: ignore else: - self.pre.nxt = self.nxt - self.nxt.pre = self.pre + self.pre.nxt = self.nxt # type: ignore + self.nxt.pre = self.pre # type: ignore self.pre = None self.nxt = None @@ -77,8 +77,8 @@ def pop_head_cache(self): return cache_head else: cache_head = self.cache_head - self.cache_head.nxt.pre = None - self.cache_head = self.cache_head.nxt + self.cache_head.nxt.pre = None # type: ignore + self.cache_head = self.cache_head.nxt # type: ignore return cache_head def append_cache_to_tail(self, cache_node): @@ -89,7 +89,7 @@ def append_cache_to_tail(self, cache_node): else: cache_node.pre = self.cache_tail cache_node.nxt = None - self.cache_tail.nxt = cache_node + self.cache_tail.nxt = cache_node # type: ignore self.cache_tail = cache_node def insert_after_me(self, freq_node): @@ -172,12 +172,12 @@ def move_forward(self, cache_node, freq_node): def dump_cache(self): head_freq_node = self.freq_link_head - self.cache.pop(head_freq_node.cache_head.key) - head_freq_node.pop_head_cache() + self.cache.pop(head_freq_node.cache_head.key) # type: ignore + head_freq_node.pop_head_cache() # type: ignore - if head_freq_node.count_caches() == 0: - self.freq_link_head = head_freq_node.nxt - head_freq_node.remove() + if head_freq_node.count_caches() == 0: # type: ignore + self.freq_link_head = head_freq_node.nxt # type: ignore + head_freq_node.remove() # type: ignore def create_cache_node(self, key, report_type, value): cache_node = CacheNode( diff --git a/docs/faq.rst b/docs/faq.rst index ce97948..497ae2a 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -149,6 +149,7 @@ Or use the tree view so you can use path(output_format='list'): Q: Why my datetimes are reported in UTC? +---------------------------------------- **Answer** diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 0000000..07a7f36 --- /dev/null +++ b/mypy.ini @@ -0,0 +1,2 @@ +[mypy] +warn_unused_ignores = False diff --git a/requirements-dev.txt b/requirements-dev.txt index 495ebc9..a0a5ea2 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -19,3 +19,4 @@ pytest-benchmark==5.1.0 pandas==2.2.3 polars==1.21.0 setuptools==75.8.0 +types-setuptools==75.8.0 diff --git a/tests/test_operators.py b/tests/test_operators.py index d3ba07b..ddc91a0 100644 --- a/tests/test_operators.py +++ b/tests/test_operators.py @@ -31,7 +31,7 @@ def _l2_distance(self, c1, c2): (c1["x"] - c2["x"]) ** 2 + (c1["y"] - c2["y"]) ** 2 ) - def give_up_diffing(self, level, diff_instance): + def give_up_diffing(self, level, diff_instance) -> bool: l2_distance = self._l2_distance(level.t1, level.t2) if l2_distance > self.distance_threshold: diff_instance.custom_report_result('distance_too_far', level, { @@ -77,7 +77,7 @@ def _l2_distance(self, c1, c2): (c1["x"] - c2["x"]) ** 2 + (c1["y"] - c2["y"]) ** 2 ) - def give_up_diffing(self, level, diff_instance): + def give_up_diffing(self, level, diff_instance) -> bool: l2_distance = self._l2_distance(level.t1, level.t2) if l2_distance > self.distance_threshold: diff_instance.custom_report_result('distance_too_far', level, { @@ -122,7 +122,7 @@ class ExpectChangeOperator(BaseOperator): def __init__(self, regex_paths): super().__init__(regex_paths) - def give_up_diffing(self, level, diff_instance): + def give_up_diffing(self, level, diff_instance) -> bool: if level.t1 == level.t2: diff_instance.custom_report_result('unexpected:still', level, { "old": level.t1, @@ -154,9 +154,10 @@ def __repr__(self): class ListMatchOperator(BaseOperator): - def give_up_diffing(self, level, diff_instance): + def give_up_diffing(self, level, diff_instance) -> bool: if set(level.t1.dict['list']) == set(level.t2.dict['list']): return True + return False ddiff = DeepDiff(custom1, custom2, custom_operators=[ ListMatchOperator(types=[CustomClass]) @@ -260,6 +261,7 @@ def __init__(self, tolerance, types): def match(self, level) -> bool: if type(level.t1) in self.types: return True + return False def give_up_diffing(self, level, diff_instance) -> bool: relative = abs(abs(level.t1 - level.t2) / level.t1)