Skip to content

Commit a8d35ab

Browse files
committed
update the method of using PandasBatches.total_rows
1 parent db015d5 commit a8d35ab

File tree

2 files changed

+29
-14
lines changed

2 files changed

+29
-14
lines changed

bigframes/display/anywidget.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +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
26-
import bigframes.dataframe
27+
import bigframes.core.blocks
2728
import bigframes.display.html
2829

2930
# anywidget and traitlets are optional dependencies. We don't want the import of this
@@ -70,21 +71,24 @@ def __init__(self, dataframe: bigframes.dataframe.DataFrame):
7071
self._table_id = str(uuid.uuid4())
7172
self._all_data_loaded = False
7273
self._batch_iter: Optional[Iterator[pd.DataFrame]] = None
74+
self._batches: Optional[bigframes.core.blocks.PandasBatches] = None
7375
self._cached_batches: List[pd.DataFrame] = []
7476

7577
# Respect display options for initial page size
7678
initial_page_size = bigframes.options.display.max_rows
7779

7880
try:
7981
# Fetches initial data batches and row count for display.
80-
# `to_pandas_batches` provides an iterable of pandas DataFrames
81-
# and eagerly retrieves the total row count
82-
self._batches = dataframe.to_pandas_batches(
82+
batches = dataframe.to_pandas_batches(
8383
page_size=initial_page_size,
8484
)
85+
self._batches = cast(bigframes.core.blocks.PandasBatches, batches)
8586

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

9094
# Generates the initial HTML table content
@@ -93,7 +97,7 @@ def __init__(self, dataframe: bigframes.dataframe.DataFrame):
9397
except Exception:
9498
self.row_count = 0
9599
self.page_size = initial_page_size
96-
self._batches = iter([])
100+
self._batches = None
97101
self.table_html = ""
98102

99103
@functools.cached_property
@@ -177,7 +181,10 @@ def _get_next_batch(self) -> bool:
177181
def _batch_iterator(self) -> Iterator[pd.DataFrame]:
178182
"""Lazily initializes and returns the batch iterator."""
179183
if self._batch_iter is None:
180-
self._batch_iter = iter(self._batches)
184+
if self._batches is None:
185+
self._batch_iter = iter([])
186+
else:
187+
self._batch_iter = iter(self._batches)
181188
return self._batch_iter
182189

183190
@property
@@ -189,7 +196,8 @@ def _cached_data(self) -> pd.DataFrame:
189196

190197
def _reset_batches_for_new_page_size(self):
191198
"""Reset the batch iterator when page size changes."""
192-
self._batches = self._dataframe._to_pandas_batches(page_size=self.page_size)
199+
batches = self._dataframe.to_pandas_batches(page_size=self.page_size)
200+
self._batches = typing.cast(bigframes.core.blocks.PandasBatches, batches)
193201
self._cached_batches = []
194202
self._batch_iter = None
195203
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)