microsoft/qlib · error · NotImplementedError
Please implement the `__add__` method
Error message
Please implement the `__add__` method
What it means
BaseSingleMetric.__add__ is abstract: the base class defines the arithmetic operator protocol (metric + metric, metric + scalar) but raises NotImplementedError. The real implementation lives in SingleMetric (line 436). The error fires when the object bound at runtime is a bare BaseSingleMetric — normally impossible if you always use SingleMetric, so it signals direct base-class use or an incomplete subclass.
Source
Thrown at qlib/backtest/high_performance_ds.py:231
def __init__(self, metric: Union[dict, pd.Series]):
"""Single data structure for each metric.
Parameters
----------
metric : Union[dict, pd.Series]
keys/index is stock_id, value is the metric value.
for example:
SH600068 NaN
SH600079 1.0
SH600266 NaN
...
SZ300692 NaN
SZ300719 NaN,
"""
raise NotImplementedError(f"Please implement the `__init__` method")
def __add__(self, other: Union[BaseSingleMetric, int, float]) -> BaseSingleMetric:
raise NotImplementedError(f"Please implement the `__add__` method")
def __radd__(self, other: Union[BaseSingleMetric, int, float]) -> BaseSingleMetric:
return self + other
def __sub__(self, other: Union[BaseSingleMetric, int, float]) -> BaseSingleMetric:
raise NotImplementedError(f"Please implement the `__sub__` method")
def __rsub__(self, other: Union[BaseSingleMetric, int, float]) -> BaseSingleMetric:
raise NotImplementedError(f"Please implement the `__rsub__` method")
def __mul__(self, other: Union[BaseSingleMetric, int, float]) -> BaseSingleMetric:
raise NotImplementedError(f"Please implement the `__mul__` method")
def __truediv__(self, other: Union[BaseSingleMetric, int, float]) -> BaseSingleMetric:
raise NotImplementedError(f"Please implement the `__truediv__` method")
def __eq__(self, other: object) -> BaseSingleMetric:
raise NotImplementedError(f"Please implement the `__eq__` method")View on GitHub (pinned to 79633dd950)
Solutions
- Use SingleMetric for arithmetic over per-stock metric vectors
- Implement __add__(self, other) in your subclass mirroring SingleMetric.__add__ (element-wise, NaN-aware)
- Verify with isinstance(m, BaseSingleMetric) and type(m).__add__ is not BaseSingleMetric.__add__ before arithmetic
Example fix
# before total = base_metric + 1.0 # base_metric is BaseSingleMetric # after from qlib.backtest.high_performance_ds import SingleMetric total = SingleMetric(s) + 1.0
Defensive patterns
Strategy: type-guard
Validate before calling
from qlib.backtest.high_performance_ds import BaseSingleMetric assert type(m).__add__ is not BaseSingleMetric.__add__, "object does not implement __add__"
Type guard
def supports_add(m) -> bool:
from qlib.backtest.high_performance_ds import BaseSingleMetric
return isinstance(m, BaseSingleMetric) and type(m).__add__ is not BaseSingleMetric.__add__ Try / catch
try:
result = m + other
except NotImplementedError as e:
if '__add__' in str(e):
result = type(m)(m.storage).storage.add(other.storage) if hasattr(m, 'storage') else NotImplemented
raise Prevention
- Use SingleMetric for arithmetic
- Implement the full operator set (__add__, __radd__ implicit, __sub__, __rsub__, __mul__, __truediv__, __eq__, __gt__, __lt__) together in subclasses
- Remember sum() over metrics goes through __radd__, so it needs __add__ too
When it happens
Trigger: base + other or sum(metrics) (sum starts with 0 and relies on __radd__ -> self + other) on a BaseSingleMetric instance; a subclass overriding __radd__ but not __add__ while being added to a scalar.
Common situations: Custom BaseSingleMetric subclasses that implement some operators but not __add__; code mixing BaseSingleMetric-typed variables with arithmetic; np.sum / functools.reduce over heterogeneous metric objects.
Related errors
- Please implement the `__sub__` method
- Please implement the `__rsub__` method
- Please implement the `__mul__` method
- Please implement the `__truediv__` method
- Please implement the `__eq__` method
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/f4911737a36b2fe5.
Report an issue: GitHub.