diff --git a/py-polars/src/file.rs b/py-polars/src/file.rs index 6e46eb22f1a6..0fcd6b3bad9b 100644 --- a/py-polars/src/file.rs +++ b/py-polars/src/file.rs @@ -1,5 +1,3 @@ -// Credits to https://github.com/omerbenamram/pyo3-file -use std::borrow::Borrow; use std::fs::File; use std::io; use std::io::{BufReader, Cursor, Read, Seek, SeekFrom, Write}; @@ -191,23 +189,34 @@ pub enum EitherRustPythonFile { Rust(BufReader), } +fn no_such_file_err(file_path: &str) -> PyResult<()> { + let msg = if file_path.len() > 88 { + let file_path: String = file_path.chars().rev().take(88).collect(); + format!("No such file or directory: ...{file_path}",) + } else { + format!("No such file or directory: {file_path}",) + }; + + Err(PyErr::new::(msg)) +} + /// /// # Arguments /// * `truncate` - open or create a new file. pub fn get_either_file(py_f: PyObject, truncate: bool) -> PyResult { Python::with_gil(|py| { if let Ok(pstring) = py_f.downcast::(py) { - let rstring = pstring.to_string(); - let str_slice: &str = rstring.borrow(); + let s = pstring.to_str()?; + let file_path = std::path::Path::new(&s); + let file_path = resolve_homedir(file_path); let f = if truncate { - BufReader::new(File::create(str_slice)?) + BufReader::new(File::create(file_path)?) } else { - match File::open(str_slice) { + match File::open(&file_path) { Ok(file) => BufReader::new(file), Err(_e) => { - return Err(PyErr::new::(format!( - "No such file or directory: {str_slice}", - ))) + no_such_file_err(s)?; + unreachable!(); } } }; @@ -234,15 +243,14 @@ pub fn get_mmap_bytes_reader<'a>(py_f: &'a PyAny) -> PyResult() { - let s = pstring.to_string(); + let s = pstring.to_str()?; let p = std::path::Path::new(&s); let p = resolve_homedir(p); let f = match File::open(p) { Ok(file) => file, Err(_e) => { - return Err(PyErr::new::(format!( - "No such file or directory: {s}", - ))) + no_such_file_err(s)?; + unreachable!(); } }; Ok(Box::new(f)) diff --git a/py-polars/tests/unit/test_errors.py b/py-polars/tests/unit/test_errors.py index 2ded07b67383..fa03eb04c287 100644 --- a/py-polars/tests/unit/test_errors.py +++ b/py-polars/tests/unit/test_errors.py @@ -447,3 +447,12 @@ def test_string_numeric_arithmetic_err() -> None: pl.ComputeError, match=r"Arithmetic on string and numeric not allowed" ): df.select(pl.col("s") + 1) + + +def test_file_path_truncate_err() -> None: + content = "lskdfj".join(str(i) for i in range(25)) + with pytest.raises( + FileNotFoundError, + match=r"\.\.\.42jfdksl32jfdksl22jfdksl12jfdksl02jfdksl91jfdksl81jfdksl71jfdksl61jfdksl51jfdksl41jfdksl", + ): + pl.read_csv(content)