Skip to content

Commit

Permalink
Add support for extracting PathBuf from pathlib.Path
Browse files Browse the repository at this point in the history
  • Loading branch information
messense committed Jun 5, 2021
1 parent 15366b9 commit 0b67577
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 1 deletion.
4 changes: 4 additions & 0 deletions examples/pyo3-pytests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod dict_iter;
pub mod misc;
pub mod objstore;
pub mod othermod;
pub mod path;
pub mod pyclass_iter;
pub mod subclassing;

Expand All @@ -17,6 +18,7 @@ use dict_iter::*;
use misc::*;
use objstore::*;
use othermod::*;
use path::*;
use pyclass_iter::*;
use subclassing::*;

Expand All @@ -28,6 +30,7 @@ fn pyo3_pytests(py: Python, m: &PyModule) -> PyResult<()> {
m.add_wrapped(wrap_pymodule!(misc))?;
m.add_wrapped(wrap_pymodule!(objstore))?;
m.add_wrapped(wrap_pymodule!(othermod))?;
m.add_wrapped(wrap_pymodule!(path))?;
m.add_wrapped(wrap_pymodule!(pyclass_iter))?;
m.add_wrapped(wrap_pymodule!(subclassing))?;

Expand All @@ -42,6 +45,7 @@ fn pyo3_pytests(py: Python, m: &PyModule) -> PyResult<()> {
sys_modules.set_item("pyo3_pytests.misc", m.getattr("misc")?)?;
sys_modules.set_item("pyo3_pytests.objstore", m.getattr("objstore")?)?;
sys_modules.set_item("pyo3_pytests.othermod", m.getattr("othermod")?)?;
sys_modules.set_item("pyo3_pytests.path", m.getattr("path")?)?;
sys_modules.set_item("pyo3_pytests.pyclass_iter", m.getattr("pyclass_iter")?)?;
sys_modules.set_item("pyo3_pytests.subclassing", m.getattr("subclassing")?)?;

Expand Down
21 changes: 21 additions & 0 deletions examples/pyo3-pytests/src/path.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use pyo3::prelude::*;
use pyo3::wrap_pyfunction;
use std::path::{Path, PathBuf};

#[pyfunction]
fn make_path() -> PathBuf {
Path::new("/root").to_owned()
}

#[pyfunction]
fn take_pathbuf(path: PathBuf) -> PathBuf {
path
}

#[pymodule]
fn path(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(make_path, m)?)?;
m.add_function(wrap_pyfunction!(take_pathbuf, m)?)?;

Ok(())
}
18 changes: 18 additions & 0 deletions examples/pyo3-pytests/tests/test_path.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import pathlib

import pyo3_pytests.path as rpath


def test_make_path():
p = rpath.make_path()
assert p == "/root"


def test_take_pathbuf():
p = "/root"
assert rpath.take_pathbuf(p) == p


def test_take_pathlib():
p = pathlib.Path("/root")
assert rpath.take_pathbuf(p) == str(p)
17 changes: 16 additions & 1 deletion src/conversions/osstr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,22 @@ impl ToPyObject for OsStr {

impl FromPyObject<'_> for OsString {
fn extract(ob: &PyAny) -> PyResult<Self> {
let pystring = <PyString as PyTryFrom>::try_from(ob)?; // Cast PyAny to PyString
let pystring = match <PyString as PyTryFrom>::try_from(ob) {
// Cast PyAny to PyString
Ok(s) => s,
Err(err) => {
let py = ob.py();
let pathlib = py.import("pathlib")?;
let pathlib_path = pathlib.getattr("Path")?;
// FIXME: right way to get the type object of pathlib.Path?
let path_instance = pathlib_path.call0()?;
if path_instance.get_type().is_instance(ob)? {
ob.call_method0("__str__")?
} else {
return Err(err.into());
}
}
};

#[cfg(not(windows))]
{
Expand Down

0 comments on commit 0b67577

Please sign in to comment.