Skip to content

Commit d315d30

Browse files
committed
feat: implement len(DirectorySnapshotDiff) to return the total number of changes
1 parent cad7f25 commit d315d30

File tree

3 files changed

+17
-0
lines changed

3 files changed

+17
-0
lines changed

changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Changelog
1010

1111
- Adjust ``Observer.schedule()`` ``path`` type annotation to reflect the ``pathlib.Path`` support. (`#1096 <https://github.com/gorakhargosh/watchdog/pull/1096>`__)
1212
- [utils] Fixed ``repr(EmptyDirectorySnapshot)``, before that it was throwing an ``AttributeError: 'EmptyDirectorySnapshot' object has no attribute '_stat_info'``.
13+
- [utils] Implemented ``len(DirectorySnapshotDiff)`` to return the total number of changes.
1314
- Thanks to our beloved contributors: @BoboTiG, @tybug
1415

1516
**Breaking Changes**

src/watchdog/utils/dirsnapshot.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,9 @@ def __repr__(self) -> str:
153153
len(self._dirs_moved),
154154
)
155155

156+
def __len__(self) -> int:
157+
return sum(len(getattr(self, attr)) for attr in dir(self) if attr.startswith(("_dirs_", "_files_")))
158+
156159
@property
157160
def files_created(self) -> list[bytes | str]:
158161
"""List of files that were created."""

tests/test_snapshot_diff.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ def test_move_to(p):
3838
ref = DirectorySnapshot(p("dir2"))
3939
mv(p("dir1", "a"), p("dir2", "b"))
4040
diff = DirectorySnapshotDiff(ref, DirectorySnapshot(p("dir2")))
41+
assert len(diff) == 2
4142
assert diff.files_created == [p("dir2", "b")]
4243

4344

@@ -51,6 +52,8 @@ def test_move_to_with_context_manager(p):
5152
with dir1_cm, dir2_cm:
5253
mv(p("dir1", "a"), p("dir2", "b"))
5354

55+
assert len(dir1_cm.diff) == 2
56+
assert len(dir2_cm.diff) == 2
5457
assert dir1_cm.diff.files_deleted == [p("dir1", "a")]
5558
assert dir2_cm.diff.files_created == [p("dir2", "b")]
5659

@@ -62,6 +65,7 @@ def test_move_from(p):
6265
ref = DirectorySnapshot(p("dir1"))
6366
mv(p("dir1", "a"), p("dir2", "b"))
6467
diff = DirectorySnapshotDiff(ref, DirectorySnapshot(p("dir1")))
68+
assert len(diff) == 2
6569
assert diff.files_deleted == [p("dir1", "a")]
6670

6771

@@ -72,6 +76,7 @@ def test_move_internal(p):
7276
ref = DirectorySnapshot(p(""))
7377
mv(p("dir1", "a"), p("dir2", "b"))
7478
diff = DirectorySnapshotDiff(ref, DirectorySnapshot(p("")))
79+
assert len(diff) == 3
7580
assert diff.files_moved == [(p("dir1", "a"), p("dir2", "b"))]
7681
assert diff.files_created == []
7782
assert diff.files_deleted == []
@@ -85,6 +90,7 @@ def test_move_replace(p):
8590
ref = DirectorySnapshot(p(""))
8691
mv(p("dir1", "a"), p("dir2", "b"))
8792
diff = DirectorySnapshotDiff(ref, DirectorySnapshot(p("")))
93+
assert len(diff) == 3
8894
assert diff.files_moved == [(p("dir1", "a"), p("dir2", "b"))]
8995
assert diff.files_deleted == [p("dir2", "b")]
9096
assert diff.files_created == []
@@ -95,6 +101,7 @@ def test_dir_modify_on_create(p):
95101
wait()
96102
touch(p("a"))
97103
diff = DirectorySnapshotDiff(ref, DirectorySnapshot(p("")))
104+
assert len(diff) == 2
98105
assert diff.dirs_modified == [p("")]
99106

100107

@@ -106,6 +113,7 @@ def test_dir_modify_on_move(p):
106113
wait()
107114
mv(p("dir1", "a"), p("dir2", "b"))
108115
diff = DirectorySnapshotDiff(ref, DirectorySnapshot(p("")))
116+
assert len(diff) == 3
109117
assert set(diff.dirs_modified) == {p("dir1"), p("dir2")}
110118

111119

@@ -116,6 +124,7 @@ def test_detect_modify_for_moved_files(p):
116124
touch(p("a"))
117125
mv(p("a"), p("b"))
118126
diff = DirectorySnapshotDiff(ref, DirectorySnapshot(p("")))
127+
assert len(diff) == 3
119128
assert diff.files_moved == [(p("a"), p("b"))]
120129
assert diff.files_modified == [p("a")]
121130

@@ -159,6 +168,7 @@ def walk(self, root):
159168

160169
diff = DirectorySnapshotDiff(ref, new_snapshot)
161170
assert repr(diff)
171+
assert len(diff) == 1
162172

163173
# Children of a/b/ are no more accessible and so removed in the new snapshot
164174
assert diff.dirs_deleted == [(p("a", "b", "c"))]
@@ -189,13 +199,15 @@ def inode(self, path):
189199
# be different), it thinks that the same file has been deleted and created again.
190200
snapshot = DirectorySnapshot(p(""))
191201
diff_with_device = DirectorySnapshotDiff(ref, snapshot)
202+
assert len(diff_with_device) == 4
192203
assert diff_with_device.files_deleted == [(p("file"))]
193204
assert diff_with_device.files_created == [(p("file"))]
194205

195206
# Otherwise, if we choose to ignore the device, the file will not be detected as
196207
# deleted and re-created.
197208
snapshot = DirectorySnapshot(p(""))
198209
diff_without_device = DirectorySnapshotDiff(ref, snapshot, ignore_device=True)
210+
assert not len(diff_without_device)
199211
assert diff_without_device.files_deleted == []
200212
assert diff_without_device.files_created == []
201213

@@ -213,5 +225,6 @@ def test_empty_snapshot(p):
213225
assert repr(empty) == "{}"
214226

215227
diff = DirectorySnapshotDiff(empty, ref)
228+
assert len(diff) == 4
216229
assert diff.files_created == [p("a")]
217230
assert sorted(diff.dirs_created) == sorted([p(""), p("b"), p("b", "c")])

0 commit comments

Comments
 (0)