Skip to content

Commit 4222027

Browse files
committed
feat: remove unsafe while loop
1 parent eff882d commit 4222027

File tree

1 file changed

+27
-52
lines changed

1 file changed

+27
-52
lines changed

bigframes/display/anywidget.py

Lines changed: 27 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,10 @@ def __init__(self, dataframe: bigframes.dataframe.DataFrame):
9696
# Initialize attributes that might be needed by observers first
9797
self._table_id = str(uuid.uuid4())
9898
self._all_data_loaded = False
99-
self._batch_iter: Iterator[pd.DataFrame] | None = None
99+
self._batch_iter: Optional[Iterator[pd.DataFrame]] = None
100100
self._cached_batches: list[pd.DataFrame] = []
101101
self._last_sort_state: Optional[_SortState] = None
102-
self._setting_html_lock = threading.Lock()
103-
self._setting_html = False
102+
self._setting_html_lock = threading.RLock()
104103

105104
# respect display options for initial page size
106105
initial_page_size = bigframes.options.display.max_rows
@@ -270,18 +269,11 @@ def _reset_batches_for_new_page_size(self) -> None:
270269
def _set_table_html(self) -> None:
271270
"""Sets the current html data based on the current page and page size."""
272271
with self._setting_html_lock:
273-
if self._setting_html:
274-
return
275-
self._setting_html = True
276-
277-
try:
278272
if self._error_message:
279-
with self._setting_html_lock:
280-
self.table_html = (
281-
f"<div class='bigframes-error-message'>"
282-
f"{self._error_message}</div>"
283-
)
284-
self._setting_html = False
273+
self.table_html = (
274+
f"<div class='bigframes-error-message'>"
275+
f"{self._error_message}</div>"
276+
)
285277
return
286278

287279
# Apply sorting if a column is selected
@@ -305,22 +297,6 @@ def _set_table_html(self) -> None:
305297
)
306298
self.page = 0 # Reset to first page
307299

308-
page_data = self._get_page_data()
309-
page_data = self._prepare_dataframe_for_display(page_data)
310-
311-
# Generate HTML table
312-
self.table_html = bigframes.display.html.render_html(
313-
dataframe=page_data,
314-
table_id=f"table-{self._table_id}",
315-
)
316-
finally:
317-
with self._setting_html_lock:
318-
self._setting_html = False
319-
320-
def _get_page_data(self) -> pd.DataFrame:
321-
"""Get the data for the current page, handling unknown row count."""
322-
# This loop is to handle auto-correction of page number when row count is unknown
323-
while True:
324300
start = self.page * self.page_size
325301
end = start + self.page_size
326302

@@ -344,31 +320,30 @@ def _get_page_data(self) -> pd.DataFrame:
344320
# Calculate the last valid page (zero-indexed)
345321
total_rows = len(cached_data)
346322
last_valid_page = max(0, math.ceil(total_rows / self.page_size) - 1)
347-
# Navigate back to the last valid page
323+
# Navigate back to the last valid page.
324+
# This triggers the observer, which will re-enter _set_table_html (allowed by RLock).
348325
self.page = last_valid_page
349-
# Continue the loop to re-calculate page data
350-
continue
351-
352-
# If page is valid, break out of the loop.
353-
return page_data
354-
355-
def _prepare_dataframe_for_display(self, page_data: pd.DataFrame) -> pd.DataFrame:
356-
"""Prepare the DataFrame for display, handling index and row numbers."""
357-
start = self.page * self.page_size
358-
# Handle index display
359-
if self._dataframe._block.has_index:
360-
is_unnamed_single_index = page_data.index.name is None and not isinstance(
361-
page_data.index, pd.MultiIndex
362-
)
363-
page_data = page_data.reset_index()
364-
if is_unnamed_single_index and "index" in page_data.columns:
365-
page_data.rename(columns={"index": ""}, inplace=True)
326+
return
366327

367-
# Default index - include as "Row" column if no index was present originally
368-
if not self._dataframe._block.has_index:
369-
page_data.insert(0, "Row", range(start + 1, start + len(page_data) + 1))
328+
# Handle index display
329+
if self._dataframe._block.has_index:
330+
is_unnamed_single_index = (
331+
page_data.index.name is None
332+
and not isinstance(page_data.index, pd.MultiIndex)
333+
)
334+
page_data = page_data.reset_index()
335+
if is_unnamed_single_index and "index" in page_data.columns:
336+
page_data.rename(columns={"index": ""}, inplace=True)
370337

371-
return page_data
338+
# Default index - include as "Row" column if no index was present originally
339+
if not self._dataframe._block.has_index:
340+
page_data.insert(0, "Row", range(start + 1, start + len(page_data) + 1))
341+
342+
# Generate HTML table
343+
self.table_html = bigframes.display.html.render_html(
344+
dataframe=page_data,
345+
table_id=f"table-{self._table_id}",
346+
)
372347

373348
@traitlets.observe("sort_column", "sort_ascending")
374349
def _sort_changed(self, _change: dict[str, Any]):

0 commit comments

Comments
 (0)