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

  1. Use SingleMetric for arithmetic over per-stock metric vectors
  2. Implement __add__(self, other) in your subclass mirroring SingleMetric.__add__ (element-wise, NaN-aware)
  3. 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

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


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/f4911737a36b2fe5. Report an issue: GitHub.