Skip to content

Commit 266ff03

Browse files
committed
updating docs
1 parent 613d6fd commit 266ff03

File tree

7 files changed

+137
-40
lines changed

7 files changed

+137
-40
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ DeepDiff gets the difference of 2 objects.
4848
> - Please take a look at the [DeepDiff docs](deepdiff/diff_doc.rst)
4949
> - The full documentation can be found on <https://deepdiff.readthedocs.io>
5050
51-
## Examples
51+
## A few Examples
52+
53+
> Note: This is just a brief overview of what DeepDiff can do. Please visit <https://deepdiff.readthedocs.io> for full documentation.
5254
5355
### List difference ignoring order or duplicates
5456

@@ -415,6 +417,8 @@ And then running
415417

416418
# ChangeLog
417419

420+
- v4-0-4: Adding ignore_string_case and ignore_type_subclasses
421+
- v4-0-3: Adding versionbump tool for release
418422
- v4-0-2: Fixing installation issue where rst files are missing.
419423
- v4-0-1: Fixing installation Tarball missing requirements.txt . DeepDiff v4+ should not show up as pip installable for Py2. Making Murmur3 installation optional.
420424
- v4-0-0: Ending Python 2 support, Adding more functionalities and documentation for DeepHash. Switching to Pytest for testing. Switching to Murmur3 128bit for hashing. Fixing classes which inherit from classes with slots didn't have all of their slots compared. Renaming ContentHash to DeepHash. Adding exclude by path and regex path to DeepHash. Adding ignore_type_in_groups. Adding match_string to DeepSearch. Adding Timedelta object diffing.

deepdiff/deephash_doc.rst

Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ At the core of it, DeepHash is a deterministic serialization of your object into
1010
can be passed to a hash function. By default it uses Murmur 3 128 bit hash function which is a
1111
fast, non-cryptographic hashing function. You have the option to pass any another hashing function to be used instead.
1212

13-
If it can't find Murmur3 package (mmh3) installed, it uses Python's built-in SHA256 for hashing which is considerably slower than Murmur3. So it is advised that you install Murmur3 by running `pip install mmh3`
13+
If it can't find Murmur3 package (mmh3) installed, it uses Python's built-in SHA256 for hashing which is considerably slower than Murmur3. So it is advised that you install Murmur3 by running `pip install 'deepdiff[murmur]`
1414

1515
**Import**
1616
>>> from deepdiff import DeepHash
@@ -138,6 +138,15 @@ ignore_type_in_groups example with custom objects:
138138
>>> d1[burrito] == d2[taco]
139139
True
140140

141+
142+
ignore_type_subclasses
143+
Use ignore_type_subclasses=True so when ignoring type (class), the subclasses of that class are ignored too.
144+
145+
146+
ignore_string_case
147+
Whether to be case-sensitive or not when comparing strings. By settings ignore_string_case=False, strings will be compared case-insensitively.
148+
149+
141150
**Returns**
142151
A dictionary of {item: item hash}.
143152
If your object is nested, it will build hashes of all the objects it contains too.
@@ -161,43 +170,87 @@ But with DeepHash:
161170
>>> DeepHash(obj)
162171
{1: 234041559348429806012597903916437026784, 2: 148655924348182454950690728321917595655, 'a': 119173504597196970070553896747624927922, 'b': 4994827227437929991738076607196210252, '!>*id4488569408': 32452838416412500686422093274247968754}
163172

164-
So what is exactly the hash of obj in this case?
165-
DeepHash is calculating the hash of the obj and any other object that obj contains.
166-
The output of DeepHash is a dictionary of object IDs to their hashes.
167-
In order to get the hash of obj itself, you need to use the object (or the id of object) to get its hash:
173+
So what is exactly the hash of obj in this case?
174+
DeepHash is calculating the hash of the obj and any other object that obj contains.
175+
The output of DeepHash is a dictionary of object IDs to their hashes.
176+
In order to get the hash of obj itself, you need to use the object (or the id of object) to get its hash:
168177
>>> hashes = DeepHash(obj)
169178
>>> hashes[obj]
170179
34150898645750099477987229399128149852
171180

172-
Which you can write as:
181+
Which you can write as:
173182
>>> hashes = DeepHash(obj)[obj]
174183

175-
At first it might seem weird why DeepHash(obj)[obj] but remember that DeepHash(obj) is a dictionary of hashes of all other objects that obj contains too.
184+
At first it might seem weird why DeepHash(obj)[obj] but remember that DeepHash(obj) is a dictionary of hashes of all other objects that obj contains too.
176185

177-
The result hash is 34150898645750099477987229399128149852 which is generated by
178-
Murmur 3 128bit hashing algorithm. If you prefer to use another hashing algorithm, you can pass it using the hasher parameter. Read more about Murmur3 here: https://en.wikipedia.org/wiki/MurmurHash
186+
The result hash is 34150898645750099477987229399128149852 which is generated by
187+
Murmur 3 128bit hashing algorithm. If you prefer to use another hashing algorithm, you can pass it using the hasher parameter. Read more about Murmur3 here: https://en.wikipedia.org/wiki/MurmurHash
179188

180-
If you do a deep copy of obj, it should still give you the same hash:
189+
If you do a deep copy of obj, it should still give you the same hash:
181190
>>> from copy import deepcopy
182191
>>> obj2 = deepcopy(obj)
183192
>>> DeepHash(obj2)[obj2]
184193
34150898645750099477987229399128149852
185194

186-
Note that by default DeepHash will include string type differences. So if your strings were bytes:
195+
Note that by default DeepHash will include string type differences. So if your strings were bytes:
187196
>>> obj3 = {1: 2, b'a': b'b'}
188197
>>> DeepHash(obj3)[obj3]
189198
64067525765846024488103933101621212760
190199

191-
But if you want the same hash if string types are different, set ignore_string_type_changes to True:
200+
But if you want the same hash if string types are different, set ignore_string_type_changes to True:
192201
>>> DeepHash(obj3, ignore_string_type_changes=True)[obj3]
193202
34150898645750099477987229399128149852
194203

195-
ignore_numeric_type_changes is by default False too.
204+
ignore_numeric_type_changes is by default False too.
196205
>>> obj1 = {4:10}
197206
>>> obj2 = {4.0: Decimal(10.0)}
198207
>>> DeepHash(obj1)[4] == DeepHash(obj2)[4.0]
199208
False
200209

201-
But by setting it to True, we can get the same hash.
210+
But by setting it to True, we can get the same hash.
202211
>>> DeepHash(obj1, ignore_numeric_type_changes=True)[4] == DeepHash(obj2, ignore_numeric_type_changes=True)[4.0]
203212
True
213+
214+
215+
ignore_type_subclasses
216+
Use ignore_type_subclasses=True so when ignoring type (class), the subclasses of that class are ignored too.
217+
218+
>>> from deepdiff import DeepHash
219+
>>>
220+
>>> class ClassB:
221+
... def __init__(self, x):
222+
... self.x = x
223+
... def __repr__(self):
224+
... return "obj b"
225+
...
226+
>>>
227+
>>> class ClassC(ClassB):
228+
... def __repr__(self):
229+
... return "obj c"
230+
...
231+
>>> obj_b = ClassB(1)
232+
>>> obj_c = ClassC(1)
233+
>>>
234+
>>> # Since these 2 objects are from 2 different classes, the hashes are different by default.
235+
... # ignore_type_in_groups is set to [(ClassB, )] which means to ignore any type conversion between
236+
... # objects of classB and itself which does not make sense but it illustrates a better point when
237+
... # ignore_type_subclasses is set to be True.
238+
... hashes_b = DeepHash(obj_b, ignore_type_in_groups=[(ClassB, )])
239+
>>> hashes_c = DeepHash(obj_c, ignore_type_in_groups=[(ClassB, )])
240+
>>> hashes_b[obj_b] != hashes_c[obj_c]
241+
True
242+
>>>
243+
>>> # Hashes of these 2 objects will be the same when ignore_type_subclasses is set to True
244+
... hashes_b = DeepHash(obj_b, ignore_type_in_groups=[(ClassB, )], ignore_type_subclasses=True)
245+
>>> hashes_c = DeepHash(obj_c, ignore_type_in_groups=[(ClassB, )], ignore_type_subclasses=True)
246+
>>> hashes_b[obj_b] == hashes_c[obj_c]
247+
True
248+
249+
ignore_string_case
250+
Whether to be case-sensitive or not when comparing strings. By settings ignore_string_case=False, strings will be compared case-insensitively.
251+
252+
>>> from deepdiff import DeepHash
253+
>>> DeepHash('hello')['hello'] == DeepHash('heLLO')['heLLO']
254+
False
255+
>>> DeepHash('hello', ignore_string_case=True)['hello'] == DeepHash('heLLO', ignore_string_case=True)['heLLO']
256+
True

deepdiff/diff_doc.rst

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ ignore_numeric_type_changes: Boolean, default = False
6969
ignore_type_in_groups: Tuple or List of Tuples, default = None
7070
ignores types when t1 and t2 are both within the same type group.
7171

72+
ignore_type_subclasses: Boolean, default = False
73+
ignore type (class) changes when dealing with the subclasses of classes that were marked to be ignored.
74+
75+
ignore_string_case: Boolean, default = False
76+
Whether to be case-sensitive or not when comparing strings. By settings ignore_string_case=False, strings will be compared case-insensitively.
77+
7278
**Returns**
7379

7480
A DeepDiff object that has already calculated the difference of the 2 items.
@@ -322,31 +328,27 @@ Exclude certain types from comparison:
322328
{}
323329

324330
ignore_type_in_groups
331+
Ignore type changes between members of groups of types. For example if you want to ignore type changes between float and decimals etc. Note that this is a more granular feature. Most of the times the shortcuts provided to you are enough.
332+
The shortcuts are ignore_string_type_changes which by default is False and ignore_numeric_type_changes which is by default False. You can read more about those shortcuts in this page. ignore_type_in_groups gives you more control compared to the shortcuts.
325333

326-
Ignore type changes between members of groups of types. For example if you want to ignore type changes between float and decimals etc. Note that this is a more granular feature. Most of the times the shortcuts provided to you are enough.
327-
The shortcuts are ignore_string_type_changes which by default is False and ignore_numeric_type_changes which is by default False. You can read more about those shortcuts in this page. ignore_type_in_groups gives you more control compared to the shortcuts.
334+
For example lets say you have specifically str and byte datatypes to be ignored for type changes. Then you have a couple of options:
328335

329-
For example lets say you have specifically str and byte datatypes to be ignored for type changes. Then you have a couple of options:
336+
1. Set ignore_string_type_changes=True.
337+
2. Or set ignore_type_in_groups=[(str, bytes)]. Here you are saying if we detect one type to be str and the other one bytes, do not report them as type change. It is exactly as passing ignore_type_in_groups=[DeepDiff.strings] or ignore_type_in_groups=DeepDiff.strings .
330338

331-
1. Set ignore_string_type_changes=True.
332-
2. Or set ignore_type_in_groups=[(str, bytes)]. Here you are saying if we detect one type to be str and the other one bytes, do not report them as type change. It is exactly as passing ignore_type_in_groups=[DeepDiff.strings] or ignore_type_in_groups=DeepDiff.strings .
339+
Now what if you want also typeA and typeB to be ignored when comparing agains each other?
333340

334-
Now what if you want also typeA and typeB to be ignored when comparing agains each other?
341+
1. ignore_type_in_groups=[DeepDiff.strings, (typeA, typeB)]
342+
2. or ignore_type_in_groups=[(str, bytes), (typeA, typeB)]
335343

336-
1. ignore_type_in_groups=[DeepDiff.strings, (typeA, typeB)]
337-
2. or ignore_type_in_groups=[(str, bytes), (typeA, typeB)]
338-
339-
ignore_string_type_changes
340-
Default: False
344+
ignore_string_type_changes Default: False
341345
>>> DeepDiff(b'hello', 'hello', ignore_string_type_changes=True)
342346
{}
343347
>>> DeepDiff(b'hello', 'hello')
344348
{'type_changes': {'root': {'old_type': <class 'bytes'>, 'new_type': <class 'str'>, 'old_value': b'hello', 'new_value': 'hello'}}}
345349

346-
ignore_numeric_type_changes
347-
Default: False
348-
349-
Ignore Type Number - Dictionary that contains float and integer:
350+
ignore_numeric_type_changes Default: False
351+
Ignore Type Number - Dictionary that contains float and integer
350352
>>> from deepdiff import DeepDiff
351353
>>> from pprint import pprint
352354
>>> t1 = {1: 1, 2: 2.22}
@@ -361,7 +363,7 @@ Ignore Type Number - Dictionary that contains float and integer:
361363
>>> pprint(ddiff, indent=2)
362364
{}
363365

364-
Ignore Type Number - List that contains float and integer:
366+
Ignore Type Number - List that contains float and integer
365367
>>> from deepdiff import DeepDiff
366368
>>> from pprint import pprint
367369
>>> t1 = [1, 2, 3]
@@ -384,7 +386,7 @@ Ignore Type Number - List that contains float and integer:
384386
>>> pprint(ddiff, indent=2)
385387
{}
386388

387-
You can pass a list of tuples or list of lists if you have various type groups. When t1 and t2 both fall under one of these type groups, the type change will be ignored. DeepDiff already comes with 2 groups: DeepDiff.strings and DeepDiff.numbers . If you want to pass both:
389+
You can pass a list of tuples or list of lists if you have various type groups. When t1 and t2 both fall under one of these type groups, the type change will be ignored. DeepDiff already comes with 2 groups: DeepDiff.strings and DeepDiff.numbers . If you want to pass both:
388390
>>> ignore_type_in_groups = [DeepDiff.strings, DeepDiff.numbers]
389391

390392

@@ -411,6 +413,39 @@ ignore_type_in_groups example with custom objects:
411413
{}
412414

413415

416+
ignore_type_subclasses
417+
Use ignore_type_subclasses=True so when ignoring type (class), the subclasses of that class are ignored too.
418+
419+
>>> from deepdiff import DeepDiff
420+
>>> class ClassA:
421+
... def __init__(self, x, y):
422+
... self.x = x
423+
... self.y = y
424+
...
425+
>>> class ClassB:
426+
... def __init__(self, x):
427+
... self.x = x
428+
...
429+
>>> class ClassC(ClassB):
430+
... pass
431+
...
432+
>>> obj_a = ClassA(1, 2)
433+
>>> obj_c = ClassC(3)
434+
>>>
435+
>>> DeepDiff(obj_a, obj_c, ignore_type_in_groups=[(ClassA, ClassB)], ignore_type_subclasses=False)
436+
{'type_changes': {'root': {'old_type': <class '__main__.ClassA'>, 'new_type': <class '__main__.ClassC'>, 'old_value': <__main__.ClassA object at 0x10076a2e8>, 'new_value': <__main__.ClassC object at 0x10082f630>}}}
437+
>>>
438+
>>> DeepDiff(obj_a, obj_c, ignore_type_in_groups=[(ClassA, ClassB)], ignore_type_subclasses=True)
439+
{'values_changed': {'root.x': {'new_value': 3, 'old_value': 1}}, 'attribute_removed': [root.y]}
440+
441+
ignore_string_case
442+
Whether to be case-sensitive or not when comparing strings. By settings ignore_string_case=False, strings will be compared case-insensitively.
443+
444+
>>> DeepDiff(t1='Hello', t2='heLLO')
445+
{'values_changed': {'root': {'new_value': 'heLLO', 'old_value': 'Hello'}}}
446+
>>> DeepDiff(t1='Hello', t2='heLLO', ignore_string_case=True)
447+
{}
448+
414449
**Tree View**
415450

416451
Starting the version 3 You can chooe the view into the deepdiff results.

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252

5353
# General information about the project.
5454
project = 'DeepDiff'
55-
copyright = '2015-2017, Sep Dehpour'
55+
copyright = '2015-2019, Sep Dehpour'
5656
author = 'Sep Dehpour'
5757

5858
# The version info for the project you're documenting, acts as replacement for

docs/index.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Install from PyPi::
2727

2828
DeepDiff prefers to use Murmur3 for hashing. However you have to manually install Murmur3 by running::
2929

30-
pip install mmh3
30+
pip install 'deepdiff[murmur]'
3131

3232
Otherwise DeepDiff will be using SHA256 for hashing which is a cryptographic hash and is considerably slower.
3333

@@ -51,7 +51,7 @@ Read The DeepDiff details in:
5151

5252
:doc:`/diff`
5353

54-
Short introduction::
54+
Short introduction
5555

5656
Supported data types
5757
~~~~~~~~~~~~~~~~~~~~
@@ -281,6 +281,8 @@ Indices and tables
281281
Changelog
282282
=========
283283

284+
- v4-0-4: Adding ignore_string_case and ignore_type_subclasses
285+
- v4-0-3: Adding versionbump tool for release
284286
- v4-0-2: Fixing installation issue where rst files are missing.
285287
- v4-0-1: Fixing installation Tarball missing requirements.txt . DeepDiff v4+ should not show up as pip installable for Py2. Making Murmur3 installation optional.
286288
- v4-0-0: Ending Python 2 support, Adding more functionalities and documentation for DeepHash. Switching to Pytest for testing. Switching to Murmur3 128bit for hashing. Fixing classes which inherit from classes with slots didn't have all of their slots compared. Renaming ContentHash to DeepHash. Adding exclude by path and regex path to DeepHash. Adding ignore_type_in_groups. Adding match_string to DeepSearch. Adding Timedelta object diffing.

tests/test_diff_text.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,8 @@ def __init__(self, x):
914914
self.x = x
915915

916916
class ClassC(ClassB):
917-
pass
917+
def __repr__(self):
918+
return "obj c"
918919

919920
obj_a = ClassA(1, 2)
920921
obj_c = ClassC(3)

tests/test_hash.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -349,17 +349,19 @@ class ClassC(ClassB):
349349
pass
350350

351351
obj_a = ClassA(1, 2)
352+
obj_b = ClassB(1, 2)
352353
obj_c = ClassC(1, 2)
353354

354355
burrito = Burrito()
355356
taco = Taco()
356357

357358
@pytest.mark.parametrize("t1, t2, ignore_type_in_groups, ignore_type_subclasses, is_qual", [
358-
# (taco, burrito, [], False, False),
359-
# (taco, burrito, [(Taco, Burrito)], False, True),
360-
# ([taco], [burrito], [(Taco, Burrito)], False, True),
361-
# ([obj_a], [obj_c], [(ClassA, ClassB)], False, False),
359+
(taco, burrito, [], False, False),
360+
(taco, burrito, [(Taco, Burrito)], False, True),
361+
([taco], [burrito], [(Taco, Burrito)], False, True),
362+
([obj_a], [obj_c], [(ClassA, ClassB)], False, False),
362363
([obj_a], [obj_c], [(ClassA, ClassB)], True, True),
364+
([obj_b], [obj_c], [(ClassB, )], True, True),
363365
])
364366
def test_objects_with_same_content(self, t1, t2, ignore_type_in_groups, ignore_type_subclasses, is_qual):
365367

0 commit comments

Comments
 (0)