Pandas version checks

  • [x] I have checked that this issue has not already been reported.

  • [x] I have confirmed this bug exists on the latest version of pandas.

  • [x] I have confirmed this bug exists on the main branch of pandas.

Reproducible Example

from typing import reveal_type
import pandas as pd
from datetime import timedelta

reveal_type(pd.Index([1]) * timedelta(days=1))
reveal_type(pd.Index([1]) * [timedelta(days=1)])
reveal_type(pd.Index([1]) * pd.Timedelta(1, "d"))
reveal_type(pd.Index([1]) * [pd.Timedelta(1, "d")])

Issue Description

Result is inconsistent

Runtime type is 'TimedeltaIndex'
Runtime type is 'Index'
Runtime type is 'TimedeltaIndex'
Runtime type is 'Index'

Expected Behavior

Results should all be `TimedeltaIndex

Installed Versions

INSTALLED VERSIONS ------------------ commit : 4665c10899bc413b639194f6fb8665a5c70f7db5 python : 3.12.10 python-bits : 64 OS : Windows OS-release : 11 Version : 10.0.26100 machine : AMD64 processor : AMD64 Family 25 Model 116 Stepping 1, AuthenticAMD byteorder : little LC_ALL : None LANG : en_US.UTF-8 LOCALE : Czech_Czechia.1252 pandas : 2.3.2 numpy : 2.3.3 pytz : 2025.2 dateutil : 2.9.0.post0 pip : 24.2 Cython : None sphinx : None IPython : None adbc-driver-postgresql: None adbc-driver-sqlite : None bs4 : 4.14.2 blosc : None bottleneck : None dataframe-api-compat : None fastparquet : None fsspec : None html5lib : 1.1 hypothesis : None gcsfs : None jinja2 : 3.1.6 lxml.etree : 6.0.2 matplotlib : 3.10.6 numba : None numexpr : 2.13.0 odfpy : None openpyxl : 3.1.5 pandas_gbq : None psycopg2 : None pymysql : None pyarrow : 21.0.0 pyreadstat : 1.3.1 pytest : 8.4.2 python-calamine : None pyxlsb : 1.0.10 s3fs : None scipy : 1.16.2 sqlalchemy : 2.0.43 tables : 3.10.2 tabulate : 0.9.0 xarray : 2025.9.0 xlrd : 2.0.2 xlsxwriter : 3.2.9 zstandard : None tzdata : 2025.2 qtpy : None pyqt5 : None

Comment From: rhshadrach

Thanks for the report. I think your expectation is somewhat reasonable, but this would lead to value-dependent behavior.

import random

if random.choice(["heads", "tails"]) == "heads":
    value = 1
else:
    value = timedelta(days=1)
reveal_type(pd.Index([1, 2]) * [timedelta(days=1), value])

Because lists can hold arbitrary types, if we were to return TimedeltaIndex as you expected in the OP, the multiplication would either have to raise when it has a valid answer, or have a different dtype depending on the values in the list.

I think Index of object dtype is the proper result here.

cc @jbrockmendel

Comment From: cmp0xff

Thank you for the reply. From my point of view, if the resulting dtype of an Index is not object but instead Timedelta or Timestamp, I would imagine that it got "promoted" to TimedeltaIndex or TimestampIndex.

Comment From: jbrockmendel

Neither is crazy.

What to do when we see a list is a Hard Problem. Do we cast it to ndarray(like)? Or do we treat it as a scalar that the user wants to operate on pointwise? xref #62423, #33807, #27911. ATM we do wrap lists for comparison ops but not for arithmetic/boolean ops.

I suspect that ultimately the correct thing will be to always wrap, but only after we have something like pd.Scalar that a user can use to specify "treat this sequence like a scalar".

Comment From: rhshadrach

@jbrockmendel - do you see value in keeping this issue open?

Comment From: jbrockmendel

i think the failure mode ("unexpected type/dtype") is distinct from the others ("it raises and shouldn't"), so yes

Comment From: Ganasekhar-gif

Hi! I’m interested in working on this issue. My approach will be to investigate the type promotion behavior in Index multiplication with Timedelta objects and implement a fix to ensure consistent TimedeltaIndex results where applicable. I will also add tests to cover different cases.