Skip to content

Commit 60ddcb5

Browse files
committed
Merge branch 'disown-tz-only-rebased' of https://github.com/TomAugspurger/pandas into disown-tz-only-rebased
2 parents 6530500 + 9ae6706 commit 60ddcb5

File tree

12 files changed

+90
-224
lines changed

12 files changed

+90
-224
lines changed

.circleci/config.yml

Lines changed: 0 additions & 38 deletions
This file was deleted.

.travis.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,23 @@ matrix:
4343
apt:
4444
packages:
4545
- language-pack-zh-hans
46+
4647
- dist: trusty
4748
env:
4849
- JOB="2.7" ENV_FILE="ci/deps/travis-27.yaml" PATTERN="not slow"
4950
addons:
5051
apt:
5152
packages:
5253
- python-gtk2
54+
55+
- dist: trusty
56+
env:
57+
- JOB="3.6, locale" ENV_FILE="ci/deps/travis-36-locale.yaml" PATTERN="not slow and not network" LOCALE_OVERRIDE="zh_CN.UTF-8"
58+
5359
- dist: trusty
5460
env:
5561
- JOB="3.6, coverage" ENV_FILE="ci/deps/travis-36.yaml" PATTERN="not slow and not network" PANDAS_TESTING_MODE="deprecate" COVERAGE=true
62+
5663
- dist: trusty
5764
env:
5865
- JOB="3.7, NumPy dev" ENV_FILE="ci/deps/travis-37-numpydev.yaml" PATTERN="not slow and not network" TEST_ARGS="-W error" PANDAS_TESTING_MODE="deprecate"

README.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,6 @@
4545
</a>
4646
</td>
4747
</tr>
48-
<tr>
49-
<td></td>
50-
<td>
51-
<a href="https://circleci.com/gh/pandas-dev/pandas">
52-
<img src="https://circleci.com/gh/circleci/mongofinil/tree/master.svg?style=shield&circle-token=223d8cafa7b02902c3e150242520af8944e34671" alt="circleci build status" />
53-
</a>
54-
</td>
55-
</tr>
5648
<tr>
5749
<td></td>
5850
<td>

ci/circle/install_circle.sh

Lines changed: 0 additions & 81 deletions
This file was deleted.
File renamed without changes.

doc/source/contributing.rst

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -686,13 +686,13 @@ See :ref:`contributing.warnings` for more.
686686
Testing With Continuous Integration
687687
-----------------------------------
688688

689-
The *pandas* test suite will run automatically on `Travis-CI <https://travis-ci.org/>`__,
690-
`Azure Pipelines <https://azure.microsoft.com/en-us/services/devops/pipelines/>`__,
691-
and `Circle CI <https://circleci.com/>`__ continuous integration services, once your pull request is submitted.
689+
The *pandas* test suite will run automatically on `Travis-CI <https://travis-ci.org/>`__ and
690+
`Azure Pipelines <https://azure.microsoft.com/en-us/services/devops/pipelines/>`__
691+
continuous integration services, once your pull request is submitted.
692692
However, if you wish to run the test suite on a branch prior to submitting the pull request,
693693
then the continuous integration services need to be hooked to your GitHub repository. Instructions are here
694-
for `Travis-CI <http://about.travis-ci.org/docs/user/getting-started/>`__,
695-
`Azure Pipelines <https://docs.microsoft.com/en-us/azure/devops/pipelines/>`__, and `CircleCI <https://circleci.com/>`__.
694+
for `Travis-CI <http://about.travis-ci.org/docs/user/getting-started/>`__ and
695+
`Azure Pipelines <https://docs.microsoft.com/en-us/azure/devops/pipelines/>`__.
696696

697697
A pull-request will be considered for merging when you have an all 'green' build. If any tests are failing,
698698
then you will get a red 'X', where you can click through to see the individual failed tests.
@@ -704,8 +704,7 @@ This is an example of a green build.
704704

705705
Each time you push to *your* fork, a *new* run of the tests will be triggered on the CI.
706706
You can enable the auto-cancel feature, which removes any non-currently-running tests for that same pull-request, for
707-
`Travis-CI here <https://docs.travis-ci.com/user/customizing-the-build/#Building-only-the-latest-commit>`__ and
708-
for `CircleCI here <https://circleci.com/changelog-legacy/#option-to-auto-cancel-redundant-builds>`__.
707+
`Travis-CI here <https://docs.travis-ci.com/user/customizing-the-build/#Building-only-the-latest-commit>`__.
709708

710709
.. _contributing.tdd:
711710

doc/source/extending.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ your ``MyExtensionArray`` class, as follows:
162162

163163
.. code-block:: python
164164
165-
from pandas.core.arrays import ExtensionArray, ExtensionScalarOpsMixin
165+
from pandas.api.extensions import ExtensionArray, ExtensionScalarOpsMixin
166166
167167
class MyExtensionArray(ExtensionArray, ExtensionScalarOpsMixin):
168168
pass

pandas/core/indexes/datetimelike.py

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,30 @@ class DatetimeIndexOpsMixin(ExtensionOpsMixin):
4949
_resolution = cache_readonly(DatetimeLikeArrayMixin._resolution.fget)
5050
resolution = cache_readonly(DatetimeLikeArrayMixin.resolution.fget)
5151

52+
def unique(self, level=None):
53+
if level is not None:
54+
self._validate_index_level(level)
55+
56+
result = self._eadata.unique()
57+
58+
# Note: if `self` is already unique, then self.unique() should share
59+
# a `freq` with self. If not already unique, then self.freq must be
60+
# None, so again sharing freq is correct.
61+
return self._shallow_copy(result._data)
62+
63+
@classmethod
64+
def _create_comparison_method(cls, op):
65+
"""
66+
Create a comparison method that dispatches to ``cls.values``.
67+
"""
68+
def wrapper(self, other):
69+
result = op(self._eadata, maybe_unwrap_index(other))
70+
return result
71+
72+
wrapper.__doc__ = op.__doc__
73+
wrapper.__name__ = '__{}__'.format(op.__name__)
74+
return wrapper
75+
5276
# A few methods that are shared
5377
_maybe_mask_results = DatetimeLikeArrayMixin._maybe_mask_results
5478

@@ -144,7 +168,7 @@ def wrapper(left, right):
144168

145169
@Appender(DatetimeLikeArrayMixin._evaluate_compare.__doc__)
146170
def _evaluate_compare(self, other, op):
147-
result = DatetimeLikeArrayMixin._evaluate_compare(self, other, op)
171+
result = self._eadata._evaluate_compare(other, op)
148172
if is_bool_dtype(result):
149173
return result
150174
try:
@@ -459,7 +483,7 @@ def _add_datetimelike_methods(cls):
459483

460484
def __add__(self, other):
461485
# dispatch to ExtensionArray implementation
462-
result = self._data.__add__(other)
486+
result = self._eadata.__add__(maybe_unwrap_index(other))
463487
return wrap_arithmetic_op(self, other, result)
464488

465489
cls.__add__ = __add__
@@ -471,13 +495,13 @@ def __radd__(self, other):
471495

472496
def __sub__(self, other):
473497
# dispatch to ExtensionArray implementation
474-
result = self._data.__sub__(other)
498+
result = self._eadata.__sub__(maybe_unwrap_index(other))
475499
return wrap_arithmetic_op(self, other, result)
476500

477501
cls.__sub__ = __sub__
478502

479503
def __rsub__(self, other):
480-
result = self._data.__rsub__(other)
504+
result = self._eadata.__rsub__(maybe_unwrap_index(other))
481505
return wrap_arithmetic_op(self, other, result)
482506

483507
cls.__rsub__ = __rsub__
@@ -633,21 +657,8 @@ def shift(self, periods, freq=None):
633657

634658
@Appender(DatetimeLikeArrayMixin._time_shift.__doc__)
635659
def _time_shift(self, periods, freq=None):
636-
result = DatetimeLikeArrayMixin._time_shift(self, periods, freq=freq)
637-
result.name = self.name
638-
return result
639-
640-
@classmethod
641-
def _create_comparison_method(cls, op):
642-
"""
643-
Create a comparison method that dispatches to ``cls._data``.
644-
"""
645-
def wrapper(self, other):
646-
return op(self._data, other)
647-
648-
wrapper.__doc__ = op.__doc__
649-
wrapper.__name__ = '__{}__'.format(op.__name__)
650-
return wrapper
660+
result = self._eadata._time_shift(periods, freq=freq)
661+
return type(self)(result, name=self.name)
651662

652663

653664
def wrap_arithmetic_op(self, other, result):
@@ -669,6 +680,28 @@ def wrap_arithmetic_op(self, other, result):
669680
return result
670681

671682

683+
def maybe_unwrap_index(obj):
684+
"""
685+
If operating against another Index object, we need to unwrap the underlying
686+
data before deferring to the DatetimeArray/TimedeltaArray/PeriodArray
687+
implementation, otherwise we will incorrectly return NotImplemented.
688+
689+
Parameters
690+
----------
691+
obj : object
692+
693+
Returns
694+
-------
695+
unwrapped object
696+
"""
697+
if isinstance(obj, ABCIndexClass):
698+
if isinstance(obj, DatetimeIndexOpsMixin):
699+
# i.e. PeriodIndex/DatetimeIndex/TimedeltaIndex
700+
return obj._eadata
701+
return obj._data
702+
return obj
703+
704+
672705
class DatetimelikeDelegateMixin(PandasDelegate):
673706
"""
674707
Delegation mechanism, specific for Datetime, Timedelta, and Period types.

pandas/core/indexes/datetimes.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -717,13 +717,6 @@ def snap(self, freq='S'):
717717
return DatetimeIndex._simple_new(snapped, freq=freq)
718718
# TODO: what about self.name? tz? if so, use shallow_copy?
719719

720-
def unique(self, level=None):
721-
if level is not None:
722-
self._validate_index_level(level)
723-
724-
result = self._data.unique()
725-
return self._shallow_copy(result._data)
726-
727720
def join(self, other, how='left', level=None, return_indexers=False,
728721
sort=False):
729722
"""
@@ -1091,6 +1084,11 @@ def slice_indexer(self, start=None, end=None, step=None, kind=None):
10911084
# --------------------------------------------------------------------
10921085
# Wrapping DatetimeArray
10931086

1087+
@property
1088+
def _eadata(self):
1089+
return DatetimeArray._simple_new(self._data,
1090+
tz=self.tz, freq=self.freq)
1091+
10941092
# Compat for frequency inference, see GH#23789
10951093
_is_monotonic_increasing = Index.is_monotonic_increasing
10961094
_is_monotonic_decreasing = Index.is_monotonic_decreasing

0 commit comments

Comments
 (0)