{"record":{"id":"abdef6626074fb4c","repo":"microsoft/qlib","slug":"all-elements-in-idx-list-must-be-of-the-same-type","errorCode":null,"errorMessage":"All elements in idx_list must be of the same type","messagePattern":"All elements in idx_list must be of the same type","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"qlib/utils/index_data.py","lineNumber":113,"sourceCode":"    NOTE: the indexing has following flaws\n    - duplicated index value is not well supported (only the first appearance will be considered)\n    - The order of the index is not considered!!!! So the slicing will not behave like pandas when indexings are ordered\n    \"\"\"\n\n    def __init__(self, idx_list: Union[List, pd.Index, \"Index\", int]):\n        self.idx_list: np.ndarray = None  # using array type for index list will make things easier\n        if isinstance(idx_list, Index):\n            # Fast read-only copy\n            self.idx_list = idx_list.idx_list\n            self.index_map = idx_list.index_map\n            self._is_sorted = idx_list._is_sorted\n        elif isinstance(idx_list, int):\n            self.index_map = self.idx_list = np.arange(idx_list)\n            self._is_sorted = True\n        else:\n            # Check if all elements in idx_list are of the same type\n            if not all(isinstance(x, type(idx_list[0])) for x in idx_list):\n                raise TypeError(\"All elements in idx_list must be of the same type\")\n            # Check if all elements in idx_list are of the same datetime64 precision\n            if isinstance(idx_list[0], np.datetime64) and not all(x.dtype == idx_list[0].dtype for x in idx_list):\n                raise TypeError(\"All elements in idx_list must be of the same datetime64 precision\")\n            self.idx_list = np.array(idx_list)\n            # NOTE: only the first appearance is indexed\n            self.index_map = dict(zip(self.idx_list, range(len(self))))\n            self._is_sorted = False\n\n    def __getitem__(self, i: int):\n        return self.idx_list[i]\n\n    def _convert_type(self, item):\n        \"\"\"\n\n        After user creates indices with Type A, user may query data with other types with the same info.\n            This method try to make type conversion and make query sane rather than raising KeyError strictly\n\n        Parameters","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/utils/index_data.py#L95-L131","documentation":"The Index class in qlib/utils/index_data.py builds a numpy array and a lookup dict from idx_list, and requires every element to share one Python type. Mixing types (e.g. strings with ints, or Timestamps with datetime64) would produce an object-dtype array and break hashing/equality downstream, so the constructor rejects it early with TypeError.","triggerScenarios":"Constructing Index(['2020-01-01', pd.Timestamp('2020-01-02')]), Index([1, '2']), or SingleData/MultiData whose index/columns argument is a mixed-type list; also passing an empty-then-heterogeneous iterable from user data files.","commonSituations":"Loading calendars or instrument lists from CSV where dates are sometimes ISO strings and sometimes parsed Timestamps; concatenating hand-written test fixtures with literals of inconsistent types; migrating code from pandas Index (which tolerates object dtype) to qlib's Index.","solutions":["Normalize every element to one type before constructing, e.g. list(pd.to_datetime(raw_dates)) or [str(x) for x in items].","If the data comes from a file, parse the date/instrument column explicitly (pd.to_datetime / astype) instead of relying on mixed raw values.","Check for accidental None/NaN entries in the list, which commonly cause the first mixed-type element."],"exampleFix":"// before\nidx = Index(['2020-01-01', pd.Timestamp('2020-01-02')])  # TypeError\n\n// after\nidx = Index(list(pd.to_datetime(['2020-01-01', '2020-01-02'])))","handlingStrategy":"validation","validationCode":"def homogeneous(items) -> bool:\n    items = list(items)\n    return len(items) == 0 or all(type(x) is type(items[0]) for x in items)\n\nassert homogeneous(raw_index), 'mixed types in index'","typeGuard":"def is_homogeneous_index(items: list) -> bool:\n    items = list(items)\n    return not items or all(isinstance(x, type(items[0])) for x in items)","tryCatchPattern":"try:\n    idx = Index(raw)\nexcept TypeError as e:\n    raw = [str(x) for x in raw]  # or normalize to timestamps\n    idx = Index(raw)","preventionTips":["Parse date/instrument columns with pd.to_datetime / astype at load time so lists never carry mixed literals.","Reject None in index inputs early — None next to str/int is the most common mixed-type source."],"tags":["qlib","index-data","typeerror","index","type-coercion"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}