⊑ dupelint Notify me

Proven on CPython: full results

The actual output.

A single full-spectrum pass over CPython 3.12.3. Over-detect, then prove down to certainty. Nothing reaches a verdict without an unconditional proof.

CPython 3.12.3 target 63,186 functions 13,970 classes 1,924 module-level 40,035 block-eligible bodies 46,608 constants & data 1,996 files 1,230 lambdas 2,793 comprehensions 22,937 nested blocks 1,250 import blocks 835 default-arg sets 669 decorator stacks 140 type aliases 8 skipped (unparseable) ~50 min single full-spectrum pass

112,181 test code ignored in test directories

ExpandCollapse▸▾ 91 test directories · 1,088 test files of 2,004
  • Lib/test · 449 files
  • Lib/idlelib/idle_test · 65 files
  • Lib/test/test_ctypes · 53 files
  • Lib/test/test_asyncio · 37 files
  • Lib/test/test_capi · 23 files
  • Lib/test/test_importlib · 22 files
  • Lib/test/libregrtest · 20 files
  • Lib/test/test_json · 19 files
  • Lib/test/support · 18 files
  • Lib/test/test_unittest · 18 files
  • Lib/test/test_email · 17 files
  • Lib/test/test_future_stmt · 16 files
  • Lib/test/test_tkinter · 15 files
  • Lib/test/test_import/data/circular_imports · 13 files
  • Lib/test/test_importlib/resources · 13 files
  • Lib/test/test_importlib/import_ · 12 files
  • Lib/test/test_sqlite3 · 12 files
  • Lib/test/test_unittest/testmock · 12 files
  • Lib/test/typinganndata · 12 files
  • Lib/test/test_concurrent_futures · 11 files
  • Lib/test/test_lib2to3 · 11 files
  • Lib/test/test_doctest · 9 files
  • Lib/test/test_gdb · 8 files
  • Lib/test/test_zipfile/_path · 8 files
  • Lib/test/crashers · 7 files
  • Lib/test/test_importlib/source · 7 files
  • Lib/test/test_inspect · 7 files
  • Lib/test/test_lib2to3/data · 7 files
  • Lib/test/test_module · 7 files
  • Lib/test/test_tools · 7 files
  • Lib/test/test_dataclasses · 6 files
  • Lib/test/test_importlib/extension · 6 files
  • Lib/test/test_lib2to3/data/fixers/myfixes · 6 files
  • Lib/test/test_peg_generator · 6 files
  • Lib/test/test_tomllib · 6 files
  • Lib/test/subprocessdata · 5 files
  • Lib/test/test_multiprocessing_fork · 5 files
  • Lib/test/test_multiprocessing_forkserver · 5 files
  • Lib/test/test_multiprocessing_spawn · 5 files
  • Lib/test/test_ttk · 5 files
  • Lib/test/test_zoneinfo · 5 files
  • Lib/test/tokenizedata · 5 files
  • Lib/test/dtracedata · 4 files
  • Lib/test/test_importlib/builtin · 4 files
  • Lib/test/test_importlib/frozen · 4 files
  • Lib/test/test_pydoc · 4 files
  • Lib/test/encoded_modules · 3 files
  • Lib/test/leakers · 3 files
  • Lib/test/support/_hypothesis_stubs · 3 files
  • Lib/test/test_lib2to3/data/fixers · 3 files
  • Lib/test/test_warnings/data · 3 files
  • Lib/test/test_zipfile · 3 files
  • Lib/test/regrtestdata/import_from_tests · 2 files
  • Lib/test/regrtestdata/import_from_tests/test_regrtest_b · 2 files
  • Lib/test/test_cppext · 2 files
  • Lib/test/test_import · 2 files
  • Lib/test/test_import/data/circular_imports/subpkg · 2 files
  • Lib/test/test_import/data/circular_imports/subpkg2/parent · 2 files
  • Lib/test/test_import/data/package · 2 files
  • Lib/test/test_import/data/package2 · 2 files
  • Lib/test/test_import/data/unwritable · 2 files
  • Lib/test/test_importlib/namespace_pkgs/both_portions/foo · 2 files
  • Lib/test/test_importlib/namespace_pkgs/not_a_namespace_pkg/foo · 2 files
  • Lib/test/test_importlib/partial · 2 files
  • Lib/test/test_warnings · 2 files
  • Lib/test/tracedmodules · 2 files
  • Tools/peg_generator/scripts · 2 files
  • Lib/test/certdata · 1 file
  • Lib/test/test_import/data · 1 file
  • Lib/test/test_import/data/circular_imports/subpkg2 · 1 file
  • Lib/test/test_importlib/data · 1 file
  • Lib/test/test_importlib/namespace_pkgs/module_and_namespace_package · 1 file
  • Lib/test/test_importlib/namespace_pkgs/portion1/foo · 1 file
  • Lib/test/test_importlib/namespace_pkgs/portion2/foo · 1 file
  • Lib/test/test_importlib/namespace_pkgs/project1/parent/child · 1 file
  • Lib/test/test_importlib/namespace_pkgs/project2/parent/child · 1 file
  • Lib/test/test_importlib/namespace_pkgs/project3/parent/child · 1 file
  • Lib/test/test_importlib/resources/data01 · 1 file
  • Lib/test/test_importlib/resources/data01/subdirectory · 1 file
  • Lib/test/test_importlib/resources/data02 · 1 file
  • Lib/test/test_importlib/resources/data02/one · 1 file
  • Lib/test/test_importlib/resources/data02/two · 1 file
  • Lib/test/test_importlib/resources/data03 · 1 file
  • Lib/test/test_importlib/resources/data03/namespace/portion1 · 1 file
  • Lib/test/test_importlib/resources/data03/namespace/portion2 · 1 file
  • Lib/test/test_importlib/resources/zipdata01 · 1 file
  • Lib/test/test_importlib/resources/zipdata02 · 1 file
  • Lib/test/test_zoneinfo/data · 1 file
  • Lib/test/ziptestdata · 1 file
  • Programs · 1 file
  • Tools/cases_generator · 1 file

345 test setup/teardown ignored in test directories

It only calls something a duplicate when math proves it. On CPython: 2,336,936 suspects, 1,458 proven duplicates, 0 false positives.

2,221,899
examined and decided by math · 95.0774%
112,526
test/setup code excluded · 4.8151%
181
proven different by math · 0.0078%
1,458
proven duplicates · 0.0624%
872
candidates → review · 0.0373%

What math can prove, we prove — and only that. For the rest, a sound verdict would take a guess about runtime behavior, so we surface every one for review rather than guess. We never guess.

Proven duplicates (1,458)

Proven to compute the same thing (same code; every name, enclosing value, decorator and class context checked identical).

Candidates (872)

Each was detected with full confidence — what sets it apart from the Confirmed set is only that whether the merge is behaviour-preserving cannot be settled by deterministic proof (it turns on a runtime value, a dynamic binding, or the shape of the right refactor). A sound prover never guesses there. So each is classified by precisely why proof stops short and routed to review — never shipped as a verdict.

1_exact 402 2_renamed 230 3_gapped 151 5_subsumption 48 4_semantic 41
Blocked by Count
cross-class180
external-module-attr-write112
unresolvable98
duplicate-comprehension66
gapped-not-auto-extractable45
method-dispatch-unprovable45
closure-cell42
free-global-divergent42
duplicate-constant-data25
duplicate-lambda21
nested-name-escape19
unbound-local-name17
same-logic-across-constructs16
module-code-binds-used-names15
duplicate-default-arguments14
frame-relocation14
gapped-trivial-helper14
duplicate-decorator-stack9
shared-data-block8
contained-data-block7
signature-contract7
function-kind-differs6
locals-reflection6
near-duplicate6
warning-dedup6
escaping-write5
block-nested-scope4
class-name-differs4
duplicate-import-block4
nested-class3
duplicate-type-alias2
mutable-default2
semantic-assumed-int2
block-binds-live-outputs1
duplicate-data-block1
duplicate-file1
method-name-contract1
mutable-shared-data1
near-duplicate-module-code1

Full per-pair detail — exact locations plus the binding that blocks a mechanical merge — comes back in the scan result from the API. All advisory; none is ever shipped as a verdict.

Full output of this scan

See the full output of this scan ↗ — the raw API response, unedited (JSON, 931,423 bytes). Its “proven different” section comes from an extra step we run only on our own scans, because that step runs the code; the public API never does.

Every number on this page is produced by the engine, not by hand — regenerated from the scan’s result.json on each run. Full machine-readable output is available from the API.

dupelint — proves duplication away instead of guessing.