inspectr 0.0.2__py3-none-any.whl → 0.0.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
inspectr/duplicates.py ADDED
@@ -0,0 +1,51 @@
1
+ # mytool/duplicates.py
2
+ import sys
3
+ import hashlib
4
+ from collections import defaultdict
5
+
6
+ def find_duplicates(files, block_size=1, min_occur=2):
7
+ """
8
+ Find duplicate blocks of code across files.
9
+
10
+ Args:
11
+ files: list of file paths
12
+ block_size: number of consecutive lines in a block
13
+ min_occur: minimum number of occurrences to report
14
+
15
+ Yields:
16
+ (filename, line_number, count)
17
+ """
18
+ blocks = defaultdict(list) # hash -> list of (file, line)
19
+
20
+ for fname in files:
21
+ try:
22
+ with open(fname, encoding="utf-8") as f:
23
+ lines = f.readlines()
24
+ except OSError as e:
25
+ print(f"Could not read {fname}: {e}", file=sys.stderr)
26
+ continue
27
+
28
+ for i in range(len(lines) - block_size + 1):
29
+ # join block of lines
30
+ block = "".join(lines[i:i + block_size])
31
+ # stable hash
32
+ h = hashlib.sha1(block.encode("utf-8")).hexdigest()
33
+ blocks[h].append((fname, i + 1))
34
+
35
+ for locs in blocks.values():
36
+ if len(locs) >= min_occur:
37
+ for fname, lnum in locs:
38
+ yield fname, lnum, len(locs)
39
+
40
+
41
+ def main(args=None) -> None:
42
+ if args is None:
43
+ args = sys.argv[1:]
44
+
45
+ if not args:
46
+ print("Usage: inspectr duplicates file1.py [file2.py ...]")
47
+ return
48
+
49
+ for fname, lnum, count in find_duplicates(args, block_size=1, min_occur=2):
50
+ print(f"{fname}:{lnum} (occurs {count} times)")
51
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: inspectr
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Summary: A collection of python tools to inspect code quality.
5
5
  Maintainer-email: Alex Mueller <amueller474@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -3,11 +3,12 @@ inspectr/__main__.py,sha256=Rojob_KTdzcHjItkGgA3TPLqPd223pIfeajpCWDP3Gc,652
3
3
  inspectr/authenticity.py,sha256=fgKJSE_1qYE1NgLdXmOjPQjo-dwD42sEhqpcsazIj3U,1703
4
4
  inspectr/bare_ratio.py,sha256=oQfag96zjGnmFHofZ5qabBGGVoKUnmRNzGq_WX_8ZZg,1997
5
5
  inspectr/count_exceptions.py,sha256=UhUc3ZZY8eDxLtlLX1USKzP_JEPY3clx8R8TPvtQ5LE,1588
6
+ inspectr/duplicates.py,sha256=3uCZkHlS2uEmCy_cPK9NBpq6NPS07adTf7d0hIPyuRY,1476
6
7
  inspectr/size_counts.py,sha256=Yw-k5v7lPylzfh-9SUs1PtlV3Bhvdy9X7w2Pi93xL9g,2920
7
8
  inspectr/with_open.py,sha256=qbCAb14cZ15yX7SbLo2C3nE1sDEKLiZ48bvFQfTAKJk,606
8
- inspectr-0.0.2.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
9
- inspectr-0.0.2.dist-info/METADATA,sha256=4L9CFN6aRG8bB1Z8rkw5exLeRU6FvApMu6U0vcGpKiE,1573
10
- inspectr-0.0.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
- inspectr-0.0.2.dist-info/entry_points.txt,sha256=IrOM4SpCRfFZzBWngg3ezXuX31ZqFBR-flSU5c8tbTo,52
12
- inspectr-0.0.2.dist-info/top_level.txt,sha256=NlTFBMaWgYmxFzjQtp4Y6itVQQV8sBPtAAZvFnviT-A,9
13
- inspectr-0.0.2.dist-info/RECORD,,
9
+ inspectr-0.0.3.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
10
+ inspectr-0.0.3.dist-info/METADATA,sha256=C_IkQpYnGMiAAUZ9xUb7dYGgE0RlWU3YKVZ6_41N1Xw,1573
11
+ inspectr-0.0.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
12
+ inspectr-0.0.3.dist-info/entry_points.txt,sha256=IrOM4SpCRfFZzBWngg3ezXuX31ZqFBR-flSU5c8tbTo,52
13
+ inspectr-0.0.3.dist-info/top_level.txt,sha256=NlTFBMaWgYmxFzjQtp4Y6itVQQV8sBPtAAZvFnviT-A,9
14
+ inspectr-0.0.3.dist-info/RECORD,,