Skip to content
This repository was archived by the owner on Apr 1, 2026. It is now read-only.

Commit f0e86aa

Browse files
committed
Merge branch 'shuowei-anywidget-disable-future-warnings' into shuowei-anywidget-disable-warning
# Conflicts: # bigframes/display/anywidget.py # bigframes/formatting_helpers.py
2 parents 647927f + ee26056 commit f0e86aa

File tree

9 files changed

+265
-194
lines changed

9 files changed

+265
-194
lines changed

bigframes/core/compile/polars/compiler.py

Lines changed: 1 addition & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import dataclasses
1717
import functools
1818
import itertools
19-
import json
2019
from typing import cast, Literal, Optional, Sequence, Tuple, Type, TYPE_CHECKING
2120

2221
import pandas as pd
@@ -430,68 +429,7 @@ def _(self, op: ops.ScalarOp, input: pl.Expr) -> pl.Expr:
430429
@compile_op.register(json_ops.JSONDecode)
431430
def _(self, op: ops.ScalarOp, input: pl.Expr) -> pl.Expr:
432431
assert isinstance(op, json_ops.JSONDecode)
433-
target_dtype = _bigframes_dtype_to_polars_dtype(op.to_type)
434-
if op.safe:
435-
# Polars does not support safe JSON decoding (returning null on failure).
436-
# We use map_elements to provide safe JSON decoding.
437-
def safe_decode(val):
438-
if val is None:
439-
return None
440-
try:
441-
decoded = json.loads(val)
442-
except Exception:
443-
return None
444-
445-
if decoded is None:
446-
return None
447-
448-
if op.to_type == bigframes.dtypes.INT_DTYPE:
449-
if type(decoded) is bool:
450-
return None
451-
if isinstance(decoded, int):
452-
return decoded
453-
if isinstance(decoded, float):
454-
if decoded.is_integer():
455-
return int(decoded)
456-
if isinstance(decoded, str):
457-
try:
458-
return int(decoded)
459-
except Exception:
460-
pass
461-
return None
462-
463-
if op.to_type == bigframes.dtypes.FLOAT_DTYPE:
464-
if type(decoded) is bool:
465-
return None
466-
if isinstance(decoded, (int, float)):
467-
return float(decoded)
468-
if isinstance(decoded, str):
469-
try:
470-
return float(decoded)
471-
except Exception:
472-
pass
473-
return None
474-
475-
if op.to_type == bigframes.dtypes.BOOL_DTYPE:
476-
if isinstance(decoded, bool):
477-
return decoded
478-
if isinstance(decoded, str):
479-
if decoded.lower() == "true":
480-
return True
481-
if decoded.lower() == "false":
482-
return False
483-
return None
484-
485-
if op.to_type == bigframes.dtypes.STRING_DTYPE:
486-
if isinstance(decoded, str):
487-
return decoded
488-
return None
489-
490-
return decoded
491-
492-
return input.map_elements(safe_decode, return_dtype=target_dtype)
493-
494-
return input.str.json_decode(target_dtype)
432+
return input.str.json_decode(_DTYPE_MAPPING[op.to_type])
495433

496434
@compile_op.register(arr_ops.ToArrayOp)
497435
def _(self, op: ops.ToArrayOp, *inputs: pl.Expr) -> pl.Expr:

bigframes/core/compile/polars/lowering.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ def _lower_cast(cast_op: ops.AsTypeOp, arg: expression.Expression):
391391
return arg
392392

393393
if arg.output_type == dtypes.JSON_DTYPE:
394-
return json_ops.JSONDecode(cast_op.to_type, safe=cast_op.safe).as_expr(arg)
394+
return json_ops.JSONDecode(cast_op.to_type).as_expr(arg)
395395
if (
396396
arg.output_type == dtypes.STRING_DTYPE
397397
and cast_op.to_type == dtypes.DATETIME_DTYPE

bigframes/display/anywidget.py

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -112,26 +112,32 @@ def __init__(self, dataframe: bigframes.dataframe.DataFrame):
112112
self.page_size = initial_page_size
113113
self.max_columns = initial_max_columns
114114

115-
# TODO(b/469861913): Nested columns from structs (e.g., 'struct_col.name') are not currently sortable.
116-
# TODO(b/463754889): Support non-string column labels for sorting.
117-
if all(isinstance(col, str) for col in dataframe.columns):
118-
with warnings.catch_warnings():
119-
warnings.simplefilter("ignore", bigframes.exceptions.JSONDtypeWarning)
120-
warnings.simplefilter("ignore", category=FutureWarning)
121-
self.orderable_columns = [
122-
str(col_name)
123-
for col_name, dtype in dataframe.dtypes.items()
124-
if dtypes.is_orderable(dtype)
125-
]
126-
else:
127-
self.orderable_columns = []
115+
self.orderable_columns = self._get_orderable_columns(dataframe)
128116

129117
self._initial_load()
130118

131119
# Signals to the frontend that the initial data load is complete.
132120
# Also used as a guard to prevent observers from firing during initialization.
133121
self._initial_load_complete = True
134122

123+
def _get_orderable_columns(
124+
self, dataframe: bigframes.dataframe.DataFrame
125+
) -> list[str]:
126+
"""Determine which columns can be used for client-side sorting."""
127+
# TODO(b/469861913): Nested columns from structs (e.g., 'struct_col.name') are not currently sortable.
128+
# TODO(b/463754889): Support non-string column labels for sorting.
129+
if not all(isinstance(col, str) for col in dataframe.columns):
130+
return []
131+
132+
with warnings.catch_warnings():
133+
warnings.simplefilter("ignore", bigframes.exceptions.JSONDtypeWarning)
134+
warnings.simplefilter("ignore", category=FutureWarning)
135+
return [
136+
str(col_name)
137+
for col_name, dtype in dataframe.dtypes.items()
138+
if dtypes.is_orderable(dtype)
139+
]
140+
135141
def _initial_load(self) -> None:
136142
"""Get initial data and row count."""
137143
# obtain the row counts
@@ -279,7 +285,8 @@ def _reset_batch_cache(self) -> None:
279285

280286
def _reset_batches_for_new_page_size(self) -> None:
281287
"""Reset the batch iterator when page size changes."""
282-
self._batches = self._dataframe.to_pandas_batches(page_size=self.page_size)
288+
with bigframes.option_context("display.progress_bar", None):
289+
self._batches = self._dataframe.to_pandas_batches(page_size=self.page_size)
283290

284291
self._reset_batch_cache()
285292

bigframes/formatting_helpers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ def progress_callback(
213213
)
214214
elif progress_bar == "terminal":
215215
if isinstance(event, bigframes.core.events.ExecutionStarted):
216+
# No action needed as "Starting execution." is too noisy for terminal.
216217
pass
217218
elif isinstance(event, bigframes.core.events.BigQuerySentEvent):
218219
message = render_bqquery_sent_event_plaintext(event)

bigframes/operations/json_ops.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,6 @@ def output_type(self, *input_types):
220220
class JSONDecode(base_ops.UnaryOp):
221221
name: typing.ClassVar[str] = "json_decode"
222222
to_type: dtypes.Dtype
223-
safe: bool = False
224223

225224
def output_type(self, *input_types):
226225
input_type = input_types[0]

bigframes/session/polars_executor.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
numeric_ops,
3535
string_ops,
3636
)
37-
import bigframes.operations.json_ops as json_ops
3837
from bigframes.session import executor, semi_executor
3938

4039
if TYPE_CHECKING:
@@ -95,7 +94,6 @@
9594
string_ops.EndsWithOp,
9695
string_ops.StrContainsOp,
9796
string_ops.StrContainsRegexOp,
98-
json_ops.JSONDecode,
9997
)
10098
_COMPATIBLE_AGG_OPS = (
10199
agg_ops.SizeOp,

0 commit comments

Comments
 (0)