{"record":{"id":"3d2f73b3cfa92f26","repo":"pandas-dev/pandas","slug":"dtype-must-be-perioddtype","errorCode":null,"errorMessage":"dtype must be PeriodDtype","messagePattern":"dtype must be PeriodDtype","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/period.py","lineNumber":1450,"sourceCode":"\n    Parameters\n    ----------\n    dtype : dtype\n    dtype2 : PeriodDtype or None\n        Dtype derived from a `freq` passed to the caller.\n\n    Returns\n    -------\n    PeriodDtype or None\n\n    Raises\n    ------\n    ValueError : non-period dtype\n    IncompatibleFrequency : mismatch between dtype and freq\n    \"\"\"\n    if dtype is not None:\n        if not isinstance(dtype, PeriodDtype):\n            raise ValueError(\"dtype must be PeriodDtype\")\n        if dtype2 is not None and dtype != dtype2:\n            raise IncompatibleFrequency(\"specified freq and dtype are different\")\n\n    elif dtype2 is not None:\n        if not isinstance(dtype2, PeriodDtype):\n            raise ValueError(\"dtype must be PeriodDtype\")\n        dtype = dtype2\n\n    return dtype\n\n\ndef dt64arr_to_periodarr(\n    data, freq, tz=None\n) -> tuple[npt.NDArray[np.int64], BaseOffset]:\n    \"\"\"\n    Convert a datetime-like array to values Period ordinals.\n\n    Parameters","sourceCodeStart":1432,"sourceCodeEnd":1468,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/period.py#L1432-L1468","documentation":"Raised by validate_dtype_freq when an explicit `dtype` is provided but is not a PeriodDtype. The helper validates that the dtype accompanying a period construction is genuinely period-typed before letting it through; anything else is rejected.","triggerScenarios":"Internal PeriodIndex/period_array construction paths that call validate_dtype_freq(dtype, freq) with a non-PeriodDtype first argument. Passing dtype='int64' or dtype=object where a period dtype is required.","commonSituations":"Wrapper libraries forwarding user dtypes into period constructors. Mixed dtype/freq APIs where the user supplies freq via dtype that isn't period-typed.","solutions":["Pass a PeriodDtype: pd.PeriodDtype(freq) or 'period[freq]'.","Omit dtype and let freq drive the inference.","Validate dtype isinstance PeriodDtype at the caller boundary."],"exampleFix":"# before\nvalidate_dtype_freq('int64', None)\n# after\nvalidate_dtype_freq(pd.PeriodDtype('D'), None)","handlingStrategy":"type-guard","validationCode":"from pandas.core.dtypes.dtypes import PeriodDtype\nfrom pandas.core.arrays.period import validate_dtype_freq\n\ndef safe_validate(dtype, freq):\n    if dtype is not None and not isinstance(dtype, PeriodDtype):\n        dtype = None\n    return validate_dtype_freq(dtype, freq)","typeGuard":"from pandas.core.dtypes.dtypes import PeriodDtype\n\ndef is_period_dtype(dtype) -> bool:\n    return isinstance(dtype, PeriodDtype)","tryCatchPattern":"try:\n    dt = validate_dtype_freq(dtype, freq)\nexcept ValueError:\n    dt = validate_dtype_freq(None, freq)","preventionTips":["Always box freq as PeriodDtype before passing as dtype.","Validate dtype type at API boundaries.","Prefer passing freq instead of dtype when unsure."],"tags":["period","dtype","validation","pandas-arrays"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}