hdx-python-country 3.7.2__tar.gz → 3.7.3__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.2 → hdx_python_country-3.7.3}/.config/pre-commit-config.yaml +4 -4
  2. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/.github/workflows/publish.yaml +2 -1
  3. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/.github/workflows/run-python-tests.yaml +4 -6
  4. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/PKG-INFO +3 -3
  5. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/documentation/main.md +2 -2
  6. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/pyproject.toml +14 -18
  7. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/requirements.txt +21 -25
  8. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/src/hdx/location/_version.py +2 -2
  9. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/src/hdx/location/adminlevel.py +12 -8
  10. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/src/hdx/location/names.py +3 -1
  11. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/src/hdx/location/phonetics.py +10 -10
  12. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/tests/fixtures/adminlevel.yaml +1 -0
  13. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/tests/fixtures/adminlevelparent.yaml +4 -3
  14. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/tests/hdx/location/test_adminlevel.py +48 -29
  15. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/.config/coveragerc +0 -0
  16. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/.config/pytest.ini +0 -0
  17. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/.config/ruff.toml +0 -0
  18. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/.gitignore +0 -0
  19. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/CONTRIBUTING.md +0 -0
  20. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/LICENSE +0 -0
  21. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/README.md +0 -0
  22. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/documentation/.readthedocs.yaml +0 -0
  23. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/documentation/pydoc-markdown.yaml +0 -0
  24. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/src/hdx/location/Countries & Territories Taxonomy MVP - C&T Taxonomy with HXL Tags.csv +0 -0
  25. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/src/hdx/location/__init__.py +0 -0
  26. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/src/hdx/location/country.py +0 -0
  27. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/src/hdx/location/currency.py +0 -0
  28. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/src/hdx/location/wfp_exchangerates.py +0 -0
  29. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/tests/fixtures/global_pcode_lengths.csv +0 -0
  30. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/tests/fixtures/global_pcodes_adm_1_2.csv +0 -0
  31. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/tests/fixtures/secondary_historic_rates.csv +0 -0
  32. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/tests/fixtures/secondary_rates.json +0 -0
  33. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/tests/hdx/location/Countries_UZB_Deleted.csv +0 -0
  34. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/tests/hdx/location/__init__.py +0 -0
  35. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/tests/hdx/location/test_country.py +0 -0
  36. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/tests/hdx/location/test_currency.py +0 -0
  37. {hdx_python_country-3.7.2 → hdx_python_country-3.7.3}/tests/hdx/location/test_wfp_exchangerates.py +0 -0
@@ -1,14 +1,14 @@
1
1
  default_language_version:
2
- python: python3.11
2
+ python: python3.12
3
3
  repos:
4
4
  - repo: https://github.com/pre-commit/pre-commit-hooks
5
- rev: v4.5.0
5
+ rev: v4.6.0
6
6
  hooks:
7
7
  - id: trailing-whitespace
8
8
  - id: end-of-file-fixer
9
9
  - id: check-ast
10
10
  - repo: https://github.com/astral-sh/ruff-pre-commit
11
- rev: v0.4.4
11
+ rev: v0.4.8
12
12
  hooks:
13
13
  # Run the linter.
14
14
  - id: ruff
@@ -17,7 +17,7 @@ repos:
17
17
  - id: ruff-format
18
18
  args: [--config, .config/ruff.toml]
19
19
  - repo: https://github.com/astral-sh/uv-pre-commit
20
- rev: 0.1.45
20
+ rev: 0.2.10
21
21
  hooks:
22
22
  # Run the pip compile
23
23
  - id: pip-compile
@@ -21,7 +21,8 @@ jobs:
21
21
  - name: Install dependencies
22
22
  run: |
23
23
  python -m pip install --upgrade pip
24
- pip install --upgrade hatch
24
+ - name: Install Hatch
25
+ uses: pypa/hatch@install
25
26
  - name: Build with hatch
26
27
  run: |
27
28
  hatch build
@@ -26,17 +26,15 @@ jobs:
26
26
  - name: Install dependencies
27
27
  run: |
28
28
  python -m pip install --upgrade pip
29
- pip install --upgrade hatch
29
+ - name: Install Hatch
30
+ uses: pypa/hatch@install
30
31
  - name: Test with hatch/pytest
31
- env:
32
- WFP_KEY: ${{ secrets.WFP_KEY }}
33
- WFP_SECRET: ${{ secrets.WFP_SECRET }}
34
32
  run: |
35
- hatch run test:test
33
+ hatch test
36
34
  - name: Check styling
37
35
  if: always()
38
36
  run: |
39
- hatch run lint:style
37
+ hatch fmt --check
40
38
  - name: Publish Unit Test Results
41
39
  uses: EnricoMi/publish-unit-test-result-action@v2
42
40
  if: always()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: hdx-python-country
3
- Version: 3.7.2
3
+ Version: 3.7.3
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,9 +25,9 @@ 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.6.8
28
+ Requires-Dist: hdx-python-utilities>=3.7.0
29
29
  Requires-Dist: libhxl>=5.2.1
30
- Requires-Dist: pyphonetics
30
+ Requires-Dist: rapidfuzz
31
31
  Provides-Extra: dev
32
32
  Requires-Dist: pre-commit; extra == 'dev'
33
33
  Provides-Extra: test
@@ -120,8 +120,8 @@ be global or they can be restricted by country or parent (if the AdminLevel
120
120
  object has been set up with parents). Keys take the form "MAPPING",
121
121
  "AFG|MAPPING" or "AF01|MAPPING".
122
122
  *admin_name_replacements* is a dictionary of textual replacements to try when
123
- fuzzy matching. It maps from string to string replacement. The replacements can
124
- be global or they can be restricted by country or parent (if the AdminLevel
123
+ fuzzy matching. It maps from string to string replacement. The replacements can
124
+ be global or they can be restricted by country or parent (if the AdminLevel
125
125
  object has been set up with parents). Keys take the form "STRING_TO_REPLACE",
126
126
  "AFG|STRING_TO_REPLACE" or "AF01|STRING_TO_REPLACE".
127
127
  *admin_fuzzy_dont* is a list of names for which fuzzy matching should not be
@@ -34,9 +34,9 @@ classifiers = [
34
34
  requires-python = ">=3.8"
35
35
 
36
36
  dependencies = [
37
- "hdx-python-utilities>=3.6.8",
37
+ "hdx-python-utilities>=3.7.0",
38
38
  "libhxl>=5.2.1",
39
- "pyphonetics",
39
+ "rapidfuzz",
40
40
  ]
41
41
  dynamic = ["version"]
42
42
 
@@ -79,25 +79,21 @@ version_scheme = "python-simplified-semver"
79
79
 
80
80
  # Tests
81
81
 
82
- [tool.hatch.envs.test]
83
- features = ["test"]#, "wfp"]
82
+ [tool.hatch.envs.hatch-test]
83
+ features = ["test"]
84
84
 
85
- [tool.hatch.envs.test.scripts]
86
- test = """
85
+ [[tool.hatch.envs.hatch-test.matrix]]
86
+ python = ["3.12"]
87
+
88
+ [tool.hatch.envs.hatch-test.scripts]
89
+ run = """
87
90
  pytest -c .config/pytest.ini --rootdir=. --junitxml=test-results.xml \
88
91
  --cov --cov-config=.config/coveragerc --no-cov-on-fail \
89
92
  --cov-report=lcov --cov-report=term-missing
90
93
  """
91
94
 
92
- [[tool.hatch.envs.test.matrix]]
93
- python = ["3.12"]
94
-
95
- [tool.hatch.envs.lint]
96
- detached = true
97
- dependencies = ["ruff"]
98
-
99
- [tool.hatch.envs.lint.scripts]
100
- style = [
101
- "ruff check --config .config/ruff.toml --diff {args:.}",
102
- "ruff format --config .config/ruff.toml --diff {args:.}",
103
- ]
95
+ [tool.hatch.envs.hatch-static-analysis.scripts]
96
+ format-check = ["ruff format --config .config/ruff.toml --check --diff {args:.}",]
97
+ format-fix = ["ruff format --config .config/ruff.toml {args:.}",]
98
+ lint-check = ["ruff check --config .config/ruff.toml {args:.}",]
99
+ lint-fix = ["ruff check --config .config/ruff.toml --fix {args:.}",]
@@ -8,7 +8,7 @@ attrs==23.2.0
8
8
  # jsonlines
9
9
  # jsonschema
10
10
  # referencing
11
- certifi==2024.2.2
11
+ certifi==2024.6.2
12
12
  # via requests
13
13
  cfgv==3.4.0
14
14
  # via pre-commit
@@ -18,17 +18,17 @@ charset-normalizer==3.3.2
18
18
  # via requests
19
19
  click==8.1.7
20
20
  # via typer
21
- coverage==7.5.1
21
+ coverage==7.5.3
22
22
  # via pytest-cov
23
23
  distlib==0.3.8
24
24
  # via virtualenv
25
25
  et-xmlfile==1.1.0
26
26
  # via openpyxl
27
- filelock==3.14.0
27
+ filelock==3.15.3
28
28
  # via virtualenv
29
29
  frictionless==5.17.0
30
30
  # via hdx-python-utilities
31
- hdx-python-utilities==3.6.8
31
+ hdx-python-utilities==3.7.0
32
32
  # via hdx-python-country (pyproject.toml)
33
33
  humanize==4.9.0
34
34
  # via frictionless
@@ -36,7 +36,7 @@ identify==2.5.36
36
36
  # via pre-commit
37
37
  idna==3.7
38
38
  # via requests
39
- ijson==3.2.3
39
+ ijson==3.3.0
40
40
  # via hdx-python-utilities
41
41
  iniconfig==2.0.0
42
42
  # via pytest
@@ -60,17 +60,17 @@ loguru==0.7.2
60
60
  # via hdx-python-utilities
61
61
  markdown-it-py==3.0.0
62
62
  # via rich
63
- marko==2.0.3
63
+ marko==2.1.1
64
64
  # via frictionless
65
65
  markupsafe==2.1.5
66
66
  # via jinja2
67
67
  mdurl==0.1.2
68
68
  # via markdown-it-py
69
- nodeenv==1.8.0
69
+ nodeenv==1.9.1
70
70
  # via pre-commit
71
- openpyxl==3.1.2
71
+ openpyxl==3.1.4
72
72
  # via hdx-python-utilities
73
- packaging==24.0
73
+ packaging==24.1
74
74
  # via pytest
75
75
  petl==1.7.15
76
76
  # via frictionless
@@ -84,21 +84,19 @@ 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.1
87
+ pydantic==2.7.4
88
88
  # via frictionless
89
- pydantic-core==2.18.2
89
+ pydantic-core==2.18.4
90
90
  # via pydantic
91
91
  pygments==2.18.0
92
92
  # via rich
93
- pyphonetics==0.5.3
94
- # via hdx-python-country (pyproject.toml)
95
- pytest==8.2.1
93
+ pytest==8.2.2
96
94
  # via
97
95
  # hdx-python-country (pyproject.toml)
98
96
  # pytest-cov
99
97
  pytest-cov==5.0.0
100
98
  # via hdx-python-country (pyproject.toml)
101
- python-dateutil==2.8.2
99
+ python-dateutil==2.9.0.post0
102
100
  # via
103
101
  # frictionless
104
102
  # hdx-python-utilities
@@ -112,13 +110,15 @@ pyyaml==6.0.1
112
110
  # frictionless
113
111
  # pre-commit
114
112
  # tableschema-to-template
113
+ rapidfuzz==3.9.3
114
+ # via hdx-python-country (pyproject.toml)
115
115
  ratelimit==2.2.1
116
116
  # via hdx-python-utilities
117
117
  referencing==0.35.1
118
118
  # via
119
119
  # jsonschema
120
120
  # jsonschema-specifications
121
- requests==2.32.2
121
+ requests==2.32.3
122
122
  # via
123
123
  # frictionless
124
124
  # libhxl
@@ -137,8 +137,6 @@ ruamel-yaml==0.18.6
137
137
  # via hdx-python-utilities
138
138
  ruamel-yaml-clib==0.2.8
139
139
  # via ruamel-yaml
140
- setuptools==70.0.0
141
- # via nodeenv
142
140
  shellingham==1.5.4
143
141
  # via typer
144
142
  simpleeval==0.9.13
@@ -149,7 +147,7 @@ six==1.16.0
149
147
  # python-dateutil
150
148
  stringcase==1.2.0
151
149
  # via frictionless
152
- structlog==24.1.0
150
+ structlog==24.2.0
153
151
  # via libhxl
154
152
  tableschema-to-template==0.0.13
155
153
  # via hdx-python-utilities
@@ -159,21 +157,19 @@ text-unidecode==1.3
159
157
  # via python-slugify
160
158
  typer==0.12.3
161
159
  # via frictionless
162
- typing-extensions==4.11.0
160
+ typing-extensions==4.12.2
163
161
  # via
164
162
  # frictionless
165
163
  # pydantic
166
164
  # pydantic-core
167
165
  # typer
168
166
  unidecode==1.3.8
169
- # via
170
- # libhxl
171
- # pyphonetics
172
- urllib3==2.2.1
167
+ # via libhxl
168
+ urllib3==2.2.2
173
169
  # via
174
170
  # libhxl
175
171
  # requests
176
- validators==0.28.1
172
+ validators==0.28.3
177
173
  # via frictionless
178
174
  virtualenv==20.26.2
179
175
  # 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.2'
16
- __version_tuple__ = version_tuple = (3, 7, 2)
15
+ __version__ = version = '3.7.3'
16
+ __version_tuple__ = version_tuple = (3, 7, 3)
@@ -5,7 +5,6 @@ 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
10
  from hdx.location.names import clean_name
@@ -147,7 +146,7 @@ class AdminLevel:
147
146
  self.pcode_to_name[pcode] = adm_name
148
147
 
149
148
  name_to_pcode = self.name_to_pcode.get(countryiso3, {})
150
- name_to_pcode[unidecode(adm_name).lower()] = pcode
149
+ name_to_pcode[clean_name(adm_name)] = pcode
151
150
  self.name_to_pcode[countryiso3] = name_to_pcode
152
151
  self.pcode_to_iso3[pcode] = countryiso3
153
152
  self.pcode_to_iso3[pcode] = countryiso3
@@ -157,7 +156,7 @@ class AdminLevel:
157
156
  countryiso3, {}
158
157
  )
159
158
  name_to_pcode = name_parent_to_pcode.get(parent, {})
160
- name_to_pcode[unidecode(adm_name).lower()] = pcode
159
+ name_to_pcode[clean_name(adm_name)] = pcode
161
160
  name_parent_to_pcode[parent] = name_to_pcode
162
161
  self.name_parent_to_pcode[countryiso3] = name_parent_to_pcode
163
162
  self.pcode_to_parent[pcode] = parent
@@ -642,22 +641,25 @@ class AdminLevel:
642
641
  break
643
642
  if not pcode:
644
643
  map_names = list(name_to_pcode.keys())
645
- lower_mapnames = [x.lower() for x in map_names]
646
644
 
647
645
  def al_transform_1(name):
648
- if name[:3] == "al ":
646
+ prefix = name[:3]
647
+ if prefix == "al ":
649
648
  return f"ad {name[3:]}"
649
+ elif prefix == "ad ":
650
+ return f"al {name[3:]}"
650
651
  else:
651
652
  return None
652
653
 
653
654
  def al_transform_2(name):
654
- if name[:3] == "al ":
655
+ prefix = name[:3]
656
+ if prefix == "al " or prefix == "ad ":
655
657
  return name[3:]
656
658
  else:
657
659
  return None
658
660
 
659
661
  matching_index = self.phonetics.match(
660
- lower_mapnames,
662
+ map_names,
661
663
  adm_name_lookup,
662
664
  alternative_name=adm_name_lookup2,
663
665
  transform_possible_names=[al_transform_1, al_transform_2],
@@ -714,6 +716,7 @@ class AdminLevel:
714
716
  countryiso3: str,
715
717
  name: str,
716
718
  fuzzy_match: bool = True,
719
+ fuzzy_length: int = 4,
717
720
  **kwargs: Any,
718
721
  ) -> Tuple[Optional[str], bool]:
719
722
  """Get pcode for a given name
@@ -722,6 +725,7 @@ class AdminLevel:
722
725
  countryiso3 (str): ISO3 country code
723
726
  name (str): Name to match
724
727
  fuzzy_match (bool): Whether to try fuzzy matching. Defaults to True.
728
+ fuzzy_length (int): Minimum length for fuzzy matching. Defaults to 4.
725
729
  **kwargs:
726
730
  parent (Optional[str]): Parent admin code
727
731
  logname (str): Log using this identifying name. Defaults to not logging.
@@ -767,7 +771,7 @@ class AdminLevel:
767
771
  pcode = name_to_pcode.get(name.lower())
768
772
  if pcode:
769
773
  return pcode, True
770
- if not fuzzy_match:
774
+ if not fuzzy_match or len(name) < fuzzy_length:
771
775
  return None, True
772
776
  pcode = self.fuzzy_pcode(countryiso3, name, **kwargs)
773
777
  return pcode, False
@@ -3,7 +3,7 @@ import unicodedata
3
3
 
4
4
  from unidecode import unidecode
5
5
 
6
- non_ascii = "([^\x00-\x7f])+"
6
+ non_ascii = r"([^\x00-\x7f])+"
7
7
 
8
8
 
9
9
  def clean_name(name: str) -> str:
@@ -25,5 +25,7 @@ def clean_name(name: str) -> str:
25
25
  )
26
26
  # Remove all non-ASCII characters
27
27
  clean_name = re.sub(non_ascii, " ", clean_name)
28
+ clean_name = clean_name.replace("'", "")
29
+ clean_name = re.sub(r"[\W_]", " ", clean_name)
28
30
  clean_name = unidecode(clean_name)
29
31
  return clean_name.strip().lower()
@@ -1,18 +1,18 @@
1
1
  from typing import Callable, Optional
2
2
 
3
- import pyphonetics
3
+ from rapidfuzz import fuzz
4
4
 
5
5
  from hdx.utilities.typehint import ListTuple
6
6
 
7
7
 
8
- class Phonetics(pyphonetics.RefinedSoundex):
8
+ class Phonetics:
9
9
  def match(
10
10
  self,
11
11
  possible_names: ListTuple,
12
12
  name: str,
13
13
  alternative_name: Optional[str] = None,
14
14
  transform_possible_names: ListTuple[Callable] = [],
15
- threshold: int = 2,
15
+ threshold: float = 60,
16
16
  ) -> Optional[int]:
17
17
  """
18
18
  Match name to one of the given possible names. Returns None if no match
@@ -23,22 +23,22 @@ class Phonetics(pyphonetics.RefinedSoundex):
23
23
  name (str): Name to match
24
24
  alternative_name (str): Alternative name to match. Defaults to None.
25
25
  transform_possible_names (ListTuple[Callable]): Functions to transform possible names.
26
- threshold: Match threshold. Defaults to 2.
26
+ threshold (float): Match threshold. Value is 0-100. Defaults to 60.
27
27
 
28
28
  Returns:
29
29
  Optional[int]: Index of matching name from possible names or None
30
30
  """
31
- mindistance = None
31
+ max_similarity = 0
32
32
  matching_index = None
33
33
 
34
34
  transform_possible_names.insert(0, lambda x: x)
35
35
 
36
36
  def check_name(name, possible_name):
37
- nonlocal mindistance, matching_index # noqa: E999
37
+ nonlocal max_similarity, matching_index # noqa: E999
38
38
 
39
- distance = self.distance(name, possible_name)
40
- if mindistance is None or distance < mindistance:
41
- mindistance = distance
39
+ similarity = fuzz.token_sort_ratio(name, possible_name)
40
+ if similarity > max_similarity:
41
+ max_similarity = similarity
42
42
  matching_index = i
43
43
 
44
44
  for i, possible_name in enumerate(possible_names):
@@ -51,6 +51,6 @@ class Phonetics(pyphonetics.RefinedSoundex):
51
51
  check_name(name, transformed_possible_name)
52
52
  if alternative_name:
53
53
  check_name(alternative_name, transformed_possible_name)
54
- if mindistance is None or mindistance > threshold:
54
+ if max_similarity < threshold:
55
55
  return None
56
56
  return matching_index
@@ -434,6 +434,7 @@ admin_info:
434
434
  - {pcode: XYZ123456, name: Random, iso3: XYZ}
435
435
 
436
436
  countries_fuzzy_try:
437
+ - AFG
437
438
  - NER
438
439
  - NGA
439
440
  - UKR
@@ -16,10 +16,11 @@ admin_name_mappings:
16
16
  "AF05|MyMapping3": "AF0501"
17
17
 
18
18
  admin_name_replacements:
19
- " city": ""
19
+ "wx": "an"
20
20
 
21
21
  alt1_admin_name_replacements:
22
- "COD| city": ""
22
+ "COD|wx": "an"
23
23
 
24
24
  alt2_admin_name_replacements:
25
- "CD20| city": ""
25
+ "CD20|wx": "an"
26
+ "CD31|wx": "en"
@@ -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,
@@ -192,14 +196,24 @@ class TestAdminLevel:
192
196
  "YE30",
193
197
  False,
194
198
  )
199
+ assert adminone.get_pcode("YEM", "Ad Jauf", logname="test") == (
200
+ "YE16",
201
+ False,
202
+ )
203
+ assert adminone.get_pcode("AFG", "Sar-E-Pul", logname="test") == (
204
+ "AF22",
205
+ False,
206
+ )
195
207
  assert adminone.get_pcode("SOM", "Bay", logname="test") == (
196
208
  "SO24",
197
209
  True,
198
210
  )
199
211
  output = adminone.output_matches()
200
212
  assert output == [
213
+ "test - YEM: Matching (fuzzy) Ad Jauf to Al Jawf on map",
201
214
  "test - YEM: Matching (fuzzy) Al Dali to Ad Dali on map",
202
215
  "test - YEM: Matching (fuzzy) Al Dhale'e / الضالع to Ad Dali on map",
216
+ "test - YEM: Matching (fuzzy) Al_Dhale'a to Ad Dali on map",
203
217
  ]
204
218
 
205
219
  def test_adminlevel_parent(self, config_parent):
@@ -281,21 +295,19 @@ class TestAdminLevel:
281
295
  ) == (None, False)
282
296
 
283
297
  output = admintwo.output_admin_name_replacements()
284
- assert output == [" city: "]
298
+ assert output == ["wx: an"]
285
299
  assert admintwo.get_pcode(
286
- "COD", "Mbanza-Ngungu city", logname="test"
300
+ "COD", "City of Mbwxza-Nanga", logname="test"
287
301
  ) == ("CD2013", False)
288
302
  assert admintwo.get_pcode(
289
- "COD", "Mbanza-Ngungu city", parent="CD20", logname="test"
303
+ "COD", "City of Mbwxza-Nanga", parent="CD20", logname="test"
290
304
  ) == ("CD2013", False)
291
305
  assert admintwo.get_pcode(
292
- "COD", "Mbanza-Ngungu city", parent="CD19", logname="test"
306
+ "COD", "City of Mbwxza-Nanga", parent="CD19", logname="test"
293
307
  ) == (None, False)
294
- assert admintwo.get_pcode("COD", "Kenge city", logname="test") == (
295
- "CD3102",
296
- False,
297
- )
298
- assert admintwo.get_pcode("MWI", "Blantyre city", logname="test") == (
308
+ assert admintwo.get_pcode(
309
+ "MWI", "City of Blwxtyre", logname="test"
310
+ ) == (
299
311
  "MW305",
300
312
  False,
301
313
  )
@@ -304,58 +316,66 @@ class TestAdminLevel:
304
316
  "alt1_admin_name_replacements"
305
317
  ]
306
318
  output = admintwo.output_admin_name_replacements()
307
- assert output == ["COD| city: "]
319
+ assert output == ["COD|wx: an"]
308
320
  assert admintwo.get_pcode(
309
- "COD", "Mbanza-Ngungu city", logname="test"
321
+ "COD", "City of Mbwxza-Nanga", logname="test"
310
322
  ) == ("CD2013", False)
311
323
  assert admintwo.get_pcode(
312
- "COD", "Mbanza-Ngungu city", parent="CD20", logname="test"
324
+ "COD", "City of Mbwxza-Nanga", parent="CD20", logname="test"
313
325
  ) == ("CD2013", False)
314
326
  assert admintwo.get_pcode(
315
- "COD", "Mbanza-Ngungu city", parent="CD19", logname="test"
327
+ "COD", "City of Mbwxza-Nanga", parent="CD19", logname="test"
316
328
  ) == (None, False)
317
- assert admintwo.get_pcode("COD", "Kenge city", logname="test") == (
329
+ assert admintwo.get_pcode("COD", "Kenge City", logname="test") == (
318
330
  "CD3102",
319
331
  False,
320
332
  )
333
+ assert admintwo.get_pcode("COD", "Kwxge City", logname="test") == (
334
+ None,
335
+ False,
336
+ )
321
337
  assert admintwo.get_pcode(
322
- "COD", "Kenge city", parent="CD31", logname="test"
323
- ) == ("CD3102", False)
324
- assert admintwo.get_pcode("MWI", "Blantyre city", logname="test") == (
338
+ "COD", "Kwxge City", parent="CD31", logname="test"
339
+ ) == (None, False)
340
+ assert admintwo.get_pcode(
341
+ "MWI", "City of Blwxtyre", logname="test"
342
+ ) == (
325
343
  None,
326
344
  False,
327
345
  )
328
346
  assert admintwo.get_pcode(
329
- "MWI", "Blantyre city", parent="MW3", logname="test"
347
+ "MWI", "City of Blwxtyre", parent="MW3", logname="test"
330
348
  ) == (None, False)
331
349
 
332
350
  admintwo.admin_name_replacements = config_parent[
333
351
  "alt2_admin_name_replacements"
334
352
  ]
335
353
  output = admintwo.output_admin_name_replacements()
336
- assert output == ["CD20| city: "]
354
+ assert output == ["CD20|wx: an", "CD31|wx: en"]
337
355
  assert admintwo.get_pcode(
338
- "COD", "Mbanza-Ngungu city", logname="test"
356
+ "COD", "City of Mbwxza-Nanga", logname="test"
339
357
  ) == (None, False)
340
358
  assert admintwo.get_pcode(
341
- "COD", "Mbanza-Ngungu city", parent="CD20", logname="test"
359
+ "COD", "City of Mbwxza-Nanga", parent="CD20", logname="test"
342
360
  ) == ("CD2013", False)
343
361
  assert admintwo.get_pcode(
344
- "COD", "Mbanza-Ngungu city", parent="CD19", logname="test"
362
+ "COD", "City of Mbwxza-Nanga", parent="CD19", logname="test"
345
363
  ) == (None, False)
346
- assert admintwo.get_pcode("COD", "Kenge city", logname="test") == (
364
+ assert admintwo.get_pcode("COD", "Kwxge City", logname="test") == (
347
365
  None,
348
366
  False,
349
367
  )
350
368
  assert admintwo.get_pcode(
351
- "COD", "Kenge city", parent="CD31", logname="test"
352
- ) == (None, False)
353
- assert admintwo.get_pcode("MWI", "Blantyre city", logname="test") == (
369
+ "COD", "Kwxge City", parent="CD31", logname="test"
370
+ ) == ("CD3102", False)
371
+ assert admintwo.get_pcode(
372
+ "MWI", "City of Blwxtyre", logname="test"
373
+ ) == (
354
374
  None,
355
375
  False,
356
376
  )
357
377
  assert admintwo.get_pcode(
358
- "MWI", "Blantyre city", parent="MW3", logname="test"
378
+ "MWI", "City of Blwxtyre", parent="MW3", logname="test"
359
379
  ) == (None, False)
360
380
 
361
381
  def test_adminlevel_with_url(self, config, url):
@@ -457,7 +477,7 @@ class TestAdminLevel:
457
477
  )
458
478
  assert adminone.get_pcode("YEM", "Ad Dali", logname="test") == (
459
479
  "YE30",
460
- False,
480
+ True,
461
481
  )
462
482
  assert adminone.get_pcode("YEM", "Ad Dal", logname="test") == (
463
483
  "YE30",
@@ -500,7 +520,6 @@ class TestAdminLevel:
500
520
  "test - NGA: Matching (pcode length conversion) NG015 to Federal Capital Territory on map",
501
521
  "test - UKR: Matching (substring) Chernihiv Oblast to Chernihivska on map",
502
522
  "test - YEM: Matching (substring) Ad Dal to Ad Dali' on map",
503
- "test - YEM: Matching (substring) Ad Dali to Ad Dali' on map",
504
523
  "test - YEM: Matching (pcode length conversion) YE30 to Ad Dali' on map",
505
524
  ]
506
525
  output = adminone.output_ignored()