|
23 | 23 | import re |
24 | 24 | import sys |
25 | 25 | import textwrap |
| 26 | +import traceback |
26 | 27 | import typing |
27 | 28 | from typing import ( |
28 | 29 | Any, |
@@ -782,9 +783,9 @@ def __repr__(self) -> str: |
782 | 783 |
|
783 | 784 | opts = bigframes.options.display |
784 | 785 | max_results = opts.max_rows |
785 | | - |
786 | | - # Only deferred mode shows dry run |
787 | | - if opts.repr_mode in ("deferred"): |
| 786 | + # anywdiget mode uses the same display logic as the "deferred" mode |
| 787 | + # for faster execution |
| 788 | + if opts.repr_mode in ("deferred", "anywidget"): |
788 | 789 | return formatter.repr_query_job(self._compute_dry_run()) |
789 | 790 |
|
790 | 791 | # TODO(swast): pass max_columns and get the true column count back. Maybe |
@@ -850,27 +851,27 @@ def _repr_html_(self) -> str: |
850 | 851 |
|
851 | 852 | if opts.repr_mode == "anywidget": |
852 | 853 | try: |
853 | | - import anywidget # noqa: F401 |
854 | 854 | from IPython.display import display as ipython_display |
855 | | - import traitlets # noqa: F401 |
856 | 855 |
|
857 | 856 | from bigframes import display |
858 | | - except ImportError: |
| 857 | + |
| 858 | + # Always create a new widget instance for each display call |
| 859 | + # This ensures that each cell gets its own widget and prevents |
| 860 | + # unintended sharing between cells |
| 861 | + widget = display.TableWidget(df.copy()) |
| 862 | + |
| 863 | + ipython_display(widget) |
| 864 | + return "" # Return empty string since we used display() |
| 865 | + |
| 866 | + except (AttributeError, ValueError, ImportError): |
| 867 | + # Fallback if anywidget is not available |
859 | 868 | warnings.warn( |
860 | | - "anywidget or its dependencies are not installed. " |
| 869 | + "Anywidget mode is not available. " |
861 | 870 | "Please `pip install anywidget traitlets` or `pip install 'bigframes[anywidget]'` to use interactive tables. " |
862 | | - "Falling back to deferred mode." |
| 871 | + f"Falling back to deferred mode. Error: {traceback.format_exc()}" |
863 | 872 | ) |
864 | 873 | return formatter.repr_query_job(self._compute_dry_run()) |
865 | 874 |
|
866 | | - # Always create a new widget instance for each display call |
867 | | - # This ensures that each cell gets its own widget and prevents |
868 | | - # unintended sharing between cells |
869 | | - widget = display.TableWidget(df.copy()) |
870 | | - |
871 | | - ipython_display(widget) |
872 | | - return "" # Return empty string since we used display() |
873 | | - |
874 | 875 | # Continue with regular HTML rendering for non-anywidget modes |
875 | 876 | # TODO(swast): pass max_columns and get the true column count back. Maybe |
876 | 877 | # get 1 more column than we have requested so that pandas can add the |
@@ -2563,33 +2564,25 @@ def sort_index( |
2563 | 2564 | ) -> None: |
2564 | 2565 | ... |
2565 | 2566 |
|
| 2567 | + @validations.requires_index |
2566 | 2568 | def sort_index( |
2567 | 2569 | self, |
2568 | 2570 | *, |
2569 | | - axis: Union[int, str] = 0, |
2570 | 2571 | ascending: bool = True, |
2571 | 2572 | inplace: bool = False, |
2572 | 2573 | na_position: Literal["first", "last"] = "last", |
2573 | 2574 | ) -> Optional[DataFrame]: |
2574 | | - if utils.get_axis_number(axis) == 0: |
2575 | | - if na_position not in ["first", "last"]: |
2576 | | - raise ValueError("Param na_position must be one of 'first' or 'last'") |
2577 | | - na_last = na_position == "last" |
2578 | | - index_columns = self._block.index_columns |
2579 | | - ordering = [ |
2580 | | - order.ascending_over(column, na_last) |
2581 | | - if ascending |
2582 | | - else order.descending_over(column, na_last) |
2583 | | - for column in index_columns |
2584 | | - ] |
2585 | | - block = self._block.order_by(ordering) |
2586 | | - else: # axis=1 |
2587 | | - _, indexer = self.columns.sort_values( |
2588 | | - return_indexer=True, ascending=ascending, na_position=na_position # type: ignore |
2589 | | - ) |
2590 | | - block = self._block.select_columns( |
2591 | | - [self._block.value_columns[i] for i in indexer] |
2592 | | - ) |
| 2575 | + if na_position not in ["first", "last"]: |
| 2576 | + raise ValueError("Param na_position must be one of 'first' or 'last'") |
| 2577 | + na_last = na_position == "last" |
| 2578 | + index_columns = self._block.index_columns |
| 2579 | + ordering = [ |
| 2580 | + order.ascending_over(column, na_last) |
| 2581 | + if ascending |
| 2582 | + else order.descending_over(column, na_last) |
| 2583 | + for column in index_columns |
| 2584 | + ] |
| 2585 | + block = self._block.order_by(ordering) |
2593 | 2586 | if inplace: |
2594 | 2587 | self._set_block(block) |
2595 | 2588 | return None |
|
0 commit comments