Repository navigation
Description
Describe the bug
RecognizerRegistry.load_predefined_recognizers(countries=[...]) can only narrow the recognizers that conf/default_recognizers.yaml already enables. Country-specific recognizers ship with enabled: false, so naming a country does not load them. For 13 countries every recognizer is disabled (au, ca, de, fi, in, kr, ng, ph, se, sg, th, tr, za), and for those countries=[...] loads no country recognizer at all, with no warning.
The docs example says otherwise. docs/analyzer/filtering_by_country.md says countries=["us", "uk"] gives "US- and UK-specific recognizers (US SSN, UK NHS, UK NINO, …)", but UkNinoRecognizer is enabled: false and is not loaded.
To Reproduce
presidio-analyzer from main at 5f5a42e (2.2.366), Python 3.12:
from presidio_analyzer import RecognizerRegistry
def country_recognizers(countries):
registry = RecognizerRegistry()
registry.load_predefined_recognizers(languages=["en"], countries=countries)
return sorted(
(r.country_code(), r.name) for r in registry.recognizers if r.country_code() is not None
)
for countries in (["in"], ["us", "uk"], ["au"]):
found = country_recognizers(countries)
print(f"countries={countries!r}: {len(found)} country-specific recognizer(s)")
for code, name in found:
print(f" {code} {name}")countries=['in']: 0 country-specific recognizer(s)
countries=['us', 'uk']: 7 country-specific recognizer(s)
uk NhsRecognizer
us MedicalLicenseRecognizer
us UsBankRecognizer
us UsItinRecognizer
us UsLicenseRecognizer
us UsPassportRecognizer
us UsSsnRecognizer
countries=['au']: 0 country-specific recognizer(s)
Expected behavior
In #2000, which added the filter, the agreed rule was "calling with a country code returns all recognizers with this country value + all recognizers with None". I expected countries=["in"] to load the six India recognizers (InAadhaarRecognizer, InPanRecognizer, …) and countries=["us", "uk"] to include UkNinoRecognizer, as in the docs example.
Additional context
RecognizerListLoader.get skips disabled entries while building the instances (recognizers_loader_utils.py:412 and :439) and applies the country filter to what is left (:466). A country that is named can't bring back a recognizer that was dropped earlier.
The filter was probably more useful when it was added. Since then, CONTRIBUTING has required new country-specific recognizers to ship enabled: false, so each new country makes the gap bigger.
I see two ways to fix it, and I'd like to know which you prefer before I open a PR:
- Naming a country enables it. When
countriesis passed toload_predefined_recognizers, load the named countries' predefined recognizers even if they shipenabled: false. This matches the docs and the rule from feat(analyzer): add optional country filter to load_predefined_recogn… #2000. It changes behavior: anyone already passingcountries=["us"]would also get the 9 US recognizers that are disabled today (UsMbiRecognizer,UsNpiRecognizer,AbaRoutingRecognizer, …), which can add false positives. A user's own YAML with an explicitenabled: falseshould keep winning. Only the shipped defaults would be overridden. - The filter stays narrow-only. Fix the docs example and the docstring to say the filter only narrows what is enabled. Log a warning when a requested country ends up with no recognizers, and point to enabling them in a registry YAML. No change in detection.
I found this while checking which of the existing India recognizers I could use instead of the custom Aadhaar and PAN recognizers in a project that redacts Indian records. I'm happy to send the PR once you pick a direction.
Activity
MaiAditya commentedon Nov 12, 2026
I'd like to pick this up. Option 1 matches
docs/analyzer/filtering_by_country.mdand the rule from #2000 (a country code returns that country's recognizers plus the locale-agnostic ones), so that's what I have ready:load_predefined_recognizers(countries=[...])enables the requested countries' predefined recognizers that ship withenabled: false; other countries stay excluded andcountries=Noneis unchanged.enabled: falsein a user's own YAML still wins.["in"]and["us", "uk"], plus a short note in the filtering docs.One side effect to confirm:
countries=["us"]would then also load the US recognizers that are disabled by default (e.g.UsMbiRecognizer,UsNpiRecognizer,AbaRoutingRecognizer), which can add false positives. If you'd rather keep the filter narrow-only (option 2), I can do the docs fix and a warning instead. Shall I open the PR?abhishek-pandey7 commentedon Nov 12, 2026
Thanks @MaiAditya ! As I mentioned in the issue, I was planning to send the PR for this once a direction is picked, so I'd like to keep it if that's OK. @omri374 , do you prefer option 1 or option 2? I can have a PR up within a few days of your answer.
MaiAditya commentedon Nov 12, 2026
Of course, go ahead. I missed that you'd planned to send it. Happy to review the PR if that helps.