Skip to content

Commit bd4f6f2

Browse files
committed
Explicitly mark abstract methods in spec
Signed-off-by: Vasily Litvinov <vasilij.n.litvinov@intel.com>
1 parent 49456c2 commit bd4f6f2

File tree

1 file changed

+30
-4
lines changed

1 file changed

+30
-4
lines changed

pandas/api/exchange/dataframe_protocol.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from typing import Tuple, Optional, Dict, Any, Iterable, Sequence, TypedDict
22
import enum
3+
from abc import ABC, abstractmethod
34

45
class DlpackDeviceType(enum.IntEnum):
56
CPU = 1
@@ -20,7 +21,7 @@ class DtypeKind(enum.IntEnum):
2021
DATETIME = 22
2122
CATEGORICAL = 23
2223

23-
class ColumnNullType:
24+
class ColumnNullType(enum.IntEnum):
2425
NON_NULLABLE = 0
2526
USE_NAN = 1
2627
USE_SENTINEL = 2
@@ -42,7 +43,7 @@ class ColumnBuffers(TypedDict):
4243
# an associated offsets buffer
4344

4445

45-
class Buffer:
46+
class Buffer(ABC):
4647
"""
4748
Data in the buffer is guaranteed to be contiguous in memory.
4849
Note that there is no dtype attribute present, a buffer can be thought of
@@ -56,19 +57,22 @@ class Buffer:
5657
"""
5758

5859
@property
60+
@abstractmethod
5961
def bufsize(self) -> int:
6062
"""
6163
Buffer size in bytes.
6264
"""
6365
pass
6466

6567
@property
68+
@abstractmethod
6669
def ptr(self) -> int:
6770
"""
6871
Pointer to start of the buffer as an integer.
6972
"""
7073
pass
7174

75+
@abstractmethod
7276
def __dlpack__(self):
7377
"""
7478
Produce DLPack capsule (see array API standard).
@@ -80,6 +84,7 @@ def __dlpack__(self):
8084
"""
8185
raise NotImplementedError("__dlpack__")
8286

87+
@abstractmethod
8388
def __dlpack_device__(self) -> Tuple[DlpackDeviceType, int]:
8489
"""
8590
Device type and device ID for where the data in the buffer resides.
@@ -89,7 +94,7 @@ def __dlpack_device__(self) -> Tuple[DlpackDeviceType, int]:
8994
pass
9095

9196

92-
class Column:
97+
class Column(ABC):
9398
"""
9499
A column object, with only the methods and properties required by the
95100
interchange protocol defined.
@@ -127,6 +132,7 @@ class Column:
127132
"""
128133

129134
@property
135+
@abstractmethod
130136
def size(self) -> Optional[int]:
131137
"""
132138
Size of the column, in elements.
@@ -136,6 +142,7 @@ def size(self) -> Optional[int]:
136142
pass
137143

138144
@property
145+
@abstractmethod
139146
def offset(self) -> int:
140147
"""
141148
Offset of first element.
@@ -146,6 +153,7 @@ def offset(self) -> int:
146153
pass
147154

148155
@property
156+
@abstractmethod
149157
def dtype(self) -> Tuple[DtypeKind, int, str, str]:
150158
"""
151159
Dtype description as a tuple ``(kind, bit-width, format string, endianness)``.
@@ -175,6 +183,7 @@ def dtype(self) -> Tuple[DtypeKind, int, str, str]:
175183
pass
176184

177185
@property
186+
@abstractmethod
178187
def describe_categorical(self) -> Tuple[bool, bool, dict]:
179188
"""
180189
If the dtype is categorical, there are two options:
@@ -194,6 +203,7 @@ def describe_categorical(self) -> Tuple[bool, bool, dict]:
194203
pass
195204

196205
@property
206+
@abstractmethod
197207
def describe_null(self) -> Tuple[ColumnNullType, Any]:
198208
"""
199209
Return the missing value (or "null") representation the column dtype
@@ -205,6 +215,7 @@ def describe_null(self) -> Tuple[ColumnNullType, Any]:
205215
pass
206216

207217
@property
218+
@abstractmethod
208219
def null_count(self) -> Optional[int]:
209220
"""
210221
Number of null elements, if known.
@@ -213,25 +224,29 @@ def null_count(self) -> Optional[int]:
213224
pass
214225

215226
@property
227+
@abstractmethod
216228
def metadata(self) -> Dict[str, Any]:
217229
"""
218230
The metadata for the column. See `DataFrame.metadata` for more details.
219231
"""
220232
pass
221233

234+
@abstractmethod
222235
def num_chunks(self) -> int:
223236
"""
224237
Return the number of chunks the column consists of.
225238
"""
226239
pass
227240

241+
@abstractmethod
228242
def get_chunks(self, n_chunks : Optional[int] = None) -> Iterable["Column"]:
229243
"""
230244
Return an iterator yielding the chunks.
231245
See `DataFrame.get_chunks` for details on ``n_chunks``.
232246
"""
233247
pass
234248

249+
@abstractmethod
235250
def get_buffers(self) -> ColumnBuffers:
236251
"""
237252
Return a dictionary containing the underlying buffers.
@@ -261,7 +276,7 @@ def get_buffers(self) -> ColumnBuffers:
261276
# pass
262277

263278

264-
class DataFrame:
279+
class DataFrame(ABC):
265280
"""
266281
A data frame class, with only the methods required by the interchange
267282
protocol defined.
@@ -276,6 +291,7 @@ class DataFrame:
276291
version = 0 # version of the protocol
277292

278293
@property
294+
@abstractmethod
279295
def metadata(self) -> Dict[str, Any]:
280296
"""
281297
The metadata for the data frame, as a dictionary with string keys. The
@@ -288,12 +304,14 @@ def metadata(self) -> Dict[str, Any]:
288304
"""
289305
pass
290306

307+
@abstractmethod
291308
def num_columns(self) -> int:
292309
"""
293310
Return the number of columns in the DataFrame.
294311
"""
295312
pass
296313

314+
@abstractmethod
297315
def num_rows(self) -> Optional[int]:
298316
# TODO: not happy with Optional, but need to flag it may be expensive
299317
# why include it if it may be None - what do we expect consumers
@@ -303,48 +321,56 @@ def num_rows(self) -> Optional[int]:
303321
"""
304322
pass
305323

324+
@abstractmethod
306325
def num_chunks(self) -> int:
307326
"""
308327
Return the number of chunks the DataFrame consists of.
309328
"""
310329
pass
311330

331+
@abstractmethod
312332
def column_names(self) -> Iterable[str]:
313333
"""
314334
Return an iterator yielding the column names.
315335
"""
316336
pass
317337

338+
@abstractmethod
318339
def get_column(self, i: int) -> Column:
319340
"""
320341
Return the column at the indicated position.
321342
"""
322343
pass
323344

345+
@abstractmethod
324346
def get_column_by_name(self, name: str) -> Column:
325347
"""
326348
Return the column whose name is the indicated name.
327349
"""
328350
pass
329351

352+
@abstractmethod
330353
def get_columns(self) -> Iterable[Column]:
331354
"""
332355
Return an iterator yielding the columns.
333356
"""
334357
pass
335358

359+
@abstractmethod
336360
def select_columns(self, indices: Sequence[int]) -> "DataFrame":
337361
"""
338362
Create a new DataFrame by selecting a subset of columns by index.
339363
"""
340364
pass
341365

366+
@abstractmethod
342367
def select_columns_by_name(self, names: Sequence[str]) -> "DataFrame":
343368
"""
344369
Create a new DataFrame by selecting a subset of columns by name.
345370
"""
346371
pass
347372

373+
@abstractmethod
348374
def get_chunks(self, n_chunks : Optional[int] = None) -> Iterable["DataFrame"]:
349375
"""
350376
Return an iterator yielding the chunks.

0 commit comments

Comments
 (0)