{"record":{"id":"77335ed3dafba0cc","repo":"microsoft/qlib","slug":"please-implement-the-rsub-method","errorCode":null,"errorMessage":"Please implement the `__rsub__` method","messagePattern":"Please implement the `__rsub__` method","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"qlib/backtest/high_performance_ds.py","lineNumber":240,"sourceCode":"                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\")\n\n    def __gt__(self, other: Union[BaseSingleMetric, int, float]) -> BaseSingleMetric:\n        raise NotImplementedError(f\"Please implement the `__gt__` method\")\n\n    def __lt__(self, other: Union[BaseSingleMetric, int, float]) -> BaseSingleMetric:\n        raise NotImplementedError(f\"Please implement the `__lt__` method\")\n\n    def __len__(self) -> int:\n        raise NotImplementedError(f\"Please implement the `__len__` method\")","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/backtest/high_performance_ds.py#L222-L258","documentation":"BaseSingleMetric.__rsub__ implements reflected subtraction (other - self). Unlike __radd__ (which the base class implements as self + other), __rsub__ is left abstract because operand order matters: the base class cannot compute scalar-minus-metric. Only SingleMetric (line 436) implements it, so 1.0 - base_metric on a bare BaseSingleMetric raises NotImplementedError.","triggerScenarios":"Expressions like 1.0 - m or np.float64(x) - m where m is a raw BaseSingleMetric; broadcasting code (numpy, pandas ops) that triggers the reflected operator because the left operand's __sub__ returns NotImplemented; custom subclasses that override __sub__ but forget __rsub__.","commonSituations":"Writing inverse/excess-return metrics (benchmark - portfolio); mixing metric objects with numpy scalars; subclassing BaseSingleMetric and implementing only the forward operators.","solutions":["Use SingleMetric, which implements both __sub__ and __rsub__","In custom subclasses, implement __rsub__ as e.g. type(self)(other - self.storage) mirroring SingleMetric","Rewrite scalar - m as m.__rsub__(scalar) only after confirming a concrete implementation exists, or compute (m * -1) + other"],"exampleFix":"# before\ninv = 1.0 - BaseSingleMetric(s)\n# after\nfrom qlib.backtest.high_performance_ds import SingleMetric\ninv = 1.0 - SingleMetric(s)","handlingStrategy":"type-guard","validationCode":"from qlib.backtest.high_performance_ds import BaseSingleMetric\nassert type(m).__rsub__ is not BaseSingleMetric.__rsub__, \"object does not implement __rsub__\"","typeGuard":"def supports_rsub(m) -> bool:\n    from qlib.backtest.high_performance_ds import BaseSingleMetric\n    return isinstance(m, BaseSingleMetric) and type(m).__rsub__ is not BaseSingleMetric.__rsub__","tryCatchPattern":null,"preventionTips":["Prefer putting the metric on the left (m - scalar) so __rsub__ is never needed","Implement __rsub__ whenever you implement __sub__ — the base class does not provide it (unlike __radd__)","Use SingleMetric which implements both directions"],"tags":["python","qlib","operator-overloading","abstract-method","metrics"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}