BUG: segfault manifesting with dateutil=2.6 w.r.t. replace when timez… · pandas-dev/pandas@f8bd08e (original) (raw)

`@@ -98,6 +98,7 @@ except NameError: # py3

`

98

98

`cdef inline object create_timestamp_from_ts(

`

99

99

` int64_t value, pandas_datetimestruct dts,

`

100

100

`object tz, object freq):

`

``

101

`+

""" convenience routine to construct a Timestamp from its parts """

`

101

102

` cdef _Timestamp ts_base

`

102

103

` ts_base = _Timestamp.new(Timestamp, dts.year, dts.month,

`

103

104

` dts.day, dts.hour, dts.min,

`

`@@ -112,6 +113,7 @@ cdef inline object create_timestamp_from_ts(

`

112

113

`cdef inline object create_datetime_from_ts(

`

113

114

` int64_t value, pandas_datetimestruct dts,

`

114

115

`object tz, object freq):

`

``

116

`+

""" convenience routine to construct a datetime.datetime from its parts """

`

115

117

`return datetime(dts.year, dts.month, dts.day, dts.hour,

`

116

118

` dts.min, dts.sec, dts.us, tz)

`

117

119

``

`@@ -378,7 +380,6 @@ class Timestamp(_Timestamp):

`

378

380

`# Mixing pydatetime positional and keyword arguments is forbidden!

`

379

381

``

380

382

` cdef _TSObject ts

`

381

``

`-

cdef _Timestamp ts_base

`

382

383

``

383

384

`if offset is not None:

`

384

385

`# deprecate offset kwd in 0.19.0, GH13593

`

`@@ -412,17 +413,7 @@ class Timestamp(_Timestamp):

`

412

413

`from pandas.tseries.frequencies import to_offset

`

413

414

` freq = to_offset(freq)

`

414

415

``

415

``

`-

make datetime happy

`

416

``

`-

ts_base = _Timestamp.new(cls, ts.dts.year, ts.dts.month,

`

417

``

`-

ts.dts.day, ts.dts.hour, ts.dts.min,

`

418

``

`-

ts.dts.sec, ts.dts.us, ts.tzinfo)

`

419

``

-

420

``

`-

fill out rest of data

`

421

``

`-

ts_base.value = ts.value

`

422

``

`-

ts_base.freq = freq

`

423

``

`-

ts_base.nanosecond = ts.dts.ps / 1000

`

424

``

-

425

``

`-

return ts_base

`

``

416

`+

return create_timestamp_from_ts(ts.value, ts.dts, ts.tzinfo, freq)

`

426

417

``

427

418

`def _round(self, freq, rounder):

`

428

419

``

`@@ -660,8 +651,80 @@ class Timestamp(_Timestamp):

`

660

651

` astimezone = tz_convert

`

661

652

``

662

653

`def replace(self, **kwds):

`

663

``

`-

return Timestamp(datetime.replace(self, **kwds),

`

664

``

`-

freq=self.freq)

`

``

654

`+

"""

`

``

655

`+

implements datetime.replace, handles nanoseconds

`

``

656

+

``

657

`+

Parameters

`

``

658

`+


`

``

659

`+

kwargs: key-value dict

`

``

660

+

``

661

`+

accepted keywords are:

`

``

662

`+

year, month, day, hour, minute, second, microsecond, nanosecond, tzinfo

`

``

663

+

``

664

`+

values must be integer, or for tzinfo, a tz-convertible

`

``

665

+

``

666

`+

Returns

`

``

667

`+


`

``

668

`+

Timestamp with fields replaced

`

``

669

`+

"""

`

``

670

+

``

671

`+

cdef:

`

``

672

`+

pandas_datetimestruct dts

`

``

673

`+

int64_t value

`

``

674

`+

object tzinfo, result, k, v

`

``

675

`+

_TSObject ts

`

``

676

+

``

677

`+

set to naive if needed

`

``

678

`+

tzinfo = self.tzinfo

`

``

679

`+

value = self.value

`

``

680

`+

if tzinfo is not None:

`

``

681

`+

value = tz_convert_single(value, 'UTC', tzinfo)

`

``

682

+

``

683

`+

setup components

`

``

684

`+

pandas_datetime_to_datetimestruct(value, PANDAS_FR_ns, &dts)

`

``

685

`+

dts.ps = self.nanosecond * 1000

`

``

686

+

``

687

`+

replace

`

``

688

`+

def validate(k, v):

`

``

689

`+

""" validate integers """

`

``

690

`+

if not isinstance(v, int):

`

``

691

`+

raise ValueError("value must be an integer, received {v} for {k}".format(v=type(v), k=k))

`

``

692

`+

return v

`

``

693

+

``

694

`+

for k, v in kwds.items():

`

``

695

`+

if k == 'year':

`

``

696

`+

dts.year = validate(k, v)

`

``

697

`+

elif k == 'month':

`

``

698

`+

dts.month = validate(k, v)

`

``

699

`+

elif k == 'day':

`

``

700

`+

dts.day = validate(k, v)

`

``

701

`+

elif k == 'hour':

`

``

702

`+

dts.hour = validate(k, v)

`

``

703

`+

elif k == 'minute':

`

``

704

`+

dts.min = validate(k, v)

`

``

705

`+

elif k == 'second':

`

``

706

`+

dts.sec = validate(k, v)

`

``

707

`+

elif k == 'microsecond':

`

``

708

`+

dts.us = validate(k, v)

`

``

709

`+

elif k == 'nanosecond':

`

``

710

`+

dts.ps = validate(k, v) * 1000

`

``

711

`+

elif k == 'tzinfo':

`

``

712

`+

tzinfo = v

`

``

713

`+

else:

`

``

714

`+

raise ValueError("invalid name {} passed".format(k))

`

``

715

+

``

716

`+

reconstruct & check bounds

`

``

717

`+

value = pandas_datetimestruct_to_datetime(PANDAS_FR_ns, &dts)

`

``

718

`+

if value != NPY_NAT:

`

``

719

`+

_check_dts_bounds(&dts)

`

``

720

+

``

721

`+

set tz if needed

`

``

722

`+

if tzinfo is not None:

`

``

723

`+

value = tz_convert_single(value, tzinfo, 'UTC')

`

``

724

+

``

725

`+

result = create_timestamp_from_ts(value, dts, tzinfo, self.freq)

`

``

726

+

``

727

`+

return result

`

665

728

``

666

729

`def isoformat(self, sep='T'):

`

667

730

` base = super(_Timestamp, self).isoformat(sep=sep)

`

`@@ -5041,7 +5104,9 @@ cpdef normalize_date(object dt):

`

5041

5104

` -------

`

5042

5105

` normalized : datetime.datetime or Timestamp

`

5043

5106

`"""

`

5044

``

`-

if PyDateTime_Check(dt):

`

``

5107

`+

if is_timestamp(dt):

`

``

5108

`+

return dt.replace(hour=0, minute=0, second=0, microsecond=0, nanosecond=0)

`

``

5109

`+

elif PyDateTime_Check(dt):

`

5045

5110

`return dt.replace(hour=0, minute=0, second=0, microsecond=0)

`

5046

5111

`elif PyDate_Check(dt):

`

5047

5112

`return datetime(dt.year, dt.month, dt.day)

`