ProvenPin Install

intervaltree overlap queries for room booking conflicts: working versions (tested 2026-10-18)

A room booking schedule on intervaltree: point and range overlap queries, merge_overlaps for busy blocks, and chop/slice to carve out blocked and split slots.

passed6 passed · 0 failed2026-10-18 03:56 UTC
Status
passed
Last passed
2026-10-18 03:56 UTC
Tests
6 / 6
Language
Python
Runtime
Python 3.13.16
pinned versions3
intervaltree@3.2.1sortedcontainers@2.4.0pytest@9.1.1
run it
uv venv -q .venv && uv pip install -q --python .venv/bin/python -r requirements.txt
.venv/bin/python -m pytest -q
test environment
Python 3.13.16
linux 6.17.0-1022-azure
x64
runner: github-actions 39095370682

The code

Exactly the files that passed. Your agent can pull them with get_recipe("intervaltree-overlap-queries") (install), or see them on GitHub.

requirements.txt
intervaltree==3.2.1
sortedcontainers==2.4.0
pytest==9.1.1
bookings.py
from intervaltree import IntervalTree


class RoomSchedule:
    def __init__(self):
        self.tree = IntervalTree()

    def reserve(self, start, end, who):
        if end <= start:
            raise ValueError("end must be after start")
        clash = self.tree.overlap(start, end)
        if clash:
            names = ", ".join(sorted(iv.data for iv in clash))
            raise ValueError(f"double booked with {names}")
        self.tree.addi(start, end, who)

    def who_at(self, moment):
        return sorted(iv.data for iv in self.tree.at(moment))

    def clashes(self, start, end):
        return sorted((iv.begin, iv.end, iv.data) for iv in self.tree.overlap(start, end))

    def busy_blocks(self):
        blocks = self.tree.copy()
        blocks.merge_overlaps(strict=False)
        return sorted((iv.begin, iv.end) for iv in blocks)

    def block_out(self, start, end):
        self.tree.chop(start, end)

    def split_at(self, moment):
        self.tree.slice(moment)
tests/test_bookings.py
import pytest
from intervaltree import Interval, IntervalTree

from bookings import RoomSchedule


def test_point_query_vs_empty_range():
    s = RoomSchedule()
    s.reserve(9, 12, "ana")
    assert s.who_at(10) == ["ana"]
    assert s.clashes(10, 10) == []
    assert s.clashes(10, 11) == [(9, 12, "ana")]


def test_touching_reservations_are_allowed():
    s = RoomSchedule()
    s.reserve(9, 10, "ana")
    s.reserve(10, 11, "bo")
    assert s.clashes(9, 11) == [(9, 10, "ana"), (10, 11, "bo")]


def test_double_booking_raises():
    s = RoomSchedule()
    s.reserve(9, 11, "ana")
    with pytest.raises(ValueError, match="double booked with ana"):
        s.reserve(10, 12, "bo")


def test_merge_overlaps_default_is_strict():
    adjacent = IntervalTree([Interval(9, 10, "a"), Interval(10, 11, "b")])
    adjacent.merge_overlaps()
    assert sorted(adjacent) == [Interval(9, 10, "a"), Interval(10, 11, "b")]
    adjacent.merge_overlaps(strict=False)
    assert sorted(adjacent) == [Interval(9, 11)]


def test_busy_blocks_join_back_to_back():
    s = RoomSchedule()
    s.reserve(9, 10, "ana")
    s.reserve(10, 11, "bo")
    s.reserve(12, 13, "cy")
    assert s.busy_blocks() == [(9, 11), (12, 13)]


def test_chop_then_slice():
    s = RoomSchedule()
    s.reserve(9, 17, "ana")
    s.block_out(12, 13)
    assert s.clashes(9, 17) == [(9, 12, "ana"), (13, 17, "ana")]
    s.split_at(15)
    assert s.clashes(9, 17) == [(9, 12, "ana"), (13, 15, "ana"), (15, 17, "ana")]
pytest.ini
[pytest]
pythonpath = .

Connect to ProvenPin

Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.

terminal
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp

Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.