Duplicate implementations in the classification app (two of them dead, drifted code)
- Dominant language
- Python
- Stars
- 30
- Forks
- 3
- Avg merge
- 9h 28m
- Merged PRs (30d)
- 42
Description
🤖 Written by Claude
A scan for duplicated implementations (token-normalised clone detection + AST structural similarity across the codebase, then manual verification) turned up several copy-paste pairs in the `classification` app. Two of them are dead code that has already drifted from its live twin.
### 1. `evidence_key_cleaner` is a broken copy of `unknown_evidence_key_cleaner`
`classification/management/commands/evidence_key_cleaner.py` and `unknown_evidence_key_cleaner.py` are identical apart from one line:
```python
parser.add_argument('--key', type='str', required=True) # evidence_key_cleaner only
```
`--key` is never read in `handle()`, and `type='str'` (the string, not the builtin) makes argparse raise `ValueError: 'str' is not callable` inside `add_argument` — so the command fails on every invocation, including `--help`. Nothing in the repo references it.
### 2. `Classification.get_allele_info_dict()` is dead and has drifted
* `classification/models/classification.py:2031` — the method, no callers anywhere (Python, templates or JS)
* `classification/models/classification_json.py:21` — the module function actually used, via `classification_json.py:179`
The live copy has since gained two things the dead one never got:
* the `elif g_hgvs := allele_info.imported_g_hgvs_obj:` fallback from "Allow g.HGVS classification imports" (#1063)
* `SpecialEKeys.VARIANT_COORDINATE` in the per-genome-build dict
This is exactly the failure duplication causes — a fix landing in one copy only.
### 3. Criteria-strength building duplicated
* `classification/models/classification_groups.py:375` — `criteria_converter` nested in `acmg_criteria`
* `classification/models/evidence_mixin_summary_cache.py:209` — `criteria_labels`
Both walk `EvidenceKeyMap.cached().criteria()` collecting met criteria, then expand `SpecialEKeys.AMP_LEVELS_TO_LEVEL` into `CriteriaStrength` objects with a `f"{letter}_{sub_value_label}"` custom strength. The two loops are identical; only the output shaping differs (`MultiValues` vs sorted labels). Both call sites hold a `ClassificationModification`, which is an `EvidenceMixin`, so this belongs on the mixin.
### 4. `DiscordanceReportAdminExport._less_more_certain` / `_up_down_for`
`classification/admin/classification_admin.py:741` and `:764` share an identical seven-line prelude — the `cs_to_index` lookup, the `from_value`/`to_value` ints, and the `withdrawn` / `same` / `?` guards. Only the final comparison differs (distance from 3 vs. straight `>`).
### Not included
The near-identical context dicts in `classification/views/views.py:187` (`classifications`) and `:284` (`classification_groupings`) are left alone — #1765 proposes deleting the `classification_groupings` page outright, which removes that duplication properly.
`_variant_ids_by_gene` and `_zipf_weight`, byte-identical in `classification/fake_reclassifications.py` and `analysis/fake_variant_tags.py`, are tracked separately with the rest of the cross-app duplication rather than here.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reading the duplicate implementations in classification/management/commands/, classification/models/classification.py and classification_json.py, then inspect the criteria and admin locations listed in the issue. Search for callers and run the relevant classification checks available in the repository before changing behavior. Done means the dead or broken copies are addressed, shared logic no longer drifts, and the live behavior remains covered.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100