From 222b449f584d61e5641f41396b1f5faf861ee62d Mon Sep 17 00:00:00 2001 From: Sanjay Nagi Date: Tue, 11 Aug 2026 11:21:03 +0100 Subject: [PATCH] Fix AttributeError when AMRFinderPlus subclass is not in CARD conversion table Fixes #28 _assign_drug_from_amrfp() called card_amrfp_conversion.get(self.amrfp_subclass) and then immediately chained .get('drug', '-') / .get('class', '-') onto the result. When the AMRFinderPlus subclass has no entry in the hand-maintained amrfp_to_card_drugs_classes.txt table, the outer .get() returns None and the chained .get() raises AttributeError: 'NoneType' object has no attribute 'get', crashing the whole run instead of falling through to the existing "unassigned markers" fallback path a few lines below. This now defaults the lookup to an empty dict when the subclass is missing (matching the .get('drug class', '-') fallback pattern already used in _assign_drug_from_rule), and emits a warnings.warn() so a gap in the conversion table is visible instead of silent. --- src/amrrules/genotype_parser.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/amrrules/genotype_parser.py b/src/amrrules/genotype_parser.py index db98382..5b6f84c 100644 --- a/src/amrrules/genotype_parser.py +++ b/src/amrrules/genotype_parser.py @@ -1,5 +1,6 @@ from typing import Any, Optional import re +import warnings from amrrules import __version__ from amrrules.utils import aa_conversion, minimal_columns, full_columns @@ -397,8 +398,15 @@ def _assign_drug_from_rule(self, card_drug_map): self.drug_class = 'penicillin beta-lactam' def _assign_drug_from_amrfp(self, card_amrfp_conversion): - self.drug = card_amrfp_conversion.get(self.amrfp_subclass).get('drug', '-') - self.drug_class = card_amrfp_conversion.get(self.amrfp_subclass).get('class', '-') + conversion = card_amrfp_conversion.get(self.amrfp_subclass) + if conversion is None: + # the amrfp_to_card_drugs_classes.txt lookup table is maintained by hand and can + # lag behind the AMRFinderPlus/NCBI database, so an unmapped subclass shouldn't crash the run + warnings.warn(f"AMRFinderPlus subclass '{self.amrfp_subclass}' was not found in the AMRFP-to-CARD " + f"conversion table. Falling back to 'unassigned markers' for this marker.") + conversion = {} + self.drug = conversion.get('drug', '-') + self.drug_class = conversion.get('class', '-') # if the drug_class is '-', set to 'unassigned markers' if self.drug_class == '-': self.drug_class = 'unassigned markers'