Skip to content

Commit a474606

Browse files
committed
refactor: move create_text_representation to plaintext.py
1 parent 945616c commit a474606

File tree

4 files changed

+98
-64
lines changed

4 files changed

+98
-64
lines changed

bigframes/dataframe.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -796,9 +796,9 @@ def __repr__(self) -> str:
796796
)
797797

798798
self._set_internal_query_job(query_job)
799-
from bigframes.display import html
799+
from bigframes.display import plaintext
800800

801-
return html.create_text_representation(self, pandas_df, row_count)
801+
return plaintext.create_text_representation(self, pandas_df, row_count)
802802

803803
def _get_display_df_and_blob_cols(self) -> tuple[DataFrame, list[str]]:
804804
"""Process blob columns for display."""
@@ -826,6 +826,40 @@ def _repr_mimebundle_(self, include=None, exclude=None):
826826

827827
return html.repr_mimebundle(self, include=include, exclude=exclude)
828828

829+
def _create_text_representation(
830+
self,
831+
pandas_df: pandas.DataFrame,
832+
total_rows: typing.Optional[int],
833+
) -> str:
834+
"""Create a text representation of the DataFrame."""
835+
opts = bigframes.options.display
836+
with display_options.pandas_repr(opts):
837+
import pandas.io.formats
838+
839+
to_string_kwargs = (
840+
pandas.io.formats.format.get_dataframe_repr_params() # type: ignore
841+
)
842+
if not self._has_index:
843+
to_string_kwargs.update({"index": False})
844+
to_string_kwargs.update({"show_dimensions": False})
845+
repr_string = pandas_df.to_string(**to_string_kwargs)
846+
847+
lines = repr_string.split("\n")
848+
is_truncated = total_rows is not None and total_rows > len(pandas_df)
849+
850+
if is_truncated:
851+
lines.append("...")
852+
lines.append("") # Add empty line for spacing only if truncated
853+
column_count = len(self.columns)
854+
lines.append(f"[{total_rows or '?'} rows x {column_count} columns]")
855+
else:
856+
# For non-truncated DataFrames, we still need to add dimensions if show_dimensions was False
857+
column_count = len(self.columns)
858+
lines.append("")
859+
lines.append(f"[{total_rows or '?'} rows x {column_count} columns]")
860+
861+
return "\n".join(lines)
862+
829863
def _create_html_representation(
830864
self,
831865
pandas_df: pandas.DataFrame,

bigframes/display/html.py

Lines changed: 27 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,12 @@
2626
import pandas.api.types
2727

2828
import bigframes
29-
from bigframes._config import display_options, options
30-
import bigframes.dataframe
31-
import bigframes.series
29+
from bigframes._config import options
30+
from bigframes.display import plaintext
31+
32+
if typing.TYPE_CHECKING:
33+
import bigframes.dataframe
34+
import bigframes.series
3235

3336

3437
def _is_dtype_numeric(dtype: Any) -> bool:
@@ -99,53 +102,6 @@ def render_html(
99102
return "\n".join(table_html)
100103

101104

102-
def create_text_representation(
103-
obj: Union[bigframes.dataframe.DataFrame, bigframes.series.Series],
104-
pandas_df: pd.DataFrame,
105-
total_rows: typing.Optional[int],
106-
) -> str:
107-
"""Create a text representation of the DataFrame or Series."""
108-
opts = bigframes.options.display
109-
with display_options.pandas_repr(opts):
110-
if isinstance(obj, bigframes.series.Series):
111-
pd_series = pandas_df.iloc[:, 0]
112-
if len(obj._block.index_columns) == 0:
113-
repr_string = pd_series.to_string(
114-
length=False, index=False, name=True, dtype=True
115-
)
116-
else:
117-
repr_string = pd_series.to_string(length=False, name=True, dtype=True)
118-
else:
119-
import pandas.io.formats
120-
121-
to_string_kwargs = (
122-
pandas.io.formats.format.get_dataframe_repr_params() # type: ignore
123-
)
124-
if not obj._has_index:
125-
to_string_kwargs.update({"index": False})
126-
to_string_kwargs.update({"show_dimensions": False})
127-
repr_string = pandas_df.to_string(**to_string_kwargs)
128-
129-
lines = repr_string.split("\n")
130-
is_truncated = total_rows is not None and total_rows > len(pandas_df)
131-
132-
if is_truncated:
133-
lines.append("...")
134-
lines.append("") # Add empty line for spacing only if truncated
135-
if isinstance(obj, bigframes.series.Series):
136-
lines.append(f"[{total_rows} rows]")
137-
else:
138-
column_count = len(obj.columns)
139-
lines.append(f"[{total_rows or '?'} rows x {column_count} columns]")
140-
elif isinstance(obj, bigframes.dataframe.DataFrame):
141-
# For non-truncated DataFrames, we still need to add dimensions if show_dimensions was False
142-
column_count = len(obj.columns)
143-
lines.append("")
144-
lines.append(f"[{total_rows or '?'} rows x {column_count} columns]")
145-
146-
return "\n".join(lines)
147-
148-
149105
def create_html_representation(
150106
obj: Union[bigframes.dataframe.DataFrame, bigframes.series.Series],
151107
pandas_df: pd.DataFrame,
@@ -154,13 +110,22 @@ def create_html_representation(
154110
blob_cols: list[str],
155111
) -> str:
156112
"""Create an HTML representation of the DataFrame or Series."""
157-
if isinstance(obj, bigframes.series.Series):
113+
# Note: We need to import Series here to avoid circular imports, but only if we use isinstance.
114+
# To check if it is a Series without importing, we can check if it has the _repr_html_ method
115+
# or rely on duck typing. However, the original code used isinstance.
116+
# Let's import inside the function if needed, or rely on attribute checks.
117+
# But wait, type checking imports are not available at runtime.
118+
# We can check __class__.__name__ or similar, or just import locally.
119+
from bigframes.series import Series
120+
121+
if isinstance(obj, Series):
158122
pd_series = pandas_df.iloc[:, 0]
159123
try:
160124
html_string = pd_series._repr_html_()
161125
except AttributeError:
162126
html_string = f"<pre>{pd_series.to_string()}</pre>"
163127
else:
128+
# It's a DataFrame
164129
html_string = obj._create_html_representation(
165130
pandas_df, total_rows, total_columns, blob_cols
166131
)
@@ -177,8 +142,9 @@ def get_anywidget_bundle(
177142
This function encapsulates the logic for anywidget display.
178143
"""
179144
from bigframes import display
145+
from bigframes.series import Series
180146

181-
if isinstance(obj, bigframes.series.Series):
147+
if isinstance(obj, Series):
182148
df = obj.to_frame()
183149
else:
184150
df, blob_cols = obj._get_display_df_and_blob_cols()
@@ -206,7 +172,9 @@ def get_anywidget_bundle(
206172
total_columns,
207173
blob_cols if "blob_cols" in locals() else [],
208174
)
209-
widget_repr["text/plain"] = create_text_representation(obj, cached_pd, total_rows)
175+
widget_repr["text/plain"] = plaintext.create_text_representation(
176+
obj, cached_pd, total_rows
177+
)
210178

211179
return widget_repr, widget_metadata
212180

@@ -219,6 +187,8 @@ def repr_mimebundle(
219187
"""
220188
Custom display method for IPython/Jupyter environments.
221189
"""
190+
from bigframes.series import Series
191+
222192
opts = bigframes.options.display
223193
if opts.repr_mode == "anywidget":
224194
try:
@@ -231,7 +201,7 @@ def repr_mimebundle(
231201
)
232202

233203
blob_cols: list[str]
234-
if isinstance(obj, bigframes.series.Series):
204+
if isinstance(obj, Series):
235205
pandas_df, row_count, query_job = obj._block.retrieve_repr_request_results(
236206
opts.max_rows
237207
)
@@ -249,6 +219,8 @@ def repr_mimebundle(
249219
obj, pandas_df, row_count, column_count, blob_cols
250220
)
251221

252-
text_representation = create_text_representation(obj, pandas_df, row_count)
222+
text_representation = plaintext.create_text_representation(
223+
obj, pandas_df, row_count
224+
)
253225

254226
return {"text/html": html_string, "text/plain": text_representation}

bigframes/display/plaintext.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2024 Google LLC
1+
# Copyright 2025 Google LLC
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License");
44
# you may not use this file except in compliance with the License.
@@ -17,17 +17,19 @@
1717
from __future__ import annotations
1818

1919
import typing
20+
from typing import Union
2021

2122
if typing.TYPE_CHECKING:
2223
import pandas as pd
2324

24-
import bigframes
25+
import bigframes.dataframe
26+
import bigframes.series
2527

2628

2729
def create_text_representation(
28-
obj: "bigframes.dataframe.DataFrame" | "bigframes.series.Series",
29-
pandas_df: "pd.DataFrame",
30-
total_rows: int | None,
30+
obj: Union[bigframes.dataframe.DataFrame, bigframes.series.Series],
31+
pandas_df: pd.DataFrame,
32+
total_rows: typing.Optional[int],
3133
) -> str:
3234
"""Create a text representation of the DataFrame or Series."""
3335
# TODO(swast): This module should probably just be removed and combined

bigframes/series.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,32 @@ def reset_index(
568568
block = block.assign_label(self._value_column, name)
569569
return bigframes.dataframe.DataFrame(block)
570570

571+
def _create_text_representation(
572+
self,
573+
pandas_df: pandas.DataFrame,
574+
total_rows: typing.Optional[int],
575+
) -> str:
576+
"""Create a text representation of the Series."""
577+
opts = bigframes.options.display
578+
with bigframes._config.display_options.pandas_repr(opts):
579+
pd_series = pandas_df.iloc[:, 0]
580+
if len(self._block.index_columns) == 0:
581+
repr_string = pd_series.to_string(
582+
length=False, index=False, name=True, dtype=True
583+
)
584+
else:
585+
repr_string = pd_series.to_string(length=False, name=True, dtype=True)
586+
587+
lines = repr_string.split("\n")
588+
is_truncated = total_rows is not None and total_rows > len(pandas_df)
589+
590+
if is_truncated:
591+
lines.append("...")
592+
lines.append("") # Add empty line for spacing only if truncated
593+
lines.append(f"[{total_rows} rows]")
594+
595+
return "\n".join(lines)
596+
571597
def _repr_mimebundle_(self, include=None, exclude=None):
572598
"""
573599
Custom display method for IPython/Jupyter environments.
@@ -592,9 +618,9 @@ def __repr__(self) -> str:
592618
opts.max_rows
593619
)
594620
self._set_internal_query_job(query_job)
595-
from bigframes.display import html
621+
from bigframes.display import plaintext
596622

597-
return html.create_text_representation(self, pandas_df, row_count)
623+
return plaintext.create_text_representation(self, pandas_df, row_count)
598624

599625
def astype(
600626
self,

0 commit comments

Comments
 (0)