commodutil 3.10.0__tar.gz → 3.10.1__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 (71) hide show
  1. {commodutil-3.10.0 → commodutil-3.10.1}/PKG-INFO +1 -1
  2. commodutil-3.10.1/commodutil/standards/__init__.py +70 -0
  3. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/standards/regions.py +9 -2
  4. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil.egg-info/PKG-INFO +1 -1
  5. {commodutil-3.10.0 → commodutil-3.10.1}/tests/test_standards_regions.py +36 -6
  6. commodutil-3.10.0/commodutil/standards/__init__.py +0 -1
  7. {commodutil-3.10.0 → commodutil-3.10.1}/.coveragerc +0 -0
  8. {commodutil-3.10.0 → commodutil-3.10.1}/.github/workflows/1_tests.yml +0 -0
  9. {commodutil-3.10.0 → commodutil-3.10.1}/.github/workflows/2_coverage.yml +0 -0
  10. {commodutil-3.10.0 → commodutil-3.10.1}/.github/workflows/3_linting.yml +0 -0
  11. {commodutil-3.10.0 → commodutil-3.10.1}/.github/workflows/4_release.yml +0 -0
  12. {commodutil-3.10.0 → commodutil-3.10.1}/.gitignore +0 -0
  13. {commodutil-3.10.0 → commodutil-3.10.1}/.pypirc +0 -0
  14. {commodutil-3.10.0 → commodutil-3.10.1}/azure-build-pipelines.yml +0 -0
  15. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/__init__.py +0 -0
  16. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/arb.py +0 -0
  17. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/convfactors.py +0 -0
  18. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/dates.py +0 -0
  19. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/forward/__init__.py +0 -0
  20. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/forward/calendar.py +0 -0
  21. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/forward/continuous.py +0 -0
  22. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/forward/fly.py +0 -0
  23. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/forward/quarterly.py +0 -0
  24. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/forward/spreads.py +0 -0
  25. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/forward/structure.py +0 -0
  26. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/forward/util.py +0 -0
  27. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/forwards.py +0 -0
  28. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/pandasutil.py +0 -0
  29. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/standards/analysis_types.py +0 -0
  30. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/standards/commodities.py +0 -0
  31. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/standards/commodity_groups.py +0 -0
  32. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/standards/currency.py +0 -0
  33. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/standards/units.py +0 -0
  34. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/stats.py +0 -0
  35. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil/transforms.py +0 -0
  36. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil.egg-info/SOURCES.txt +0 -0
  37. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil.egg-info/dependency_links.txt +0 -0
  38. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil.egg-info/requires.txt +0 -0
  39. {commodutil-3.10.0 → commodutil-3.10.1}/commodutil.egg-info/top_level.txt +0 -0
  40. {commodutil-3.10.0 → commodutil-3.10.1}/pyproject.toml +0 -0
  41. {commodutil-3.10.0 → commodutil-3.10.1}/requirements-test.txt +0 -0
  42. {commodutil-3.10.0 → commodutil-3.10.1}/requirements.txt +0 -0
  43. {commodutil-3.10.0 → commodutil-3.10.1}/requirements_dev.txt +0 -0
  44. {commodutil-3.10.0 → commodutil-3.10.1}/scripts/rbw_structure_scan.py +0 -0
  45. {commodutil-3.10.0 → commodutil-3.10.1}/setup.cfg +0 -0
  46. {commodutil-3.10.0 → commodutil-3.10.1}/tests/__init__.py +0 -0
  47. {commodutil-3.10.0 → commodutil-3.10.1}/tests/conftest.py +0 -0
  48. {commodutil-3.10.0 → commodutil-3.10.1}/tests/forward/__init__.py +0 -0
  49. {commodutil-3.10.0 → commodutil-3.10.1}/tests/forward/conftest.py +0 -0
  50. {commodutil-3.10.0 → commodutil-3.10.1}/tests/forward/test_calendar.py +0 -0
  51. {commodutil-3.10.0 → commodutil-3.10.1}/tests/forward/test_continuous.py +0 -0
  52. {commodutil-3.10.0 → commodutil-3.10.1}/tests/forward/test_fly.py +0 -0
  53. {commodutil-3.10.0 → commodutil-3.10.1}/tests/forward/test_quarterly.py +0 -0
  54. {commodutil-3.10.0 → commodutil-3.10.1}/tests/forward/test_spreads.py +0 -0
  55. {commodutil-3.10.0 → commodutil-3.10.1}/tests/forward/test_structure.py +0 -0
  56. {commodutil-3.10.0 → commodutil-3.10.1}/tests/forward/test_util.py +0 -0
  57. {commodutil-3.10.0 → commodutil-3.10.1}/tests/test_arb.py +0 -0
  58. {commodutil-3.10.0 → commodutil-3.10.1}/tests/test_cl.csv +0 -0
  59. {commodutil-3.10.0 → commodutil-3.10.1}/tests/test_conv.py +0 -0
  60. {commodutil-3.10.0 → commodutil-3.10.1}/tests/test_dates.py +0 -0
  61. {commodutil-3.10.0 → commodutil-3.10.1}/tests/test_forwards.py +0 -0
  62. {commodutil-3.10.0 → commodutil-3.10.1}/tests/test_pandasutils.py +0 -0
  63. {commodutil-3.10.0 → commodutil-3.10.1}/tests/test_price_conv.py +0 -0
  64. {commodutil-3.10.0 → commodutil-3.10.1}/tests/test_standards_analysis_types.py +0 -0
  65. {commodutil-3.10.0 → commodutil-3.10.1}/tests/test_standards_commodities.py +0 -0
  66. {commodutil-3.10.0 → commodutil-3.10.1}/tests/test_standards_commodity_groups.py +0 -0
  67. {commodutil-3.10.0 → commodutil-3.10.1}/tests/test_standards_currency.py +0 -0
  68. {commodutil-3.10.0 → commodutil-3.10.1}/tests/test_standards_units.py +0 -0
  69. {commodutil-3.10.0 → commodutil-3.10.1}/tests/test_stats.py +0 -0
  70. {commodutil-3.10.0 → commodutil-3.10.1}/tests/test_transforms.py +0 -0
  71. {commodutil-3.10.0 → commodutil-3.10.1}/tests/test_weekly.csv +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: commodutil
3
- Version: 3.10.0
3
+ Version: 3.10.1
4
4
  Summary: common commodity/oil analytics utils
5
5
  Author-email: aeorxc <author@example.com>
6
6
  Project-URL: Homepage, https://dev.azure.com/RWEST-MFI-TE/Oil/_git/commodutil
@@ -0,0 +1,70 @@
1
+ """commodutil.standards: canonical vocabularies for commodity trading.
2
+
3
+ Re-exports the public surface of each submodule so callers can write
4
+ `from commodutil.standards import normalize_region` instead of reaching
5
+ into the submodule directly.
6
+ """
7
+
8
+ from commodutil.standards.analysis_types import (
9
+ ANALYSIS_TYPES,
10
+ infer_analysis_type,
11
+ )
12
+ from commodutil.standards.commodities import (
13
+ COMMODITY_CONVERSION_MAP,
14
+ COMMODITY_KEYWORDS,
15
+ )
16
+ from commodutil.standards.commodity_groups import (
17
+ COMMODITY_GROUPS,
18
+ VALID_COMMODITY_GROUPS,
19
+ is_valid_commodity_group,
20
+ )
21
+ from commodutil.standards.currency import (
22
+ FRACTIONAL_CURRENCY_DIVISORS,
23
+ FRACTIONAL_TO_MAJOR,
24
+ VALID_CURRENCY_TOKENS,
25
+ fractional_to_major,
26
+ is_fractional_currency,
27
+ required_fx_pair,
28
+ split_currency_unit,
29
+ to_symbol,
30
+ )
31
+ from commodutil.standards.regions import (
32
+ REGION_PATTERNS,
33
+ VALID_REGIONS,
34
+ is_valid_region,
35
+ normalize_region,
36
+ )
37
+ from commodutil.standards.units import (
38
+ UNIT_MAP,
39
+ default_unit_for_commodity,
40
+ )
41
+
42
+ __all__ = [
43
+ # analysis_types
44
+ "ANALYSIS_TYPES",
45
+ "infer_analysis_type",
46
+ # commodities
47
+ "COMMODITY_CONVERSION_MAP",
48
+ "COMMODITY_KEYWORDS",
49
+ # commodity_groups
50
+ "COMMODITY_GROUPS",
51
+ "VALID_COMMODITY_GROUPS",
52
+ "is_valid_commodity_group",
53
+ # currency
54
+ "FRACTIONAL_CURRENCY_DIVISORS",
55
+ "FRACTIONAL_TO_MAJOR",
56
+ "VALID_CURRENCY_TOKENS",
57
+ "fractional_to_major",
58
+ "is_fractional_currency",
59
+ "required_fx_pair",
60
+ "split_currency_unit",
61
+ "to_symbol",
62
+ # regions
63
+ "REGION_PATTERNS",
64
+ "VALID_REGIONS",
65
+ "is_valid_region",
66
+ "normalize_region",
67
+ # units
68
+ "UNIT_MAP",
69
+ "default_unit_for_commodity",
70
+ ]
@@ -60,8 +60,15 @@ def normalize_region(text: Optional[str]) -> Optional[str]:
60
60
 
61
61
  lower = text.lower()
62
62
 
63
- # RBOB convention: always NY Harbor
64
- if "rbob" in lower:
63
+ # CARBOB short-circuit: California Reformulated Blendstock for Oxygenate
64
+ # Blending Los Angeles / US West Coast, NOT NY Harbor. Must run BEFORE
65
+ # the RBOB check so "carbob" doesn't fall through to the NYH heuristic.
66
+ if re.search(r"\bcarbob\b", lower):
67
+ return "LA"
68
+
69
+ # RBOB convention: always NY Harbor. Use word boundary so "carbob" (which
70
+ # has 'a' before 'rbob' — no word boundary) does not match here.
71
+ if re.search(r"\brbob\b", lower):
65
72
  return "NYH"
66
73
 
67
74
  # Pattern-match against REGION_PATTERNS
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: commodutil
3
- Version: 3.10.0
3
+ Version: 3.10.1
4
4
  Summary: common commodity/oil analytics utils
5
5
  Author-email: aeorxc <author@example.com>
6
6
  Project-URL: Homepage, https://dev.azure.com/RWEST-MFI-TE/Oil/_git/commodutil
@@ -19,6 +19,21 @@ def test_normalize_region_rbob_heuristic():
19
19
  assert normalize_region("RBOB Feb25") == "NYH"
20
20
 
21
21
 
22
+ def test_normalize_region_carbob_is_not_nyh():
23
+ """CARBOB is California gasoline (Los Angeles / USWC), NOT NY Harbor.
24
+
25
+ Regression guard against the prior substring bug where `"rbob" in lower`
26
+ matched "carbob" and mis-classified California gasoline as NYH. The fix
27
+ uses a word-boundary regex plus an explicit CARBOB short-circuit that
28
+ maps to "LA".
29
+ """
30
+ assert normalize_region("CARBOB") != "NYH"
31
+ assert normalize_region("CARBOB") == "LA"
32
+ assert normalize_region("Los Angeles CARBOB") == "LA"
33
+ # Sanity: plain RBOB still resolves to NYH.
34
+ assert normalize_region("RBOB") == "NYH"
35
+
36
+
22
37
  def test_normalize_region_rdam_substring():
23
38
  assert normalize_region("RDam fuel oil") == "Rott"
24
39
 
@@ -106,16 +121,31 @@ def test_short_pattern_parity_with_curvemetadata():
106
121
  """Short-pattern (len <= 3) regions used to diverge between
107
122
  normalize_region and curvemetadata.taxonomy.infer_region because
108
123
  the latter had a `\\b` regex bug (literal backslash-b instead of
109
- a word boundary). The bug was fixed in curvemetadata 2026-05;
110
- this test is now a regression guard against the bug returning.
124
+ a word boundary). The bug was fixed in curvemetadata 1.4.0 (commit
125
+ e8ba20e on the 1.2.0 release branch); this test is a regression
126
+ guard once that fix is published.
127
+
128
+ Skips gracefully when the installed curvemetadata still has the
129
+ bug (e.g. CI envs pulling curvemetadata < 1.4.0 from the package
130
+ index during the release-window between commodutil 3.10.0 and
131
+ curvemetadata 1.4.0 publishing).
111
132
  """
133
+ import pytest
134
+
112
135
  try:
113
136
  from curvemetadata.taxonomy import infer_region
114
137
  except ImportError:
115
- import pytest
116
-
117
138
  pytest.skip("curvemetadata not available in this environment")
118
139
 
140
+ # Probe: does the installed curvemetadata have the `\b` fix? Any of
141
+ # the short patterns would return None if the bug is still present.
142
+ if infer_region("Brent NYH") is None:
143
+ pytest.skip(
144
+ "Installed curvemetadata has the pre-1.4.0 `\\b` regex bug "
145
+ "(short-pattern regions never match). Upgrade curvemetadata "
146
+ "to >=1.4.0 to enable this parity test."
147
+ )
148
+
119
149
  # Only patterns of len <= 3 hit the previously-broken regex branch.
120
150
  # Among the configured patterns those are: "nyh", "ara", "med", "nwe".
121
151
  short_pattern_cases = [
@@ -132,8 +162,8 @@ def test_short_pattern_parity_with_curvemetadata():
132
162
  )
133
163
  assert infer_region(text) == expected, (
134
164
  f"curvemetadata.infer_region({text!r}) should match {expected!r} "
135
- f"(got {infer_region(text)!r}). If you see None for one of the "
136
- f"short patterns, the curvemetadata `\\b` regex bug has regressed."
165
+ f"(got {infer_region(text)!r}). The `\\b` fix is present (probe "
166
+ f"above passed) but parity broke on this input -- investigate."
137
167
  )
138
168
 
139
169
 
@@ -1 +0,0 @@
1
- """commodutil.standards: canonical vocabularies for commodity trading."""
File without changes
File without changes
File without changes
File without changes
File without changes