From 8101943dd8b2dc1bf7a35f368c50e2a6ef25b1fe Mon Sep 17 00:00:00 2001 From: Mike German Date: Sat, 11 Jul 2026 20:42:01 -0400 Subject: [PATCH 1/2] fix: add missing self to reindex_subcomponent_taxa TaxonNamespaceAssociated.reindex_subcomponent_taxa was defined without self but called as self.reindex_subcomponent_taxa() from reindex_taxa(), raising TypeError instead of the intended NotImplementedError on any class relying on the base stub (e.g. TreeList). TreeList's own override in treecollectionmodel.py had the same bug. Both now take self. Signed-off-by: Mike German --- src/dendropy/datamodel/taxonmodel.py | 2 +- src/dendropy/datamodel/treecollectionmodel.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dendropy/datamodel/taxonmodel.py b/src/dendropy/datamodel/taxonmodel.py index 153656bdb..e459a6c1b 100644 --- a/src/dendropy/datamodel/taxonmodel.py +++ b/src/dendropy/datamodel/taxonmodel.py @@ -407,7 +407,7 @@ def reindex_taxa(self, taxon_namespace=None, clear=False): self.reindex_subcomponent_taxa() return self.taxon_namespace - def reindex_subcomponent_taxa(): + def reindex_subcomponent_taxa(self): """ DEPRECATED: Use :meth:`reconstruct_taxon_namespace()` instead. Derived classes should override this to ensure that their various diff --git a/src/dendropy/datamodel/treecollectionmodel.py b/src/dendropy/datamodel/treecollectionmodel.py index d5fec7ec7..9ab15201a 100644 --- a/src/dendropy/datamodel/treecollectionmodel.py +++ b/src/dendropy/datamodel/treecollectionmodel.py @@ -1019,7 +1019,7 @@ def poll_taxa(self, taxa=None): tree.poll_taxa(taxa) return taxa - def reindex_subcomponent_taxa(): + def reindex_subcomponent_taxa(self): raise NotImplementedError() ############################################################################## From 2e27011950bb0a343be11cf43f81f23566d52ec5 Mon Sep 17 00:00:00 2001 From: Matthew Andres Moreno Date: Sun, 12 Jul 2026 00:17:03 -0400 Subject: [PATCH 2/2] Add regression test for missing self params Tests drafted via @claude and hand-reviewed. --- tests/unittests/test_datamodel_tree_list.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/unittests/test_datamodel_tree_list.py b/tests/unittests/test_datamodel_tree_list.py index 6a8e3c7f3..f8010c29d 100644 --- a/tests/unittests/test_datamodel_tree_list.py +++ b/tests/unittests/test_datamodel_tree_list.py @@ -25,6 +25,7 @@ import collections import dendropy import random +import warnings import os import sys sys.path.insert(0, os.path.dirname(__file__)) @@ -1011,6 +1012,22 @@ def test_migrate_taxon_namespace_unifying_case_insensitive(self): case_sensitive_label_mapping=False, original_tns=original_tns) + def test_reindex_subcomponent_taxa_raises_not_implemented(self): + # Regression: the stub was defined without a `self` parameter, so + # calling it as an instance method raised TypeError instead of the + # intended NotImplementedError. + with self.assertRaises(NotImplementedError): + self.tree_list.reindex_subcomponent_taxa() + + def test_reindex_taxa_raises_not_implemented(self): + # `reindex_taxa` is deprecated and delegates to + # `reindex_subcomponent_taxa`; it should surface NotImplementedError + # rather than a TypeError about positional argument counts. + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + with self.assertRaises(NotImplementedError): + self.tree_list.reindex_taxa() + class TestTreeListAppend( curated_test_tree.CuratedTestTree, unittest.TestCase):