Add support for extracting PathBuf from pathlib.Path
This commit is contained in:
parent
15366b9b48
commit
bd1045e289
|
@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
- Add `#[pyo3(name = "...")]` syntax for setting Python names. [#1567](https://github.com/PyO3/pyo3/pull/1567)
|
||||
- Add FFI definition `PyDateTime_TimeZone_UTC`. [#1572](https://github.com/PyO3/pyo3/pull/1572)
|
||||
- Add support for `#[pyclass(extends=Exception)]`. [#1591](https://github.com/PyO3/pyo3/pull/1591)
|
||||
- Add support for extracting `PathBuf` from `pathlib.Path`. [#1654](https://github.com/PyO3/pyo3/pull/1654)
|
||||
|
||||
### Changed
|
||||
- Allow only one `#[pymethods]` block per `#[pyclass]` by default, to simplify the proc macro implementations. Add `multiple-pymethods` feature to opt-in to the more complex full behavior. [#1457](https://github.com/PyO3/pyo3/pull/1457)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -17,6 +18,7 @@ use dict_iter::*;
|
|||
use misc::*;
|
||||
use objstore::*;
|
||||
use othermod::*;
|
||||
use path::*;
|
||||
use pyclass_iter::*;
|
||||
use subclassing::*;
|
||||
|
||||
|
@ -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))?;
|
||||
|
||||
|
@ -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")?)?;
|
||||
|
||||
|
|
|
@ -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(())
|
||||
}
|
|
@ -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)
|
|
@ -1,4 +1,5 @@
|
|||
use crate::{FromPyObject, IntoPy, PyAny, PyObject, PyResult, Python, ToPyObject};
|
||||
use crate::types::PyType;
|
||||
use crate::{FromPyObject, IntoPy, PyAny, PyNativeType, PyObject, PyResult, Python, ToPyObject};
|
||||
use std::borrow::Cow;
|
||||
use std::ffi::OsString;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
@ -13,7 +14,21 @@ impl ToPyObject for Path {
|
|||
|
||||
impl FromPyObject<'_> for PathBuf {
|
||||
fn extract(ob: &PyAny) -> PyResult<Self> {
|
||||
Ok(PathBuf::from(OsString::extract(ob)?))
|
||||
let os_str = match OsString::extract(ob) {
|
||||
Ok(s) => s,
|
||||
Err(err) => {
|
||||
let py = ob.py();
|
||||
let pathlib = py.import("pathlib")?;
|
||||
let pathlib_path: &PyType = pathlib.getattr("Path")?.downcast()?;
|
||||
if pathlib_path.is_instance(ob)? {
|
||||
let path_str = ob.call_method0("__str__")?;
|
||||
OsString::extract(path_str)?
|
||||
} else {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
};
|
||||
Ok(PathBuf::from(os_str))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue