From bfc94887b886bbfd2f0df6e6043e390c8461358b Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Tue, 22 Oct 2024 13:40:33 -0400 Subject: [PATCH 1/3] Unit test that would previously deadlock. --- py-polars/tests/unit/dataframe/test_getitem.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/py-polars/tests/unit/dataframe/test_getitem.py b/py-polars/tests/unit/dataframe/test_getitem.py index 5d112ad67528..78a87aa6ebc1 100644 --- a/py-polars/tests/unit/dataframe/test_getitem.py +++ b/py-polars/tests/unit/dataframe/test_getitem.py @@ -479,3 +479,9 @@ def test_df_getitem_5343() -> None: assert df[4, 5] == 1024 assert_frame_equal(df[4, [2]], pl.DataFrame({"foo2": [16]})) assert_frame_equal(df[4, [5]], pl.DataFrame({"foo5": [1024]})) + + +def test_no_deadlock_19358(): + s = pl.Series(["text"] * 100 + [1] * 100, dtype=pl.Object) + result = s.to_frame()[[0, -1]] + assert result[""].to_list() == ["text", 1] From ef5c7bfe98e47b4ee39c8d0e238477353f2c0e38 Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Tue, 22 Oct 2024 13:43:56 -0400 Subject: [PATCH 2/3] Release GIL to prevent deadlock with GIL-releasing in ObjectValue::clone(). --- crates/polars-python/src/dataframe/general.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/polars-python/src/dataframe/general.rs b/crates/polars-python/src/dataframe/general.rs index be2652a1fb8b..d7bbab29177f 100644 --- a/crates/polars-python/src/dataframe/general.rs +++ b/crates/polars-python/src/dataframe/general.rs @@ -262,16 +262,16 @@ impl PyDataFrame { Ok(PyDataFrame::new(df)) } - pub fn gather(&self, indices: Wrap>) -> PyResult { + pub fn gather(&self, py: Python, indices: Wrap>) -> PyResult { let indices = indices.0; let indices = IdxCa::from_vec("".into(), indices); - let df = self.df.take(&indices).map_err(PyPolarsErr::from)?; + let df = Python::allow_threads(py, || self.df.take(&indices).map_err(PyPolarsErr::from))?; Ok(PyDataFrame::new(df)) } - pub fn gather_with_series(&self, indices: &PySeries) -> PyResult { + pub fn gather_with_series(&self, py: Python, indices: &PySeries) -> PyResult { let indices = indices.series.idx().map_err(PyPolarsErr::from)?; - let df = self.df.take(indices).map_err(PyPolarsErr::from)?; + let df = Python::allow_threads(py, || self.df.take(indices).map_err(PyPolarsErr::from))?; Ok(PyDataFrame::new(df)) } From 0421cc3ff390ecee5209dfe23af7fd97ab999b83 Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Tue, 22 Oct 2024 13:45:20 -0400 Subject: [PATCH 3/3] Lint --- py-polars/tests/unit/dataframe/test_getitem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py-polars/tests/unit/dataframe/test_getitem.py b/py-polars/tests/unit/dataframe/test_getitem.py index 78a87aa6ebc1..ab618a944b80 100644 --- a/py-polars/tests/unit/dataframe/test_getitem.py +++ b/py-polars/tests/unit/dataframe/test_getitem.py @@ -481,7 +481,7 @@ def test_df_getitem_5343() -> None: assert_frame_equal(df[4, [5]], pl.DataFrame({"foo5": [1024]})) -def test_no_deadlock_19358(): +def test_no_deadlock_19358() -> None: s = pl.Series(["text"] * 100 + [1] * 100, dtype=pl.Object) result = s.to_frame()[[0, -1]] assert result[""].to_list() == ["text", 1]