diff --git a/spacy/errors.py b/spacy/errors.py index 5d4d4298e..d75b1cec8 100644 --- a/spacy/errors.py +++ b/spacy/errors.py @@ -498,6 +498,7 @@ class Errors(object): "details: https://spacy.io/api/lemmatizer#init") E174 = ("Architecture '{name}' not found in registry. Available " "names: {names}") + E175 = ("Can't remove rule for unknown match pattern ID: {key}") @add_codes diff --git a/spacy/matcher/matcher.pyx b/spacy/matcher/matcher.pyx index eb1eecda0..376020f3a 100644 --- a/spacy/matcher/matcher.pyx +++ b/spacy/matcher/matcher.pyx @@ -133,9 +133,11 @@ cdef class Matcher: key (unicode): The ID of the match rule. """ - key = self._normalize_key(key) - self._patterns.pop(key) - self._callbacks.pop(key) + norm_key = self._normalize_key(key) + if not norm_key in self._patterns: + raise ValueError(Errors.E175.format(key=key)) + self._patterns.pop(norm_key) + self._callbacks.pop(norm_key) cdef int i = 0 while i < self.patterns.size(): pattern_key = get_ent_id(self.patterns.at(i)) diff --git a/spacy/tests/matcher/test_matcher_logic.py b/spacy/tests/matcher/test_matcher_logic.py index 21b5ac52d..003383757 100644 --- a/spacy/tests/matcher/test_matcher_logic.py +++ b/spacy/tests/matcher/test_matcher_logic.py @@ -143,3 +143,18 @@ def test_matcher_sets_return_correct_tokens(en_vocab): matches = matcher(doc) texts = [Span(doc, s, e, label=L).text for L, s, e in matches] assert texts == ["zero", "one", "two"] + + +def test_matcher_remove(en_vocab): + matcher = Matcher(en_vocab) + pattern = [{"ORTH": "test"}, {"OP": "?"}] + assert len(matcher) == 0 + matcher.add("Rule", None, pattern) + assert "Rule" in matcher + + # removing once should work + matcher.remove("Rule") + + # removing again should throw an error + with pytest.raises(ValueError): + matcher.remove("Rule")