commodutil 5.5.0__tar.gz → 5.5.2__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.
- {commodutil-5.5.0 → commodutil-5.5.2}/CHANGELOG.md +4 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/PKG-INFO +1 -1
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/standards/geography.py +8 -3
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil.egg-info/PKG-INFO +1 -1
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_standards_geography.py +13 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/uv.lock +3 -3
- {commodutil-5.5.0 → commodutil-5.5.2}/.coveragerc +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/.github/workflows/1_tests.yml +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/.github/workflows/2_coverage.yml +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/.github/workflows/3_linting.yml +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/.github/workflows/4_release.yml +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/.gitignore +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/.pypirc +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/README.md +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/azure-build-pipelines.yml +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/__init__.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/arb.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/convfactors.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/dates.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/forward/__init__.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/forward/calendar.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/forward/continuous.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/forward/fly.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/forward/quarterly.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/forward/spreads.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/forward/structure.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/forward/util.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/forwards.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/pandasutil.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/priceconv.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/standards/__init__.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/standards/analysis_types.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/standards/commodities.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/standards/commodity_groups.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/standards/currency.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/standards/price_unit.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/standards/trading_hubs.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/standards/unit_registry.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/standards/units.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/stats.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil/transforms.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil.egg-info/SOURCES.txt +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil.egg-info/dependency_links.txt +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil.egg-info/requires.txt +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/commodutil.egg-info/top_level.txt +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/pyproject.toml +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/setup.cfg +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/__init__.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/conftest.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/forward/__init__.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/forward/conftest.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/forward/test_calendar.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/forward/test_continuous.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/forward/test_fly.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/forward/test_quarterly.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/forward/test_spreads.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/forward/test_structure.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/forward/test_util.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/golden/golden_factors.json +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_aliases.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_align_fx_result.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_arb.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_cl.csv +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_conv.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_dates.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_forwards.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_golden_factors.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_pandasutils.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_price_conv.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_price_unit.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_priceconv_reexports.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_rate_pint.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_regex_literals.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_standards_analysis_types.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_standards_commodities.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_standards_commodity_groups.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_standards_currency.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_standards_trading_hubs.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_standards_units.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_stats.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_transforms.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_unit_registry.py +0 -0
- {commodutil-5.5.0 → commodutil-5.5.2}/tests/test_weekly.csv +0 -0
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 5.5.2 - 2026-07-28
|
|
4
|
+
|
|
5
|
+
- Fixed country-name resolution to normalize ampersands to `and`, matching ISO names such as Antigua and Barbuda.
|
|
6
|
+
|
|
3
7
|
## 5.5.0 - 2026-07-27
|
|
4
8
|
|
|
5
9
|
- Added `commodutil.standards.geography` with pycountry-backed countries, desk aliases, and membership-defined country groups; added `pycountry` as a production dependency.
|
|
@@ -98,6 +98,11 @@ COUNTRY_ALIASES: dict[str, str] = {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
|
|
101
|
+
def _normalize_country_name(name: str) -> str:
|
|
102
|
+
"""Return the case-folded lookup key for a country name."""
|
|
103
|
+
return " ".join(name.replace("&", " and ").split()).casefold()
|
|
104
|
+
|
|
105
|
+
|
|
101
106
|
def _build_country_name_map(aliases: Dict[str, str]) -> Dict[str, str]:
|
|
102
107
|
"""Build the case-folded name map and reject conflicting aliases."""
|
|
103
108
|
result: Dict[str, str] = {}
|
|
@@ -106,7 +111,7 @@ def _build_country_name_map(aliases: Dict[str, str]) -> Dict[str, str]:
|
|
|
106
111
|
name = getattr(country, attribute, None)
|
|
107
112
|
if name is None:
|
|
108
113
|
continue
|
|
109
|
-
key = name
|
|
114
|
+
key = _normalize_country_name(name)
|
|
110
115
|
existing = result.get(key)
|
|
111
116
|
if existing is not None and existing != country.alpha_2:
|
|
112
117
|
raise ValueError(
|
|
@@ -120,7 +125,7 @@ def _build_country_name_map(aliases: Dict[str, str]) -> Dict[str, str]:
|
|
|
120
125
|
raise ValueError(
|
|
121
126
|
f"country alias {alias!r} has unknown country code {code!r}"
|
|
122
127
|
)
|
|
123
|
-
key = alias
|
|
128
|
+
key = _normalize_country_name(alias)
|
|
124
129
|
existing = result.get(key)
|
|
125
130
|
if existing is not None and existing != code:
|
|
126
131
|
raise ValueError(
|
|
@@ -144,7 +149,7 @@ def canonical_country(text: object) -> Optional[str]:
|
|
|
144
149
|
code = cleaned.upper()
|
|
145
150
|
if code in VALID_COUNTRY_CODES:
|
|
146
151
|
return code
|
|
147
|
-
return COUNTRY_NAME_MAP.get(cleaned
|
|
152
|
+
return COUNTRY_NAME_MAP.get(_normalize_country_name(cleaned))
|
|
148
153
|
|
|
149
154
|
|
|
150
155
|
def is_canonical_country(code: object) -> bool:
|
|
@@ -66,6 +66,19 @@ def test_country_name_map_contains_pycountry_names_and_aliases():
|
|
|
66
66
|
assert COUNTRY_NAME_MAP["uk"] == "GB"
|
|
67
67
|
|
|
68
68
|
|
|
69
|
+
@pytest.mark.parametrize(
|
|
70
|
+
"value,expected",
|
|
71
|
+
[
|
|
72
|
+
("Antigua & Barbuda", "AG"),
|
|
73
|
+
("Trinidad & Tobago", "TT"),
|
|
74
|
+
("Bosnia & Herzegovina", "BA"),
|
|
75
|
+
("&", None),
|
|
76
|
+
],
|
|
77
|
+
)
|
|
78
|
+
def test_canonical_country_normalizes_ampersands(value, expected):
|
|
79
|
+
assert canonical_country(value) == expected
|
|
80
|
+
|
|
81
|
+
|
|
69
82
|
@pytest.mark.parametrize(
|
|
70
83
|
"value,expected",
|
|
71
84
|
[
|
|
@@ -1627,7 +1627,7 @@ wheels = [
|
|
|
1627
1627
|
|
|
1628
1628
|
[[package]]
|
|
1629
1629
|
name = "twine"
|
|
1630
|
-
version = "
|
|
1630
|
+
version = "7.0.0"
|
|
1631
1631
|
source = { registry = "https://pypi.org/simple" }
|
|
1632
1632
|
dependencies = [
|
|
1633
1633
|
{ name = "id" },
|
|
@@ -1640,9 +1640,9 @@ dependencies = [
|
|
|
1640
1640
|
{ name = "rich" },
|
|
1641
1641
|
{ name = "urllib3" },
|
|
1642
1642
|
]
|
|
1643
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
1643
|
+
sdist = { url = "https://files.pythonhosted.org/packages/92/3c/58f808a359700f39a967dffede33efeac809262c03303fa3eec6afff8f49/twine-7.0.0.tar.gz", hash = "sha256:85cdb29c518efef867360ae4acd4b0dfd61c8654a22fca08e6f8539f05022177", size = 215032, upload-time = "2026-07-27T15:59:00.825Z" }
|
|
1644
1644
|
wheels = [
|
|
1645
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1645
|
+
{ url = "https://files.pythonhosted.org/packages/96/08/ddcdc06225eaad6de0e48e1002b06d919dbde20582d0662c7af51308e5d6/twine-7.0.0-py3-none-any.whl", hash = "sha256:b854164df26db268af05f49aa5c0344b10e27a494343ff05b1e0bad3b135f5a7", size = 43204, upload-time = "2026-07-27T15:58:59.26Z" },
|
|
1646
1646
|
]
|
|
1647
1647
|
|
|
1648
1648
|
[[package]]
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|