human-input-validator 0.1.0__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {human_input_validator-0.1.0 → human_input_validator-0.1.2}/PKG-INFO +3 -2
- {human_input_validator-0.1.0 → human_input_validator-0.1.2}/README.md +2 -1
- {human_input_validator-0.1.0 → human_input_validator-0.1.2}/pyproject.toml +1 -1
- {human_input_validator-0.1.0 → human_input_validator-0.1.2}/src/human_input_validator/validators.py +29 -5
- {human_input_validator-0.1.0 → human_input_validator-0.1.2}/src/human_input_validator.egg-info/PKG-INFO +3 -2
- {human_input_validator-0.1.0 → human_input_validator-0.1.2}/setup.cfg +0 -0
- {human_input_validator-0.1.0 → human_input_validator-0.1.2}/src/human_input_validator/__init__.py +0 -0
- {human_input_validator-0.1.0 → human_input_validator-0.1.2}/src/human_input_validator/py.typed +0 -0
- {human_input_validator-0.1.0 → human_input_validator-0.1.2}/src/human_input_validator.egg-info/SOURCES.txt +0 -0
- {human_input_validator-0.1.0 → human_input_validator-0.1.2}/src/human_input_validator.egg-info/dependency_links.txt +0 -0
- {human_input_validator-0.1.0 → human_input_validator-0.1.2}/src/human_input_validator.egg-info/requires.txt +0 -0
- {human_input_validator-0.1.0 → human_input_validator-0.1.2}/src/human_input_validator.egg-info/top_level.txt +0 -0
- {human_input_validator-0.1.0 → human_input_validator-0.1.2}/tests/test_validators.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: human-input-validator
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Small validators for common human-entered data.
|
|
5
5
|
Author: Snorlena
|
|
6
6
|
License-Expression: MIT
|
|
@@ -41,7 +41,8 @@ invalid input.
|
|
|
41
41
|
|
|
42
42
|
- `email(value)` — returns a trimmed, lower-cased email address.
|
|
43
43
|
- `country(value)` — returns the official ISO 3166-1 country name, given a
|
|
44
|
-
name or code.
|
|
44
|
+
name or code. Also accepts localized country names (e.g. "Deutschland",
|
|
45
|
+
"España") via pycountry's bundled translations.
|
|
45
46
|
- `username(value, max_length=12)` — returns a lower-cased username, checking
|
|
46
47
|
length and allowed characters.
|
|
47
48
|
- `phonenumber(value, pattern)` — checks a phone number against one or more
|
|
@@ -31,7 +31,8 @@ invalid input.
|
|
|
31
31
|
|
|
32
32
|
- `email(value)` — returns a trimmed, lower-cased email address.
|
|
33
33
|
- `country(value)` — returns the official ISO 3166-1 country name, given a
|
|
34
|
-
name or code.
|
|
34
|
+
name or code. Also accepts localized country names (e.g. "Deutschland",
|
|
35
|
+
"España") via pycountry's bundled translations.
|
|
35
36
|
- `username(value, max_length=12)` — returns a lower-cased username, checking
|
|
36
37
|
length and allowed characters.
|
|
37
38
|
- `phonenumber(value, pattern)` — checks a phone number against one or more
|
{human_input_validator-0.1.0 → human_input_validator-0.1.2}/src/human_input_validator/validators.py
RENAMED
|
@@ -5,6 +5,7 @@ Each function returns a normalized value or raises :class:`ValidationError`.
|
|
|
5
5
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
|
+
import difflib
|
|
8
9
|
import functools
|
|
9
10
|
import gettext
|
|
10
11
|
import os
|
|
@@ -31,7 +32,12 @@ def _localized_country_names() -> dict[str, str]:
|
|
|
31
32
|
except FileNotFoundError:
|
|
32
33
|
continue
|
|
33
34
|
for entry in pycountry.countries:
|
|
34
|
-
|
|
35
|
+
names = (
|
|
36
|
+
entry.name,
|
|
37
|
+
getattr(entry, "official_name", None),
|
|
38
|
+
getattr(entry, "common_name", None),
|
|
39
|
+
)
|
|
40
|
+
for candidate in filter(None, names):
|
|
35
41
|
translated = translation.gettext(candidate).strip().lower()
|
|
36
42
|
index.setdefault(translated, entry.alpha_2)
|
|
37
43
|
return index
|
|
@@ -45,22 +51,40 @@ def email(value: str) -> str:
|
|
|
45
51
|
return normalized
|
|
46
52
|
|
|
47
53
|
|
|
54
|
+
_FUZZY_MATCH_CUTOFF = 0.8
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _display_name(entry: object) -> str:
|
|
58
|
+
"""Prefer the short common name (e.g. 'Tanzania') over the formal ISO name."""
|
|
59
|
+
common_name: str | None = getattr(entry, "common_name", None)
|
|
60
|
+
name: str = getattr(entry, "name")
|
|
61
|
+
return common_name or name
|
|
62
|
+
|
|
63
|
+
|
|
48
64
|
def country(value: str) -> str:
|
|
49
|
-
"""Return the
|
|
65
|
+
"""Return the common name of an ISO 3166-1 country, given its name or code in any supported language."""
|
|
50
66
|
normalized = value.strip()
|
|
51
67
|
try:
|
|
52
68
|
result = pycountry.countries.lookup(normalized)
|
|
53
|
-
return result
|
|
69
|
+
return _display_name(result)
|
|
54
70
|
except LookupError:
|
|
55
71
|
pass
|
|
56
72
|
|
|
57
|
-
|
|
73
|
+
index = _localized_country_names()
|
|
74
|
+
lowered = normalized.lower()
|
|
75
|
+
alpha_2 = index.get(lowered)
|
|
76
|
+
if alpha_2 is None:
|
|
77
|
+
# Fall back to fuzzy matching for close spelling variants (e.g. hyphenation
|
|
78
|
+
# or transliteration differences) not covered by the exact translation.
|
|
79
|
+
close_matches = difflib.get_close_matches(lowered, index.keys(), n=1, cutoff=_FUZZY_MATCH_CUTOFF)
|
|
80
|
+
if close_matches:
|
|
81
|
+
alpha_2 = index[close_matches[0]]
|
|
58
82
|
if alpha_2 is None:
|
|
59
83
|
raise ValidationError("Please enter a valid country")
|
|
60
84
|
result = pycountry.countries.get(alpha_2=alpha_2)
|
|
61
85
|
if result is None:
|
|
62
86
|
raise ValidationError("Please enter a valid country")
|
|
63
|
-
return result
|
|
87
|
+
return _display_name(result)
|
|
64
88
|
|
|
65
89
|
|
|
66
90
|
def username(value: str, max_length: int = 12) -> str:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: human-input-validator
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Small validators for common human-entered data.
|
|
5
5
|
Author: Snorlena
|
|
6
6
|
License-Expression: MIT
|
|
@@ -41,7 +41,8 @@ invalid input.
|
|
|
41
41
|
|
|
42
42
|
- `email(value)` — returns a trimmed, lower-cased email address.
|
|
43
43
|
- `country(value)` — returns the official ISO 3166-1 country name, given a
|
|
44
|
-
name or code.
|
|
44
|
+
name or code. Also accepts localized country names (e.g. "Deutschland",
|
|
45
|
+
"España") via pycountry's bundled translations.
|
|
45
46
|
- `username(value, max_length=12)` — returns a lower-cased username, checking
|
|
46
47
|
length and allowed characters.
|
|
47
48
|
- `phonenumber(value, pattern)` — checks a phone number against one or more
|
|
File without changes
|
{human_input_validator-0.1.0 → human_input_validator-0.1.2}/src/human_input_validator/__init__.py
RENAMED
|
File without changes
|
{human_input_validator-0.1.0 → human_input_validator-0.1.2}/src/human_input_validator/py.typed
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|