Span: An Ergonomic Wrapper for tuple[int, int]#
- class my.types.Span.Span#
- class my.types.Span.Span(arg0: S, arg1: S)
- class my.types.Span.Span(arg0: Span[S] | tuple[S, S])
- class my.types.Span.Span(arg0: str | bytes | bytearray | memoryview | IO | int | float | complex | bool | tuple[int | float | complex | bool, int | float | complex | bool] | Span, arg1: str | bytes | bytearray | memoryview | IO | int | float | complex | bool, tvar: type[S] | MyType[S])
An immutable half-open interval [start, end), typically representing a text range.
Spans are a simple wrapper around
tuple[int, int]built to support arithmetic (shifting by integers), containment testing (checking if positions or other spans intersect), and merging operations (combining overlapping spans into minimal non-overlapping sets).The class provides flexible construction from strings like
"10-20"or abbreviated forms like"432-3"(interpreted as 432-433). Theparse()classmethod handles smart abbreviation expansion, where trailing digits inherit leading digits from the start position. Note thatstr()renders the inclusive form –Span(3, 9)becomes'3-8'– which is whatparse()expects back.Examples
Construct spans from points, pairs, or strings:
>>> from my import Span >>> Span(3, 9) Span(3, 9) >>> Span('10-20') Span(10, 20)
Shift a span by an integer and test containment:
>>> Span(3, 9) + 1 Span(4, 10) >>> 5 in Span(3, 9) True >>> (8, 12) in Span(3, 9) True
Render the inclusive string form:
>>> str(Span(3, 9)) '3-8'
I Properties#
- property Span.delta: T#
Return the length of this span.
II Methods#
- Span.intersects(other: tuple[T, T] | Self | list[Self]) bool#
Check if this span overlaps with another span.
- Parameters:
other – Span to test for intersection.
- Returns:
True if the spans overlap.
Examples
Test a partial overlap:
>>> from my import Span >>> Span(3, 9).intersects((8, 12)) True
- Span.join(other: Self | tuple[T, T]) Self#
Create a span that encompasses both this span and another.
- Parameters:
other – Span to join with.
- Returns:
New span from the minimum start to maximum end.
Examples
Join two overlapping spans:
>>> from my import Span >>> Span(3, 9).join((7, 15)) Span(3, 15)
- classmethod Span.serialize(*args: Self | tuple[T, T]) str#
Serialize multiple spans to a delimited string.
- Parameters:
*args – Spans to serialize.
- Returns:
String with spans separated by
DELIM.
Examples
Serialize two spans (inclusive display form):
>>> from my import Span >>> Span.serialize(Span(1, 3), Span(8, 12)) '1-2 // 8-11'
- classmethod Span.parse(text: str) Self#
Parse a span from text with smart abbreviation handling.
Handles formats like:
"10-20": Full range"432-3": Abbreviated end (becomes 432-433)"1475-33": Abbreviated end with rollover (becomes 1475-1533)"42": Single position (becomes 42-43)
- Parameters:
text – String to parse.
- Returns:
Parsed Span, or empty Span (0, 0) if parsing fails.
Examples
Expand abbreviated inclusive ranges into half-open spans:
>>> from my import Span >>> Span.parse('432-3') Span(432, 434) >>> Span.parse('1475-33') Span(1475, 1534) >>> Span.parse('42') Span(42, 43)
- classmethod Span.merge(*args: tuple[int, int] | Self) list[Self]#
Merge overlapping spans into a minimal set of non-overlapping spans.
- Parameters:
*args – Spans to merge.
- Returns:
Sorted list of non-overlapping spans covering the same positions.
Examples
Collapse overlapping spans:
>>> from my import Span >>> Span.merge((0, 5), (3, 9), (12, 15)) [Span(0, 9), Span(12, 15)]