ml4t-engineer 0.1.0__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.
Files changed (204) hide show
  1. ml4t/engineer/AGENTS.md +83 -0
  2. ml4t/engineer/__init__.py +151 -0
  3. ml4t/engineer/_numba.py +32 -0
  4. ml4t/engineer/_polars_compat.py +71 -0
  5. ml4t/engineer/_version.py +24 -0
  6. ml4t/engineer/api.py +620 -0
  7. ml4t/engineer/artifacts/AGENTS.md +17 -0
  8. ml4t/engineer/artifacts/__init__.py +17 -0
  9. ml4t/engineer/artifacts/features.py +72 -0
  10. ml4t/engineer/artifacts/labels.py +85 -0
  11. ml4t/engineer/artifacts/predictions.py +80 -0
  12. ml4t/engineer/bars/AGENTS.md +72 -0
  13. ml4t/engineer/bars/__init__.py +88 -0
  14. ml4t/engineer/bars/base.py +152 -0
  15. ml4t/engineer/bars/imbalance.py +1766 -0
  16. ml4t/engineer/bars/run.py +1008 -0
  17. ml4t/engineer/bars/tick.py +97 -0
  18. ml4t/engineer/bars/vectorized.py +644 -0
  19. ml4t/engineer/bars/volume.py +309 -0
  20. ml4t/engineer/config/AGENTS.md +28 -0
  21. ml4t/engineer/config/__init__.py +44 -0
  22. ml4t/engineer/config/base.py +330 -0
  23. ml4t/engineer/config/data_contract.py +35 -0
  24. ml4t/engineer/config/experiment.py +348 -0
  25. ml4t/engineer/config/labeling.py +526 -0
  26. ml4t/engineer/config/preprocessing_config.py +311 -0
  27. ml4t/engineer/config/spec_bridge.py +35 -0
  28. ml4t/engineer/core/AGENTS.md +22 -0
  29. ml4t/engineer/core/__init__.py +113 -0
  30. ml4t/engineer/core/calendars/AGENTS.md +16 -0
  31. ml4t/engineer/core/calendars/__init__.py +19 -0
  32. ml4t/engineer/core/calendars/base.py +66 -0
  33. ml4t/engineer/core/calendars/crypto.py +107 -0
  34. ml4t/engineer/core/calendars/equity.py +215 -0
  35. ml4t/engineer/core/decorators.py +225 -0
  36. ml4t/engineer/core/dispatch.py +22 -0
  37. ml4t/engineer/core/exceptions.py +311 -0
  38. ml4t/engineer/core/lookbacks.py +242 -0
  39. ml4t/engineer/core/registry.py +250 -0
  40. ml4t/engineer/core/schemas.py +198 -0
  41. ml4t/engineer/core/types.py +49 -0
  42. ml4t/engineer/core/validation.py +218 -0
  43. ml4t/engineer/dataset.py +778 -0
  44. ml4t/engineer/discovery/AGENTS.md +19 -0
  45. ml4t/engineer/discovery/__init__.py +9 -0
  46. ml4t/engineer/discovery/catalog.py +578 -0
  47. ml4t/engineer/features/AGENTS.md +65 -0
  48. ml4t/engineer/features/__init__.py +53 -0
  49. ml4t/engineer/features/composite.py +312 -0
  50. ml4t/engineer/features/cross_asset.py +711 -0
  51. ml4t/engineer/features/fdiff.py +394 -0
  52. ml4t/engineer/features/math/AGENTS.md +35 -0
  53. ml4t/engineer/features/math/__init__.py +10 -0
  54. ml4t/engineer/features/math/max.py +155 -0
  55. ml4t/engineer/features/math/min.py +155 -0
  56. ml4t/engineer/features/math/sum.py +127 -0
  57. ml4t/engineer/features/microstructure/AGENTS.md +37 -0
  58. ml4t/engineer/features/microstructure/__init__.py +20 -0
  59. ml4t/engineer/features/microstructure/amihud_illiquidity.py +202 -0
  60. ml4t/engineer/features/microstructure/effective_tick_rule.py +41 -0
  61. ml4t/engineer/features/microstructure/kyle_lambda.py +192 -0
  62. ml4t/engineer/features/microstructure/order_book.py +297 -0
  63. ml4t/engineer/features/microstructure/order_flow_imbalance.py +94 -0
  64. ml4t/engineer/features/microstructure/price_impact_ratio.py +78 -0
  65. ml4t/engineer/features/microstructure/quote_stuffing_indicator.py +79 -0
  66. ml4t/engineer/features/microstructure/realized_spread.py +58 -0
  67. ml4t/engineer/features/microstructure/roll_spread_estimator.py +68 -0
  68. ml4t/engineer/features/microstructure/trade_intensity.py +61 -0
  69. ml4t/engineer/features/microstructure/volume_at_price_ratio.py +76 -0
  70. ml4t/engineer/features/microstructure/volume_synchronicity.py +70 -0
  71. ml4t/engineer/features/microstructure/volume_weighted_price_momentum.py +60 -0
  72. ml4t/engineer/features/ml/AGENTS.md +35 -0
  73. ml4t/engineer/features/ml/__init__.py +18 -0
  74. ml4t/engineer/features/ml/create_lag_features.py +87 -0
  75. ml4t/engineer/features/ml/cyclical_encode.py +73 -0
  76. ml4t/engineer/features/ml/directional_targets.py +96 -0
  77. ml4t/engineer/features/ml/fourier_features.py +68 -0
  78. ml4t/engineer/features/ml/interaction_features.py +84 -0
  79. ml4t/engineer/features/ml/multi_horizon_returns.py +72 -0
  80. ml4t/engineer/features/ml/percentile_rank_features.py +83 -0
  81. ml4t/engineer/features/ml/regime_conditional_features.py +73 -0
  82. ml4t/engineer/features/ml/rolling_entropy.py +713 -0
  83. ml4t/engineer/features/ml/time_decay_weights.py +84 -0
  84. ml4t/engineer/features/ml/volatility_adjusted_returns.py +70 -0
  85. ml4t/engineer/features/momentum/AGENTS.md +104 -0
  86. ml4t/engineer/features/momentum/__init__.py +35 -0
  87. ml4t/engineer/features/momentum/adx.py +405 -0
  88. ml4t/engineer/features/momentum/adxr.py +174 -0
  89. ml4t/engineer/features/momentum/apo.py +182 -0
  90. ml4t/engineer/features/momentum/aroon.py +374 -0
  91. ml4t/engineer/features/momentum/bop.py +175 -0
  92. ml4t/engineer/features/momentum/cci.py +119 -0
  93. ml4t/engineer/features/momentum/cmo.py +180 -0
  94. ml4t/engineer/features/momentum/directional.py +473 -0
  95. ml4t/engineer/features/momentum/imi.py +166 -0
  96. ml4t/engineer/features/momentum/macd.py +426 -0
  97. ml4t/engineer/features/momentum/macdfix.py +315 -0
  98. ml4t/engineer/features/momentum/mfi.py +266 -0
  99. ml4t/engineer/features/momentum/minus_dm.py +159 -0
  100. ml4t/engineer/features/momentum/mom.py +152 -0
  101. ml4t/engineer/features/momentum/plus_dm.py +159 -0
  102. ml4t/engineer/features/momentum/ppo.py +185 -0
  103. ml4t/engineer/features/momentum/roc.py +87 -0
  104. ml4t/engineer/features/momentum/rocp.py +121 -0
  105. ml4t/engineer/features/momentum/rocr.py +119 -0
  106. ml4t/engineer/features/momentum/rocr100.py +119 -0
  107. ml4t/engineer/features/momentum/rsi.py +181 -0
  108. ml4t/engineer/features/momentum/sar.py +305 -0
  109. ml4t/engineer/features/momentum/stochastic.py +270 -0
  110. ml4t/engineer/features/momentum/stochf.py +256 -0
  111. ml4t/engineer/features/momentum/stochrsi.py +252 -0
  112. ml4t/engineer/features/momentum/trix.py +144 -0
  113. ml4t/engineer/features/momentum/ultosc.py +246 -0
  114. ml4t/engineer/features/momentum/willr.py +115 -0
  115. ml4t/engineer/features/price_transform/AGENTS.md +34 -0
  116. ml4t/engineer/features/price_transform/__init__.py +12 -0
  117. ml4t/engineer/features/price_transform/avgprice.py +158 -0
  118. ml4t/engineer/features/price_transform/medprice.py +139 -0
  119. ml4t/engineer/features/price_transform/midprice.py +245 -0
  120. ml4t/engineer/features/price_transform/typprice.py +153 -0
  121. ml4t/engineer/features/price_transform/wclprice.py +155 -0
  122. ml4t/engineer/features/regime.py +547 -0
  123. ml4t/engineer/features/risk.py +749 -0
  124. ml4t/engineer/features/statistics/AGENTS.md +25 -0
  125. ml4t/engineer/features/statistics/__init__.py +16 -0
  126. ml4t/engineer/features/statistics/avgdev.py +147 -0
  127. ml4t/engineer/features/statistics/linearreg.py +158 -0
  128. ml4t/engineer/features/statistics/linearreg_angle.py +159 -0
  129. ml4t/engineer/features/statistics/linearreg_intercept.py +158 -0
  130. ml4t/engineer/features/statistics/linearreg_slope.py +156 -0
  131. ml4t/engineer/features/statistics/stddev.py +179 -0
  132. ml4t/engineer/features/statistics/structural_break.py +659 -0
  133. ml4t/engineer/features/statistics/tsf.py +151 -0
  134. ml4t/engineer/features/statistics/var.py +173 -0
  135. ml4t/engineer/features/trend/AGENTS.md +26 -0
  136. ml4t/engineer/features/trend/__init__.py +17 -0
  137. ml4t/engineer/features/trend/dema.py +159 -0
  138. ml4t/engineer/features/trend/donchian.py +200 -0
  139. ml4t/engineer/features/trend/ema.py +174 -0
  140. ml4t/engineer/features/trend/kama.py +184 -0
  141. ml4t/engineer/features/trend/midpoint.py +135 -0
  142. ml4t/engineer/features/trend/sma.py +160 -0
  143. ml4t/engineer/features/trend/t3.py +243 -0
  144. ml4t/engineer/features/trend/tema.py +131 -0
  145. ml4t/engineer/features/trend/trima.py +142 -0
  146. ml4t/engineer/features/trend/wma.py +123 -0
  147. ml4t/engineer/features/utils/AGENTS.md +16 -0
  148. ml4t/engineer/features/utils/__init__.py +8 -0
  149. ml4t/engineer/features/utils/arithmetic.py +119 -0
  150. ml4t/engineer/features/utils/helpers.py +87 -0
  151. ml4t/engineer/features/utils/ma_types.py +92 -0
  152. ml4t/engineer/features/volatility/AGENTS.md +31 -0
  153. ml4t/engineer/features/volatility/__init__.py +22 -0
  154. ml4t/engineer/features/volatility/atr.py +243 -0
  155. ml4t/engineer/features/volatility/bollinger_bands.py +183 -0
  156. ml4t/engineer/features/volatility/conditional_volatility_ratio.py +72 -0
  157. ml4t/engineer/features/volatility/ewma_volatility.py +88 -0
  158. ml4t/engineer/features/volatility/garch_forecast.py +132 -0
  159. ml4t/engineer/features/volatility/garman_klass_volatility.py +79 -0
  160. ml4t/engineer/features/volatility/natr.py +177 -0
  161. ml4t/engineer/features/volatility/parkinson_volatility.py +76 -0
  162. ml4t/engineer/features/volatility/realized_volatility.py +65 -0
  163. ml4t/engineer/features/volatility/rogers_satchell_volatility.py +77 -0
  164. ml4t/engineer/features/volatility/trange.py +208 -0
  165. ml4t/engineer/features/volatility/volatility_of_volatility.py +128 -0
  166. ml4t/engineer/features/volatility/volatility_percentile_rank.py +74 -0
  167. ml4t/engineer/features/volatility/volatility_regime_probability.py +83 -0
  168. ml4t/engineer/features/volatility/yang_zhang_volatility.py +156 -0
  169. ml4t/engineer/features/volume/AGENTS.md +32 -0
  170. ml4t/engineer/features/volume/__init__.py +10 -0
  171. ml4t/engineer/features/volume/ad.py +213 -0
  172. ml4t/engineer/features/volume/adosc.py +184 -0
  173. ml4t/engineer/features/volume/obv.py +162 -0
  174. ml4t/engineer/labeling/AGENTS.md +71 -0
  175. ml4t/engineer/labeling/__init__.py +121 -0
  176. ml4t/engineer/labeling/atr_barriers.py +402 -0
  177. ml4t/engineer/labeling/calendar.py +505 -0
  178. ml4t/engineer/labeling/horizon_labels.py +611 -0
  179. ml4t/engineer/labeling/meta_labels.py +349 -0
  180. ml4t/engineer/labeling/numba_ops.py +473 -0
  181. ml4t/engineer/labeling/percentile_labels.py +645 -0
  182. ml4t/engineer/labeling/triple_barrier.py +557 -0
  183. ml4t/engineer/labeling/uniqueness.py +417 -0
  184. ml4t/engineer/labeling/utils.py +499 -0
  185. ml4t/engineer/logging/AGENTS.md +14 -0
  186. ml4t/engineer/logging/__init__.py +24 -0
  187. ml4t/engineer/logging/config.py +212 -0
  188. ml4t/engineer/logging/core.py +598 -0
  189. ml4t/engineer/preprocessing.py +1131 -0
  190. ml4t/engineer/py.typed +0 -0
  191. ml4t/engineer/relationships/AGENTS.md +15 -0
  192. ml4t/engineer/relationships/__init__.py +31 -0
  193. ml4t/engineer/relationships/correlation.py +248 -0
  194. ml4t/engineer/relationships/plot_correlation.py +220 -0
  195. ml4t/engineer/store/AGENTS.md +14 -0
  196. ml4t/engineer/store/__init__.py +9 -0
  197. ml4t/engineer/store/offline.py +576 -0
  198. ml4t/engineer/utils/AGENTS.md +13 -0
  199. ml4t/engineer/utils/__init__.py +0 -0
  200. ml4t/engineer/utils/dependencies.py +320 -0
  201. ml4t_engineer-0.1.0.dist-info/METADATA +307 -0
  202. ml4t_engineer-0.1.0.dist-info/RECORD +204 -0
  203. ml4t_engineer-0.1.0.dist-info/WHEEL +4 -0
  204. ml4t_engineer-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,83 @@
1
+ # ml4t.engineer Package
2
+
3
+ Package-level navigation for the public `ml4t-engineer` surface.
4
+
5
+ ## Main Modules
6
+
7
+ | Module | Purpose | Key Exports |
8
+ |--------|---------|-------------|
9
+ | `api.py` | Feature-computation entry point | `compute_features()` |
10
+ | `dataset.py` | Leakage-safe dataset preparation | `MLDatasetBuilder`, `create_dataset_builder()` |
11
+ | `preprocessing.py` | Train-only scalers and transform pipelines | `StandardScaler`, `MinMaxScaler`, `RobustScaler`, `PreprocessingPipeline` |
12
+ | `discovery/catalog.py` | Metadata-driven feature exploration | `FeatureCatalog`, `feature_catalog` |
13
+ | `config/` | Reusable config models | `LabelingConfig`, `PreprocessingConfig`, `DataContractConfig` |
14
+ | `__init__.py` | Public re-exports and AGENTS discovery helper | `get_agent_docs()` |
15
+
16
+ ## Subdirectories
17
+
18
+ | Directory | Purpose | AGENTS |
19
+ |-----------|---------|--------|
20
+ | `features/` | Registry-backed indicator implementations and standalone feature helpers | [features/AGENTS.md](features/AGENTS.md) |
21
+ | `labeling/` | Barrier labels, percentile labels, meta-labeling, uniqueness | [labeling/AGENTS.md](labeling/AGENTS.md) |
22
+ | `bars/` | Tick, volume, dollar, imbalance, and run bars | [bars/AGENTS.md](bars/AGENTS.md) |
23
+ | `core/` | Registry, metadata, schemas, decorators, validation | [core/AGENTS.md](core/AGENTS.md) |
24
+ | `config/` | Pydantic configuration models and schema bridges | [config/AGENTS.md](config/AGENTS.md) |
25
+ | `discovery/` | Metadata-driven feature search and filtering | [discovery/AGENTS.md](discovery/AGENTS.md) |
26
+ | `relationships/` | Correlation helpers and plotting utilities | [relationships/AGENTS.md](relationships/AGENTS.md) |
27
+ | `store/` | Offline DuckDB storage helpers | [store/AGENTS.md](store/AGENTS.md) |
28
+ | `artifacts/` | Lightweight artifact records for features, labels, predictions | [artifacts/AGENTS.md](artifacts/AGENTS.md) |
29
+ | `logging/` | Structured logging configuration | [logging/AGENTS.md](logging/AGENTS.md) |
30
+ | `utils/` | optional dependency helpers and low-level utilities | [utils/AGENTS.md](utils/AGENTS.md) |
31
+
32
+ ## Current Public API Shape
33
+
34
+ ```python
35
+ from ml4t.engineer import (
36
+ compute_features,
37
+ create_dataset_builder,
38
+ feature_catalog,
39
+ MLDatasetBuilder,
40
+ StandardScaler,
41
+ RobustScaler,
42
+ )
43
+ from ml4t.engineer.config import LabelingConfig, PreprocessingConfig
44
+ from ml4t.engineer.labeling import triple_barrier_labels, atr_triple_barrier_labels
45
+ from ml4t.engineer.bars import TickBarSampler, VolumeBarSampler, DollarBarSampler
46
+ ```
47
+
48
+ ## Core Patterns
49
+
50
+ ### Compute features through the registry
51
+
52
+ ```python
53
+ from ml4t.engineer import compute_features
54
+
55
+ result = compute_features(df, ["rsi", "macd", "atr"])
56
+ ```
57
+
58
+ ### Discover features through metadata
59
+
60
+ ```python
61
+ from ml4t.engineer import feature_catalog
62
+
63
+ feature_catalog.list(category="momentum")
64
+ feature_catalog.search("volatility estimator")
65
+ feature_catalog.describe("rsi")
66
+ ```
67
+
68
+ ### Build train/test data without leakage
69
+
70
+ ```python
71
+ from ml4t.engineer import create_dataset_builder
72
+
73
+ builder = create_dataset_builder(features, labels, scaler="robust")
74
+ X_train, X_test, y_train, y_test = builder.train_test_split(train_size=0.8)
75
+ ```
76
+
77
+ ## Notes
78
+
79
+ - `FeatureSelector` has moved out of this library and belongs in `ml4t-diagnostic`
80
+ - `store/` exists but is lower-priority than the core feature, labeling, bar, and
81
+ dataset workflows
82
+ - AGENTS files are the current navigation surface; older singular filename references
83
+ should be treated as stale
@@ -0,0 +1,151 @@
1
+ """ml4t-engineer - A Financial Machine Learning Feature Engineering Library.
2
+
3
+ ml4t-engineer is a comprehensive FML stack designed for correctness, reproducibility,
4
+ and performance. It provides tools for feature engineering, labeling, and preprocessing
5
+ for financial machine learning models.
6
+
7
+ Agent Navigation:
8
+ This package includes AGENTS.md files for AI agent navigation.
9
+ Call `get_agent_docs()` to get paths to all documentation files.
10
+ Start with the root AGENTS.md for package overview and navigation.
11
+ """
12
+
13
+ from importlib.metadata import PackageNotFoundError as _PackageNotFoundError
14
+ from importlib.metadata import version as _dist_version
15
+ from pathlib import Path as _Path
16
+
17
+ from . import _polars_compat as _polars_compat
18
+ from . import (
19
+ core,
20
+ dataset,
21
+ discovery,
22
+ features,
23
+ labeling,
24
+ preprocessing,
25
+ relationships,
26
+ store,
27
+ )
28
+ from .api import compute_features
29
+ from .dataset import (
30
+ DatasetInfo,
31
+ FoldResult,
32
+ MLDatasetBuilder,
33
+ create_dataset_builder,
34
+ )
35
+ from .discovery import FeatureCatalog
36
+ from .discovery.catalog import features as feature_catalog
37
+ from .preprocessing import (
38
+ BaseScaler,
39
+ MinMaxScaler,
40
+ NotFittedError,
41
+ PreprocessingPipeline,
42
+ Preprocessor,
43
+ RobustScaler,
44
+ StandardScaler,
45
+ TransformType,
46
+ )
47
+
48
+ try:
49
+ from ._version import version as __version__
50
+ except Exception:
51
+ try:
52
+ __version__ = _dist_version("ml4t-engineer")
53
+ except _PackageNotFoundError:
54
+ __version__ = "0+unknown"
55
+
56
+
57
+ def get_agent_docs() -> dict[str, _Path]:
58
+ """Get paths to AGENTS.md documentation files for AI agent navigation.
59
+
60
+ Returns a dict mapping logical names to file paths. Start with 'root'
61
+ for package overview, then drill into specific areas as needed.
62
+
63
+ Returns
64
+ -------
65
+ dict[str, Path]
66
+ Mapping of doc names to paths. Keys include:
67
+ - 'root': Package overview and directory map
68
+ - 'features': Feature category index (120 indicators)
69
+ - 'features/{category}': Category-specific signatures
70
+ - 'labeling': ML label generation methods
71
+ - 'bars': Alternative bar sampling
72
+ - 'core', 'core/calendars': Registry and validation internals
73
+ - 'config': Reusable configuration models
74
+ - 'discovery': Metadata-driven feature search
75
+ - 'artifacts', 'relationships', 'store', 'logging', 'utils': Secondary
76
+ package areas with their own navigation guides
77
+
78
+ Example
79
+ -------
80
+ >>> from ml4t.engineer import get_agent_docs
81
+ >>> docs = get_agent_docs()
82
+ >>> print(docs['root'].read_text()[:200]) # Read overview
83
+ """
84
+ pkg_dir = _Path(__file__).parent
85
+ docs: dict[str, _Path] = {}
86
+
87
+ # Root and package-level
88
+ if (p := pkg_dir / "AGENTS.md").exists():
89
+ docs["root"] = p
90
+
91
+ # Features index and categories
92
+ features_dir = pkg_dir / "features"
93
+ if (p := features_dir / "AGENTS.md").exists():
94
+ docs["features"] = p
95
+ for category_dir in features_dir.iterdir():
96
+ if category_dir.is_dir() and (p := category_dir / "AGENTS.md").exists():
97
+ docs[f"features/{category_dir.name}"] = p
98
+
99
+ # Other modules
100
+ for module in [
101
+ "labeling",
102
+ "bars",
103
+ "core",
104
+ "config",
105
+ "discovery",
106
+ "artifacts",
107
+ "relationships",
108
+ "store",
109
+ "logging",
110
+ "utils",
111
+ ]:
112
+ if (p := pkg_dir / module / "AGENTS.md").exists():
113
+ docs[module] = p
114
+ if (p := pkg_dir / "core" / "calendars" / "AGENTS.md").exists():
115
+ docs["core/calendars"] = p
116
+
117
+ return docs
118
+
119
+
120
+ __all__ = [
121
+ # Main API
122
+ "compute_features",
123
+ # Agent navigation
124
+ "get_agent_docs",
125
+ # Feature Discovery (discoverability API)
126
+ "FeatureCatalog",
127
+ "feature_catalog",
128
+ # Dataset builder (leakage-safe train/test preparation)
129
+ "MLDatasetBuilder",
130
+ "create_dataset_builder",
131
+ "FoldResult",
132
+ "DatasetInfo",
133
+ # Preprocessing (leakage-safe scalers)
134
+ "Preprocessor",
135
+ "PreprocessingPipeline",
136
+ "TransformType",
137
+ "StandardScaler",
138
+ "MinMaxScaler",
139
+ "RobustScaler",
140
+ "BaseScaler",
141
+ "NotFittedError",
142
+ # Submodules
143
+ "core",
144
+ "dataset",
145
+ "discovery",
146
+ "features",
147
+ "labeling",
148
+ "preprocessing",
149
+ "relationships",
150
+ "store",
151
+ ]
@@ -0,0 +1,32 @@
1
+ """Numba decorators with a pure-Python fallback for unsupported runtimes."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Callable
6
+ from importlib import import_module
7
+ from typing import Any, TypeVar
8
+
9
+ _Function = TypeVar("_Function", bound=Callable[..., Any])
10
+
11
+
12
+ def _identity_jit(*args: Any, **kwargs: Any) -> Any:
13
+ """Return the undecorated function when Numba is unavailable."""
14
+ del kwargs
15
+ if len(args) == 1 and callable(args[0]):
16
+ return args[0]
17
+
18
+ def decorate(function: _Function) -> _Function:
19
+ return function
20
+
21
+ return decorate
22
+
23
+
24
+ def _load_numba_decorators() -> tuple[Any, Any, bool]:
25
+ try:
26
+ numba = import_module("numba")
27
+ except ImportError:
28
+ return _identity_jit, _identity_jit, False
29
+ return numba.jit, numba.njit, True
30
+
31
+
32
+ jit, njit, NUMBA_AVAILABLE = _load_numba_decorators()
@@ -0,0 +1,71 @@
1
+ """Compatibility repair for Polars Series dispatch on CPython 3.15."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+ from collections.abc import Container
7
+ from datetime import datetime
8
+ from importlib import import_module
9
+ from types import FunctionType
10
+
11
+ _SERIES_CLASSES = (
12
+ ("polars.series.series", "Series"),
13
+ ("polars.series.array", "ArrayNameSpace"),
14
+ ("polars.series.binary", "BinaryNameSpace"),
15
+ ("polars.series.categorical", "CatNameSpace"),
16
+ ("polars.series.datetime", "DateTimeNameSpace"),
17
+ ("polars.series.ext", "ExtensionNameSpace"),
18
+ ("polars.series.list", "ListNameSpace"),
19
+ ("polars.series.string", "StringNameSpace"),
20
+ ("polars.series.struct", "StructNameSpace"),
21
+ )
22
+ _BROKEN_SERIES_ERROR = "'NoneType' object has no attribute '_s'"
23
+
24
+
25
+ def _has_py315_docstring_layout(function: FunctionType, empty_bytecode: Container[bytes]) -> bool:
26
+ code = function.__code__
27
+ return (
28
+ code.co_code in empty_bytecode
29
+ and isinstance(function.__doc__, str)
30
+ and code.co_consts == (function.__doc__,)
31
+ )
32
+
33
+
34
+ def ensure_polars_series_dispatch() -> None:
35
+ """Repair pola-rs/polars#28347 only when its Python 3.15 failure is present."""
36
+ if sys.version_info < (3, 15):
37
+ return
38
+
39
+ import polars as pl
40
+
41
+ expected = datetime(2000, 1, 1)
42
+ try:
43
+ pl.Series("_ml4t_polars_probe", [expected])
44
+ return
45
+ except AttributeError as error:
46
+ if _BROKEN_SERIES_ERROR not in str(error):
47
+ raise
48
+
49
+ utils = import_module("polars.series.utils")
50
+ predicate_name = "_is_empty_method"
51
+ original_is_empty = getattr(utils, predicate_name)
52
+ empty_bytecode = utils._EMPTY_BYTECODE
53
+
54
+ def is_empty_method(function: FunctionType) -> bool:
55
+ return original_is_empty(function) or _has_py315_docstring_layout(function, empty_bytecode)
56
+
57
+ setattr(utils, predicate_name, is_empty_method)
58
+ try:
59
+ for module_name, class_name in _SERIES_CLASSES:
60
+ utils.expr_dispatch(getattr(import_module(module_name), class_name))
61
+
62
+ probe = pl.Series("_ml4t_polars_probe", [expected])
63
+ if probe.to_list() != [expected]:
64
+ raise RuntimeError("Polars Series dispatch probe returned an invalid result")
65
+ except Exception as error:
66
+ raise RuntimeError("Unable to repair Polars Series dispatch on Python 3.15") from error
67
+ finally:
68
+ setattr(utils, predicate_name, original_is_empty)
69
+
70
+
71
+ ensure_polars_series_dispatch()
@@ -0,0 +1,24 @@
1
+ # file generated by vcs-versioning
2
+ # don't change, don't track in version control
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "__version__",
7
+ "__version_tuple__",
8
+ "version",
9
+ "version_tuple",
10
+ "__commit_id__",
11
+ "commit_id",
12
+ ]
13
+
14
+ version: str
15
+ __version__: str
16
+ __version_tuple__: tuple[int | str, ...]
17
+ version_tuple: tuple[int | str, ...]
18
+ commit_id: str | None
19
+ __commit_id__: str | None
20
+
21
+ __version__ = version = '0.1.0'
22
+ __version_tuple__ = version_tuple = (0, 1, 0)
23
+
24
+ __commit_id__ = commit_id = None