Skip to content

Commit fbbbda1

Browse files
authored
Fix start/end chars for empty and out-of-bounds spans (#8816)
1 parent 9ad3b8c commit fbbbda1

2 files changed

Lines changed: 37 additions & 2 deletions

File tree

spacy/tests/doc/test_span.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,9 @@ def test_span_eq_hash(doc, doc_not_parsed):
357357
assert hash(doc[0:2]) != hash(doc[1:3])
358358
assert hash(doc[0:2]) != hash(doc_not_parsed[0:2])
359359

360+
# check that an out-of-bounds is not equivalent to the span of the full doc
361+
assert doc[0 : len(doc)] != doc[len(doc) : len(doc) + 1]
362+
360363

361364
def test_span_boundaries(doc):
362365
start = 1
@@ -369,6 +372,33 @@ def test_span_boundaries(doc):
369372
with pytest.raises(IndexError):
370373
span[5]
371374

375+
empty_span_0 = doc[0:0]
376+
assert empty_span_0.text == ""
377+
assert empty_span_0.start == 0
378+
assert empty_span_0.end == 0
379+
assert empty_span_0.start_char == 0
380+
assert empty_span_0.end_char == 0
381+
382+
empty_span_1 = doc[1:1]
383+
assert empty_span_1.text == ""
384+
assert empty_span_1.start == 1
385+
assert empty_span_1.end == 1
386+
assert empty_span_1.start_char == empty_span_1.end_char
387+
388+
oob_span_start = doc[-len(doc) - 1 : -len(doc) - 10]
389+
assert oob_span_start.text == ""
390+
assert oob_span_start.start == 0
391+
assert oob_span_start.end == 0
392+
assert oob_span_start.start_char == 0
393+
assert oob_span_start.end_char == 0
394+
395+
oob_span_end = doc[len(doc) + 1 : len(doc) + 10]
396+
assert oob_span_end.text == ""
397+
assert oob_span_end.start == len(doc)
398+
assert oob_span_end.end == len(doc)
399+
assert oob_span_end.start_char == len(doc.text)
400+
assert oob_span_end.end_char == len(doc.text)
401+
372402

373403
def test_span_lemma(doc):
374404
# span lemmas should have the same number of spaces as the span

spacy/tokens/span.pyx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,18 @@ cdef class Span:
105105
if label not in doc.vocab.strings:
106106
raise ValueError(Errors.E084.format(label=label))
107107

108+
start_char = doc[start].idx if start < doc.length else len(doc.text)
109+
if start == end:
110+
end_char = start_char
111+
else:
112+
end_char = doc[end - 1].idx + len(doc[end - 1])
108113
self.c = SpanC(
109114
label=label,
110115
kb_id=kb_id,
111116
start=start,
112117
end=end,
113-
start_char=doc[start].idx if start < doc.length else 0,
114-
end_char=doc[end - 1].idx + len(doc[end - 1]) if end >= 1 else 0,
118+
start_char=start_char,
119+
end_char=end_char,
115120
)
116121
self._vector = vector
117122
self._vector_norm = vector_norm

0 commit comments

Comments
 (0)