diff --git a/python/CHANGELOG.rst b/python/CHANGELOG.rst index c208248e8a..2377707c59 100644 --- a/python/CHANGELOG.rst +++ b/python/CHANGELOG.rst @@ -72,8 +72,11 @@ values with mutations over roots. (:user:`benjeffery`, :pr:`3274`, :issue:`3273`) +- Prevent iterating over a ``TopologyCounter`` + (:user:`benjeffery` , :pr:`3202`, :issue:`1462`) -**Breaking changes** + +**Breaking changes** - ``ltrim``, ``rtrim``, ``trim`` and ``shift`` raise an error if used on a tree sequence containing a reference sequence (:user:`hyanwong`, :pr:`3210`, :issue:`2091`) diff --git a/python/tests/test_combinatorics.py b/python/tests/test_combinatorics.py index 97c85af8e8..8073b845df 100644 --- a/python/tests/test_combinatorics.py +++ b/python/tests/test_combinatorics.py @@ -635,6 +635,11 @@ def verify_topologies(self, ts, sample_sets=None, expected=None): assert actual_topologies == expected[i][sample_set_indexes] assert actual_topologies == actual_inc_topologies + def test_no_iterate(self): + with pytest.raises(TypeError, match="not iterable"): + for _ in tskit.Tree.generate_star(3).count_topologies(): + pass + def subsample_topologies(self, ts, sample_sets, sample_set_indexes): subsample_sets = [sample_sets[i] for i in sample_set_indexes] topologies = collections.Counter() diff --git a/python/tskit/combinatorics.py b/python/tskit/combinatorics.py index 880ec73675..058f6e633e 100644 --- a/python/tskit/combinatorics.py +++ b/python/tskit/combinatorics.py @@ -541,6 +541,12 @@ def __setitem__(self, sample_set_indexes, counter): k = TopologyCounter._to_key(sample_set_indexes) self.topologies[k] = counter + def __iter__(self): + raise TypeError( + "TopologyCounter object is not iterable, " + "iterate over '.topologies' instead" + ) + @staticmethod def _to_key(sample_set_indexes): if not isinstance(sample_set_indexes, collections.abc.Iterable):