diff --git a/CHANGELOG.md b/CHANGELOG.md index 4608a81090..0ff4fcf829 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ All notable changes to this project will be documented in this file. - Added `PhUmidRecognizer` for Philippine Unified Multi-Purpose ID (UMID/CRN) numbers in dashed and plain 12-digit formats; disabled by default (#2045) (Thanks @Surya-5555) #### Fixed -- `PhoneRecognizer.DEFAULT_SUPPORTED_REGIONS` used `"UK"`, which is not a valid `phonenumbers` (libphonenumber) region code — region codes are ISO 3166-1 alpha-2, where the United Kingdom is `"GB"`. The `"UK"` entry was a no-op, so UK numbers in national/local format (e.g. `020 7946 0958`) were never detected by default; only international-format `+44 …` numbers matched, because they carry the country code and match under any region. Replaced `"UK"` with `"GB"`. +- `PhoneRecognizer.DEFAULT_SUPPORTED_REGIONS` used `"UK"`, which is not a valid `phonenumbers` (libphonenumber) region code; the United Kingdom uses `"GB"`. The invalid region pass could not apply GB metadata to national-format UK numbers, so those numbers could be missed or recognized only through unrelated regional matchers. International-format `+44 …` numbers were unaffected because they carry their country code. Replaced `"UK"` with `"GB"`. - Language model recognizers (`BasicLangExtractRecognizer`, `AzureOpenAILangExtractRecognizer`) configured in a recognizer registry YAML now honour `config_path` (and other recognizer-specific kwargs). Previously these entries were validated by the strict `PredefinedRecognizerConfig` schema, which has no `config_path` field and does not allow extra keys, so `config_path` was silently dropped and the recognizer fell back to its bundled default model configuration. Added a `LangExtractRecognizerConfig` model (`extra="allow"`) and registered both recognizer class names in `CONFIG_MODEL_MAP`. - `BasicLangExtractRecognizer` now honours values under `langextract.model.provider.language_model_params` (including `timeout` and `num_ctx`). Previously these were silently dropped because `langextract.extract()` ignores its `language_model_params` argument when a pre-built `ModelConfig` is passed via `config=`, causing Ollama-backed recognizers to fall back to langextract's 120s default regardless of the configured timeout. The recognizer now merges `language_model_params` into `ModelConfig.provider_kwargs`, which is the path that reaches the provider constructor. Explicit entries under `provider.kwargs:` still take precedence. Also fixed a `TypeError` when `kwargs:` or `language_model_params:` is `null` in the YAML. (#1943, Thanks @lsternlicht) - Fixed `UsSsnRecognizer` over-blocking valid SSNs in the `987654320`-`987654329` range due to an 8-digit instead of full 9-digit prefix in the sample-SSN denylist check (#2074) (Thanks @AUTHENSOR) diff --git a/presidio-analyzer/tests/test_phone_recognizer.py b/presidio-analyzer/tests/test_phone_recognizer.py index fbbe3ffe6e..860413f6ea 100644 --- a/presidio-analyzer/tests/test_phone_recognizer.py +++ b/presidio-analyzer/tests/test_phone_recognizer.py @@ -1,6 +1,9 @@ +import phonenumbers import pytest +from presidio_analyzer.predefined_recognizers.generic.phone_recognizer import ( + PhoneRecognizer, +) -from presidio_analyzer.predefined_recognizers.generic.phone_recognizer import PhoneRecognizer from tests import assert_result, assert_result_with_textual_explanation @@ -28,9 +31,6 @@ def recognizer(): ("BR: +55 11 98456 5666", 1, ["PHONE_NUMBER"], ((4, 21), ), 0.4), ("My Japanese number is 090-1234-5678", 1, ["PHONE_NUMBER"],((22, 35), ), 0.4), ("My CN number is 13812345678", 1, ["PHONE_NUMBER"],((16, 27), ), 0.4), - # GB national-format number: only matched when region is the valid ISO code - # "GB" (not "UK"). Regression test for the DEFAULT_SUPPORTED_REGIONS fix. - ("My UK number is 020 7946 0958", 1, ["PHONE_NUMBER"], ((16, 29), ), 0.4), # fmt: on ], ) @@ -50,6 +50,38 @@ def test_when_all_phones_then_succeed( assert_result(res, entities[i], st_pos, fn_pos, score) +def test_default_supported_regions_are_valid(): + """Ensure every default phone region is supported by libphonenumber.""" + invalid_regions = ( + set(PhoneRecognizer.DEFAULT_SUPPORTED_REGIONS) + - phonenumbers.SUPPORTED_REGIONS + ) + assert not invalid_regions + + +def test_when_gb_national_phone_then_succeed_with_gb_explanation( + spacy_nlp_engine, +): + """Ensure a GB national phone number is attributed to the GB region.""" + text = "My UK number is 020 7946 0958" + nlp_artifacts = spacy_nlp_engine.process_text(text, "en") + results = PhoneRecognizer().analyze( + text, + ["PHONE_NUMBER"], + nlp_artifacts=nlp_artifacts, + ) + + assert len(results) == 1 + assert_result_with_textual_explanation( + results[0], + "PHONE_NUMBER", + 16, + 29, + 0.4, + "Recognized as GB region phone number, using PhoneRecognizer", + ) + + @pytest.mark.parametrize( "text, expected_len, entities, expected_positions, score, leniency", [