{"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":"validation","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/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/interval.py#L319-L355","documentation":"Raised when `left` is a `PeriodIndex`. Period intervals are not supported inside IntervalArray because periods need their own array semantics; pandas directs users to PeriodIndex (or interval over the period ordinal codes).","triggerScenarios":"`IntervalArray.from_arrays(pd.period_range('2020', periods=3, freq='M'), pd.period_range('2020-03', periods=3, freq='M'))`; converting a DataFrame with period columns into an interval index.","commonSituations":"Time-bucketing workflows that naturally produce PeriodIndex endpoints; users wanting 'period intervals' (e.g. terms spanning months).","solutions":["Convert periods to timestamps: `left.to_timestamp()` and `right.to_timestamp()` then build the IntervalArray over DatetimeIndex.","Operate on period ordinals: `left.astype('int64')` (the underlying ordinal) if you only need ordering.","Keep endpoints as a PeriodIndex and do not wrap them in an IntervalArray."],"exampleFix":"# before\nIntervalArray.from_arrays(pd.period_range('2020', periods=2, freq='M'), pd.period_range('2020-02', periods=2, freq='M'))\n\n# after\npli = pd.period_range('2020', periods=2, freq='M')\npri = pd.period_range('2020-02', periods=2, freq='M')\nIntervalArray.from_arrays(pli.to_timestamp(), pri.to_timestamp())","handlingStrategy":"validation","validationCode":"import pandas as pd\n\ndef to_interval_bounds(left, right):\n    if isinstance(left, pd.PeriodIndex):\n        left = left.to_timestamp()\n    if isinstance(right, pd.PeriodIndex):\n        right = right.to_timestamp()\n    return left, right","typeGuard":"import pandas as pd\n\ndef has_no_period_bounds(left, right) -> bool:\n    return not isinstance(left, pd.PeriodIndex) and not isinstance(right, pd.PeriodIndex)","tryCatchPattern":"try:\n    arr = IntervalArray.from_arrays(left, right)\nexcept ValueError as e:\n    if 'Period dtypes are not supported' in str(e):\n        arr = IntervalArray.from_arrays(left.to_timestamp(), right.to_timestamp())\n    else:\n        raise","preventionTips":["Convert PeriodIndex endpoints to timestamps before building IntervalArray.","Keep period-bounded data as PeriodIndex rather than forcing into IntervalArray.","Document endpoint-type requirements in library wrappers."],"tags":["interval","period","periodindex","unsupported-dtype","value-error"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}