{"record":{"id":"81356a8dbc7543f0","repo":"pandas-dev/pandas","slug":"period-dtypes-are-not-supported-use-a-periodindex","errorCode":null,"errorMessage":"Period dtypes are not supported, use a PeriodIndex instead","messagePattern":"Period dtypes are not supported, use a PeriodIndex instead","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/interval.py","lineNumber":337,"sourceCode":"            msg = (\n                f\"must not have differing left [{type(left).__name__}] and \"\n                f\"right [{type(right).__name__}] types\"\n            )\n            raise ValueError(msg)\n        if (\n            isinstance(left.dtype, CategoricalDtype)\n            or is_string_dtype(left.dtype)\n            or is_string_dtype(right.dtype)\n        ):\n            # GH 19016, GH 66518: reject unsupported right-side dtypes too.\n            msg = (\n                \"category, object, and string subtypes are not supported \"\n                \"for IntervalArray\"\n            )\n            raise TypeError(msg)\n        if isinstance(left, ABCPeriodIndex):\n            msg = \"Period dtypes are not supported, use a PeriodIndex instead\"\n            raise ValueError(msg)\n        if isinstance(left, ABCDatetimeIndex) and str(left.tz) != str(right.tz):\n            msg = (\n                \"left and right must have the same time zone, got \"\n                f\"'{left.tz}' and '{right.tz}'\"\n            )\n            raise ValueError(msg)\n        elif needs_i8_conversion(left.dtype) and left.unit != right.unit:\n            # e.g. m8[s] vs m8[ms], try to cast to a common dtype GH#55714\n            left_arr, right_arr = left._data._ensure_matching_resos(right._data)\n            left = ensure_index(left_arr)\n            right = ensure_index(right_arr)\n\n        # For dt64/td64 we want DatetimeArray/TimedeltaArray instead of ndarray\n        left = ensure_wrapped_if_datetimelike(left)\n        left = extract_array(left, extract_numpy=True)\n        right = ensure_wrapped_if_datetimelike(right)\n        right = extract_array(right, extract_numpy=True)\n","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/interval.py#L319-L355","documentation":"Raised as a ValueError when one side of the interval is a PeriodIndex. Periods represent fixed-frequency spans themselves, so nesting them inside an IntervalArray is ambiguous; pandas directs you to PeriodIndex instead. Fires at pandas/core/arrays/interval.py:337.","triggerScenarios":"`pd.IntervalIndex.from_arrays(period_idx_a, period_idx_b)` where both inputs are `pd.PeriodIndex`, or passing a `PeriodDtype` as the interval subtype.","commonSituations":"Trying to build ranges over period data (e.g., 'from Q1 to Q3') by treating two PeriodIndex arrays as bounds.","solutions":["Use a `pd.PeriodIndex` directly to represent period spans.","If you need true intervals, convert periods to timestamps: `left.to_timestamp()`, `right.to_timestamp(how='end')`."],"exampleFix":"// before\npd.IntervalIndex.from_arrays(per_left, per_right)\n// after\npd.PeriodIndex(per_left.to_timestamp(), freq='Q')  # or\npd.IntervalIndex.from_arrays(per_left.to_timestamp(), per_right.to_timestamp(how='end'))","handlingStrategy":"type-guard","validationCode":"import pandas as pd\n\ndef build_from_periods(left, right):\n    if isinstance(left, pd.PeriodIndex) or isinstance(right, pd.PeriodIndex):\n        left = left.to_timestamp() if isinstance(left, pd.PeriodIndex) else left\n        right = right.to_timestamp(how='end') if isinstance(right, pd.PeriodIndex) else right\n    return pd.IntervalArray(left, right)","typeGuard":"import pandas as pd\n\ndef is_period_index(arr) -> bool:\n    return isinstance(arr, pd.PeriodIndex)","tryCatchPattern":"try:\n    ia = pd.IntervalArray(left, right)\nexcept ValueError as e:\n    if \"Period dtypes are not supported\" in str(e):\n        ia = pd.IntervalArray(left.to_timestamp(), right.to_timestamp(how='end'))\n    else:\n        raise","preventionTips":["Detect PeriodIndex inputs upstream and convert to timestamps.","Document that interval bounds must be numeric/datetime/timedelta.","Add an integration test with period inputs to lock in the conversion."],"tags":["interval","period","dtype","constructor"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}