{"record":{"id":"f4911737a36b2fe5","repo":"microsoft/qlib","slug":"please-implement-the-add-method","errorCode":null,"errorMessage":"Please implement the `__add__` method","messagePattern":"Please implement the `__add__` method","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"qlib/backtest/high_performance_ds.py","lineNumber":231,"sourceCode":"    def __init__(self, metric: Union[dict, pd.Series]):\n        \"\"\"Single data structure for each metric.\n\n        Parameters\n        ----------\n        metric : Union[dict, pd.Series]\n            keys/index is stock_id, value is the metric value.\n            for example:\n                SH600068    NaN\n                SH600079    1.0\n                SH600266    NaN\n                           ...\n                SZ300692    NaN\n                SZ300719    NaN,\n        \"\"\"\n        raise NotImplementedError(f\"Please implement the `__init__` method\")\n\n    def __add__(self, other: Union[BaseSingleMetric, int, float]) -> BaseSingleMetric:\n        raise NotImplementedError(f\"Please implement the `__add__` method\")\n\n    def __radd__(self, other: Union[BaseSingleMetric, int, float]) -> BaseSingleMetric:\n        return self + other\n\n    def __sub__(self, other: Union[BaseSingleMetric, int, float]) -> BaseSingleMetric:\n        raise NotImplementedError(f\"Please implement the `__sub__` method\")\n\n    def __rsub__(self, other: Union[BaseSingleMetric, int, float]) -> BaseSingleMetric:\n        raise NotImplementedError(f\"Please implement the `__rsub__` method\")\n\n    def __mul__(self, other: Union[BaseSingleMetric, int, float]) -> BaseSingleMetric:\n        raise NotImplementedError(f\"Please implement the `__mul__` method\")\n\n    def __truediv__(self, other: Union[BaseSingleMetric, int, float]) -> BaseSingleMetric:\n        raise NotImplementedError(f\"Please implement the `__truediv__` method\")\n\n    def __eq__(self, other: object) -> BaseSingleMetric:\n        raise NotImplementedError(f\"Please implement the `__eq__` method\")","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/backtest/high_performance_ds.py#L213-L249","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\ntotal = base_metric + 1.0  # base_metric is BaseSingleMetric\n# after\nfrom qlib.backtest.high_performance_ds import SingleMetric\ntotal = SingleMetric(s) + 1.0","handlingStrategy":"type-guard","validationCode":"from qlib.backtest.high_performance_ds import BaseSingleMetric\nassert type(m).__add__ is not BaseSingleMetric.__add__, \"object does not implement __add__\"","typeGuard":"def supports_add(m) -> bool:\n    from qlib.backtest.high_performance_ds import BaseSingleMetric\n    return isinstance(m, BaseSingleMetric) and type(m).__add__ is not BaseSingleMetric.__add__","tryCatchPattern":"try:\n    result = m + other\nexcept NotImplementedError as e:\n    if '__add__' in str(e):\n        result = type(m)(m.storage).storage.add(other.storage) if hasattr(m, 'storage') else NotImplemented\n    raise","preventionTips":["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"],"tags":["python","qlib","operator-overloading","abstract-method","metrics"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}