Repository: lincc-frameworks/nested-pandas

Issue:
Add tooling to embed a base column into a nested column
**Feature request**

It would be nice if we have a way to convert a base column to a field of a nested column, so the values are repeated for each row. Possible interface:
```python
ndf = generate_data(100, 10)
ndf.add_repeated_nested(ndf["a"], name="nested.a")
# Now ndf["nested"][0] has "a" column and all the values are equal to ndf["a"][0]
ndf.add_repeated_nested("b", to="nested")
# The same, but by base column name, so ndf["nested.b"] is np.repeat(ndf["b"], list_lengths)
```

It would also require adding lower-level implementations to the accessor and the extension array.

The example use-case: moving band information in ZTF DR23 catalog to light-curves, so we can merge multiple light curves with different passbands later.

**Before submitting**
Please check the following:

- [x] I have described the purpose of the suggested change, specifying what I need the enhancement to accomplish, i.e. what problem it solves.
- [x] I have included any relevant links, screenshots, environment information, and data relevant to implementing the requested feature, as well as pseudocode for how I want to access the new functionality.
- [ ] If I have ideas for how the new feature could be implemented, I have provided explanations and/or pseudocode and/or task lists for the steps.


Discussion:
review-notebook-app[bot]: Check out this pull request on&nbsp; <a href="https://app.reviewnb.com/lincc-frameworks/nested-pandas/pull/213"><img align="absmiddle"  alt="ReviewNB" height="28" class="BotMessageButtonImage" src="https://raw.githubusercontent.com/ReviewNB/support/master/images/button_reviewnb.png"/></a> 

 See visual diffs & provide feedback on Jupyter Notebooks. 

---

 <i>Powered by <a href='https://www.reviewnb.com/?utm_source=gh'>ReviewNB</a></i>
github-actions[bot]: | Before [d12ec6ec] <v0.3.7>   | After [590baab1]    | Ratio   | Benchmark (Parameter)                               |
|------------------------------|---------------------|---------|-----------------------------------------------------|
| 32.0±7ms                     | 38.2±7ms            | ~1.20   | benchmarks.ReassignHalfOfNestedSeries.time_run      |
| 1.24±0.01ms                  | 1.27±0.03ms         | 1.03    | benchmarks.NestedFrameReduce.time_run               |
| 270M                         | 269M                | 1.00    | benchmarks.AssignSingleDfToNestedSeries.peakmem_run |
| 25.1±0.7ms                   | 25.1±0.7ms          | 1.00    | benchmarks.AssignSingleDfToNestedSeries.time_run    |
| 92M                          | 92M                 | 1.00    | benchmarks.NestedFrameAddNested.peakmem_run         |
| 96.5M                        | 96.6M               | 1.00    | benchmarks.NestedFrameQuery.peakmem_run             |
| 10.6±0.06ms                  | 10.6±0.06ms         | 1.00    | benchmarks.NestedFrameQuery.time_run                |
| 95.6M                        | 95.7M               | 1.00    | benchmarks.NestedFrameReduce.peakmem_run            |
| 289M                         | 289M                | 1.00    | benchmarks.ReassignHalfOfNestedSeries.peakmem_run   |
| 9.78±0.1ms                   | 9.52±0.07ms         | 0.97    | benchmarks.NestedFrameAddNested.time_run            |


Click [here](https://github.com/lincc-frameworks/nested-pandas/actions/runs/13685103945/job/38266582487#step:10:1) to view all benchmarks.
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/lincc-frameworks/nested-pandas/pull/213?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=lincc-frameworks) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 98.31%. Comparing base [(`1ef99be`)](https://app.codecov.io/gh/lincc-frameworks/nested-pandas/commit/1ef99becb4af31bfda3f3f9e92258863905e8338?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=lincc-frameworks) to head [(`383c9fb`)](https://app.codecov.io/gh/lincc-frameworks/nested-pandas/commit/383c9fbe6605cfbe6a7e3bab077082c81cbf98f7?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=lincc-frameworks).
> Report is 12 commits behind head on main.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main     #213      +/-   ##
==========================================
- Coverage   98.49%   98.31%   -0.19%     
==========================================
  Files          13       13              
  Lines        1197     1245      +48     
==========================================
+ Hits         1179     1224      +45     
- Misses         18       21       +3     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/lincc-frameworks/nested-pandas/pull/213?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=lincc-frameworks).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=lincc-frameworks).

<details><summary>🚀 New features to boost your workflow: </summary>

- ❄ [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
</details>

Patch:
diff --git a/docs/tutorials/low_level.ipynb b/docs/tutorials/low_level.ipynb
index 02f815b..e0004a5 100644
--- a/docs/tutorials/low_level.ipynb
+++ b/docs/tutorials/low_level.ipynb
@@ -17,7 +17,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "619f088e7ac0f327",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:51.884860Z",
+     "start_time": "2025-03-05T20:34:51.881771Z"
+    }
+   },
    "outputs": [],
    "source": [
     "import numpy as np\n",
@@ -44,7 +49,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "f9dd16a4bb9aaa63",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:51.930103Z",
+     "start_time": "2025-03-05T20:34:51.922425Z"
+    }
+   },
    "outputs": [],
    "source": [
     "nested_df = generate_data(4, 3, seed=42)\n",
@@ -83,7 +93,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "fb7beb750d3e2893",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:51.954391Z",
+     "start_time": "2025-03-05T20:34:51.952196Z"
+    }
+   },
    "outputs": [],
    "source": [
     "list(nested_series.nest.keys())"
@@ -101,7 +116,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "56b0d9ffc5820d22",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.001459Z",
+     "start_time": "2025-03-05T20:34:51.999259Z"
+    }
+   },
    "outputs": [],
    "source": [
     "nested_series.nest.fields"
@@ -119,7 +139,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "30ee9a430b6ff641",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.044695Z",
+     "start_time": "2025-03-05T20:34:52.041331Z"
+    }
+   },
    "outputs": [],
    "source": [
     "nested_series.nest[\"t\"]"
@@ -137,7 +162,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "f0db15d31b289140",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.078645Z",
+     "start_time": "2025-03-05T20:34:52.076097Z"
+    }
+   },
    "outputs": [],
    "source": [
     "nested_series.nest[[\"t\", \"flux\"]].dtype"
@@ -159,7 +189,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "66ae5cc26fa17458",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.106880Z",
+     "start_time": "2025-03-05T20:34:52.099658Z"
+    }
+   },
    "outputs": [],
    "source": [
     "new_series = nested_series.copy()\n",
@@ -179,6 +214,10 @@
     "    [1, 2] * (new_series.nest.flat_length // 2),\n",
     ")\n",
     "\n",
+    "# Add a new column repeating values for each nested element\n",
+    "# It can be useful when you want to move some metadata to the nested data\n",
+    "new_series = new_series.nest.with_filled_field(\"index_mult_100\", new_series.index * 100)\n",
+    "\n",
     "# Create a new series, with a column dtype changed\n",
     "new_series = new_series.nest.with_field(\"t\", new_series.nest[\"t\"].astype(np.int8))\n",
     "\n",
@@ -203,7 +242,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "ce6d519d8d37ead3",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.146725Z",
+     "start_time": "2025-03-05T20:34:52.142850Z"
+    }
+   },
    "outputs": [],
    "source": [
     "nested_series.nest.to_flat([\"flux\", \"t\"])"
@@ -213,7 +257,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "2421b91387487995",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.193472Z",
+     "start_time": "2025-03-05T20:34:52.190517Z"
+    }
+   },
    "outputs": [],
    "source": [
     "lists_df = nested_series.nest.to_lists()  # may also accept a list of fields (nested columns) to get\n",
@@ -232,7 +281,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "f2c205e95affb9ba",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.265575Z",
+     "start_time": "2025-03-05T20:34:52.259768Z"
+    }
+   },
    "outputs": [],
    "source": [
     "# Adjust each time to be relative to the first observation\n",
@@ -271,7 +325,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "8ef96243c6d74aff",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.306357Z",
+     "start_time": "2025-03-05T20:34:52.303097Z"
+    }
+   },
    "outputs": [],
    "source": [
     "struct_series = pd.Series(nested_series, dtype=nested_series.dtype.to_pandas_arrow_dtype())\n",
@@ -282,7 +341,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "422e719861ae40f6",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.352751Z",
+     "start_time": "2025-03-05T20:34:52.350143Z"
+    }
+   },
    "outputs": [],
    "source": [
     "nested_series.equals(pd.Series(struct_series, dtype=NestedDtype.from_pandas_arrow_dtype(struct_series.dtype)))"
@@ -312,7 +376,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "926f2c9fcffc5f03",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.380059Z",
+     "start_time": "2025-03-05T20:34:52.376281Z"
+    }
+   },
    "outputs": [],
    "source": [
     "new_series = pack(nested_series.nest.to_flat())\n",
@@ -323,7 +392,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "3a1d2025c232ac82",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.411904Z",
+     "start_time": "2025-03-05T20:34:52.406436Z"
+    }
+   },
    "outputs": [],
    "source": [
     "series_from_flat = pack(\n",
@@ -360,7 +434,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "2de4619726ab3d5c",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.436451Z",
+     "start_time": "2025-03-05T20:34:52.431913Z"
+    }
+   },
    "outputs": [],
    "source": [
     "series_from_pack = pack(\n",
@@ -387,7 +466,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "9c63ae45dd0b6a29",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.461662Z",
+     "start_time": "2025-03-05T20:34:52.457289Z"
+    }
+   },
    "outputs": [],
    "source": [
     "series_from_pack = pack(\n",
@@ -428,7 +512,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "1284d9b536b9e784",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.486561Z",
+     "start_time": "2025-03-05T20:34:52.482191Z"
+    }
+   },
    "outputs": [],
    "source": [
     "series_from_dtype = pd.Series(\n",
@@ -454,7 +543,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "b7c7fd878bc97f68",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.510415Z",
+     "start_time": "2025-03-05T20:34:52.506423Z"
+    }
+   },
    "outputs": [],
    "source": [
     "series_pa_type = pa.struct({\"t\": pa.list_(pa.float64()), \"band\": pa.list_(pa.string())})\n",
@@ -486,7 +580,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "e837d25dcb0a2b4d",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.533325Z",
+     "start_time": "2025-03-05T20:34:52.531035Z"
+    }
+   },
    "outputs": [],
    "source": [
     "pa_struct_array = pa.StructArray.from_arrays(\n",
@@ -524,7 +623,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "116c902ea8681c9e",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.556192Z",
+     "start_time": "2025-03-05T20:34:52.553399Z"
+    }
+   },
    "outputs": [],
    "source": [
     "# Convert to pd.ArrowDtype Series of struct-arrays\n",
@@ -549,7 +653,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "30ea40dee30795d1",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.581407Z",
+     "start_time": "2025-03-05T20:34:52.577087Z"
+    }
+   },
    "outputs": [],
    "source": [
     "for element in nested_series:\n",
@@ -568,7 +677,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "81f6c1f98dfc26a9",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.623288Z",
+     "start_time": "2025-03-05T20:34:52.619263Z"
+    }
+   },
    "outputs": [],
    "source": [
     "nested_elements = list(nested_series)\n",
@@ -587,7 +701,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "69ed758c48c55015",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.644347Z",
+     "start_time": "2025-03-05T20:34:52.641497Z"
+    }
+   },
    "outputs": [],
    "source": [
     "nested_series_with_na = pack([None, pd.NA, {\"t\": [1, 2], \"flux\": [0.1, None]}])\n",
@@ -600,7 +719,12 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "99ce9d18bc69ae49",
-   "metadata": {},
+   "metadata": {
+    "ExecuteTime": {
+     "end_time": "2025-03-05T20:34:52.721086Z",
+     "start_time": "2025-03-05T20:34:52.718368Z"
+    }
+   },
    "outputs": [],
    "source": [
     "# Would have empty pd.DataFrame for top-level missed data\n",
diff --git a/src/nested_pandas/series/accessor.py b/src/nested_pandas/series/accessor.py
index fa95763..2ae9afc 100644
--- a/src/nested_pandas/series/accessor.py
+++ b/src/nested_pandas/series/accessor.py
@@ -178,7 +178,7 @@ class NestSeriesAccessor(Mapping):
             Name of the field to set. If not present, it will be added.
         value : ArrayLike
             Array of values to set. It must be a list-array of the same length
-             as the series, e.g. length of the series.
+             as the series.
 
         Returns
         -------
@@ -189,6 +189,31 @@ class NestSeriesAccessor(Mapping):
         new_array.set_list_field(field, value)
         return pd.Series(new_array, copy=False, index=self._series.index, name=self._series.name)
 
+    def with_filled_field(self, field: str, value: ArrayLike) -> pd.Series:
+        """Set the field by repeating values and return a new series
+
+        The input value array must have as many elements as the Series,
+        each of them will be repeated in the corresponding list.
+
+        .nest.with_repeated_field("a", [1, 2, 3]) will create a nested field
+        "a" with values [[1, 1, ...], [2, 2, ...], [3, 3, ...]].
+
+        Parameters
+        ----------
+        field : str
+            Name of the field to set. If not present, it will be added.
+        value : ArrayLike
+            Array of values to set. It must have the same length as the series.
+
+        Returns
+        -------
+        pd.Series
+            The new series with the field set.
+        """
+        new_array = self._series.array.copy()
+        new_array.fill_field_lists(field, value)
+        return pd.Series(new_array, copy=False, index=self._series.index, name=self._series.name)
+
     def without_field(self, field: str | list[str]) -> pd.Series:
         """Remove the field(s) from the series and return a new series
 
diff --git a/src/nested_pandas/series/ext_array.py b/src/nested_pandas/series/ext_array.py
index c1d152b..43735db 100644
--- a/src/nested_pandas/series/ext_array.py
+++ b/src/nested_pandas/series/ext_array.py
@@ -977,6 +977,41 @@ class NestedExtensionArray(ExtensionArray):
 
         self._replace_chunked_array(chunked_array, validate=True)
 
+    def fill_field_lists(self, field: str, value: ArrayLike, *, keep_dtype: bool = False) -> None:
+        """Fill list-arrays with values from the input array
+
+        The input value array must have as many elements as the array, e.g.
+        number of lists, not number of elements in the lists.
+
+        .fill_value("a", [1,2,3]) would set "a" to be
+        [1, 1, ...], [2, 2, ...], [3, 3, ...]
+
+        Parameters
+        ----------
+        field : str
+            The name of the field to fill.
+        value : ArrayLike
+            The array of values to fill the field with. The length of the array
+            is len(self).
+        keep_dtype : bool, default False
+            Whether to keep the original dtype of the field. If True,
+            now new field will be created, and the dtype of the existing
+            field will be kept. If False, the dtype of the field will be
+            inferred from the input value.
+        """
+        if np.ndim(value) == 0:
+            raise ValueError(
+                "The input array must be 1-dimensional, please use NestedExtenstionArray.set_flat_field() or"
+                " .nest.with_flat_field() for scalars"
+            )
+        if np.size(value) != len(self):
+            raise ValueError("The length of the input array must be equal to the length of the series")
+        if isinstance(value, (pa.ChunkedArray, pa.Array)):
+            value = pa.compute.take(value, self.get_list_index())
+        else:
+            value = np.repeat(value, self.list_lengths)
+        return self.set_flat_field(field, value, keep_dtype=keep_dtype)
+
     def pop_fields(self, fields: Iterable[str]):
         """Delete fields from the struct array
 


Test patch:
diff --git a/tests/nested_pandas/series/test_accessor.py b/tests/nested_pandas/series/test_accessor.py
index 4bc46e7..37b385a 100644
--- a/tests/nested_pandas/series/test_accessor.py
+++ b/tests/nested_pandas/series/test_accessor.py
@@ -377,6 +377,33 @@ def test_with_list_field():
     )
 
 
+def test_with_filled_field():
+    """Test .nest.with_filled_field("field", value)"""
+    series = pack_seq(
+        [
+            pd.DataFrame({"a": [1, 2, 3], "b": [1.0, 5.0, 6.0]}),
+            pd.DataFrame({"a": [1, 2], "b": [None, 0.0]}),
+        ]
+    )
+    new_series = series.nest.with_filled_field(
+        "a",
+        [0, 100],
+    ).nest.with_filled_field(
+        "c",
+        ["abc", "xyz"],
+    )
+
+    desired = pack_seq(
+        [
+            pd.DataFrame({"a": [0, 0, 0], "b": [1.0, 5.0, 6.0], "c": ["abc", "abc", "abc"]}),
+            pd.DataFrame({"a": [100, 100], "b": [None, 0.0], "c": ["xyz", "xyz"]}),
+        ]
+    )
+
+    assert_series_equal(new_series.nest["a"], desired.nest["a"])
+    assert_series_equal(new_series.nest["c"], desired.nest["c"])
+
+
 def test_without_field_single_field():
     """Test .nest.without_field("field")"""
     struct_array = pa.StructArray.from_arrays(
diff --git a/tests/nested_pandas/series/test_ext_array.py b/tests/nested_pandas/series/test_ext_array.py
index 98a7e06..391e06c 100644
--- a/tests/nested_pandas/series/test_ext_array.py
+++ b/tests/nested_pandas/series/test_ext_array.py
@@ -1653,6 +1653,53 @@ def test_set_list_field_keep_dtype_raises_for_new_field():
     ext_array.set_list_field("c", [["x", "y", "z"]], keep_dtype=False)
 
 
+def test_fill_field_lists():
+    """Tests that we can fill a field with an array"""
+    ext_array = NestedExtensionArray(
+        pa.StructArray.from_arrays(
+            arrays=[
+                pa.array([np.array([1.0, 2.0, 3.0]), np.array([4.0, 5.0])]),
+                pa.array([-np.array([4.0, 5.0, 6.0]), np.array([7.0, 8.0])]),
+            ],
+            names=["a", "b"],
+        )
+    )
+
+    ext_array.fill_field_lists("a", pa.array([1.0, 2.0]))
+    ext_array.fill_field_lists("c", ["abc", "def"])
+
+    desired = NestedExtensionArray(
+        pa.StructArray.from_arrays(
+            arrays=[
+                pa.array([np.array([1.0, 1.0, 1.0]), np.array([2.0, 2.0])]),
+                pa.array([-np.array([4.0, 5.0, 6.0]), np.array([7.0, 8.0])]),
+                pa.array([np.array(["abc", "abc", "abc"]), np.array(["def", "def"])]),
+            ],
+            names=["a", "b", "c"],
+        )
+    )
+    assert_series_equal(pd.Series(ext_array), pd.Series(desired))
+
+
+def test_fill_field_lists_fails_for_wrong_length():
+    """Test for multiple exceptions when fill_field_lists fails for wrong length."""
+    ext_array = NestedExtensionArray(
+        pa.StructArray.from_arrays(
+            arrays=[
+                pa.array([np.array([1.0, 2.0, 3.0]), np.array([4.0, 5.0])]),
+                pa.array([-np.array([4.0, 5.0, 6.0]), np.array([7.0, 8.0])]),
+            ],
+            names=["a", "b"],
+        )
+    )
+
+    with pytest.raises(ValueError):
+        ext_array.fill_field_lists("a", [1.0, 2.0, 3.0, 4.0])
+
+    with pytest.raises(ValueError):
+        ext_array.fill_field_lists("c", 1.0)
+
+
 def test_pop_fields():
     """Tests that we can pop a field from the extension array."""
     struct_array = pa.StructArray.from_arrays(