|
5 | 5 | from pandas.errors import AbstractMethodError
|
6 | 6 |
|
7 | 7 |
|
8 |
| -class ExtensionDtype(object): |
9 |
| - """A custom data type, to be paired with an ExtensionArray. |
10 |
| -
|
11 |
| - Notes |
12 |
| - ----- |
13 |
| - The interface includes the following abstract methods that must |
14 |
| - be implemented by subclasses: |
15 |
| -
|
16 |
| - * type |
17 |
| - * name |
18 |
| - * construct_from_string |
19 |
| -
|
20 |
| - This class does not inherit from 'abc.ABCMeta' for performance reasons. |
21 |
| - Methods and properties required by the interface raise |
22 |
| - ``pandas.errors.AbstractMethodError`` and no ``register`` method is |
23 |
| - provided for registering virtual subclasses. |
24 |
| - """ |
25 |
| - |
26 |
| - def __str__(self): |
27 |
| - return self.name |
| 8 | +class _DtypeOpsMixin(object): |
| 9 | + # Not all of pandas' extension dtypes are compatibile with |
| 10 | + # the new ExtensionArray interface. This means PandasExtensionDtype |
| 11 | + # can't subclass ExtensionDtype yet, as is_extension_array_dtype would |
| 12 | + # incorrectly say that these types are extension types. |
| 13 | + # |
| 14 | + # In the interim, we put methods that are shared between the two base |
| 15 | + # classes ExtensionDtype and PandasExtensionDtype here. Both those base |
| 16 | + # classes will inherit from this Mixin. Once everything is compatible, this |
| 17 | + # class's methods can be moved to ExtensionDtype and removed. |
28 | 18 |
|
29 | 19 | def __eq__(self, other):
|
30 | 20 | """Check whether 'other' is equal to self.
|
@@ -52,6 +42,74 @@ def __eq__(self, other):
|
52 | 42 | def __ne__(self, other):
|
53 | 43 | return not self.__eq__(other)
|
54 | 44 |
|
| 45 | + @property |
| 46 | + def names(self): |
| 47 | + # type: () -> Optional[List[str]] |
| 48 | + """Ordered list of field names, or None if there are no fields. |
| 49 | +
|
| 50 | + This is for compatibility with NumPy arrays, and may be removed in the |
| 51 | + future. |
| 52 | + """ |
| 53 | + return None |
| 54 | + |
| 55 | + @classmethod |
| 56 | + def is_dtype(cls, dtype): |
| 57 | + """Check if we match 'dtype'. |
| 58 | +
|
| 59 | + Parameters |
| 60 | + ---------- |
| 61 | + dtype : object |
| 62 | + The object to check. |
| 63 | +
|
| 64 | + Returns |
| 65 | + ------- |
| 66 | + is_dtype : bool |
| 67 | +
|
| 68 | + Notes |
| 69 | + ----- |
| 70 | + The default implementation is True if |
| 71 | +
|
| 72 | + 1. ``cls.construct_from_string(dtype)`` is an instance |
| 73 | + of ``cls``. |
| 74 | + 2. ``dtype`` is an object and is an instance of ``cls`` |
| 75 | + 3. ``dtype`` has a ``dtype`` attribute, and any of the above |
| 76 | + conditions is true for ``dtype.dtype``. |
| 77 | + """ |
| 78 | + dtype = getattr(dtype, 'dtype', dtype) |
| 79 | + |
| 80 | + if isinstance(dtype, np.dtype): |
| 81 | + return False |
| 82 | + elif dtype is None: |
| 83 | + return False |
| 84 | + elif isinstance(dtype, cls): |
| 85 | + return True |
| 86 | + try: |
| 87 | + return cls.construct_from_string(dtype) is not None |
| 88 | + except TypeError: |
| 89 | + return False |
| 90 | + |
| 91 | + |
| 92 | +class ExtensionDtype(_DtypeOpsMixin): |
| 93 | + """A custom data type, to be paired with an ExtensionArray. |
| 94 | +
|
| 95 | + Notes |
| 96 | + ----- |
| 97 | + The interface includes the following abstract methods that must |
| 98 | + be implemented by subclasses: |
| 99 | +
|
| 100 | + * type |
| 101 | + * name |
| 102 | + * construct_from_string |
| 103 | +
|
| 104 | + This class does not inherit from 'abc.ABCMeta' for performance reasons. |
| 105 | + Methods and properties required by the interface raise |
| 106 | + ``pandas.errors.AbstractMethodError`` and no ``register`` method is |
| 107 | + provided for registering virtual subclasses. |
| 108 | + """ |
| 109 | + |
| 110 | + def __str__(self): |
| 111 | + return self.name |
| 112 | + |
55 | 113 | @property
|
56 | 114 | def type(self):
|
57 | 115 | # type: () -> type
|
@@ -87,16 +145,6 @@ def name(self):
|
87 | 145 | """
|
88 | 146 | raise AbstractMethodError(self)
|
89 | 147 |
|
90 |
| - @property |
91 |
| - def names(self): |
92 |
| - # type: () -> Optional[List[str]] |
93 |
| - """Ordered list of field names, or None if there are no fields. |
94 |
| -
|
95 |
| - This is for compatibility with NumPy arrays, and may be removed in the |
96 |
| - future. |
97 |
| - """ |
98 |
| - return None |
99 |
| - |
100 | 148 | @classmethod
|
101 | 149 | def construct_from_string(cls, string):
|
102 | 150 | """Attempt to construct this type from a string.
|
@@ -128,39 +176,3 @@ def construct_from_string(cls, string):
|
128 | 176 | ... "'{}'".format(cls, string))
|
129 | 177 | """
|
130 | 178 | raise AbstractMethodError(cls)
|
131 |
| - |
132 |
| - @classmethod |
133 |
| - def is_dtype(cls, dtype): |
134 |
| - """Check if we match 'dtype'. |
135 |
| -
|
136 |
| - Parameters |
137 |
| - ---------- |
138 |
| - dtype : object |
139 |
| - The object to check. |
140 |
| -
|
141 |
| - Returns |
142 |
| - ------- |
143 |
| - is_dtype : bool |
144 |
| -
|
145 |
| - Notes |
146 |
| - ----- |
147 |
| - The default implementation is True if |
148 |
| -
|
149 |
| - 1. ``cls.construct_from_string(dtype)`` is an instance |
150 |
| - of ``cls``. |
151 |
| - 2. ``dtype`` is an object and is an instance of ``cls`` |
152 |
| - 3. ``dtype`` has a ``dtype`` attribute, and any of the above |
153 |
| - conditions is true for ``dtype.dtype``. |
154 |
| - """ |
155 |
| - dtype = getattr(dtype, 'dtype', dtype) |
156 |
| - |
157 |
| - if isinstance(dtype, np.dtype): |
158 |
| - return False |
159 |
| - elif dtype is None: |
160 |
| - return False |
161 |
| - elif isinstance(dtype, cls): |
162 |
| - return True |
163 |
| - try: |
164 |
| - return cls.construct_from_string(dtype) is not None |
165 |
| - except TypeError: |
166 |
| - return False |
|
0 commit comments