{"record":{"id":"51bc5665c5b8aad7","repo":"microsoft/qlib","slug":"please-implement-the-generate-method","errorCode":null,"errorMessage":"Please implement the `generate` method.","messagePattern":"Please implement the `generate` method\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"qlib/workflow/record_temp.py","lineNumber":79,"sourceCode":"\n    @property\n    def recorder(self):\n        if self._recorder is None:\n            raise ValueError(\"This RecordTemp did not set recorder yet.\")\n        return self._recorder\n\n    def generate(self, **kwargs):\n        \"\"\"\n        Generate certain records such as IC, backtest etc., and save them.\n\n        Parameters\n        ----------\n        kwargs\n\n        Return\n        ------\n        \"\"\"\n        raise NotImplementedError(f\"Please implement the `generate` method.\")\n\n    def load(self, name: str, parents: bool = True):\n        \"\"\"\n        It behaves the same as self.recorder.load_object.\n        But it is an easier interface because users don't have to care about `get_path` and `artifact_path`\n\n        Parameters\n        ----------\n        name : str\n            the name for the file to be load.\n\n        parents : bool\n            Each recorder has different `artifact_path`.\n            So parents recursively find the path in parents\n            Sub classes has higher priority\n\n        Return\n        ------","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/workflow/record_temp.py#L61-L97","documentation":"RecordTemp.generate is the abstract entry point of the record-template hierarchy: it should run the record generation (IC, backtest, signal analysis...) and save results to the recorder. The base class raises NotImplementedError to force subclasses to define generation logic. Seeing it means generate() was called on the base class or on a subclass that did not override it.","triggerScenarios":"Instantiating RecordTemp directly and calling generate(); defining a custom record class without a generate method and listing it in the workflow 'record' config, which Qlib will call after training; misspelling the override (e.g. genrate).","commonSituations":"Writing a custom analysis record for the first time; copying an existing record class and renaming its generate method; upgrading qlib where generate's expected signature stayed the same but the subclass was dropped.","solutions":["Subclass an existing record (SignalRecord, PortAnaRecord, IC record) instead of RecordTemp when possible","Implement generate(self, **kwargs) in your custom record class performing the computation and calling self.save(...)","Check spelling/signature of the override so it truly replaces the base method"],"exampleFix":"# before\nclass MyRecord(RecordTemp):\n    def __init__(self, recorder):\n        super().__init__(recorder)\n    # generate missing\n\n# after\nclass MyRecord(RecordTemp):\n    def __init__(self, recorder):\n        super().__init__(recorder)\n    def generate(self, **kwargs):\n        pred = self.load('pred.pkl')\n        self.save(my_metric=len(pred))","handlingStrategy":"type-guard","validationCode":"from qlib.workflow.record_temp import RecordTemp\n\ndef assert_generatable(record):\n    if type(record).generate is RecordTemp.generate:\n        raise TypeError(f'{type(record).__name__} must implement generate()')","typeGuard":"from qlib.workflow.record_temp import RecordTemp\n\ndef has_generate(record) -> bool:\n    return type(record).generate is not RecordTemp.generate","tryCatchPattern":"try:\n    record.generate()\nexcept NotImplementedError as e:\n    raise TypeError(f'{type(record).__name__} is not a usable record: {e}') from e","preventionTips":["Subclass SignalRecord/PortAnaRecord rather than RecordTemp for common analyses","Validate custom record classes in unit tests by calling generate on a dummy recorder","Keep the exact method name generate(self, **kwargs) in overrides"],"tags":["qlib","record-temp","abstract-method","not-implemented"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}