Skip to content

Commit 791335f

Browse files
gforsythkszucs
authored andcommitted
feat: add experimental decorator
1 parent 3a88170 commit 791335f

File tree

4 files changed

+106
-8
lines changed

4 files changed

+106
-8
lines changed

ibis/backends/base/__init__.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ def _table_or_column_schema(expr: ir.Expr) -> sch.Schema:
231231
# ColumnExpr has no schema method, define single-column schema
232232
return sch.schema([(expr.get_name(), expr.type())])
233233

234+
@util.experimental
234235
def to_pyarrow(
235236
self,
236237
expr: ir.Expr,
@@ -239,6 +240,26 @@ def to_pyarrow(
239240
limit: int | str | None = None,
240241
**kwargs: Any,
241242
) -> pa.Table:
243+
"""Execute expression and return results in as a pyarrow table.
244+
245+
This method is eager and will execute the associated expression
246+
immediately.
247+
248+
Parameters
249+
----------
250+
expr
251+
Ibis expression to export to pyarrow
252+
params
253+
Mapping of scalar parameter expressions to value.
254+
limit
255+
An integer to effect a specific row limit. A value of `None` means
256+
"no limit". The default is in `ibis/config.py`.
257+
258+
Returns
259+
-------
260+
Table
261+
A pyarrow table holding the results of the executed expression.
262+
"""
242263
pa = self._import_pyarrow()
243264
try:
244265
# Can't construct an array from record batches
@@ -269,6 +290,7 @@ def to_pyarrow(
269290
else:
270291
raise ValueError
271292

293+
@util.experimental
272294
def to_pyarrow_batches(
273295
self,
274296
expr: ir.Expr,
@@ -278,6 +300,29 @@ def to_pyarrow_batches(
278300
chunk_size: int = 1_000_000,
279301
**kwargs: Any,
280302
) -> pa.RecordBatchReader:
303+
"""Execute expression and return results in an iterator of pyarrow
304+
record batches.
305+
306+
This method is eager and will execute the associated expression
307+
immediately.
308+
309+
Parameters
310+
----------
311+
expr
312+
Ibis expression to export to pyarrow
313+
limit
314+
An integer to effect a specific row limit. A value of `None` means
315+
"no limit". The default is in `ibis/config.py`.
316+
params
317+
Mapping of scalar parameter expressions to value.
318+
chunk_size
319+
Number of rows in each returned record batch.
320+
321+
Returns
322+
-------
323+
record_batches
324+
An iterator of pyarrow record batches.
325+
"""
281326
raise NotImplementedError
282327

283328

ibis/backends/base/sql/__init__.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ def _cursor_batches(
158158
while batch := cursor.fetchmany(chunk_size):
159159
yield batch
160160

161+
@util.experimental
161162
def to_pyarrow_batches(
162163
self,
163164
expr: ir.Expr,
@@ -167,6 +168,29 @@ def to_pyarrow_batches(
167168
chunk_size: int = 1_000_000,
168169
**kwargs: Any,
169170
) -> pa.RecordBatchReader:
171+
"""Execute expression and return results in an iterator of pyarrow
172+
record batches.
173+
174+
This method is eager and will execute the associated expression
175+
immediately.
176+
177+
Parameters
178+
----------
179+
expr
180+
Ibis expression to export to pyarrow
181+
limit
182+
An integer to effect a specific row limit. A value of `None` means
183+
"no limit". The default is in `ibis/config.py`.
184+
params
185+
Mapping of scalar parameter expressions to value.
186+
chunk_size
187+
Number of rows in each returned record batch.
188+
189+
Returns
190+
-------
191+
record_batches
192+
An iterator of pyarrow record batches.
193+
"""
170194
pa = self._import_pyarrow()
171195

172196
from ibis.backends.pyarrow.datatypes import ibis_to_pyarrow_struct

ibis/expr/types/core.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from ibis.common.grounds import Immutable
1414
from ibis.config import _default_backend, options
1515
from ibis.expr.typing import TimeContext
16-
from ibis.util import UnnamedMarker
16+
from ibis.util import UnnamedMarker, experimental
1717

1818
if TYPE_CHECKING:
1919
import pyarrow as pa
@@ -308,6 +308,7 @@ def compile(
308308
self, limit=limit, timecontext=timecontext, params=params
309309
)
310310

311+
@experimental
311312
def to_pyarrow_batches(
312313
self,
313314
*,
@@ -319,8 +320,8 @@ def to_pyarrow_batches(
319320
"""Execute expression and return results in an iterator of pyarrow
320321
record batches.
321322
322-
**Warning**: This method is eager and will execute the associated
323-
expression immediately. This API is experimental and subject to change.
323+
This method is eager and will execute the associated expression
324+
immediately.
324325
325326
Parameters
326327
----------
@@ -345,6 +346,7 @@ def to_pyarrow_batches(
345346
**kwargs,
346347
)
347348

349+
@experimental
348350
def to_pyarrow(
349351
self,
350352
*,
@@ -354,17 +356,16 @@ def to_pyarrow(
354356
) -> pa.Table:
355357
"""Execute expression and return results in as a pyarrow table.
356358
357-
**Warning**: This method is eager and will execute the associated
358-
expression immediately. This API is experimental and subject to change.
359-
359+
This method is eager and will execute the associated expression
360+
immediately.
360361
361362
Parameters
362363
----------
364+
params
365+
Mapping of scalar parameter expressions to value.
363366
limit
364367
An integer to effect a specific row limit. A value of `None` means
365368
"no limit". The default is in `ibis/config.py`.
366-
params
367-
Mapping of scalar parameter expressions to value.
368369
369370
Returns
370371
-------

ibis/util.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,34 @@ def wrapper(*args, **kwargs):
448448
return decorator
449449

450450

451+
def experimental(func):
452+
"""Decorate experimental function to add warning about potential API
453+
instability in docstring."""
454+
455+
msg = "This API is experimental and subject to change."
456+
457+
if docstr := func.__doc__:
458+
preamble, *rest = docstr.split("\n\n", maxsplit=1)
459+
460+
leading_spaces = " " * sum(
461+
1
462+
for _ in itertools.takewhile(str.isspace, rest[0] if rest else [])
463+
)
464+
465+
warning_doc = f'{leading_spaces}!!! warning "{msg}"'
466+
467+
docstr = "\n\n".join([preamble, warning_doc, *rest])
468+
else:
469+
docstr = f'!!! warning "{msg}"'
470+
func.__doc__ = docstr
471+
472+
@functools.wraps(func)
473+
def wrapper(*args, **kwargs):
474+
return func(*args, **kwargs)
475+
476+
return wrapper
477+
478+
451479
class ToFrame(abc.ABC):
452480
"""Interface for in-memory objects that can be converted to a DataFrame."""
453481

0 commit comments

Comments
 (0)