{"record":{"id":"35c99bd70bdf9a8b","repo":"pandas-dev/pandas","slug":"of-the-three-parameters-start-end-and-periods","errorCode":null,"errorMessage":"Of the three parameters: start, end, and periods, exactly two must be specified","messagePattern":"Of the three parameters: start, end, and periods, exactly two must be specified","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/period.py","lineNumber":1516,"sourceCode":"                    \"Pass `freq` explicitly instead.\",\n                    Pandas4Warning,\n                    stacklevel=find_stack_level(),\n                )\n                freq = inferred_freq\n            data = data._values\n\n    elif isinstance(data, (ABCIndex, ABCSeries)):\n        data = data._values\n\n    reso = get_unit_from_dtype(data.dtype)\n    freq = Period._maybe_convert_freq(freq)\n    base = freq._period_dtype_code\n    return c_dt64arr_to_periodarr(data.view(\"i8\"), base, tz, reso=reso), freq\n\n\ndef _get_ordinal_range(start, end, periods, freq, mult: int = 1):\n    if com.count_not_none(start, end, periods) != 2:\n        raise ValueError(\n            \"Of the three parameters: start, end, and periods, \"\n            \"exactly two must be specified\"\n        )\n\n    if freq is not None:\n        freq = to_offset(freq, is_period=True)\n        mult = freq.n\n\n    if start is not None:\n        start = Period(start, freq)\n    if end is not None:\n        end = Period(end, freq)\n\n    is_start_per = isinstance(start, Period)\n    is_end_per = isinstance(end, Period)\n\n    if is_start_per and is_end_per and start.freq != end.freq:\n        raise ValueError(\"start and end must have same freq\")","sourceCodeStart":1498,"sourceCodeEnd":1534,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/period.py#L1498-L1534","documentation":"Raised by _get_ordinal_range when com.count_not_none(start, end, periods) != 2. A period range is fully determined by exactly two of {start, end, periods} together with freq; supplying all three is over-determined and supplying fewer than two is under-determined, both rejected.","triggerScenarios":"pd.period_range(start=..., end=..., periods=...) (all three); pd.period_range(freq='D') (none of the three); pd.period_range(start='2020-01-01', freq='D') (only one).","commonSituations":"Dynamic config where all three fields default to provided values. Refactors that accidentally pass periods alongside start+end. UI forms exposing all three fields.","solutions":["Pass exactly two: start + end, start + periods, or end + periods.","Drop the redundant parameter if all three are set.","Compute the missing one upstream and pass exactly two."],"exampleFix":"# before\npd.period_range(start='2020-01-01', end='2020-01-05', periods=5, freq='D')\n# after\npd.period_range(start='2020-01-01', end='2020-01-05', freq='D')\n# or\npd.period_range(start='2020-01-01', periods=5, freq='D')","handlingStrategy":"validation","validationCode":"import pandas as pd\n\ndef exactly_two_of(start, end, periods, freq):\n    provided = sum(x is not None for x in (start, end, periods))\n    if provided != 2:\n        raise ValueError(f'Exactly two of start/end/periods required, got {provided}')\n    return pd.period_range(start=start, end=end, periods=periods, freq=freq)","typeGuard":"def has_exactly_two_anchors(start, end, periods) -> bool:\n    return sum(x is not None for x in (start, end, periods)) == 2","tryCatchPattern":"try:\n    rng = pd.period_range(start=start, end=end, periods=periods, freq=freq)\nexcept ValueError:\n    # drop periods if start and end are both set\n    rng = pd.period_range(start=start, end=end, freq=freq)","preventionTips":["Enforce 'exactly two of three' in calling code/config validators.","Default unset params to None (not 0) so the count is meaningful.","Unit-test range builders with all combinations of None."],"tags":["period","range","validation","pandas-arrays"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}