Skip to content

Commit

Permalink
BUG: do freq validation in DTA.__init__ (pandas-dev#24686)
Browse files Browse the repository at this point in the history
* do freq validation in DTA.__init__

* troubleshoot parquet fail

* troubleshoot feather

* troubleshoot pyarrow fail
  • Loading branch information
jbrockmendel authored and Pingviinituutti committed Feb 28, 2019
1 parent b7a3984 commit 9ed29b7
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 4 deletions.
2 changes: 1 addition & 1 deletion pandas/core/arrays/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ def _concat_same_type(cls, to_concat):

def copy(self, deep=False):
values = self.asi8.copy()
return type(self)(values, dtype=self.dtype, freq=self.freq)
return type(self)._simple_new(values, dtype=self.dtype, freq=self.freq)

def _values_for_factorize(self):
return self.asi8, iNaT
Expand Down
17 changes: 15 additions & 2 deletions pandas/core/arrays/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,8 @@ def __init__(self, values, dtype=_NS_DTYPE, freq=None, copy=False):
if isinstance(values, (ABCSeries, ABCIndexClass)):
values = values._values

inferred_freq = getattr(values, "_freq", None)

if isinstance(values, type(self)):
# validation
dtz = getattr(dtype, 'tz', None)
Expand Down Expand Up @@ -322,9 +324,20 @@ def __init__(self, values, dtype=_NS_DTYPE, freq=None, copy=False):
self._dtype = dtype
self._freq = freq

if inferred_freq is None and freq is not None:
type(self)._validate_frequency(self, freq)

@classmethod
def _simple_new(cls, values, freq=None, dtype=None):
return cls(values, freq=freq, dtype=dtype)
def _simple_new(cls, values, freq=None, dtype=_NS_DTYPE):
assert isinstance(values, np.ndarray)
if values.dtype == 'i8':
values = values.view(_NS_DTYPE)

result = object.__new__(cls)
result._data = values
result._freq = freq
result._dtype = dtype
return result

@classmethod
def _from_sequence(cls, data, dtype=None, copy=False,
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/internals/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -3084,7 +3084,7 @@ def make_block(values, placement, klass=None, ndim=None, dtype=None,
elif klass is DatetimeTZBlock and not is_datetime64tz_dtype(values):
# TODO: This is no longer hit internally; does it need to be retained
# for e.g. pyarrow?
values = DatetimeArray(values, dtype)
values = DatetimeArray._simple_new(values, dtype=dtype)

return klass(values, ndim=ndim, placement=placement)

Expand Down
10 changes: 10 additions & 0 deletions pandas/tests/arrays/test_datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@


class TestDatetimeArrayConstructor(object):
def test_freq_validation(self):
# GH#24623 check that invalid instances cannot be created with the
# public constructor
arr = np.arange(5, dtype=np.int64) * 3600 * 10**9

msg = ("Inferred frequency H from passed values does not "
"conform to passed frequency W-SUN")
with pytest.raises(ValueError, match=msg):
DatetimeArray(arr, freq="W")

@pytest.mark.parametrize('meth', [DatetimeArray._from_sequence,
sequence_to_dt64ns,
pd.to_datetime,
Expand Down

0 comments on commit 9ed29b7

Please sign in to comment.