Skip to content

Commit df85824

Browse files
committed
update the method of using PandasBatches.total_rows
1 parent b3aab68 commit df85824

File tree

2 files changed

+29
-13
lines changed

2 files changed

+29
-13
lines changed

bigframes/display/anywidget.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@
1717
from importlib import resources
1818
import functools
1919
import math
20-
from typing import Any, Dict, Iterator, List, Optional, Type
20+
import typing
21+
from typing import Any, cast, Dict, Iterator, List, Optional, Type
2122
import uuid
2223

2324
import pandas as pd
2425

2526
import bigframes
27+
import bigframes.core.blocks
2628

2729
# anywidget and traitlets are optional dependencies. We don't want the import of this
2830
# module to fail if they aren't installed, though. Instead, we try to limit the surface that
@@ -68,21 +70,24 @@ def __init__(self, dataframe: bigframes.dataframe.DataFrame):
6870
self._table_id = str(uuid.uuid4())
6971
self._all_data_loaded = False
7072
self._batch_iter: Optional[Iterator[pd.DataFrame]] = None
73+
self._batches: Optional[bigframes.core.blocks.PandasBatches] = None
7174
self._cached_batches: List[pd.DataFrame] = []
7275

7376
# Respect display options for initial page size
7477
initial_page_size = bigframes.options.display.max_rows
7578

7679
try:
7780
# Fetches initial data batches and row count for display.
78-
# `to_pandas_batches` provides an iterable of pandas DataFrames
79-
# and eagerly retrieves the total row count
80-
self._batches = dataframe.to_pandas_batches(
81+
batches = dataframe.to_pandas_batches(
8182
page_size=initial_page_size,
8283
)
84+
self._batches = cast(bigframes.core.blocks.PandasBatches, batches)
8385

84-
# Access the total_rows property directly
85-
self.row_count = self._batches.total_rows or 0
86+
# Use total_rows if available, otherwise default to 0.
87+
if self._batches:
88+
self.row_count = self._batches.total_rows or 0
89+
else:
90+
self.row_count = 0
8691
self.page_size = initial_page_size
8792

8893
# Generates the initial HTML table content
@@ -91,7 +96,7 @@ def __init__(self, dataframe: bigframes.dataframe.DataFrame):
9196
except Exception:
9297
self.row_count = 0
9398
self.page_size = initial_page_size
94-
self._batches = iter([])
99+
self._batches = None
95100
self.table_html = ""
96101

97102
@functools.cached_property
@@ -175,7 +180,10 @@ def _get_next_batch(self) -> bool:
175180
def _batch_iterator(self) -> Iterator[pd.DataFrame]:
176181
"""Lazily initializes and returns the batch iterator."""
177182
if self._batch_iter is None:
178-
self._batch_iter = iter(self._batches)
183+
if self._batches is None:
184+
self._batch_iter = iter([])
185+
else:
186+
self._batch_iter = iter(self._batches)
179187
return self._batch_iter
180188

181189
@property
@@ -187,7 +195,8 @@ def _cached_data(self) -> pd.DataFrame:
187195

188196
def _reset_batches_for_new_page_size(self):
189197
"""Reset the batch iterator when page size changes."""
190-
self._batches = self._dataframe.to_pandas_batches(page_size=self.page_size)
198+
batches = self._dataframe.to_pandas_batches(page_size=self.page_size)
199+
self._batches = typing.cast(bigframes.core.blocks.PandasBatches, batches)
191200
self._cached_batches = []
192201
self._batch_iter = None
193202
self._all_data_loaded = False

tests/system/small/test_anywidget.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -476,14 +476,21 @@ def test_widget_row_count_should_be_immutable_after_creation(
476476
assert widget.row_count == initial_row_count
477477

478478

479+
class FaultyIterator:
480+
def __iter__(self):
481+
return self
482+
483+
def __next__(self):
484+
raise ValueError("Simulated read error")
485+
486+
479487
@pytest.mark.parametrize(
480488
"total_rows_param, arrow_batches_param",
481489
[
482-
# Corresponds to mock_execute_total_rows_is_none
490+
# Case 1: total_rows is None, which should be handled gracefully.
483491
(None, []),
484-
# Corresponds to mock_execute_batches_are_invalid (assuming empty list
485-
# for invalid batches for now)
486-
(100, []),
492+
# Case 2: Batches are invalid and will raise an error during iteration.
493+
(100, FaultyIterator()),
487494
],
488495
ids=[
489496
"when_total_rows_is_None",

0 commit comments

Comments
 (0)