microsoft/qlib · error · NotImplementedError
Please implement the `empty` method
Error message
Please implement the `empty` method
What it means
BaseSingleMetric.empty is an abstract property that should return True when the metric holds no data. The base class property body raises NotImplementedError; SingleMetric implements it. Accessing .empty on a bare BaseSingleMetric — including in truthiness guards like `if m.empty:` — raises this error rather than returning a bool.
Source
Thrown at qlib/backtest/high_performance_ds.py:278
def sum(self) -> float:
raise NotImplementedError(f"Please implement the `sum` method")
def mean(self) -> float:
raise NotImplementedError(f"Please implement the `mean` method")
def count(self) -> int:
"""Return the count of the single metric, NaN is not included."""
raise NotImplementedError(f"Please implement the `count` method")
def abs(self) -> BaseSingleMetric:
raise NotImplementedError(f"Please implement the `abs` method")
@property
def empty(self) -> bool:
"""If metric is empty, return True."""
raise NotImplementedError(f"Please implement the `empty` method")
def add(self, other: BaseSingleMetric, fill_value: float = None) -> BaseSingleMetric:
"""Replace np.nan with fill_value in two metrics and add them."""
raise NotImplementedError(f"Please implement the `add` method")
def replace(self, replace_dict: dict) -> BaseSingleMetric:
"""Replace the value of metric according to replace_dict."""
raise NotImplementedError(f"Please implement the `replace` method")
def apply(self, func: Callable) -> BaseSingleMetric:
"""Replace the value of metric with func (metric).
Currently, the func is only qlib/backtest/order/Order.parse_dir.
"""
raise NotImplementedError(f"Please implement the 'apply' method")
View on GitHub (pinned to 79633dd950)
Solutions
- Use SingleMetric, where empty checks the underlying storage
- Implement @property def empty(self) in your subclass (e.g. return self.storage.empty)
- Do not replace it with len(m) == 0 — implement len() too, since both are part of the protocol
Example fix
# before m = BaseSingleMetric(s) if m.empty: ... # after from qlib.backtest.high_performance_ds import SingleMetric m = SingleMetric(s) if m.empty: ...
Defensive patterns
Strategy: type-guard
Validate before calling
from qlib.backtest.high_performance_ds import BaseSingleMetric assert type(m).empty.fget is not BaseSingleMetric.empty.fget, "object does not implement empty"
Type guard
def supports_empty(m) -> bool:
from qlib.backtest.high_performance_ds import BaseSingleMetric
fget = getattr(type(m).__dict__.get('empty'), 'fget', None)
return fget is not None and fget is not BaseSingleMetric.empty.fget Prevention
- Use SingleMetric so .empty is a real property
- When overriding in subclasses, keep the @property decorator so `.empty` stays attribute access
- Guard aggregation code with .empty checks after confirming a concrete type
When it happens
Trigger: m.empty on a raw BaseSingleMetric; guard clauses before aggregations (if metric.empty: return 0); subclasses that define other methods but not the empty property (note: it must be decorated @property to keep attribute access semantics).
Common situations: Defensive checks added by user code around aggregation calls; report templates handling empty trading days; custom subclasses missing the property decorator, making .empty return a bound method instead.
Related errors
- Please implement the `__init__` method
- Please implement the `__add__` method
- Please implement the `__sub__` method
- Please implement the `__rsub__` method
- Please implement the `__mul__` method
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/f1893680673170bf.
Report an issue: GitHub.