Repository: pandas-dev/pandas
Pull request: BUG : Series.to_timestamp and Series.to_period raise user-facing AssertionError
- [X] closes #33327
- [X] tests added / passed
- [X] passes `black pandas`
- [X] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [X] whatsnew entry


Problem statement:
BUG: User-facing AssertionError in Series.to_timestamp
- [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] (optional) I have confirmed this bug exists on the master branch of pandas.

---

#### Code Sample, a copy-pastable example

```python

In [5]: import pandas as pd

In [6]: pd.Series([0]).to_timestamp()
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-6-1a9d08d7daba> in <module>
----> 1 pd.Series([0]).to_timestamp()

~/sandbox/pandas/pandas/core/series.py in to_timestamp(self, freq, how, copy)
   4565             new_values = new_values.copy()
   4566
-> 4567         assert isinstance(self.index, (ABCDatetimeIndex, ABCPeriodIndex))
   4568         new_index = self.index.to_timestamp(freq=freq, how=how)
   4569         return self._constructor(new_values, index=new_index).__finalize__(

AssertionError:
```

#### Problem description

Users shouldn't see AssertionErrors like this, since they may be disabled when the interpreter starts up.

#### Expected Output

We probably want this to be a `TypeError`.

Hints from issue discussion:
Same issue applies to Series.to_period
@TomAugspurger Are those assertions in order to placate mypy? Wonder if there's another way of doing that?
Not sure. I would hope that with

```python
if not isinstance(self.index (ABCDatetimeIndex, ABCPeriodIndex)):
    raise TypeError(...)

# hopefully mypy knows the types here
```

but we can make the `assert` for mypy after we've done the user-facing check if needed.
take

Hello @CerseiO are you working on this or shall I work ?
Hello @vipulrai91, not now, you can work on this.
> Hello @vipulrai91, not now, you can work on this.

Thanks for confirming.
take
@TomAugspurger 

Does this work ?

```python
>>> pd.Series([0]).to_timestamp()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/vipul/Work/Github/pandas/pandas/core/series.py", line 4665, in to_timestamp
    raise TypeError(f"unsupported Type {self.index}")
TypeError: unsupported Type RangeIndex(start=0, stop=1, step=1)
```

The code change made was:
```python
if not isinstance(self.index, (ABCDatetimeIndex, ABCPeriodIndex)):
          raise TypeError(f"unsupported Type {self.index}")
new_index = self.index.to_timestamp(freq=freq, how=how)
return self._constructor(new_values, index=new_index).__finalize__(
            self, method="to_timestamp")
```

Commit message: resolves series.py issue #33327

Patch to review:
diff --git a/pandas/core/series.py b/pandas/core/series.py
index eb409b432f89c..4f4749ff342d7 100644
--- a/pandas/core/series.py
+++ b/pandas/core/series.py
@@ -4661,7 +4661,8 @@ def to_timestamp(self, freq=None, how="start", copy=True) -> "Series":
         if copy:
             new_values = new_values.copy()
 
-        assert isinstance(self.index, (ABCDatetimeIndex, ABCPeriodIndex))
+        if not isinstance(self.index, (ABCDatetimeIndex, ABCPeriodIndex)):
+            raise TypeError(f"unsupported Type {self.index}")
         new_index = self.index.to_timestamp(freq=freq, how=how)
         return self._constructor(new_values, index=new_index).__finalize__(
             self, method="to_timestamp"
@@ -4688,7 +4689,8 @@ def to_period(self, freq=None, copy=True) -> "Series":
         if copy:
             new_values = new_values.copy()
 
-        assert isinstance(self.index, ABCDatetimeIndex)
+        if not isinstance(self.index, ABCDatetimeIndex):
+            raise TypeError(f"unsupported Type {self.index}")
         new_index = self.index.to_period(freq=freq)
         return self._constructor(new_values, index=new_index).__finalize__(
             self, method="to_period"


Code review comments:
diff_hunk: @@ -4661,7 +4661,8 @@ def to_timestamp(self, freq=None, how="start", copy=True) -> "Series":
         if copy:
             new_values = new_values.copy()
 
-        assert isinstance(self.index, (ABCDatetimeIndex, ABCPeriodIndex))
+        if not isinstance(self.index, (ABCDatetimeIndex, ABCPeriodIndex)):
+            raise TypeError(f"unsupported Type {self.index}")
path: pandas/core/series.py
text: @user1:
I _think_ should also raise the TypeError for DatetimeIndex

```
>>> import pandas as pd
>>>
>>> pd.__version__
'1.1.0.dev0+1502.g3ed7dff48'
>>>
>>> rng = pd.date_range("1/1/2012", periods=5, freq="M")
>>>
>>> ts = pd.Series(np.random.randn(len(rng)), index=rng)
>>>
>>> ts
2012-01-31    0.384143
2012-02-29   -0.060017
2012-03-31   -1.506513
2012-04-30    0.898198
2012-05-31    1.035634
Freq: M, dtype: float64
>>>
>>> ts.index
DatetimeIndex(['2012-01-31', '2012-02-29', '2012-03-31', '2012-04-30',
               '2012-05-31'],
              dtype='datetime64[ns]', freq='M')
>>>
>>> ts.to_timestamp()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\simon\pandas\pandas\core\series.py", line 4665, in to_timestamp
    new_index = self.index.to_timestamp(freq=freq, how=how)
AttributeError: 'DatetimeIndex' object has no attribute 'to_timestamp'
```