---
title: spans | CodeWeaver Docs
description: API reference for codeweaver.core.spans
url: "https://docs.knitli.com/api/core/spans"
type: static
generatedAt: "2026-04-17T17:21:08.070Z"
---

# spans
       [Open in ChatGPT](https://chatgpt.com/?q=Read%20https%3A%2F%2Fdocs.knitli.com%2Fcodeweaver%2Fapi%2Fcore%2Fspans%2F.%20I%20want%20to%20ask%20questions%20about%20it.)[Open in Claude](https://claude.ai/new?q=Read%20https%3A%2F%2Fdocs.knitli.com%2Fcodeweaver%2Fapi%2Fcore%2Fspans%2F.%20I%20want%20to%20ask%20questions%20about%20it.)[View in Markdown](/codeweaver/api/core/spans.md)       [Share on LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fdocs.knitli.com%2Fcodeweaver%2Fapi%2Fcore%2Fspans%2F)[Share on X](https://x.com/intent/tweet?url=https%3A%2F%2Fdocs.knitli.com%2Fcodeweaver%2Fapi%2Fcore%2Fspans%2F&text=spans)[Share on Threads](https://threads.net/intent/post?url=https%3A%2F%2Fdocs.knitli.com%2Fcodeweaver%2Fapi%2Fcore%2Fspans%2F&text=spans)[Share on Bluesky](https://bsky.app/intent/compose?text=spans%20https%3A%2F%2Fdocs.knitli.com%2Fcodeweaver%2Fapi%2Fcore%2Fspans%2F)[Share on Facebook](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fdocs.knitli.com%2Fcodeweaver%2Fapi%2Fcore%2Fspans%2F)[Share on Reddit](https://reddit.com/submit?url=https%3A%2F%2Fdocs.knitli.com%2Fcodeweaver%2Fapi%2Fcore%2Fspans%2F&title=spans)[Share on Hacker News](https://news.ycombinator.com/submitlink?u=https%3A%2F%2Fdocs.knitli.com%2Fcodeweaver%2Fapi%2Fcore%2Fspans%2F&t=spans)[Share on Email](mailto:?subject=spans&body=https%3A%2F%2Fdocs.knitli.com%2Fcodeweaver%2Fapi%2Fcore%2Fspans%2F)[Share on WhatsApp](https://wa.me/?text=spans%20https%3A%2F%2Fdocs.knitli.com%2Fcodeweaver%2Fapi%2Fcore%2Fspans%2F)[Share on Telegram](https://t.me/share/url?url=https%3A%2F%2Fdocs.knitli.com%2Fcodeweaver%2Fapi%2Fcore%2Fspans%2F&text=spans)
# `codeweaver.core.spans`
[Section titled “codeweaver.core.spans”](#codeweavercorespans)
Span data structures and operations for CodeWeaver.

## Class: `Span`
[Section titled “Class: Span”](#class-span)
An immutable span of lines in a file, defined by a start and end line number, and a source identifier.

`Span`s are a big part of CodeWeaver’s foundational data structures, so they have a robust API for manipulation and comparison. `Span` supports intersection, union, difference, and symmetric difference operations (both by using operators and methods), as well as containment checks and subset/superset checks.

All spans have an identifier, that they should share with the source (e.g. file) of the span. This allows for operations between spans from different sources to be safely handled, as they will not interfere with each other.

While we want it to be intuitive to us, it might not be intuitive for everyone, so let’s break down the key features and caveats:

 - Spans are inclusive of their start and end lines.
 - Operations between spans from different sources will not interfere with each other (but can return None in some cases, so get your null checks ready).
 - All spans have an identifier that they should share with the source (e.g. file) of the span.
 - Spans are immutable and cannot be modified after creation, but you can easily create new spans based on existing ones, including with a Span.
 - Spans are iterable, *and iterate over the lines*. If you want to iterate over the attributes, use `span.as_tuple`.
 - Operations:

 - `in` can test if an integer (i.e. line number), a tuple (i.e. (start, end)), or another `Span` is contained within the span.
 - For line numbers and tuples, it only checks the start and end lines, not the source identifier.
 - For spans, or tuples with a source identifier, it checks if the span overlaps with the current span in the source.
 - `difference` (`-`) operation can return a single span (if the difference is contiguous), a tuple of spans (if the other span is fully contained), or None (if the spans do not overlap).
 - `union` (`|`) operation will return a new span that covers both spans, but only if they share the same source identifier. Otherwise returns the original span.
 - `intersection` (`&`) operation will return a new span that is the overlap of both spans, or None if they do not overlap.
 - `symmetric_difference` (`^`) operation will return a tuple of spans that are the parts of each span that do not overlap with the other, or None if they do not overlap.
 - `equals` (`==`) operation will return True if the spans are equal, and False otherwise. Spans are only equal if they have the same start, end, **and** source identifier.

Why immutable? Because we don’t want to accidentally modify a span that is being used elsewhere, and we want to ensure that spans are always in a valid state. It also allows us to comfortably use them as keys, and in sets, and supports our data-safe set-like operations here.

### Method: `check_span`
[Section titled “Method: check_span”](#method-check_span)

**

```
check_span()
```

Ensure that the start is less than or equal to the end.

### Method: `contains_line`
[Section titled “Method: contains_line”](#method-contains_line)

**

```
contains_line()
```

Check if this span contains a specific line.

Note: This is a naive check that assumes the line is from the same source.

### Method: `difference`
[Section titled “Method: difference”](#method-difference)

**

```
difference()
```

Return the difference between this span and another span.

If the spans don’t overlap,

### Method: `from_sourced_lines`
[Section titled “Method: from_sourced_lines”](#method-from_sourced_lines)

**

```
from_sourced_lines()
```

Create a Span for the same source as this one, but with a new start and end.

### Method: `from_tuple`
[Section titled “Method: from_tuple”](#method-from_tuple)

**

```
from_tuple()
```

Create a Span from a tuple of (start, end, source_id).

### Method: `intersection`
[Section titled “Method: intersection”](#method-intersection)

**

```
intersection()
```

Return the intersection of this span with another span.

### Method: `is_adjacent`
[Section titled “Method: is_adjacent”](#method-is_adjacent)

**

```
is_adjacent()
```

Check if this span is adjacent to another span.

### Method: `is_subset`
[Section titled “Method: is_subset”](#method-is_subset)

**

```
is_subset()
```

Check if this span is a subset of another span.

### Method: `is_superset`
[Section titled “Method: is_superset”](#method-is_superset)

**

```
is_superset()
```

Check if this span is a superset of another span.

### Method: `serialize_for_cli`
[Section titled “Method: serialize_for_cli”](#method-serialize_for_cli)

**

```
serialize_for_cli()
```

Serialize the span for CLI output.

### Method: `symmetric_difference`
[Section titled “Method: symmetric_difference”](#method-symmetric_difference)

**

```
symmetric_difference()
```

Return the symmetric difference between this span and another span.

### Method: `union`
[Section titled “Method: union”](#method-union)

**

```
union()
```

Combine this span with another span.

## Class: `SpanGroup`
[Section titled “Class: SpanGroup”](#class-spangroup)
A group of spans that can be manipulated as a single unit.

SpanGroups allow for set-like operations on groups of spans, including union, intersection, difference, and symmetric difference.

SpanGroups normalize spans on creation and when spans are added, merging overlapping or adjacent spans with the same source_id. This ensures that the spans in a SpanGroup are always non-overlapping and non-adjacent within the same source.

### Method: `add`
[Section titled “Method: add”](#method-add)

**

```
add()
```

Add a span to the group.

### Method: `from_simple_spans`
[Section titled “Method: from_simple_spans”](#method-from_simple_spans)

**

```
from_simple_spans()
```

Create a SpanGroup from a sequence of simple spans. Assumes all input spans are from the same source.

Intended for ingestion, where a parser identifies spans as simple tuples of (start, end) from a single source/file, and passes them for grouping into a SpanGroup.

## Class: `SpanTuple`
[Section titled “Class: SpanTuple”](#class-spantuple)
A tuple representing a span of lines in a file.

Attributes: start (PositiveInt): The starting line number of the span (inclusive). end (PositiveInt): The ending line number of the span (inclusive). source_id (UUID7): The unique identifier for the source of the span.

### Method: `from_span`
[Section titled “Method: from_span”](#method-from_span)

**

```
from_span()
```

Convert a Span to a SpanTuple.

Reads fields directly rather than using span._asdict(), because Span.**iter** yields line numbers and NamedTuple._asdict() uses zip(fields, self), which would fill the dict with line-number integers instead of the actual field values.

### Method: `to_span`
[Section titled “Method: to_span”](#method-to_span)

**

```
to_span()
```

Convert a SpanTuple to a Span.