inspectr 0.0.2__py3-none-any.whl → 0.0.4__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,50 @@
1
+ import sys
2
+ import hashlib
3
+ from collections import defaultdict
4
+
5
+ def find_duplicates(files, block_size=10, min_occur=3):
6
+ """
7
+ Find duplicate blocks of code across files.
8
+
9
+ Args:
10
+ files: list of file paths
11
+ block_size: number of consecutive lines in a block
12
+ min_occur: minimum number of occurrences to report
13
+
14
+ Yields:
15
+ (filename, line_number, count)
16
+ """
17
+ blocks = defaultdict(list) # hash -> list of (file, line)
18
+
19
+ for fname in files:
20
+ try:
21
+ with open(fname, encoding="utf-8") as f:
22
+ lines = f.readlines()
23
+ except OSError as e:
24
+ print(f"Could not read {fname}: {e}", file=sys.stderr)
25
+ continue
26
+
27
+ for i in range(len(lines) - block_size + 1):
28
+ # join block of lines
29
+ block = "".join(lines[i:i + block_size])
30
+ # stable hash
31
+ h = hashlib.sha1(block.encode("utf-8")).hexdigest()
32
+ blocks[h].append((fname, i + 1))
33
+
34
+ for locs in blocks.values():
35
+ if len(locs) >= min_occur:
36
+ for fname, lnum in locs:
37
+ yield fname, lnum, len(locs)
38
+
39
+
40
+ def main(args=None) -> None:
41
+ if args is None:
42
+ args = sys.argv[1:]
43
+
44
+ if not args:
45
+ print("Usage: inspectr duplicates file1.py [file2.py ...]")
46
+ return
47
+
48
+ for fname, lnum, count in find_duplicates(args, block_size=10, min_occur=3):
49
+ print(f"{fname}:{lnum} (occurs {count} times)")
50
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: inspectr
3
- Version: 0.0.2
3
+ Version: 0.0.4
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=xAFNO90JVEhzZqmyHg8gXAo28e_DIrB3SYh7tONAzbU,1455
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.4.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
10
+ inspectr-0.0.4.dist-info/METADATA,sha256=2YAiL5P6MPWIgR54rlkZXzt3fXxaW6CsT1vT1krn_uo,1573
11
+ inspectr-0.0.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
12
+ inspectr-0.0.4.dist-info/entry_points.txt,sha256=IrOM4SpCRfFZzBWngg3ezXuX31ZqFBR-flSU5c8tbTo,52
13
+ inspectr-0.0.4.dist-info/top_level.txt,sha256=NlTFBMaWgYmxFzjQtp4Y6itVQQV8sBPtAAZvFnviT-A,9
14
+ inspectr-0.0.4.dist-info/RECORD,,