pydeflate 2.0.2__py3-none-any.whl → 2.1.1__py3-none-any.whl

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.
pydeflate/__init__.py CHANGED
@@ -1,5 +1,5 @@
1
1
  __author__ = """Jorge Rivera"""
2
- __version__ = "2.0.2"
2
+ __version__ = "2.1.1"
3
3
 
4
4
  from pydeflate.deflate.deflators import (
5
5
  oecd_dac_deflate,
@@ -12,7 +12,12 @@ from pydeflate.deflate.deflators import (
12
12
  )
13
13
 
14
14
  from pydeflate.deflate.legacy_deflate import deflate
15
- from pydeflate.exchange.exchangers import oecd_dac_exchange, wb_exchange, imf_exchange
15
+ from pydeflate.exchange.exchangers import (
16
+ oecd_dac_exchange,
17
+ wb_exchange,
18
+ wb_exchange_ppp,
19
+ imf_exchange,
20
+ )
16
21
  from pydeflate.pydeflate_config import setup_logger
17
22
 
18
23
 
pydeflate/core/api.py CHANGED
@@ -77,7 +77,9 @@ def _base_operation(
77
77
  )
78
78
 
79
79
  # Flag missing data
80
- flag_missing_pydeflate_data(base_obj._unmatched_data)
80
+ flag_missing_pydeflate_data(
81
+ base_obj._unmatched_data, entity_column=entity_column, year_column=year_column
82
+ )
81
83
  x = base_obj._merged_data[value_column]
82
84
  y = base_obj._merged_data[
83
85
  "pydeflate_EXCHANGE" if exchange else "pydeflate_deflator"
@@ -174,6 +176,8 @@ class BaseExchange:
174
176
  pydeflate_data=self.pydeflate_data,
175
177
  entity_column=entity_column,
176
178
  ix=self._idx,
179
+ source_codes=self._idx[-1] == "pydeflate_entity_code",
180
+ dac=self.exchange_rates.source.name == "DAC",
177
181
  )
178
182
 
179
183
  # store unmatched data
@@ -363,6 +367,9 @@ class BaseDeflate:
363
367
  pydeflate_data=self.pydeflate_data,
364
368
  entity_column=entity_column,
365
369
  ix=self._idx,
370
+ source_codes=self.use_source_codes,
371
+ dac=self.exchange_deflator.source.name == "DAC"
372
+ or self.price_deflator.source.name == "DAC",
366
373
  )
367
374
 
368
375
  # store unmatched data
pydeflate/core/source.py CHANGED
@@ -5,7 +5,7 @@ import pandas as pd
5
5
  from pydeflate.sources.common import AvailableDeflators
6
6
  from pydeflate.sources.dac import read_dac
7
7
  from pydeflate.sources.imf import read_weo
8
- from pydeflate.sources.world_bank import read_wb
8
+ from pydeflate.sources.world_bank import read_wb, read_wb_lcu_ppp, read_wb_usd_ppp
9
9
 
10
10
 
11
11
  @dataclass
@@ -49,6 +49,15 @@ class WorldBank(Source):
49
49
  super().__init__(name="World Bank", reader=read_wb, update=update)
50
50
 
51
51
 
52
+ class WorldBankPPP(Source):
53
+ def __init__(self, update: bool = False, *, from_lcu: bool = True):
54
+ super().__init__(
55
+ name="World Bank PPP",
56
+ reader=read_wb_lcu_ppp if from_lcu else read_wb_usd_ppp,
57
+ update=update,
58
+ )
59
+
60
+
52
61
  class DAC(Source):
53
62
  def __init__(self, update: bool = False):
54
63
  super().__init__(name="DAC", reader=read_dac, update=update)
@@ -1,9 +1,10 @@
1
1
  from functools import wraps
2
2
 
3
3
  import pandas as pd
4
+ from frictionless.console.common import source
4
5
 
5
6
  from pydeflate.core.api import BaseExchange
6
- from pydeflate.core.source import DAC, WorldBank, IMF
7
+ from pydeflate.core.source import DAC, WorldBank, IMF, WorldBankPPP
7
8
 
8
9
 
9
10
  def _generate_docstring(source_name: str) -> str:
@@ -28,26 +29,33 @@ def _generate_docstring(source_name: str) -> str:
28
29
  )
29
30
 
30
31
 
31
- def _exchange(exchange_source_cls):
32
+ def _exchange(exchange_source_cls, **fixed_params):
32
33
  """Decorator to create exchange wrappers with specific source"""
33
34
 
34
35
  def decorator(func):
35
36
  @wraps(func)
36
- def wrapper(
37
- data: pd.DataFrame,
38
- *,
39
- source_currency: str = "USA",
40
- target_currency: str = "USA",
41
- id_column: str = "iso_code",
42
- year_column: str = "year",
43
- use_source_codes: bool = False,
44
- value_column: str = "value",
45
- target_value_column: str = "value",
46
- reversed_: bool = False,
47
- year_format: str | None = None,
48
- update_rates: bool = False,
49
- ):
37
+ def wrapper(data: pd.DataFrame, **kwargs):
50
38
  # Validate input parameters
39
+ for param in fixed_params:
40
+ if param in kwargs:
41
+ raise ValueError(
42
+ f"The parameter '{param}' cannot be passed to this function."
43
+ )
44
+ # set fixed parameters
45
+ kwargs.update(fixed_params)
46
+
47
+ # Unpack the parameters
48
+ source_currency = kwargs.get("source_currency", "USA")
49
+ target_currency = kwargs.get("target_currency", "USA")
50
+ id_column = kwargs.get("id_column", "iso_code")
51
+ year_column = kwargs.get("year_column", "year")
52
+ use_source_codes = kwargs.get("use_source_codes", False)
53
+ value_column = kwargs.get("value_column", "value")
54
+ target_value_column = kwargs.get("target_value_column", "value")
55
+ reversed_ = kwargs.get("reversed_", False)
56
+ year_format = kwargs.get("year_format", None)
57
+ update_rates = kwargs.get("update_rates", False)
58
+
51
59
  if not isinstance(data, pd.DataFrame):
52
60
  raise ValueError("The 'data' parameter must be a pandas DataFrame.")
53
61
 
@@ -68,7 +76,14 @@ def _exchange(exchange_source_cls):
68
76
  to_exchange = data.copy()
69
77
 
70
78
  # Initialize the deflator source
71
- source = exchange_source_cls(update=update_rates)
79
+ if exchange_source_cls.__name__ == "WorldBankPPP":
80
+ source = exchange_source_cls(
81
+ update=update_rates,
82
+ from_lcu=False if source_currency == "USA" else True,
83
+ )
84
+ source_currency = "LCU" if source_currency == "USA" else source_currency
85
+ else:
86
+ source = exchange_source_cls(update=update_rates)
72
87
 
73
88
  # Create a deflator object
74
89
  exchange = BaseExchange(
@@ -130,6 +145,22 @@ def wb_exchange(
130
145
  ) -> pd.DataFrame: ...
131
146
 
132
147
 
148
+ @_exchange(WorldBankPPP, target_currency="PPP")
149
+ def wb_exchange_ppp(
150
+ data: pd.DataFrame,
151
+ *,
152
+ source_currency: str = "USA",
153
+ id_column: str = "iso_code",
154
+ year_column: str = "year",
155
+ use_source_codes: bool = False,
156
+ value_column: str = "value",
157
+ target_value_column: str = "value",
158
+ reversed_: bool = False,
159
+ year_format: str | None = None,
160
+ update_rates: bool = False,
161
+ ) -> pd.DataFrame: ...
162
+
163
+
133
164
  @_exchange(IMF)
134
165
  def imf_exchange(
135
166
  data: pd.DataFrame,
@@ -21,7 +21,7 @@ def check_file_age(file: Path) -> int:
21
21
  """
22
22
  current_date = datetime.today()
23
23
  # Extract date from the filename (format: weo_YYYY-MM-DD.parquet)
24
- file_date = datetime.strptime(file.stem.split("_")[1], "%Y-%m-%d")
24
+ file_date = datetime.strptime(file.stem.split("_")[-1], "%Y-%m-%d")
25
25
 
26
26
  # Return the difference in days between today and the file's date
27
27
  return (current_date - file_date).days
@@ -21,6 +21,18 @@ _INDICATORS: dict = {
21
21
  "PA.NUS.FCRF": "EXCHANGE", # Official Exchange Rate
22
22
  }
23
23
 
24
+ _INDICATORS_LCU_PPP: dict = {
25
+ "NY.GDP.DEFL.ZS": "NGDP_D", # GDP Deflator (Index)
26
+ "NY.GDP.DEFL.ZS.AD": "NGDP_DL", # GDP Deflator linked series
27
+ "PA.NUS.PPP": "EXCHANGE", # PPP conversion factor
28
+ }
29
+
30
+ _INDICATORS_USD_PPP: dict = {
31
+ "NY.GDP.DEFL.ZS": "NGDP_D", # GDP Deflator (Index)
32
+ "NY.GDP.DEFL.ZS.AD": "NGDP_DL", # GDP Deflator linked series
33
+ "PA.NUS.PPPC.RF": "EXCHANGE", # PPP conversion factor to market exchange rate
34
+ }
35
+
24
36
 
25
37
  def get_wb_indicator(series: str, value_name: str | None = None) -> pd.DataFrame:
26
38
  """Fetch a World Bank indicator and transform it into a cleaned DataFrame.
@@ -126,7 +138,28 @@ def _parallel_download_indicators(indicators: dict) -> list[pd.DataFrame]:
126
138
  return dfs
127
139
 
128
140
 
129
- def download_wb() -> None:
141
+ def _add_ppp_ppp_exchange(df: pd.DataFrame) -> pd.DataFrame:
142
+ """
143
+ Add the PPP exchange rate to the DataFrame.
144
+
145
+ Args:
146
+ df: pd.DataFrame: The DataFrame containing the World Bank data.
147
+
148
+ Returns:
149
+ pd.DataFrame: The DataFrame with the PPP exchange rates
150
+
151
+ """
152
+ ppp = df.loc[lambda d: d["entity_code"] == "USA"].copy()
153
+ ppp[["entity_code", "entity", "pydeflate_iso3"]] = "PPP"
154
+
155
+ df = pd.concat([df, ppp], ignore_index=True)
156
+
157
+ return df
158
+
159
+
160
+ def _download_wb(
161
+ indicators: dict, prefix: str = "wb", add_ppp_exchange: bool = False
162
+ ) -> None:
130
163
  """Download multiple World Bank indicators in parallel and save as a parquet file.
131
164
 
132
165
  This function fetches all indicators defined in _INDICATORS in parallel, concatenates
@@ -134,7 +167,7 @@ def download_wb() -> None:
134
167
  """
135
168
  logger.info("Downloading the latest World Bank data...")
136
169
 
137
- indicators_data = _parallel_download_indicators(indicators=_INDICATORS)
170
+ indicators_data = _parallel_download_indicators(indicators=indicators)
138
171
 
139
172
  # Concatenate all DataFrames horizontally (by columns)
140
173
  df = pd.concat(indicators_data, axis=1).reset_index()
@@ -145,7 +178,13 @@ def download_wb() -> None:
145
178
  .pipe(compute_exchange_deflator, base_year_measure="NGDP_D")
146
179
  .assign(pydeflate_iso3=lambda d: d.entity_code)
147
180
  .sort_values(by=["year", "entity_code"])
148
- .pipe(prefix_pydeflate_to_columns)
181
+ )
182
+
183
+ if add_ppp_exchange:
184
+ df = df.pipe(_add_ppp_ppp_exchange)
185
+
186
+ df = (
187
+ df.pipe(prefix_pydeflate_to_columns)
149
188
  .pipe(enforce_pyarrow_types)
150
189
  .reset_index(drop=True)
151
190
  )
@@ -154,10 +193,29 @@ def download_wb() -> None:
154
193
  suffix = today()
155
194
 
156
195
  # Save the DataFrame as a parquet file
157
- output_path = PYDEFLATE_PATHS.data / f"wb_{suffix}.parquet"
196
+ output_path = PYDEFLATE_PATHS.data / f"{prefix}_{suffix}.parquet"
158
197
  df.to_parquet(output_path)
159
198
 
160
- logger.info(f"Saved World Bank data to wb_{suffix}.parquet")
199
+ logger.info(f"Saved World Bank data to {prefix}_{suffix}.parquet")
200
+
201
+
202
+ def download_wb() -> None:
203
+ """Download the latest World Bank data."""
204
+ _download_wb(indicators=_INDICATORS, prefix="wb")
205
+
206
+
207
+ def download_wb_lcu_ppp() -> None:
208
+ """Download the latest World Bank data (PPP)."""
209
+ _download_wb(
210
+ indicators=_INDICATORS_LCU_PPP, prefix="wb_lcu_ppp", add_ppp_exchange=True
211
+ )
212
+
213
+
214
+ def download_wb_usd_ppp() -> None:
215
+ """Download the latest World Bank data (PPP)."""
216
+ _download_wb(
217
+ indicators=_INDICATORS_USD_PPP, prefix="wb_usd_ppp", add_ppp_exchange=True
218
+ )
161
219
 
162
220
 
163
221
  def _find_wb_files_in_path(path: Path) -> list:
@@ -169,7 +227,31 @@ def _find_wb_files_in_path(path: Path) -> list:
169
227
  Returns:
170
228
  list: List of WB parquet files found in the directory.
171
229
  """
172
- return list(path.glob("wb_*.parquet"))
230
+ return list(path.glob(f"wb_*.parquet"))
231
+
232
+
233
+ def _find_wb_lcu_ppp_files_in_path(path: Path) -> list:
234
+ """Find all WB PPP parquet files in the specified directory.
235
+
236
+ Args:
237
+ path (Path): The directory path to search for WB parquet files.
238
+
239
+ Returns:
240
+ list: List of WB parquet files found in the directory.
241
+ """
242
+ return list(path.glob(f"wb_lcu_ppp_*.parquet"))
243
+
244
+
245
+ def _find_wb_usd_ppp_files_in_path(path: Path) -> list:
246
+ """Find all WB PPP parquet files in the specified directory.
247
+
248
+ Args:
249
+ path (Path): The directory path to search for WB parquet files.
250
+
251
+ Returns:
252
+ list: List of WB parquet files found in the directory.
253
+ """
254
+ return list(path.glob(f"wb_usd_ppp_*.parquet"))
173
255
 
174
256
 
175
257
  def read_wb(update: bool = False) -> pd.DataFrame:
@@ -182,5 +264,27 @@ def read_wb(update: bool = False) -> pd.DataFrame:
182
264
  )
183
265
 
184
266
 
267
+ def read_wb_lcu_ppp(update: bool = False) -> pd.DataFrame:
268
+ """Read the latest World Bank data from parquet files or download fresh data."""
269
+ return read_data(
270
+ file_finder_func=_find_wb_lcu_ppp_files_in_path,
271
+ download_func=download_wb_lcu_ppp,
272
+ data_name="World Bank",
273
+ update=update,
274
+ )
275
+
276
+
277
+ def read_wb_usd_ppp(update: bool = False) -> pd.DataFrame:
278
+ """Read the latest World Bank data from parquet files or download fresh data."""
279
+ return read_data(
280
+ file_finder_func=_find_wb_usd_ppp_files_in_path,
281
+ download_func=download_wb_usd_ppp,
282
+ data_name="World Bank",
283
+ update=update,
284
+ )
285
+
286
+
185
287
  if __name__ == "__main__":
186
- df = read_wb(True)
288
+ df_wb = read_wb(False)
289
+ df_usd = read_wb_usd_ppp(False)
290
+ df_lcu = read_wb_lcu_ppp(False)
pydeflate/utils.py CHANGED
@@ -35,6 +35,7 @@ def clean_number(number):
35
35
 
36
36
  return float(number)
37
37
 
38
+
38
39
  def create_pydeflate_year(
39
40
  data: pd.DataFrame, year_column: str, year_format: str | None = None
40
41
  ) -> pd.DataFrame:
@@ -50,21 +51,68 @@ def create_pydeflate_year(
50
51
  return data
51
52
 
52
53
 
54
+ def _use_implied_dac_rates(
55
+ data: pd.DataFrame,
56
+ pydeflate_data: pd.DataFrame,
57
+ ix: list[str],
58
+ entity_column: str,
59
+ source_codes: bool,
60
+ ) -> pd.DataFrame:
61
+ """When rates are missing for entities in DAC data, the correct behaviour is to use
62
+ the DAC overall rates"""
63
+
64
+ # Assign the DAC code to a temporary column
65
+ data.loc[
66
+ lambda d: ~d[f"temp_{entity_column}"].isin(pydeflate_data[ix[-1]].unique()),
67
+ f"temp_{entity_column}",
68
+ ] = (
69
+ 20001 if source_codes else "DAC"
70
+ )
71
+
72
+ # Log the fact that implied rates are being used
73
+ flag_missing_pydeflate_data(
74
+ unmatched_data=data.loc[
75
+ lambda d: ~d[f"{entity_column}"].isin(pydeflate_data[ix[-1]].unique())
76
+ ],
77
+ entity_column=entity_column,
78
+ year_column="pydeflate_year",
79
+ using_implied=True,
80
+ )
81
+
82
+ return data
83
+
84
+
53
85
  def merge_user_and_pydeflate_data(
54
86
  data: pd.DataFrame,
55
87
  pydeflate_data: pd.DataFrame,
56
88
  entity_column: str,
57
89
  ix: list[str],
90
+ source_codes: bool = True,
91
+ dac: bool = False,
58
92
  ) -> pd.DataFrame:
59
- return data.merge(
93
+
94
+ data[f"temp_{entity_column}"] = data[entity_column]
95
+
96
+ if dac:
97
+ data = _use_implied_dac_rates(
98
+ data=data,
99
+ pydeflate_data=pydeflate_data,
100
+ ix=ix,
101
+ entity_column=entity_column,
102
+ source_codes=source_codes,
103
+ )
104
+
105
+ df_ = data.merge(
60
106
  pydeflate_data,
61
107
  how="outer",
62
- left_on=["pydeflate_year", entity_column],
108
+ left_on=["pydeflate_year", f"temp_{entity_column}"],
63
109
  right_on=ix,
64
110
  suffixes=("", "_pydeflate"),
65
111
  indicator=True,
66
112
  ).pipe(enforce_pyarrow_types)
67
113
 
114
+ return df_.drop(columns=[f"temp_{entity_column}"])
115
+
68
116
 
69
117
  def get_unmatched_pydeflate_data(
70
118
  merged_data: pd.DataFrame,
@@ -84,17 +132,29 @@ def get_matched_pydeflate_data(
84
132
  )
85
133
 
86
134
 
87
- def flag_missing_pydeflate_data(unmatched_data: pd.DataFrame):
135
+ def flag_missing_pydeflate_data(
136
+ unmatched_data: pd.DataFrame,
137
+ entity_column: str,
138
+ year_column: str,
139
+ using_implied: bool = False,
140
+ ):
88
141
  """Flag data which is present in the input data but missing in pydeflate's data."""
89
142
  if unmatched_data.empty:
90
143
  return
91
-
92
144
  missing = (
93
- unmatched_data.drop_duplicates()
94
- .dropna(axis=1)
95
- .drop(columns="_merge")
96
- .to_string(index=False)
145
+ unmatched_data.filter([entity_column, year_column])
146
+ .drop_duplicates()
147
+ .groupby(entity_column)[year_column]
148
+ .apply(lambda x: ", ".join(map(str, sorted(x))))
149
+ .to_dict()
97
150
  )
98
151
 
152
+ missing_str = "\n".join(f"{entity}: {years}" for entity, years in missing.items())
153
+
99
154
  # log all missing data
100
- logger.info(f"Missing exchange data for:\n {missing}")
155
+ message = (
156
+ "Using DAC members' rates (given missing data) for:"
157
+ if using_implied
158
+ else "Missing exchange data for:"
159
+ )
160
+ logger.info(f"{message}\n{missing_str}")
@@ -1,26 +1,23 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: pydeflate
3
- Version: 2.0.2
3
+ Version: 2.1.1
4
4
  Summary: Package to convert current prices figures to constant prices and vice versa
5
5
  License: MIT
6
6
  Author: Jorge Rivera
7
7
  Author-email: jorge.rivera@one.org
8
- Requires-Python: >=3.10,<4.0
9
- Classifier: Development Status :: 5 - Production/Stable
10
- Classifier: Intended Audience :: End Users/Desktop
11
- Classifier: Intended Audience :: Science/Research
8
+ Requires-Python: >=3.10, <4.0
12
9
  Classifier: License :: OSI Approved :: MIT License
13
- Classifier: Natural Language :: English
14
10
  Classifier: Programming Language :: Python :: 3
15
11
  Classifier: Programming Language :: Python :: 3.10
16
12
  Classifier: Programming Language :: Python :: 3.11
17
13
  Classifier: Programming Language :: Python :: 3.12
18
14
  Classifier: Programming Language :: Python :: 3.13
19
- Requires-Dist: hdx-python-country (>=3.8.1,<4.0.0)
20
- Requires-Dist: imf-reader (>=1.1.0,<2.0.0)
21
- Requires-Dist: oda-reader (>=1.0.0,<2.0.0)
22
- Requires-Dist: pandas (>=2,<3)
23
- Requires-Dist: pyarrow (>14)
15
+ Requires-Dist: hdx-python-country (>=3.8,<4.0.0)
16
+ Requires-Dist: imf-reader (>=1.2.0,<2.0.0)
17
+ Requires-Dist: oda-reader (>=1.0.5,<2.0.0)
18
+ Requires-Dist: pandas (>=2.2.3,<3.0.0)
19
+ Requires-Dist: pyarrow (>=14.0)
20
+ Requires-Dist: requests (>=2.32.3,<3.0.0)
24
21
  Requires-Dist: wbgapi (>=1.0.12,<2.0.0)
25
22
  Description-Content-Type: text/markdown
26
23
 
@@ -1,25 +1,25 @@
1
1
  pydeflate/.pydeflate_data/README.md,sha256=atNtUL9dD8G184YSd6juFib8TgEQBcSLogiz99APPVs,25
2
- pydeflate/__init__.py,sha256=ucS093TzuhZ6Gxr-GQ4KCMU6RY0vqCZjemGukpcc_kM,975
2
+ pydeflate/__init__.py,sha256=JJqxQpHXxfqzada3FkaneDTW9BlNM40CBwjJgEZZ4tQ,1013
3
3
  pydeflate/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- pydeflate/core/api.py,sha256=-MpFRtn9H99B72M_m3-dwQe9zp0gUkBJJhMaG8iDcBU,14329
4
+ pydeflate/core/api.py,sha256=mD5zhGlAIvlpT6KcmrHW5rmYwtEq5x2Pqo-jQCQMGpo,14687
5
5
  pydeflate/core/deflator.py,sha256=Ax3dmOF3tYRZnkIfFvMMo3SOLgAJHkXSmA-OtIUZkp0,5932
6
6
  pydeflate/core/exchange.py,sha256=br6RVgTGa7LW09XemUJZ4Koazf65zuXPQKYKGhS6ROM,8535
7
- pydeflate/core/source.py,sha256=tIN9fAPhhE-6C5Ye608qTMQblm3yva7u5p1nJwepXm4,1724
7
+ pydeflate/core/source.py,sha256=n603ocgGjthXNcBWwgADkefxWmSFuN77Km9Z0T2zpIg,2027
8
8
  pydeflate/deflate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  pydeflate/deflate/deflators.py,sha256=hyLFoX46BAn5m8gTLjw-TFv3x3W6CTQmvmUvq5a_cio,7768
10
10
  pydeflate/deflate/legacy_deflate.py,sha256=9pfqsi5KeWgP1yhXeI6K7bAjUeFY-fmRxrpDB7Zu0zo,3900
11
11
  pydeflate/exchange/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- pydeflate/exchange/exchangers.py,sha256=DWHvfH7FivgPV25R3dvBuMHWA9bxlvTDQPzg062AMN0,5384
12
+ pydeflate/exchange/exchangers.py,sha256=_3QA3gzUQJgtR6o5n7qrVq8WKLL7x01A8V_DtW8ocPI,6768
13
13
  pydeflate/pydeflate_config.py,sha256=5s4SLJf5is5XcUgJHDRx4f27pPiaVh0H2BL8w9QjW0k,1097
14
14
  pydeflate/settings/emu.json,sha256=BIvbiMUeHUtCESR3sMcBNrS028yp2YraCJdhDJGvAAo,133
15
15
  pydeflate/settings/oecd_codes.json,sha256=jAKI1EgQP4rttjoG3Z-44r1tUJrIEzPCZF5V2aboQhE,911
16
16
  pydeflate/sources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- pydeflate/sources/common.py,sha256=ctSL2JQ_6kVSSGkh7UphU98G-HTJL0s8JvSMic-EGnY,9881
17
+ pydeflate/sources/common.py,sha256=TvoN3jnqn0xXNuxM52vvgSLA5WRGX8PUD-b5YH6S7GE,9882
18
18
  pydeflate/sources/dac.py,sha256=ngFiApGZ_tIQg74ogGVTIbGUA0efnF1SYwfUuqGofOQ,3791
19
19
  pydeflate/sources/imf.py,sha256=10vc8xhNJvANb7RDD1WFn9oaZ8g53yUV5LxCQCz6ImM,6337
20
- pydeflate/sources/world_bank.py,sha256=YxQgUUDMXlPArIfvYJTjNIAU5_I_OeUYDzc7NtTq9EA,6288
21
- pydeflate/utils.py,sha256=sfocGBQook3S7gvutCFovknyCv0cV37MHPJB-EMIumQ,2321
22
- pydeflate-2.0.2.dist-info/LICENSE,sha256=q5tm9mQxwSbV5Ivvjxs7MMqBgan6DM8I4r4irPvmqZM,1075
23
- pydeflate-2.0.2.dist-info/METADATA,sha256=myZ1BRAU-zIm3N4uLXUslMJuyGFQNWmGmCcIqldOCf8,12582
24
- pydeflate-2.0.2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
25
- pydeflate-2.0.2.dist-info/RECORD,,
20
+ pydeflate/sources/world_bank.py,sha256=uMHidFVgEpj1HVUnNhIZV-rV64hsCBV9ZAbYKk6H0Vw,9333
21
+ pydeflate/utils.py,sha256=tJBd271WzZxVhW9ZMiIRHR0fZWr_MagAYLdmXXaUY3M,3983
22
+ pydeflate-2.1.1.dist-info/LICENSE,sha256=q5tm9mQxwSbV5Ivvjxs7MMqBgan6DM8I4r4irPvmqZM,1075
23
+ pydeflate-2.1.1.dist-info/METADATA,sha256=9_x0yAsOsj70V9dESsz9C89UuQuxc_TTQkyamDDXne4,12437
24
+ pydeflate-2.1.1.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
25
+ pydeflate-2.1.1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.9.1
2
+ Generator: poetry-core 2.1.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any