Repository: dask-contrib/dask-expr
Pull request #941 (2024-03-06 15:20:28)

Revert "Add _repr_html_ and updated __repr__ for FrameBase (#930)"
This reverts commit 226f5da06889a2a19db9d2cef9252a5e0ad2299a.

The `self.dask` triggers a graph materialization which is something that must not happen during a `__repr__`.

I suspect this code was copy pasted from the dask/dask DataFrame since it explicitly mentions "layers" but that's no longer valid in dask-expr. Instead, this is probably supposed to use `Expr.walk` or smth similar

cc @milesgranger 

phofl: Walk should be fine yes and just count the unique names of the expressions

Patch:
diff --git a/dask_expr/_collection.py b/dask_expr/_collection.py
index db926c1..c110636 100644
--- a/dask_expr/_collection.py
+++ b/dask_expr/_collection.py
@@ -400,25 +400,6 @@ class FrameBase(DaskMethodsMixin):
             other = other.copy()
         return new_collection(self.expr.__getitem__(other))
 
-    def __repr__(self):
-        data = self._repr_data().to_string(max_rows=5)
-        _str_fmt = """Dask {klass} Structure:
-{data}
-Dask Name: {name}, {layers}
-Expr={expr}"""
-        if len(self.columns) == 0:
-            data = data.partition("\n")[-1].replace("Index", "Divisions")
-            _str_fmt = f"Empty {_str_fmt}"
-        layers = len({k for (k, *_) in self.dask.keys()})
-
-        return _str_fmt.format(
-            klass=self.__class__.__name__,
-            data=data,
-            name=key_split(self._name),
-            layers=maybe_pluralize(layers, "graph layer"),
-            expr=self.expr,
-        )
-
     def __bool__(self):
         raise ValueError(
             f"The truth value of a {self.__class__.__name__} is ambiguous. "
@@ -2433,9 +2414,6 @@ class DataFrame(FrameBase):
     def _ipython_key_completions_(self):
         return methods.tolist(self.columns)
 
-    def _repr_html_(self):
-        return self.to_html()
-
     @derived_from(pd.DataFrame)
     def assign(self, **pairs):
         result = self
@@ -2737,6 +2715,9 @@ class DataFrame(FrameBase):
             warnings.warn(meta_warning(meta))
         return new_collection(expr.Map(self, arg=func, na_action=na_action, meta=meta))
 
+    def __repr__(self):
+        return f"<dask_expr.expr.DataFrame: expr={self.expr}>"
+
     @derived_from(pd.DataFrame)
     def nlargest(self, n=5, columns=None, split_every=None):
         return new_collection(
@@ -3821,6 +3802,9 @@ class Series(FrameBase):
         axis = self._validate_axis(axis)
         return new_collection(self.expr.clip(lower, upper, axis))
 
+    def __repr__(self):
+        return f"<dask_expr.expr.Series: expr={self.expr}>"
+
     @derived_from(pd.Series)
     def to_frame(self, name=no_default):
         return new_collection(expr.ToFrame(self, name=name))


Test patch:
diff --git a/dask_expr/tests/test_collection.py b/dask_expr/tests/test_collection.py
index 9506384..d07327b 100644
--- a/dask_expr/tests/test_collection.py
+++ b/dask_expr/tests/test_collection.py
@@ -953,7 +953,7 @@ def test_isin_repr(df):
     result = df.isin([1, 2])
     # This was raising previously
     result = result.__repr__()
-    assert "Expr=Isin(frame=df, values=" in result
+    assert "<dask_expr.expr.DataFrame: expr=Isin(frame=df, values=" in result
 
 
 def test_round(pdf):
diff --git a/dask_expr/tests/test_concat.py b/dask_expr/tests/test_concat.py
index e75f63e..6e55922 100644
--- a/dask_expr/tests/test_concat.py
+++ b/dask_expr/tests/test_concat.py
@@ -22,8 +22,8 @@ def df(pdf):
 
 def test_concat_str(df):
     result = str(concat([df, df], join="inner"))
-    expected = "Expr=Concat(frames=[df, df], join=inner)"
-    assert expected in result
+    expected = "<dask_expr.expr.DataFrame: expr=Concat(frames=[df, df], join=inner)>"
+    assert result == expected
 
 
 def test_concat(pdf, df):
diff --git a/dask_expr/tests/test_format.py b/dask_expr/tests/test_format.py
index 9b18ae1..926d315 100644
--- a/dask_expr/tests/test_format.py
+++ b/dask_expr/tests/test_format.py
@@ -95,88 +95,3 @@ def test_series_format():
     H      ..."""
     )
     assert ds.to_string() == exp
-
-
-def test_series_repr():
-    s = pd.Series([1, 2, 3, 4, 5, 6, 7, 8], index=list("ABCDEFGH"))
-    ds = from_pandas(s, 3)
-
-    exp = dedent(
-        """\
-        Empty Dask Series Structure:
-        A    int64
-        D      ...
-        G      ...
-        H      ...
-        Dask Name: frompandas, 1 graph layer
-        Expr=df"""
-    )
-    assert repr(ds) == exp
-
-
-def test_df_repr():
-    df = pd.DataFrame({"col1": range(10), "col2": map(float, range(10))})
-    ddf = from_pandas(df, 3)
-
-    exp = dedent(
-        """\
-        Dask DataFrame Structure:
-                        col1     col2
-        npartitions=3                
-        0              int64  float64
-        4                ...      ...
-        7                ...      ...
-        9                ...      ...
-        Dask Name: frompandas, 1 graph layer
-        Expr=df"""
-    )
-    assert repr(ddf) == exp
-
-
-def test_df_to_html():
-    df = pd.DataFrame({"col1": range(10), "col2": map(float, range(10))})
-    ddf = from_pandas(df, 3)
-
-    exp = dedent(
-        """\
-        <div><strong>Dask DataFrame Structure:</strong></div>
-        <table border="1" class="dataframe">
-          <thead>
-            <tr style="text-align: right;">
-              <th></th>
-              <th>col1</th>
-              <th>col2</th>
-            </tr>
-            <tr>
-              <th>npartitions=3</th>
-              <th></th>
-              <th></th>
-            </tr>
-          </thead>
-          <tbody>
-            <tr>
-              <th>0</th>
-              <td>int64</td>
-              <td>float64</td>
-            </tr>
-            <tr>
-              <th>4</th>
-              <td>...</td>
-              <td>...</td>
-            </tr>
-            <tr>
-              <th>7</th>
-              <td>...</td>
-              <td>...</td>
-            </tr>
-            <tr>
-              <th>9</th>
-              <td>...</td>
-              <td>...</td>
-            </tr>
-          </tbody>
-        </table>
-        <div>Dask Name: frompandas, 1 graph layer</div>"""
-    )
-    assert ddf.to_html() == exp
-    assert ddf._repr_html_() == exp  # for jupyter