pandas-dev/pandas · error · TypeError
periods must be an integer, got
Error message
periods must be an integer, got {periods} What it means
Raised by validate_periods when the 'periods' argument is not None and is not an integer (checked via lib.is_integer). date_range / period_range / timedelta_range require periods to be a python int (or numpy integer) because it drives array sizing; floats, strings, or other types are rejected early with a clear message.
Solutions
- Coerce explicitly: periods=int(value) before passing.
- Fix the upstream computation to use integer division // or math.ceil with an int cast.
- Validate periods is None or isinstance(periods, (int, np.integer)) at the config boundary.
Example fix
// before
pd.date_range('2020-01-01', periods=10/3) # TypeError: periods must be an integer, got 3.333...
// after
pd.date_range('2020-01-01', periods=int(np.ceil(10/3))) Defensive patterns
Strategy: validation
Validate before calling
def coerce_periods(periods):
if periods is not None and not isinstance(periods, (int, np.integer)):
periods = int(periods)
return periods Type guard
def is_valid_periods(p) -> bool:
return p is None or isinstance(p, (int, np.integer)) Try / catch
try:
rng = pd.date_range(start=start, periods=periods, freq=freq)
except TypeError as e:
if "periods must be an integer" in str(e):
rng = pd.date_range(start=start, periods=int(periods), freq=freq)
else:
raise Prevention
- Coerce computed counts with int(...) or math.ceil before passing as periods.
- Use integer division // for stride math.
- Validate config-driven counts at the parse boundary.
When it happens
Trigger: Calling pd.date_range(..., periods=value) where value is a float (e.g. 3.0), a numpy float, a string, or any non-integer; same for pd.period_range / pd.timedelta_range which both route through validate_periods.
Common situations: Computing periods from a division that yields a float (len(df)/stride); reading a count from JSON/config as a string; numpy scalar that is np.float64 rather than np.int64.
Related errors
- Must provide freq argument if no data is supplied
- Neither `start` nor `end` can be NaT
- Of the four parameters: start, end, periods, and freq…
- 'unit' must be one of 's', 'ms', 'us', 'ns'
- Cannot assign expression output to target
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/711381b191be5075.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/arrays/datetimelike.py:2520
"""
If a `periods` argument is passed to the Datetime/Timedelta Array/Index
constructor, cast it to an integer.
Parameters
----------
periods : None, int
Returns
-------
periods : None or int
Raises
------
TypeError
if periods is not None or int
"""
if periods is not None and not lib.is_integer(periods):
raise TypeError(f"periods must be an integer, got {periods}")
# error: Incompatible return value type (got "int | integer[Any] | None",
# expected "int | None")
return periods # type: ignore[return-value]
def dtype_to_unit(dtype: DatetimeTZDtype | np.dtype | ArrowDtype) -> str:
"""
Return the unit str corresponding to the dtype's resolution.
Parameters
----------
dtype : DatetimeTZDtype or np.dtype
If np.dtype, we assume it is a datetime64 dtype.
Returns
-------
str
"""View on GitHub (pinned to 3b7651241d)