Skip to content

Commit

Permalink
feat(python): truncate file path on error msg (#6917)
Browse files Browse the repository at this point in the history
  • Loading branch information
ritchie46 committed Feb 16, 2023
1 parent c4267fc commit e3e2b2b
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 13 deletions.
34 changes: 21 additions & 13 deletions py-polars/src/file.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -191,23 +189,34 @@ pub enum EitherRustPythonFile {
Rust(BufReader<File>),
}

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::<PyFileNotFoundError, _>(msg))
}

///
/// # Arguments
/// * `truncate` - open or create a new file.
pub fn get_either_file(py_f: PyObject, truncate: bool) -> PyResult<EitherRustPythonFile> {
Python::with_gil(|py| {
if let Ok(pstring) = py_f.downcast::<PyString>(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::<PyFileNotFoundError, _>(format!(
"No such file or directory: {str_slice}",
)))
no_such_file_err(s)?;
unreachable!();
}
}
};
Expand All @@ -234,15 +243,14 @@ pub fn get_mmap_bytes_reader<'a>(py_f: &'a PyAny) -> PyResult<Box<dyn MmapBytesR
}
// string so read file
else if let Ok(pstring) = py_f.downcast::<PyString>() {
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::<PyFileNotFoundError, _>(format!(
"No such file or directory: {s}",
)))
no_such_file_err(s)?;
unreachable!();
}
};
Ok(Box::new(f))
Expand Down
9 changes: 9 additions & 0 deletions py-polars/tests/unit/test_errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

0 comments on commit e3e2b2b

Please sign in to comment.