-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
REF: Refactor Datetimelike delegation #24039
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e614a80
649843b
96b7d93
a8e3e50
de13b2d
1107059
1f3f4c9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
""" | ||
Base and utility classes for tseries type pandas objects. | ||
""" | ||
import operator | ||
import warnings | ||
|
||
import numpy as np | ||
|
@@ -19,6 +20,7 @@ | |
from pandas.core.dtypes.generic import ABCIndex, ABCIndexClass, ABCSeries | ||
|
||
from pandas.core import algorithms, ops | ||
from pandas.core.accessor import PandasDelegate | ||
from pandas.core.arrays.datetimelike import ( | ||
DatetimeLikeArrayMixin, _ensure_datetimelike_to_i8) | ||
import pandas.core.indexes.base as ibase | ||
|
@@ -637,3 +639,48 @@ def f(self): | |
f.__name__ = fget.__name__ | ||
f.__doc__ = fget.__doc__ | ||
return property(f) | ||
|
||
|
||
class DatetimelikeDelegateMixin(PandasDelegate): | ||
""" | ||
Delegation mechanism, specific for Datetime, Timedelta, and Period types. | ||
|
||
Functionality is delegated from the Index class to an Array class. A | ||
few things can be customized | ||
|
||
* _delegate_class : type | ||
The class being delegated to. | ||
* _delegated_methods, delegated_properties : List | ||
The list of property / method names being delagated. | ||
* raw_methods : Set | ||
The set of methods whose results should should *not* be | ||
boxed in an index, after being returned from the array | ||
* raw_properties : Set | ||
The set of properties whose results should should *not* be | ||
boxed in an index, after being returned from the array | ||
""" | ||
# raw_methods : dispatch methods that shouldn't be boxed in an Index | ||
_raw_methods = set() | ||
# raw_properties : dispatch properties that shouldn't be boxed in an Index | ||
_raw_properties = set() | ||
name = None | ||
_data = None | ||
|
||
@property | ||
def _delegate_class(self): | ||
raise AbstractMethodError | ||
|
||
def _delegate_property_get(self, name, *args, **kwargs): | ||
result = getattr(self._data, name) | ||
if name not in self._raw_properties: | ||
result = Index(result, name=self.name) | ||
return result | ||
|
||
def _delegate_property_set(self, name, value, *args, **kwargs): | ||
setattr(self._data, name, value) | ||
|
||
def _delegate_method(self, name, *args, **kwargs): | ||
result = operator.methodcaller(name, *args, **kwargs)(self._data) | ||
if name not in self._raw_methods: | ||
result = Index(result, name=self.name) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this will need checks for 2-tuples in divmod and rdivmod, for scalars for eventual reduction ops There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think all the delegated methods return a single value. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If #23885 goes through that will change There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Gotcha. I'd prefer to wait until we can hit that code path before worrying about it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Totally fair. |
||
return result |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is PandasDelegate overkill for this situation? It's not like
Series.dt
where we construct an object and need to cache it. Couldn't we just use something like:There's definitely overlap with the PandasDelegate machinery, but I think that machinery makes for really dense reading, so should be reserved for when we really need it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps you're thinking of
Properties
(which subclassesPandasDelegate
)?PandasDelegate
doesn't have an__init__
, it just handles registering and creating the delegated properties.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But, I don't have a strong preference of one of the other. We use
PandasDelegate
on master, for period, so this PR is a strict generalization of that.