diff --git a/spacy/errors.py b/spacy/errors.py index f12c73c69..0ccff4c75 100644 --- a/spacy/errors.py +++ b/spacy/errors.py @@ -358,6 +358,11 @@ class Errors(object): "arguments to exclude fields from being serialized or deserialized " "is now deprecated. Please use the `exclude` argument instead. " "For example: exclude=['{arg}'].") + E129 = ("Cannot write the label of an existing Span object because a Span " + "is a read-only view of the underlying Token objects stored in the Doc. " + "Instead, create a new Span object and specify the `label` keyword argument, " + "for example:\nfrom spacy.tokens import Span\n" + "span = Span(doc, start={start}, end={end}, label='{label}')") @add_codes diff --git a/spacy/tests/doc/test_span.py b/spacy/tests/doc/test_span.py index 412917273..087006f26 100644 --- a/spacy/tests/doc/test_span.py +++ b/spacy/tests/doc/test_span.py @@ -178,11 +178,10 @@ def test_span_string_label(doc): assert span.label == doc.vocab.strings["hello"] -def test_span_string_set_label(doc): +def test_span_label_readonly(doc): span = Span(doc, 0, 1) - span.label_ = "hello" - assert span.label_ == "hello" - assert span.label == doc.vocab.strings["hello"] + with pytest.raises(NotImplementedError): + span.label_ = "hello" def test_span_ents_property(doc): diff --git a/spacy/tokens/span.pyx b/spacy/tokens/span.pyx index b51ca3e57..36eaeb568 100644 --- a/spacy/tokens/span.pyx +++ b/spacy/tokens/span.pyx @@ -653,7 +653,9 @@ cdef class Span: return self.doc.vocab.strings[self.label] def __set__(self, unicode label_): - self.label = self.doc.vocab.strings.add(label_) + if not label_: + label_ = '' + raise NotImplementedError(Errors.E129.format(start=self.start, end=self.end, label=label_)) cdef int _count_words_to_root(const TokenC* token, int sent_length) except -1: