From 9f7d3c775d104839938ca21b1e0d3ec940f0ee94 Mon Sep 17 00:00:00 2001 From: Rudrendu Date: Sat, 18 Apr 2026 22:59:29 -0700 Subject: [PATCH] fix: add is_base_form to FrenchLemmatizer to prevent over-lemmatizing infinitives French infinitives ending in -dre, -re, etc. (e.g. 'descendre', 'prendre') were incorrectly lemmatized to 'descendrer', 'prendrer' because suffix rules like 'e -> er' were applied to them after no match was found in the lookup tables. Fix: add is_base_form() to FrenchLemmatizer that returns True when the token morphology has VerbForm=Inf, and add a call to it at the top of rule_lemmatize (mirroring the parent Lemmatizer.rule_lemmatize pattern and the EnglishLemmatizer implementation). Infinitives are returned as-is without suffix rule application. Fixes #7320 Built by Rudrendu Paul, developed with Claude Code --- spacy/lang/fr/lemmatizer.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/spacy/lang/fr/lemmatizer.py b/spacy/lang/fr/lemmatizer.py index a7cbe0bcf6d..fb5f646c37d 100644 --- a/spacy/lang/fr/lemmatizer.py +++ b/spacy/lang/fr/lemmatizer.py @@ -14,6 +14,14 @@ class FrenchLemmatizer(Lemmatizer): the lookup table. """ + def is_base_form(self, token: Token) -> bool: + """Check whether the token is already in base form so that suffix + rules are skipped. French infinitives (VerbForm=Inf) are already in + base form; applying further suffix rules to them produces incorrect + results (e.g. "descendre" → "descendrer"). + """ + return token.morph.to_dict().get("VerbForm") == "Inf" + @classmethod def get_lookups_config(cls, mode: str) -> Tuple[List[str], List[str]]: if mode == "rule": @@ -30,6 +38,8 @@ def rule_lemmatize(self, token: Token) -> List[str]: univ_pos = token.pos_.lower() if univ_pos in ("", "eol", "space"): return [string.lower()] + if self.is_base_form(token): + return [string.lower()] elif "lemma_rules" not in self.lookups or univ_pos not in ( "noun", "verb",