hdx-python-country 3.9.5__tar.gz → 3.9.8__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.
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/.pre-commit-config.yaml +4 -4
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/PKG-INFO +2 -2
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/hatch.toml +1 -1
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/pyproject.toml +1 -1
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/requirements.txt +43 -40
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/src/hdx/location/_version.py +16 -3
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/src/hdx/location/country.py +78 -27
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/src/hdx/location/wfp_api.py +2 -2
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/hdx/location/test_country.py +112 -4
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/.coveragerc +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/.github/workflows/publish.yaml +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/.github/workflows/run-python-tests.yaml +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/.gitignore +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/LICENSE +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/README.md +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/documentation/.readthedocs.yaml +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/documentation/index.md +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/documentation/mkdocs.yaml +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/pytest.ini +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/ruff.toml +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/src/hdx/location/Countries & Territories Taxonomy MVP - C&T Taxonomy with HXL Tags.csv +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/src/hdx/location/__init__.py +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/src/hdx/location/adminlevel.py +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/src/hdx/location/currency.py +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/src/hdx/location/int_timestamp.py +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/src/hdx/location/wfp_exchangerates.py +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/adminlevel.yaml +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/adminlevelparent.yaml +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/download-global-pcode-lengths.csv +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/download-global-pcodes-adm-1-2.csv +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/secondary_historic_rates.csv +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/secondary_rates.json +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/wfp/Currency_List_1.json +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/wfp/Currency_List_2.json +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_1.json +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_10.json +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_2.json +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_3.json +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_4.json +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_5.json +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_6.json +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_7.json +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_8.json +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_9.json +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/hdx/location/Countries_UZB_Deleted.csv +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/hdx/location/__init__.py +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/hdx/location/conftest.py +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/hdx/location/test_adminlevel.py +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/hdx/location/test_currency.py +0 -0
- {hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/hdx/location/test_wfp_exchangerates.py +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
default_language_version:
|
|
2
|
-
python: python3.
|
|
2
|
+
python: python3.13
|
|
3
3
|
repos:
|
|
4
4
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
5
5
|
rev: v5.0.0
|
|
@@ -8,15 +8,15 @@ repos:
|
|
|
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.
|
|
11
|
+
rev: v0.12.0
|
|
12
12
|
hooks:
|
|
13
13
|
# Run the linter.
|
|
14
|
-
- id: ruff
|
|
14
|
+
- id: ruff-check
|
|
15
15
|
args: [ --fix ]
|
|
16
16
|
# Run the formatter.
|
|
17
17
|
- id: ruff-format
|
|
18
18
|
- repo: https://github.com/astral-sh/uv-pre-commit
|
|
19
|
-
rev: 0.
|
|
19
|
+
rev: 0.7.14
|
|
20
20
|
hooks:
|
|
21
21
|
# Run the pip compile
|
|
22
22
|
- id: pip-compile
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hdx-python-country
|
|
3
|
-
Version: 3.9.
|
|
3
|
+
Version: 3.9.8
|
|
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.
|
|
28
|
+
Requires-Dist: hdx-python-utilities>=3.9.2
|
|
29
29
|
Requires-Dist: libhxl>=5.2.2
|
|
30
30
|
Requires-Dist: tenacity
|
|
31
31
|
Provides-Extra: dev
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# uv pip compile pyproject.toml --resolver=backtracking --all-extras -o requirements.txt
|
|
3
3
|
annotated-types==0.7.0
|
|
4
4
|
# via pydantic
|
|
5
|
-
astdoc==1.2
|
|
5
|
+
astdoc==1.3.2
|
|
6
6
|
# via mkapi
|
|
7
7
|
attrs==25.3.0
|
|
8
8
|
# via
|
|
@@ -12,39 +12,40 @@ attrs==25.3.0
|
|
|
12
12
|
# referencing
|
|
13
13
|
babel==2.17.0
|
|
14
14
|
# via mkdocs-material
|
|
15
|
-
backrefs==5.
|
|
15
|
+
backrefs==5.9
|
|
16
16
|
# via mkdocs-material
|
|
17
|
-
certifi==2025.
|
|
17
|
+
certifi==2025.8.3
|
|
18
18
|
# via requests
|
|
19
19
|
cfgv==3.4.0
|
|
20
20
|
# via pre-commit
|
|
21
21
|
chardet==5.2.0
|
|
22
22
|
# via frictionless
|
|
23
|
-
charset-normalizer==3.4.
|
|
23
|
+
charset-normalizer==3.4.3
|
|
24
24
|
# via requests
|
|
25
|
-
click==8.1
|
|
25
|
+
click==8.2.1
|
|
26
26
|
# via
|
|
27
27
|
# mkdocs
|
|
28
|
+
# mkdocs-material
|
|
28
29
|
# typer
|
|
29
30
|
colorama==0.4.6
|
|
30
31
|
# via mkdocs-material
|
|
31
|
-
coverage==7.
|
|
32
|
+
coverage==7.10.7
|
|
32
33
|
# via pytest-cov
|
|
33
|
-
distlib==0.
|
|
34
|
+
distlib==0.4.0
|
|
34
35
|
# via virtualenv
|
|
35
36
|
et-xmlfile==2.0.0
|
|
36
37
|
# via openpyxl
|
|
37
|
-
filelock==3.
|
|
38
|
+
filelock==3.19.1
|
|
38
39
|
# via virtualenv
|
|
39
40
|
frictionless==5.18.1
|
|
40
41
|
# via hdx-python-utilities
|
|
41
42
|
ghp-import==2.1.0
|
|
42
43
|
# via mkdocs
|
|
43
|
-
hdx-python-utilities==3.
|
|
44
|
+
hdx-python-utilities==3.9.2
|
|
44
45
|
# via hdx-python-country (pyproject.toml)
|
|
45
|
-
humanize==4.
|
|
46
|
+
humanize==4.13.0
|
|
46
47
|
# via frictionless
|
|
47
|
-
identify==2.6.
|
|
48
|
+
identify==2.6.14
|
|
48
49
|
# via pre-commit
|
|
49
50
|
idna==3.10
|
|
50
51
|
# via requests
|
|
@@ -64,24 +65,24 @@ jsonlines==4.0.0
|
|
|
64
65
|
# via hdx-python-utilities
|
|
65
66
|
jsonpath-ng==1.7.0
|
|
66
67
|
# via libhxl
|
|
67
|
-
jsonschema==4.
|
|
68
|
+
jsonschema==4.25.1
|
|
68
69
|
# via
|
|
69
70
|
# frictionless
|
|
70
71
|
# tableschema-to-template
|
|
71
|
-
jsonschema-specifications==2025.
|
|
72
|
+
jsonschema-specifications==2025.9.1
|
|
72
73
|
# via jsonschema
|
|
73
74
|
libhxl==5.2.2
|
|
74
75
|
# via hdx-python-country (pyproject.toml)
|
|
75
76
|
loguru==0.7.3
|
|
76
77
|
# via hdx-python-utilities
|
|
77
|
-
markdown==3.
|
|
78
|
+
markdown==3.9
|
|
78
79
|
# via
|
|
79
80
|
# mkdocs
|
|
80
81
|
# mkdocs-material
|
|
81
82
|
# pymdown-extensions
|
|
82
|
-
markdown-it-py==
|
|
83
|
+
markdown-it-py==4.0.0
|
|
83
84
|
# via rich
|
|
84
|
-
marko==2.
|
|
85
|
+
marko==2.2.0
|
|
85
86
|
# via frictionless
|
|
86
87
|
markupsafe==3.0.2
|
|
87
88
|
# via
|
|
@@ -93,7 +94,7 @@ mergedeep==1.3.4
|
|
|
93
94
|
# via
|
|
94
95
|
# mkdocs
|
|
95
96
|
# mkdocs-get-deps
|
|
96
|
-
mkapi==4.4.
|
|
97
|
+
mkapi==4.4.5
|
|
97
98
|
# via hdx-python-country (pyproject.toml)
|
|
98
99
|
mkdocs==1.6.1
|
|
99
100
|
# via
|
|
@@ -101,7 +102,7 @@ mkdocs==1.6.1
|
|
|
101
102
|
# mkdocs-material
|
|
102
103
|
mkdocs-get-deps==0.2.0
|
|
103
104
|
# via mkdocs
|
|
104
|
-
mkdocs-material==9.6.
|
|
105
|
+
mkdocs-material==9.6.20
|
|
105
106
|
# via mkapi
|
|
106
107
|
mkdocs-material-extensions==1.3.1
|
|
107
108
|
# via mkdocs-material
|
|
@@ -117,37 +118,40 @@ paginate==0.5.7
|
|
|
117
118
|
# via mkdocs-material
|
|
118
119
|
pathspec==0.12.1
|
|
119
120
|
# via mkdocs
|
|
120
|
-
petl==1.7.
|
|
121
|
+
petl==1.7.17
|
|
121
122
|
# via frictionless
|
|
122
|
-
platformdirs==4.
|
|
123
|
+
platformdirs==4.4.0
|
|
123
124
|
# via
|
|
124
125
|
# mkdocs-get-deps
|
|
125
126
|
# virtualenv
|
|
126
127
|
pluggy==1.6.0
|
|
127
|
-
# via
|
|
128
|
+
# via
|
|
129
|
+
# pytest
|
|
130
|
+
# pytest-cov
|
|
128
131
|
ply==3.11
|
|
129
132
|
# via
|
|
130
133
|
# jsonpath-ng
|
|
131
134
|
# libhxl
|
|
132
|
-
pre-commit==4.
|
|
135
|
+
pre-commit==4.3.0
|
|
133
136
|
# via hdx-python-country (pyproject.toml)
|
|
134
|
-
pydantic==2.11.
|
|
137
|
+
pydantic==2.11.9
|
|
135
138
|
# via frictionless
|
|
136
139
|
pydantic-core==2.33.2
|
|
137
140
|
# via pydantic
|
|
138
|
-
pygments==2.19.
|
|
141
|
+
pygments==2.19.2
|
|
139
142
|
# via
|
|
140
143
|
# mkdocs-material
|
|
144
|
+
# pytest
|
|
141
145
|
# rich
|
|
142
|
-
pymdown-extensions==10.
|
|
146
|
+
pymdown-extensions==10.16.1
|
|
143
147
|
# via mkdocs-material
|
|
144
148
|
pyphonetics==0.5.3
|
|
145
149
|
# via hdx-python-utilities
|
|
146
|
-
pytest==8.
|
|
150
|
+
pytest==8.4.2
|
|
147
151
|
# via
|
|
148
152
|
# hdx-python-country (pyproject.toml)
|
|
149
153
|
# pytest-cov
|
|
150
|
-
pytest-cov==
|
|
154
|
+
pytest-cov==7.0.0
|
|
151
155
|
# via hdx-python-country (pyproject.toml)
|
|
152
156
|
python-dateutil==2.9.0.post0
|
|
153
157
|
# via
|
|
@@ -176,7 +180,7 @@ referencing==0.36.2
|
|
|
176
180
|
# via
|
|
177
181
|
# jsonschema
|
|
178
182
|
# jsonschema-specifications
|
|
179
|
-
requests==2.32.
|
|
183
|
+
requests==2.32.5
|
|
180
184
|
# via
|
|
181
185
|
# frictionless
|
|
182
186
|
# libhxl
|
|
@@ -186,13 +190,13 @@ requests-file==2.1.0
|
|
|
186
190
|
# via hdx-python-utilities
|
|
187
191
|
rfc3986==2.0.0
|
|
188
192
|
# via frictionless
|
|
189
|
-
rich==14.
|
|
193
|
+
rich==14.1.0
|
|
190
194
|
# via typer
|
|
191
|
-
rpds-py==0.
|
|
195
|
+
rpds-py==0.27.1
|
|
192
196
|
# via
|
|
193
197
|
# jsonschema
|
|
194
198
|
# referencing
|
|
195
|
-
ruamel-yaml==0.18.
|
|
199
|
+
ruamel-yaml==0.18.15
|
|
196
200
|
# via hdx-python-utilities
|
|
197
201
|
ruamel-yaml-clib==0.2.12
|
|
198
202
|
# via ruamel-yaml
|
|
@@ -202,7 +206,7 @@ simpleeval==1.0.3
|
|
|
202
206
|
# via frictionless
|
|
203
207
|
six==1.17.0
|
|
204
208
|
# via python-dateutil
|
|
205
|
-
structlog==25.
|
|
209
|
+
structlog==25.4.0
|
|
206
210
|
# via libhxl
|
|
207
211
|
tableschema-to-template==0.0.13
|
|
208
212
|
# via hdx-python-utilities
|
|
@@ -212,41 +216,40 @@ tenacity==9.1.2
|
|
|
212
216
|
# via hdx-python-country (pyproject.toml)
|
|
213
217
|
text-unidecode==1.3
|
|
214
218
|
# via python-slugify
|
|
215
|
-
typer==0.
|
|
219
|
+
typer==0.19.1
|
|
216
220
|
# via frictionless
|
|
217
|
-
typing-extensions==4.
|
|
221
|
+
typing-extensions==4.15.0
|
|
218
222
|
# via
|
|
219
223
|
# frictionless
|
|
220
224
|
# pydantic
|
|
221
225
|
# pydantic-core
|
|
222
|
-
# referencing
|
|
223
226
|
# typer
|
|
224
227
|
# typing-inspection
|
|
225
|
-
typing-inspection==0.4.
|
|
228
|
+
typing-inspection==0.4.1
|
|
226
229
|
# via pydantic
|
|
227
230
|
unidecode==1.4.0
|
|
228
231
|
# via
|
|
229
232
|
# libhxl
|
|
230
233
|
# pyphonetics
|
|
231
|
-
urllib3==2.
|
|
234
|
+
urllib3==2.5.0
|
|
232
235
|
# via
|
|
233
236
|
# libhxl
|
|
234
237
|
# requests
|
|
235
238
|
validators==0.35.0
|
|
236
239
|
# via frictionless
|
|
237
|
-
virtualenv==20.
|
|
240
|
+
virtualenv==20.34.0
|
|
238
241
|
# via pre-commit
|
|
239
242
|
watchdog==6.0.0
|
|
240
243
|
# via mkdocs
|
|
241
244
|
wheel==0.45.1
|
|
242
245
|
# via libhxl
|
|
243
|
-
xlrd==2.0.
|
|
246
|
+
xlrd==2.0.2
|
|
244
247
|
# via hdx-python-utilities
|
|
245
248
|
xlrd3==1.1.0
|
|
246
249
|
# via libhxl
|
|
247
250
|
xlsx2csv==0.8.4
|
|
248
251
|
# via hdx-python-utilities
|
|
249
|
-
xlsxwriter==3.2.
|
|
252
|
+
xlsxwriter==3.2.9
|
|
250
253
|
# via tableschema-to-template
|
|
251
254
|
xlwt==1.3.0
|
|
252
255
|
# via hdx-python-utilities
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
# file generated by setuptools-scm
|
|
2
2
|
# don't change, don't track in version control
|
|
3
3
|
|
|
4
|
-
__all__ = [
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
5
12
|
|
|
6
13
|
TYPE_CHECKING = False
|
|
7
14
|
if TYPE_CHECKING:
|
|
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
|
|
|
9
16
|
from typing import Union
|
|
10
17
|
|
|
11
18
|
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
12
20
|
else:
|
|
13
21
|
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
14
23
|
|
|
15
24
|
version: str
|
|
16
25
|
__version__: str
|
|
17
26
|
__version_tuple__: VERSION_TUPLE
|
|
18
27
|
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
19
30
|
|
|
20
|
-
__version__ = version = '3.9.
|
|
21
|
-
__version_tuple__ = version_tuple = (3, 9,
|
|
31
|
+
__version__ = version = '3.9.8'
|
|
32
|
+
__version_tuple__ = version_tuple = (3, 9, 8)
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = None
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
"""Country location"""
|
|
2
2
|
|
|
3
|
-
import copy
|
|
4
3
|
import logging
|
|
5
4
|
import os.path
|
|
6
5
|
import re
|
|
7
|
-
from string import punctuation
|
|
8
6
|
from typing import Dict, List, Optional, Tuple, Union
|
|
9
7
|
|
|
10
8
|
import hxl
|
|
@@ -62,6 +60,7 @@ class Country:
|
|
|
62
60
|
"BOLIVARIAN",
|
|
63
61
|
"PLURINATIONAL",
|
|
64
62
|
"PEOPLE'S",
|
|
63
|
+
"PEOPLES",
|
|
65
64
|
"DUTCH PART",
|
|
66
65
|
"FRENCH PART",
|
|
67
66
|
"MALVINAS",
|
|
@@ -721,38 +720,90 @@ class Country:
|
|
|
721
720
|
Returns:
|
|
722
721
|
Tuple[str, List[str]]: Uppercase simplified country name and list of removed words
|
|
723
722
|
"""
|
|
724
|
-
|
|
723
|
+
# Convert the input into an upper-cased list of words
|
|
724
|
+
countryupper = country.upper().strip()
|
|
725
725
|
words = get_words_in_sentence(countryupper)
|
|
726
|
+
|
|
727
|
+
# Strip common patterns
|
|
726
728
|
index = countryupper.find(",")
|
|
727
729
|
if index != -1:
|
|
728
730
|
countryupper = countryupper[:index]
|
|
729
731
|
index = countryupper.find(":")
|
|
730
732
|
if index != -1:
|
|
731
733
|
countryupper = countryupper[:index]
|
|
732
|
-
|
|
733
|
-
countryupper
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
for
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
734
|
+
|
|
735
|
+
if countryupper and not (countryupper[0] == "(" and countryupper[-1] == ")"):
|
|
736
|
+
regex = re.compile(r"\(.+?\)")
|
|
737
|
+
countryupper = regex.sub("", countryupper)
|
|
738
|
+
|
|
739
|
+
# Find the words that remain as candidates for the simplified name.
|
|
740
|
+
# These are guaranteed to be a subset of `words` because we have only pruned
|
|
741
|
+
# parts from the sentence and not done any transformative processing.
|
|
742
|
+
candidate_words = get_words_in_sentence(countryupper)
|
|
743
|
+
|
|
744
|
+
if candidate_words:
|
|
745
|
+
# Make the simplifying terms indexable for efficient lookup
|
|
746
|
+
multiword_terms = {}
|
|
747
|
+
singleword_terms = set()
|
|
748
|
+
|
|
749
|
+
for terms in [
|
|
750
|
+
cls.simplifications,
|
|
751
|
+
cls.abbreviations.keys(),
|
|
752
|
+
cls.abbreviations.values(),
|
|
753
|
+
cls.multiple_abbreviations.keys(),
|
|
754
|
+
] + list(cls.multiple_abbreviations.values()):
|
|
755
|
+
for term in terms:
|
|
756
|
+
if " " in term:
|
|
757
|
+
# Index multi-word terms by the first term against a list of the terms
|
|
758
|
+
term_parts = term.split(" ")
|
|
759
|
+
multiword_terms[term_parts[0]] = term_parts
|
|
760
|
+
else:
|
|
761
|
+
# Add single word terms to the set, and add their dot-less form as well
|
|
762
|
+
singleword_terms.add(term)
|
|
763
|
+
if term[-1] == ".":
|
|
764
|
+
singleword_terms.add(term.strip("."))
|
|
765
|
+
|
|
766
|
+
num_candidate_words = len(candidate_words)
|
|
767
|
+
simplified_term = ""
|
|
768
|
+
enumerated_words = enumerate(candidate_words)
|
|
769
|
+
default = (num_candidate_words, "")
|
|
770
|
+
|
|
771
|
+
# Iterate through the candidate terms until we a) find a non-simplified word
|
|
772
|
+
# or b) hit the end of the list of words
|
|
773
|
+
while (val := next(enumerated_words, default)) != default:
|
|
774
|
+
i, word = val
|
|
775
|
+
if word in singleword_terms:
|
|
776
|
+
# If the word was a single word simplification term then skip it
|
|
777
|
+
continue
|
|
778
|
+
if (
|
|
779
|
+
# If the current term is the first word in a multi-part term
|
|
780
|
+
(term_parts := multiword_terms.get(word))
|
|
781
|
+
# And there are enough words left in the sentence
|
|
782
|
+
and i + len(term_parts) <= num_candidate_words
|
|
783
|
+
# And all of the words in the multi-word phrase are in sequence
|
|
784
|
+
# in the candidate term starting at the current position
|
|
785
|
+
and all(
|
|
786
|
+
candidate_words[i + j] == term_part
|
|
787
|
+
for j, term_part in enumerate(term_parts)
|
|
788
|
+
)
|
|
789
|
+
):
|
|
790
|
+
# Then skip the other words in the term and continue
|
|
791
|
+
for _ in range(len(term_parts) - 1):
|
|
792
|
+
next(enumerated_words)
|
|
793
|
+
|
|
794
|
+
continue
|
|
795
|
+
# Else we found a word that we aren't dropping - it is our simplified word.
|
|
796
|
+
# Take it and break.
|
|
797
|
+
simplified_term = word
|
|
798
|
+
break
|
|
799
|
+
|
|
800
|
+
if simplified_term:
|
|
801
|
+
# We found a simplified term. Remove it from the list of other terms
|
|
802
|
+
words.remove(simplified_term)
|
|
803
|
+
else:
|
|
804
|
+
simplified_term = ""
|
|
805
|
+
|
|
806
|
+
return simplified_term, words
|
|
756
807
|
|
|
757
808
|
@classmethod
|
|
758
809
|
def get_iso3_country_code(
|
|
@@ -28,8 +28,8 @@ class WFPAPI:
|
|
|
28
28
|
"""
|
|
29
29
|
|
|
30
30
|
token_url = "https://api.wfp.org/token"
|
|
31
|
-
base_url = "https://api.wfp.org/vam-data-bridges/
|
|
32
|
-
scope = "vamdatabridges_commodities-list_get vamdatabridges_commodityunits-list_get vamdatabridges_marketprices-alps_get vamdatabridges_commodities-categories-list_get vamdatabridges_commodityunits-conversion-list_get vamdatabridges_marketprices-priceweekly_get vamdatabridges_markets-geojsonlist_get vamdatabridges_marketprices-pricemonthly_get vamdatabridges_markets-list_get vamdatabridges_currency-list_get vamdatabridges_currency-usdindirectquotation_get"
|
|
31
|
+
base_url = "https://api.wfp.org/vam-data-bridges/6.0.0/"
|
|
32
|
+
scope = "gefs_geoless-items-countries_get vamdatabridges_commodities-list_get vamdatabridges_commodityunits-list_get vamdatabridges_marketprices-alps_get vamdatabridges_commodities-categories-list_get vamdatabridges_commodityunits-conversion-list_get vamdatabridges_marketprices-priceweekly_get vamdatabridges_markets-geojsonlist_get vamdatabridges_marketprices-pricemonthly_get vamdatabridges_markets-list_get vamdatabridges_currency-list_get vamdatabridges_currency-usdindirectquotation_get"
|
|
33
33
|
default_retry_params = {
|
|
34
34
|
"retry": retry_if_exception_type(DownloadError),
|
|
35
35
|
"after": after_log(logger, logging.INFO),
|
|
@@ -644,36 +644,143 @@ class TestCountry:
|
|
|
644
644
|
]
|
|
645
645
|
|
|
646
646
|
def test_simplify_countryname(self):
|
|
647
|
-
|
|
647
|
+
# Test that we handle the empty string case
|
|
648
|
+
assert Country.simplify_countryname("") == ("", [])
|
|
649
|
+
|
|
650
|
+
# Test that country codes and arbitrary words return just the word but capitalised
|
|
651
|
+
assert Country.simplify_countryname("jpn") == ("JPN", [])
|
|
652
|
+
assert Country.simplify_countryname("test") == ("TEST", [])
|
|
653
|
+
|
|
654
|
+
# Test simplified terms are removed, including abbreviations
|
|
648
655
|
assert Country.simplify_countryname("United Rep. of Tanzania") == (
|
|
649
656
|
"TANZANIA",
|
|
650
657
|
["UNITED", "REP", "OF"],
|
|
651
658
|
)
|
|
659
|
+
assert Country.simplify_countryname(
|
|
660
|
+
"The former Yugoslav Republic of Macedonia"
|
|
661
|
+
) == ("MACEDONIA", ["THE", "FORMER", "YUGOSLAV", "REPUBLIC", "OF"])
|
|
662
|
+
|
|
663
|
+
# Test different word orderings and bracketing are consistent
|
|
652
664
|
assert Country.simplify_countryname("Micronesia (Federated States of)") == (
|
|
653
665
|
"MICRONESIA",
|
|
654
666
|
["FEDERATED", "STATES", "OF"],
|
|
655
667
|
)
|
|
668
|
+
assert Country.simplify_countryname("Federated States of Micronesia") == (
|
|
669
|
+
"MICRONESIA",
|
|
670
|
+
["FEDERATED", "STATES", "OF"],
|
|
671
|
+
)
|
|
672
|
+
assert Country.simplify_countryname("(Federated States of) Micronesia") == (
|
|
673
|
+
"MICRONESIA",
|
|
674
|
+
["FEDERATED", "STATES", "OF"],
|
|
675
|
+
)
|
|
676
|
+
|
|
677
|
+
# Test that the simplified terms on their own are dropped and that we handle
|
|
678
|
+
# the "no simplified term" case
|
|
679
|
+
assert Country.simplify_countryname("Federated States") == (
|
|
680
|
+
"",
|
|
681
|
+
["FEDERATED", "STATES"],
|
|
682
|
+
)
|
|
683
|
+
|
|
684
|
+
# Test that multi-word simplifications are dropped
|
|
685
|
+
assert Country.simplify_countryname("French Part of Saint Martin") == (
|
|
686
|
+
"MARTIN",
|
|
687
|
+
["FRENCH", "PART", "OF", "SAINT"],
|
|
688
|
+
)
|
|
689
|
+
assert Country.simplify_countryname("French Part of Saint-Martin") == (
|
|
690
|
+
"MARTIN",
|
|
691
|
+
["FRENCH", "PART", "OF", "SAINT"],
|
|
692
|
+
)
|
|
693
|
+
# "French Part" is a simplification and so can't be the simplified term
|
|
694
|
+
assert Country.simplify_countryname("French Part") == ("", ["FRENCH", "PART"])
|
|
695
|
+
# But the words must be consecutive for multi-part terms,
|
|
696
|
+
# so we don't drop "French" and "part" here
|
|
697
|
+
assert Country.simplify_countryname("French and Part") == (
|
|
698
|
+
"FRENCH",
|
|
699
|
+
["AND", "PART"],
|
|
700
|
+
)
|
|
701
|
+
|
|
702
|
+
# Test that we handle abbreviations with and without punctuation
|
|
656
703
|
assert Country.simplify_countryname("Dem. Rep. of the Congo") == (
|
|
657
704
|
"CONGO",
|
|
658
705
|
["DEM", "REP", "OF", "THE"],
|
|
659
706
|
)
|
|
707
|
+
assert Country.simplify_countryname("Dem Rep of the Congo") == (
|
|
708
|
+
"CONGO",
|
|
709
|
+
["DEM", "REP", "OF", "THE"],
|
|
710
|
+
)
|
|
711
|
+
|
|
712
|
+
# Test that we handle the "Country, Specifics" comma format
|
|
660
713
|
assert Country.simplify_countryname(
|
|
661
714
|
"Korea, Democratic People's Republic of"
|
|
662
715
|
) == ("KOREA", ["DEMOCRATIC", "PEOPLE'S", "REPUBLIC", "OF"])
|
|
663
716
|
assert Country.simplify_countryname(
|
|
664
717
|
"Democratic People's Republic of Korea"
|
|
665
718
|
) == ("KOREA", ["DEMOCRATIC", "PEOPLE'S", "REPUBLIC", "OF"])
|
|
719
|
+
|
|
720
|
+
# Test that we handle more bracketed formats
|
|
666
721
|
assert Country.simplify_countryname("Korea (the Republic of))") == (
|
|
667
722
|
"KOREA",
|
|
668
723
|
["THE", "REPUBLIC", "OF"],
|
|
669
724
|
)
|
|
725
|
+
# Regression test for bug #70 - partial brackets
|
|
670
726
|
assert Country.simplify_countryname("Korea (the Republic of") == (
|
|
671
727
|
"KOREA",
|
|
672
728
|
["THE", "REPUBLIC", "OF"],
|
|
673
729
|
)
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
730
|
+
|
|
731
|
+
# Test that we don't strip everything just because it's bracketed, even if the brackets
|
|
732
|
+
# are surrounded by whitespace
|
|
733
|
+
assert Country.simplify_countryname("(the Republic of Korea)") == (
|
|
734
|
+
"KOREA",
|
|
735
|
+
["THE", "REPUBLIC", "OF"],
|
|
736
|
+
)
|
|
737
|
+
assert Country.simplify_countryname(" (the Republic of Korea) ") == (
|
|
738
|
+
"KOREA",
|
|
739
|
+
["THE", "REPUBLIC", "OF"],
|
|
740
|
+
)
|
|
741
|
+
|
|
742
|
+
# Test that we're actually stripping the brackets and that it's not all just been
|
|
743
|
+
# simplified words that we'd drop anyway, even if they weren't in brackets
|
|
744
|
+
assert Country.simplify_countryname("(Sometimes) Korea") == (
|
|
745
|
+
"KOREA",
|
|
746
|
+
["SOMETIMES"],
|
|
747
|
+
)
|
|
748
|
+
|
|
749
|
+
# Regression test for bug #75 - apostrophes in simplified term
|
|
750
|
+
assert Country.simplify_countryname("d'Ivoire Côte") == ("D'IVOIRE", ["CÔTE"])
|
|
751
|
+
|
|
752
|
+
# Regression test for bug #77 - other punctuation in simplified term
|
|
753
|
+
assert Country.simplify_countryname("Guinea-Bissau") == ("GUINEA", ["BISSAU"])
|
|
754
|
+
|
|
755
|
+
# Test simplification of terms with apostrophes, and the non-apostrophe form
|
|
756
|
+
assert Country.simplify_countryname("People's Republic of Bangladesh") == (
|
|
757
|
+
"BANGLADESH",
|
|
758
|
+
["PEOPLE'S", "REPUBLIC", "OF"],
|
|
759
|
+
)
|
|
760
|
+
assert Country.simplify_countryname("Peoples Republic of Bangladesh") == (
|
|
761
|
+
"BANGLADESH",
|
|
762
|
+
["PEOPLES", "REPUBLIC", "OF"],
|
|
763
|
+
)
|
|
764
|
+
# Known limitation with "smart quote" handling
|
|
765
|
+
assert Country.simplify_countryname("People’s Republic of Bangladesh") == (
|
|
766
|
+
"PEOPLE’S",
|
|
767
|
+
["REPUBLIC", "OF", "BANGLADESH"],
|
|
768
|
+
)
|
|
769
|
+
|
|
770
|
+
# Simplifying assumes that it isn't getting an address and simplifies to the first
|
|
771
|
+
# part around commas, even if it isn't a country
|
|
772
|
+
assert Country.simplify_countryname("Paris, France") == (
|
|
773
|
+
"PARIS",
|
|
774
|
+
["FRANCE"],
|
|
775
|
+
)
|
|
776
|
+
|
|
777
|
+
# Some people supply strings that aren't countries
|
|
778
|
+
# (often indirectly via `get_iso3_country_code_fuzzy()`)
|
|
779
|
+
# Ensure the function doesn't error, even if the value is meaningless.
|
|
780
|
+
assert Country.simplify_countryname("3.1 Global scores and ranking") == (
|
|
781
|
+
"3",
|
|
782
|
+
["1", "GLOBAL", "SCORES", "AND", "RANKING"],
|
|
783
|
+
)
|
|
677
784
|
|
|
678
785
|
def test_get_iso3_country_code(self):
|
|
679
786
|
assert Country.get_iso3_country_code("jpn") == "JPN"
|
|
@@ -826,6 +933,7 @@ class TestCountry:
|
|
|
826
933
|
self.setup_unofficial_date()
|
|
827
934
|
assert Country.get_iso3_country_code_fuzzy("Kosovo") == ("XKX", True)
|
|
828
935
|
assert Country.get_iso3_country_code_fuzzy("Kosovo*") == ("XKX", False)
|
|
936
|
+
assert Country.get_iso3_country_code_fuzzy("d'Ivoire Côte") == ("CIV", False)
|
|
829
937
|
|
|
830
938
|
def test_get_countries_in_region(self):
|
|
831
939
|
assert Country.get_countries_in_region("Eastern Asia") == [
|
|
File without changes
|
|
File without changes
|
{hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/.github/workflows/run-python-tests.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/secondary_historic_rates.csv
RENAMED
|
File without changes
|
|
File without changes
|
{hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/wfp/Currency_List_1.json
RENAMED
|
File without changes
|
{hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/fixtures/wfp/Currency_List_2.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/hdx/location/Countries_UZB_Deleted.csv
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{hdx_python_country-3.9.5 → hdx_python_country-3.9.8}/tests/hdx/location/test_wfp_exchangerates.py
RENAMED
|
File without changes
|