hdx-python-country 4.2.9__tar.gz → 4.3.0__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 (40) hide show
  1. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/PKG-INFO +1 -1
  2. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/src/hdx/location/_version.py +2 -2
  3. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/src/hdx/location/wfp_api.py +23 -8
  4. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/.github/workflows/publish.yaml +0 -0
  5. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/.github/workflows/run-python-tests.yaml +0 -0
  6. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/.gitignore +0 -0
  7. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/.pre-commit-config.yaml +0 -0
  8. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/LICENSE +0 -0
  9. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/README.md +0 -0
  10. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/documentation/.readthedocs.yaml +0 -0
  11. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/documentation/index.md +0 -0
  12. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/documentation/mkdocs.yaml +0 -0
  13. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/pyproject.toml +0 -0
  14. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/src/hdx/location/Countries & Territories Taxonomy MVP - C&T Taxonomy.csv +0 -0
  15. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/src/hdx/location/__init__.py +0 -0
  16. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/src/hdx/location/adminlevel.py +0 -0
  17. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/src/hdx/location/country.py +0 -0
  18. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/src/hdx/location/currency.py +0 -0
  19. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/src/hdx/location/int_timestamp.py +0 -0
  20. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/src/hdx/location/wfp_exchangerates.py +0 -0
  21. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/tests/fixtures/adminlevel.yaml +0 -0
  22. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/tests/fixtures/adminlevelparent.yaml +0 -0
  23. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/tests/fixtures/fixtures-download-global-pcode-lengths.csv +0 -0
  24. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/tests/fixtures/fixtures-download-global-pcodes-adm-1-2.csv +0 -0
  25. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/tests/fixtures/secondary_historic_rates.csv +0 -0
  26. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/tests/fixtures/secondary_rates.json +0 -0
  27. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/tests/fixtures/wfp/Currency_List.csv +0 -0
  28. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_AFN.csv +0 -0
  29. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/tests/fixtures/wfp/Currency_UsdIndirectQuotation_SYP.csv +0 -0
  30. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/tests/fixtures/wfp/MarketPrices_PriceMonthly_BTN.csv +0 -0
  31. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/tests/fixtures/wfp/Markets_List_AFG.csv +0 -0
  32. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/tests/hdx/location/Countries_UZB_Deleted.csv +0 -0
  33. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/tests/hdx/location/__init__.py +0 -0
  34. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/tests/hdx/location/conftest.py +0 -0
  35. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/tests/hdx/location/test_adminlevel.py +0 -0
  36. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/tests/hdx/location/test_country.py +0 -0
  37. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/tests/hdx/location/test_currency.py +0 -0
  38. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/tests/hdx/location/test_wfp_api.py +0 -0
  39. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/tests/hdx/location/test_wfp_exchangerates.py +0 -0
  40. {hdx_python_country-4.2.9 → hdx_python_country-4.3.0}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: hdx-python-country
3
- Version: 4.2.9
3
+ Version: 4.3.0
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
  Project-URL: Repository, https://github.com/OCHA-DAP/hdx-python-country
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '4.2.9'
22
- __version_tuple__ = version_tuple = (4, 2, 9)
21
+ __version__ = version = '4.3.0'
22
+ __version_tuple__ = version_tuple = (4, 3, 0)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -1,5 +1,4 @@
1
1
  import csv
2
- import io
3
2
  import logging
4
3
  import types
5
4
  from collections.abc import Callable
@@ -117,6 +116,11 @@ def _parse_csv(text: str, model_cls: type) -> list:
117
116
  value is a string. Blank strings are kept as "" (as JSON returns them)
118
117
  but blank values of non-string fields become None.
119
118
 
119
+ To limit memory use (IDN has 462,027 price rows), lines are split
120
+ lazily rather than with io.StringIO, which holds 4 bytes per character,
121
+ each column reuses one object per distinct value and rows with the same
122
+ fields share one pydantic fields set (2,264 bytes each otherwise).
123
+
120
124
  Args:
121
125
  text: CSV text
122
126
  model_cls: data_bridges_client model class of each row
@@ -125,19 +129,30 @@ def _parse_csv(text: str, model_cls: type) -> list:
125
129
  List of model_cls objects
126
130
  """
127
131
  converters = _csv_converters(model_cls)
128
- reader = csv.reader(io.StringIO(text))
132
+ reader = csv.reader(f"{line}\n" for line in text.split("\n"))
129
133
  keys = [header[0].lower() + header[1:] for header in next(reader, [])]
130
- columns = [(key, converters.get(key)) for key in keys]
134
+ columns = [(key, converters.get(key), {}) for key in keys]
135
+ fields_sets = {}
131
136
  items = []
132
137
  for row in reader:
133
138
  if not row:
134
139
  continue
135
140
  obj = {}
136
- for (key, converter), value in zip(columns, row):
137
- if converter:
138
- value = converter(value) if value else None
139
- obj[key] = value
140
- items.append(model_cls.from_dict(obj))
141
+ for (key, converter, values), value in zip(columns, row):
142
+ try:
143
+ obj[key] = values[value]
144
+ except KeyError:
145
+ if converter:
146
+ converted = converter(value) if value else None
147
+ else:
148
+ converted = value
149
+ values[value] = converted
150
+ obj[key] = converted
151
+ item = model_cls.from_dict(obj)
152
+ fields_set = frozenset(item.__pydantic_fields_set__)
153
+ fields_set = fields_sets.setdefault(fields_set, item.__pydantic_fields_set__)
154
+ object.__setattr__(item, "__pydantic_fields_set__", fields_set)
155
+ items.append(item)
141
156
  return items
142
157
 
143
158