Files
Yunare MaiaandSameer Kadam e12eec40a1 refactor(ner): remove dead _extract_with_spacy method and unused self.nlp (#1220)
* test(ner): fix NER configuration tests for the typed LLM extraction API

Two of the three failing tests tracked in #1059 were still red after
#1070 was closed because the mocks targeted the pre-typed provider API:

- test_ner_llm_config mocked generate_structured, but the LLM path now
  goes through generate_typed with a Pydantic schema. Mock the typed
  response (namespace items with .text/.label/.start/.end/.confidence)
  and expect extraction_method 'llm_typed'.
- test_ner_pattern_config asserted 'Apple Inc' without the trailing
  dot, but the ORG pattern captures it via (?:\.|\b). Assert 'Apple
  Inc.' to match current production behavior.

Verified locally: 8/8 pass in test_ner_configurations.py; the
performance-test failures in tests/semantic_extract/ reproduce on a
clean main checkout and are unrelated.

Fixes #1059

Signed-off-by: Yunare Maia <yunare@gmail.com>

* refactor(ner): remove dead _extract_with_spacy method and unused self.nlp

_extract_with_spacy() had no callers: the ML dispatch path goes through
get_entity_method('ml') -> extract_entities_ml(), which loads the spaCy
model lazily via the process-level cache in methods.py. The instance
attribute self.nlp was only read by that dead method, so __init__ now
just validates the runtime (keeping the _ml_runtime_usable gate) instead
of eagerly loading a model that was never used.

Fixes #1058

Signed-off-by: Yunare Maia <yunare@gmail.com>

* test(split): rewrite NERExtractor cache tests to not rely on removed .nlp attribute

NERExtractor.nlp was removed in this PR as part of dead-code cleanup
(the attribute was only used by the equally-dead _extract_with_spacy()).
The three affected tests in TestNERExtractorSpacyModelCache previously
verified cache behavior through .nlp identity comparisons; rewrite them
to use load-call counts and direct se_methods.load_spacy_model() cache
queries instead:

- test_ner_extractor_reuses_cached_model_across_instances: drop the
  e1.nlp is e2.nlp is e3.nlp assertion; len(calls)==1 already proves
  reuse; add a cache query to confirm the cached object is non-None.

- test_ner_extractor_distinct_model_names_load_separately: store each
  mock nlp in a dict keyed by name, then query the cache to assert
  sm_cached is loaded['en_core_web_sm'] and sm_cached is not lg_cached.

- test_ner_extractor_failed_load_not_cached_and_retried: replace
  extractor.nlp is None/not None with is-not-None construction checks
  and a final cache query that verifies the recovered model is the
  exact object returned by working_load.

All three tests still exercise the original behavioral contract (no
crash on missing model, failures not cached / retried, successful load
shared across instances); they just no longer rely on a private
instance attribute that no longer exists.

---------

Signed-off-by: Yunare Maia <yunare@gmail.com>
Co-authored-by: Sameer Kadam <sskadam6305@gmail.com>
2026-08-27 17:56:03 +05:30
..