{"record":{"id":"9561691aa1bd0a95","repo":"microsoft/qlib","slug":"subclass-of-featurestorage-must-implement-clear","errorCode":null,"errorMessage":"Subclass of FeatureStorage must implement `clear` method","messagePattern":"Subclass of FeatureStorage must implement `clear` method","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"qlib/data/storage/storage.py","lineNumber":297,"sourceCode":"        \"\"\"\n        raise NotImplementedError(\"Subclass of FeatureStorage must implement `start_index` method\")\n\n    @property\n    def end_index(self) -> Union[int, None]:\n        \"\"\"get FeatureStorage end index\n\n        Notes\n        -----\n        The  right index of the data range (both sides are closed)\n\n            The next  data appending point will be  `end_index + 1`\n\n        If the data(storage) does not exist, return None\n        \"\"\"\n        raise NotImplementedError(\"Subclass of FeatureStorage must implement `end_index` method\")\n\n    def clear(self) -> None:\n        raise NotImplementedError(\"Subclass of FeatureStorage must implement `clear` method\")\n\n    def write(self, data_array: Union[List, np.ndarray, Tuple], index: int = None):\n        \"\"\"Write data_array to FeatureStorage starting from index.\n\n        Notes\n        ------\n            If index is None, append data_array to feature.\n\n            If len(data_array) == 0; return\n\n            If (index - self.end_index) >= 1, self[end_index+1: index] will be filled with np.nan\n\n        Examples\n        ---------\n            .. code-block::\n\n                feature:\n                    3   4","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/data/storage/storage.py#L279-L315","documentation":"FeatureStorage.clear (qlib/data/storage/storage.py:297) is an abstract method that must remove all stored data for the feature. The base class raises NotImplementedError to enforce that every backend defines its own deletion semantics (deleting files, clearing binary segments, dropping DB rows). Calling clear() on the base class or an incomplete subclass raises this error.","triggerScenarios":"Calling storage.clear() on a directly instantiated FeatureStorage; a custom backend missing the clear() override; data re-dump pipelines that clear storage before rewriting.","commonSituations":"Custom backend development where clear was skipped; scripts that wipe qlib data directories feature-by-feature; tests exercising storage lifecycle methods.","solutions":["Use a concrete backend such as FileFeatureStorage whose clear() deletes the backing files","Implement clear() in your subclass to remove all persisted data for the feature","If you never clear data, delete the storage files/directories manually instead","Verify the object returned by the storage factory is a concrete class before calling lifecycle methods"],"exampleFix":"// before\nstorage = FeatureStorage(...)  # or incomplete subclass\nstorage.clear()  # NotImplementedError\n\n// after\nclass MyStorage(FeatureStorage):\n    def clear(self) -> None:\n        self._file.unlink(missing_ok=True)","handlingStrategy":"type-guard","validationCode":"from qlib.data.storage.storage import FeatureStorage\nassert type(storage).clear is not FeatureStorage.clear, 'clear not implemented'","typeGuard":"def has_concrete_clear(storage) -> bool:\n    return type(storage).clear is not FeatureStorage.clear","tryCatchPattern":"try:\n    storage.clear()\nexcept NotImplementedError:\n    logger.warning('storage %s cannot be cleared programmatically; delete files manually', storage)","preventionTips":["Implement the complete FeatureStorage interface, not just read paths","Prefer deleting backing files directly when no clear() is available"],"tags":["qlib","storage","abstract-method","not-implemented","clear"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}