diff --git a/py-polars/polars/io/spreadsheet/functions.py b/py-polars/polars/io/spreadsheet/functions.py index 198b69404290..7e88687a6493 100644 --- a/py-polars/polars/io/spreadsheet/functions.py +++ b/py-polars/polars/io/spreadsheet/functions.py @@ -445,6 +445,10 @@ def _read_spreadsheet( if hasattr(parser, "close"): parser.close() + if not parsed_sheets: + param, value = ("id", sheet_id) if sheet_name is None else ("name", sheet_name) + raise ValueError(f"no matching sheets found when `sheet_{param}` is {value!r}") + if return_multi: return parsed_sheets return next(iter(parsed_sheets.values())) diff --git a/py-polars/polars/utils/_construction.py b/py-polars/polars/utils/_construction.py index 9e38b3e4d38f..8baf75cd19fb 100644 --- a/py-polars/polars/utils/_construction.py +++ b/py-polars/polars/utils/_construction.py @@ -1024,7 +1024,11 @@ def _sequence_of_sequence_to_pydf( local_schema_override = ( include_unknowns(schema_overrides, column_names) if schema_overrides else {} ) - if column_names and first_element and len(first_element) != len(column_names): + if ( + column_names + and len(first_element) > 0 + and len(first_element) != len(column_names) + ): raise ShapeError("the row data does not match the number of columns") unpack_nested = False diff --git a/py-polars/tests/unit/io/test_spreadsheet.py b/py-polars/tests/unit/io/test_spreadsheet.py index a777e8af318b..79ad6300fd7e 100644 --- a/py-polars/tests/unit/io/test_spreadsheet.py +++ b/py-polars/tests/unit/io/test_spreadsheet.py @@ -194,6 +194,36 @@ def test_read_excel_basic_datatypes( assert_frame_equal(df, df) +@pytest.mark.parametrize( + ("read_spreadsheet", "source", "params"), + [ + (pl.read_excel, "path_xlsx", {"engine": "xlsx2csv"}), + (pl.read_excel, "path_xlsx", {"engine": "openpyxl"}), + (pl.read_excel, "path_xlsb", {"engine": "pyxlsb"}), + (pl.read_ods, "path_ods", {}), + ], +) +def test_read_invalid_worksheet( + read_spreadsheet: Callable[..., dict[str, pl.DataFrame]], + source: str, + params: dict[str, str], + request: pytest.FixtureRequest, +) -> None: + spreadsheet_path = request.getfixturevalue(source) + for param, sheet_id, sheet_name in ( + ("id", 999, None), + ("name", None, "not_a_sheet_name"), + ): + value = sheet_id if param == "id" else sheet_name + with pytest.raises( + ValueError, + match=f"no matching sheets found when `sheet_{param}` is {value!r}", + ): + read_spreadsheet( + spreadsheet_path, sheet_id=sheet_id, sheet_name=sheet_name, **params + ) + + @pytest.mark.parametrize("engine", ["xlsx2csv", "openpyxl"]) def test_write_excel_bytes(engine: Literal["xlsx2csv", "openpyxl", "pyxlsb"]) -> None: df = pl.DataFrame({"A": [1, 2, 3, 4, 5]}) diff --git a/py-polars/tests/unit/test_constructors.py b/py-polars/tests/unit/test_constructors.py index 82263ba09a81..a09eb469eeab 100644 --- a/py-polars/tests/unit/test_constructors.py +++ b/py-polars/tests/unit/test_constructors.py @@ -592,6 +592,10 @@ def test_init_ndarray(monkeypatch: Any) -> None: assert df.shape == (2, 1) assert df.rows() == [([0, 1, 2, 3, 4],), ([5, 6, 7, 8, 9],)] + test_rows = [(1, 2), (3, 4)] + df = pl.DataFrame([np.array(test_rows[0]), np.array(test_rows[1])], orient="row") + assert_frame_equal(df, pl.DataFrame(test_rows, orient="row")) + # numpy arrays containing NaN df0 = pl.DataFrame( data={"x": [1.0, 2.5, float("nan")], "y": [4.0, float("nan"), 6.5]}, diff --git a/py-polars/tests/unit/test_errors.py b/py-polars/tests/unit/test_errors.py index 059c63776c75..f45ee6445bf1 100644 --- a/py-polars/tests/unit/test_errors.py +++ b/py-polars/tests/unit/test_errors.py @@ -105,7 +105,7 @@ def test_string_numeric_comp_err() -> None: def test_panic_error() -> None: with pytest.raises( pl.PolarsPanicError, - match="""dimensions cannot be empty""", + match="dimensions cannot be empty", ): pl.Series("a", [1, 2, 3]).reshape(())