Skip to content

Interval removal breaks this tree #41

Closed
@escalonn

Description

@escalonn

I ran chop on a few thousand IntervalTrees, and found that it crashed on several of them. Looking at the library code showed that remove failed to find Intervals where they were supposed to be. I tested until I found something more consistent.

Here, I add 9 intervals to an empty tree (in sorted order, so I could have used an iterable). Then, I remove the interval in the root node, leaving the tree with a broken node. Trying to remove one of the intervals left under that node then raises a KeyError.

>>> from intervaltree import IntervalTree
>>> t = IntervalTree()
>>> t.addi(860, 917, 1)
>>> t.addi(860, 917, 2)
>>> t.addi(860, 917, 3)
>>> t.addi(860, 917, 4)
>>> t.addi(871, 917, 1)
>>> t.addi(871, 917, 2)
>>> t.addi(871, 917, 3)
>>> t.addi(961, 986, 1)
>>> t.addi(1047, 1064, 1)
>>> t.addi(1047, 1064, 2)
>>> t.removei(961, 986, 1) # remove root node. t.verify() would fail now
>>> t.removei(871, 917, 3)
Node<871, depth=2, balance=0>
 Interval(860, 917, 1)
 Interval(860, 917, 2)
 Interval(860, 917, 3)
 Interval(860, 917, 4)
<:  Node<871, depth=1, balance=0>
     Interval(871, 917, 1)
     Interval(871, 917, 2)
     Interval(871, 917, 3)
>:  Node<1047, depth=1, balance=0>
     Interval(1047, 1064, 1)
     Interval(1047, 1064, 2)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/site-packages/intervaltree/intervaltree.py", line 372, in removei
    return self.remove(Interval(begin, end, data))
  File "/usr/lib/python2.7/site-packages/intervaltree/intervaltree.py", line 361, in remove
    self.top_node = self.top_node.remove(interval)
  File "/usr/lib/python2.7/site-packages/intervaltree/node.py", line 211, in remove
    return self.remove_interval_helper(interval, done, should_raise_error=True)
  File "/usr/lib/python2.7/site-packages/intervaltree/node.py", line 248, in remove_interval_helper
    raise KeyError(interval)
KeyError: Interval(871, 917, 3)

That's with Python 2.7; the same behavior exists in Python 3.4.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions