hdx-python-country 3.7.4__tar.gz → 3.7.5__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.
Files changed (37) hide show
  1. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/PKG-INFO +2 -2
  2. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/documentation/main.md +3 -0
  3. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/pyproject.toml +1 -1
  4. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/requirements.txt +6 -6
  5. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/src/hdx/location/_version.py +2 -2
  6. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/src/hdx/location/adminlevel.py +14 -11
  7. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/tests/hdx/location/test_adminlevel.py +6 -2
  8. hdx_python_country-3.7.4/src/hdx/location/names.py +0 -29
  9. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/.config/coveragerc +0 -0
  10. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/.config/pre-commit-config.yaml +0 -0
  11. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/.config/pytest.ini +0 -0
  12. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/.config/ruff.toml +0 -0
  13. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/.github/workflows/publish.yaml +0 -0
  14. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/.github/workflows/run-python-tests.yaml +0 -0
  15. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/.gitignore +0 -0
  16. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/CONTRIBUTING.md +0 -0
  17. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/LICENSE +0 -0
  18. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/README.md +0 -0
  19. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/documentation/.readthedocs.yaml +0 -0
  20. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/documentation/pydoc-markdown.yaml +0 -0
  21. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/src/hdx/location/Countries & Territories Taxonomy MVP - C&T Taxonomy with HXL Tags.csv +0 -0
  22. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/src/hdx/location/__init__.py +0 -0
  23. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/src/hdx/location/country.py +0 -0
  24. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/src/hdx/location/currency.py +0 -0
  25. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/src/hdx/location/phonetics.py +0 -0
  26. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/src/hdx/location/wfp_exchangerates.py +0 -0
  27. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/tests/fixtures/adminlevel.yaml +0 -0
  28. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/tests/fixtures/adminlevelparent.yaml +0 -0
  29. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/tests/fixtures/global_pcode_lengths.csv +0 -0
  30. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/tests/fixtures/global_pcodes_adm_1_2.csv +0 -0
  31. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/tests/fixtures/secondary_historic_rates.csv +0 -0
  32. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/tests/fixtures/secondary_rates.json +0 -0
  33. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/tests/hdx/location/Countries_UZB_Deleted.csv +0 -0
  34. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/tests/hdx/location/__init__.py +0 -0
  35. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/tests/hdx/location/test_country.py +0 -0
  36. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/tests/hdx/location/test_currency.py +0 -0
  37. {hdx_python_country-3.7.4 → hdx_python_country-3.7.5}/tests/hdx/location/test_wfp_exchangerates.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: hdx-python-country
3
- Version: 3.7.4
3
+ Version: 3.7.5
4
4
  Summary: HDX Python country code and exchange rate (fx) utilities
5
5
  Project-URL: Homepage, https://github.com/OCHA-DAP/hdx-python-country
6
6
  Author: Michael Rans
@@ -25,7 +25,7 @@ Classifier: Programming Language :: Python :: 3.11
25
25
  Classifier: Programming Language :: Python :: 3.12
26
26
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
27
  Requires-Python: >=3.8
28
- Requires-Dist: hdx-python-utilities>=3.7.0
28
+ Requires-Dist: hdx-python-utilities>=3.7.2
29
29
  Requires-Dist: libhxl>=5.2.1
30
30
  Requires-Dist: pyphonetics
31
31
  Provides-Extra: dev
@@ -42,6 +42,9 @@ The code for the library is [here](https://github.com/OCHA-DAP/hdx-python-countr
42
42
  The library has detailed API documentation which can be found in the menu at the top.
43
43
 
44
44
  ## Breaking Changes
45
+ From 3.7.5, removed clean_name function. There is now a function normalise in
46
+ HDX Python Utilities.
47
+
45
48
  From 3.5.5, after creating an Adminlevel, call either setup_from_admin_info,
46
49
  setup_from_libhxl_dataset or setup_from_url.
47
50
 
@@ -34,7 +34,7 @@ classifiers = [
34
34
  requires-python = ">=3.8"
35
35
 
36
36
  dependencies = [
37
- "hdx-python-utilities>=3.7.0",
37
+ "hdx-python-utilities>=3.7.2",
38
38
  "libhxl>=5.2.1",
39
39
  "pyphonetics",
40
40
  ]
@@ -8,7 +8,7 @@ attrs==23.2.0
8
8
  # jsonlines
9
9
  # jsonschema
10
10
  # referencing
11
- certifi==2024.6.2
11
+ certifi==2024.7.4
12
12
  # via requests
13
13
  cfgv==3.4.0
14
14
  # via pre-commit
@@ -28,7 +28,7 @@ filelock==3.15.4
28
28
  # via virtualenv
29
29
  frictionless==5.17.0
30
30
  # via hdx-python-utilities
31
- hdx-python-utilities==3.7.0
31
+ hdx-python-utilities==3.7.2
32
32
  # via hdx-python-country (pyproject.toml)
33
33
  humanize==4.9.0
34
34
  # via frictionless
@@ -68,7 +68,7 @@ mdurl==0.1.2
68
68
  # via markdown-it-py
69
69
  nodeenv==1.9.1
70
70
  # via pre-commit
71
- openpyxl==3.1.4
71
+ openpyxl==3.1.5
72
72
  # via hdx-python-utilities
73
73
  packaging==24.1
74
74
  # via pytest
@@ -84,9 +84,9 @@ ply==3.11
84
84
  # libhxl
85
85
  pre-commit==3.7.1
86
86
  # via hdx-python-country (pyproject.toml)
87
- pydantic==2.7.4
87
+ pydantic==2.8.2
88
88
  # via frictionless
89
- pydantic-core==2.18.4
89
+ pydantic-core==2.20.1
90
90
  # via pydantic
91
91
  pygments==2.18.0
92
92
  # via rich
@@ -171,7 +171,7 @@ urllib3==2.2.2
171
171
  # via
172
172
  # libhxl
173
173
  # requests
174
- validators==0.28.3
174
+ validators==0.30.0
175
175
  # via frictionless
176
176
  virtualenv==20.26.3
177
177
  # via pre-commit
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '3.7.4'
16
- __version_tuple__ = version_tuple = (3, 7, 4)
15
+ __version__ = version = '3.7.5'
16
+ __version_tuple__ = version_tuple = (3, 7, 5)
@@ -5,13 +5,11 @@ from typing import Any, Dict, List, Optional, Tuple
5
5
  import hxl
6
6
  from hxl import InputOptions
7
7
  from hxl.input import HXLIOException
8
- from unidecode import unidecode
9
8
 
10
9
  from hdx.location.country import Country
11
- from hdx.location.names import clean_name
12
10
  from hdx.location.phonetics import Phonetics
13
11
  from hdx.utilities.dictandlist import dict_of_sets_add
14
- from hdx.utilities.text import multiple_replace
12
+ from hdx.utilities.text import multiple_replace, normalise
15
13
  from hdx.utilities.typehint import ListTuple
16
14
 
17
15
  logger = logging.getLogger(__name__)
@@ -147,7 +145,7 @@ class AdminLevel:
147
145
  self.pcode_to_name[pcode] = adm_name
148
146
 
149
147
  name_to_pcode = self.name_to_pcode.get(countryiso3, {})
150
- name_to_pcode[unidecode(adm_name).lower()] = pcode
148
+ name_to_pcode[normalise(adm_name)] = pcode
151
149
  self.name_to_pcode[countryiso3] = name_to_pcode
152
150
  self.pcode_to_iso3[pcode] = countryiso3
153
151
  self.pcode_to_iso3[pcode] = countryiso3
@@ -157,7 +155,7 @@ class AdminLevel:
157
155
  countryiso3, {}
158
156
  )
159
157
  name_to_pcode = name_parent_to_pcode.get(parent, {})
160
- name_to_pcode[unidecode(adm_name).lower()] = pcode
158
+ name_to_pcode[normalise(adm_name)] = pcode
161
159
  name_parent_to_pcode[parent] = name_to_pcode
162
160
  self.name_parent_to_pcode[countryiso3] = name_parent_to_pcode
163
161
  self.pcode_to_parent[pcode] = parent
@@ -599,7 +597,7 @@ class AdminLevel:
599
597
  if logname:
600
598
  self.errors.add((logname, countryiso3, parent))
601
599
  return None
602
- adm_name_lookup = clean_name(name)
600
+ adm_name_lookup = normalise(name)
603
601
  adm_name_lookup2 = multiple_replace(
604
602
  adm_name_lookup,
605
603
  self.get_admin_name_replacements(countryiso3, parent),
@@ -642,22 +640,25 @@ class AdminLevel:
642
640
  break
643
641
  if not pcode:
644
642
  map_names = list(name_to_pcode.keys())
645
- lower_mapnames = [x.lower() for x in map_names]
646
643
 
647
644
  def al_transform_1(name):
648
- if name[:3] == "al ":
645
+ prefix = name[:3]
646
+ if prefix == "al ":
649
647
  return f"ad {name[3:]}"
648
+ elif prefix == "ad ":
649
+ return f"al {name[3:]}"
650
650
  else:
651
651
  return None
652
652
 
653
653
  def al_transform_2(name):
654
- if name[:3] == "al ":
654
+ prefix = name[:3]
655
+ if prefix == "al " or prefix == "ad ":
655
656
  return name[3:]
656
657
  else:
657
658
  return None
658
659
 
659
660
  matching_index = self.phonetics.match(
660
- lower_mapnames,
661
+ map_names,
661
662
  adm_name_lookup,
662
663
  alternative_name=adm_name_lookup2,
663
664
  transform_possible_names=[al_transform_1, al_transform_2],
@@ -714,6 +715,7 @@ class AdminLevel:
714
715
  countryiso3: str,
715
716
  name: str,
716
717
  fuzzy_match: bool = True,
718
+ fuzzy_length: int = 4,
717
719
  **kwargs: Any,
718
720
  ) -> Tuple[Optional[str], bool]:
719
721
  """Get pcode for a given name
@@ -722,6 +724,7 @@ class AdminLevel:
722
724
  countryiso3 (str): ISO3 country code
723
725
  name (str): Name to match
724
726
  fuzzy_match (bool): Whether to try fuzzy matching. Defaults to True.
727
+ fuzzy_length (int): Minimum length for fuzzy matching. Defaults to 4.
725
728
  **kwargs:
726
729
  parent (Optional[str]): Parent admin code
727
730
  logname (str): Log using this identifying name. Defaults to not logging.
@@ -767,7 +770,7 @@ class AdminLevel:
767
770
  pcode = name_to_pcode.get(name.lower())
768
771
  if pcode:
769
772
  return pcode, True
770
- if not fuzzy_match:
773
+ if not fuzzy_match or len(name) < fuzzy_length:
771
774
  return None, True
772
775
  pcode = self.fuzzy_pcode(countryiso3, name, **kwargs)
773
776
  return pcode, False
@@ -182,6 +182,10 @@ class TestAdminLevel:
182
182
  def test_adminlevel_fuzzy(self, config):
183
183
  adminone = AdminLevel(config)
184
184
  adminone.setup_from_admin_info(config["admin_info"])
185
+ assert adminone.get_pcode("YEM", "Al_Dhale'a", logname="test") == (
186
+ "YE30",
187
+ False,
188
+ )
185
189
  assert adminone.get_pcode("YEM", "Al Dali", logname="test") == (
186
190
  "YE30",
187
191
  False,
@@ -200,6 +204,7 @@ class TestAdminLevel:
200
204
  assert output == [
201
205
  "test - YEM: Matching (fuzzy) Al Dali to Ad Dali on map",
202
206
  "test - YEM: Matching (fuzzy) Al Dhale'e / الضالع to Ad Dali on map",
207
+ "test - YEM: Matching (fuzzy) Al_Dhale'a to Ad Dali on map",
203
208
  ]
204
209
 
205
210
  def test_adminlevel_parent(self, config_parent):
@@ -457,7 +462,7 @@ class TestAdminLevel:
457
462
  )
458
463
  assert adminone.get_pcode("YEM", "Ad Dali", logname="test") == (
459
464
  "YE30",
460
- False,
465
+ True,
461
466
  )
462
467
  assert adminone.get_pcode("YEM", "Ad Dal", logname="test") == (
463
468
  "YE30",
@@ -500,7 +505,6 @@ class TestAdminLevel:
500
505
  "test - NGA: Matching (pcode length conversion) NG015 to Federal Capital Territory on map",
501
506
  "test - UKR: Matching (substring) Chernihiv Oblast to Chernihivska on map",
502
507
  "test - YEM: Matching (substring) Ad Dal to Ad Dali' on map",
503
- "test - YEM: Matching (substring) Ad Dali to Ad Dali' on map",
504
508
  "test - YEM: Matching (pcode length conversion) YE30 to Ad Dali' on map",
505
509
  ]
506
510
  output = adminone.output_ignored()
@@ -1,29 +0,0 @@
1
- import re
2
- import unicodedata
3
-
4
- from unidecode import unidecode
5
-
6
- non_ascii = "([^\x00-\x7f])+"
7
-
8
-
9
- def clean_name(name: str) -> str:
10
- """
11
- Replace accented characters with non-accented ones in given name. Also
12
- strip whitespace from start and end and make lwoercase.
13
-
14
- Args:
15
- name (str): Name to change
16
-
17
- Returns:
18
- str: Name without accented characters
19
- """
20
- #
21
- clean_name = "".join(
22
- c
23
- for c in unicodedata.normalize("NFD", name)
24
- if unicodedata.category(c) != "Mn"
25
- )
26
- # Remove all non-ASCII characters
27
- clean_name = re.sub(non_ascii, " ", clean_name)
28
- clean_name = unidecode(clean_name)
29
- return clean_name.strip().lower()