Skip to content

Commit

Permalink
Upgrades to PyO3 0.21
Browse files Browse the repository at this point in the history
  • Loading branch information
Tpt committed Mar 26, 2024
1 parent 0f0c1d2 commit c1dba98
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 213 deletions.
20 changes: 10 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ oxiri = "0.2.3"
peg = "0.8"
pkg-config = "0.3.25"
predicates = ">=2.0, <4.0"
pyo3 = "0.20.1"
pyo3 = "0.21.0"
quick-xml = ">=0.29, <0.32"
rand = "0.8"
rayon-core = "1.11"
Expand Down
40 changes: 22 additions & 18 deletions python/src/dataset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub struct PyDataset {
impl PyDataset {
#[new]
#[pyo3(signature = (quads = None))]
fn new(quads: Option<&PyAny>) -> PyResult<Self> {
fn new(quads: Option<&Bound<'_, PyAny>>) -> PyResult<Self> {
let mut inner = Dataset::new();
if let Some(quads) = quads {
for quad in quads.iter()? {
Expand All @@ -50,15 +50,16 @@ impl PyDataset {
/// >>> store = Dataset([Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1'), NamedNode('http://example.com/g'))])
/// >>> list(store.quads_for_subject(NamedNode('http://example.com')))
/// [<Quad subject=<NamedNode value=http://example.com> predicate=<NamedNode value=http://example.com/p> object=<Literal value=1 datatype=<NamedNode value=http://www.w3.org/2001/XMLSchema#string>> graph_name=<NamedNode value=http://example.com/g>>]
pub fn quads_for_subject(&self, subject: &PyAny) -> PyResult<QuadIter> {
Ok(QuadIter {
#[allow(clippy::needless_pass_by_value)]
pub fn quads_for_subject(&self, subject: PySubjectRef<'_>) -> QuadIter {
QuadIter {
inner: self
.inner
.quads_for_subject(&PySubjectRef::try_from(subject)?)
.quads_for_subject(&subject)
.map(QuadRef::into_owned)
.collect::<Vec<_>>()
.into_iter(),
})
}
}

/// Looks for the quads with the given predicate.
Expand All @@ -71,15 +72,16 @@ impl PyDataset {
/// >>> store = Dataset([Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1'), NamedNode('http://example.com/g'))])
/// >>> list(store.quads_for_predicate(NamedNode('http://example.com/p')))
/// [<Quad subject=<NamedNode value=http://example.com> predicate=<NamedNode value=http://example.com/p> object=<Literal value=1 datatype=<NamedNode value=http://www.w3.org/2001/XMLSchema#string>> graph_name=<NamedNode value=http://example.com/g>>]
pub fn quads_for_predicate(&self, predicate: &PyAny) -> PyResult<QuadIter> {
Ok(QuadIter {
#[allow(clippy::needless_pass_by_value)]
pub fn quads_for_predicate(&self, predicate: PyNamedNodeRef<'_>) -> QuadIter {
QuadIter {
inner: self
.inner
.quads_for_predicate(&PyNamedNodeRef::try_from(predicate)?)
.quads_for_predicate(&predicate)
.map(QuadRef::into_owned)
.collect::<Vec<_>>()
.into_iter(),
})
}
}

/// Looks for the quads with the given object.
Expand All @@ -92,15 +94,16 @@ impl PyDataset {
/// >>> store = Dataset([Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1'), NamedNode('http://example.com/g'))])
/// >>> list(store.quads_for_object(Literal('1')))
/// [<Quad subject=<NamedNode value=http://example.com> predicate=<NamedNode value=http://example.com/p> object=<Literal value=1 datatype=<NamedNode value=http://www.w3.org/2001/XMLSchema#string>> graph_name=<NamedNode value=http://example.com/g>>]
pub fn quads_for_object(&self, object: &PyAny) -> PyResult<QuadIter> {
Ok(QuadIter {
#[allow(clippy::needless_pass_by_value)]
pub fn quads_for_object(&self, object: PyTermRef<'_>) -> QuadIter {
QuadIter {
inner: self
.inner
.quads_for_object(&PyTermRef::try_from(object)?)
.quads_for_object(&object)
.map(QuadRef::into_owned)
.collect::<Vec<_>>()
.into_iter(),
})
}
}

/// Looks for the quads with the given graph name.
Expand All @@ -113,15 +116,16 @@ impl PyDataset {
/// >>> store = Dataset([Quad(NamedNode('http://example.com'), NamedNode('http://example.com/p'), Literal('1'), NamedNode('http://example.com/g'))])
/// >>> list(store.quads_for_graph_name(NamedNode('http://example.com/g')))
/// [<Quad subject=<NamedNode value=http://example.com> predicate=<NamedNode value=http://example.com/p> object=<Literal value=1 datatype=<NamedNode value=http://www.w3.org/2001/XMLSchema#string>> graph_name=<NamedNode value=http://example.com/g>>]
pub fn quads_for_graph_name(&self, graph_name: &PyAny) -> PyResult<QuadIter> {
Ok(QuadIter {
#[allow(clippy::needless_pass_by_value)]
pub fn quads_for_graph_name(&self, graph_name: PyGraphNameRef<'_>) -> QuadIter {
QuadIter {
inner: self
.inner
.quads_for_graph_name(&PyGraphNameRef::try_from(graph_name)?)
.quads_for_graph_name(&graph_name)
.map(QuadRef::into_owned)
.collect::<Vec<_>>()
.into_iter(),
})
}
}

/// Adds a quad to the dataset.
Expand Down Expand Up @@ -317,7 +321,7 @@ impl PyCanonicalizationAlgorithm {
/// :type memo: typing.Any
/// :rtype: CanonicalizationAlgorithm
#[allow(unused_variables)]
fn __deepcopy__<'a>(slf: PyRef<'a, Self>, memo: &'_ PyAny) -> PyRef<'a, Self> {
fn __deepcopy__<'a>(slf: PyRef<'a, Self>, memo: &'_ Bound<'_, PyAny>) -> PyRef<'a, Self> {
slf
}
}
45 changes: 26 additions & 19 deletions python/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use oxigraph::model::QuadRef;
use pyo3::exceptions::{PyDeprecationWarning, PySyntaxError, PyValueError};
use pyo3::intern;
use pyo3::prelude::*;
use pyo3::types::PyBytes;
use pyo3::types::{PyBytes, PyString};
use std::cmp::max;
use std::ffi::OsStr;
use std::fs::File;
Expand Down Expand Up @@ -118,12 +118,12 @@ pub fn parse(
/// b'<http://example.com> <http://example.com/p> "1" .\n'
#[pyfunction]
#[pyo3(signature = (input, output = None, format = None))]
pub fn serialize<'a>(
input: &PyAny,
pub fn serialize<'py>(
input: &Bound<'py, PyAny>,
output: Option<PyWritableOutput>,
format: Option<PyRdfFormatInput>,
py: Python<'a>,
) -> PyResult<Option<&'a PyBytes>> {
py: Python<'py>,
) -> PyResult<Option<Bound<'py, PyBytes>>> {
PyWritable::do_write(
|output, file_path| {
let format = lookup_rdf_format(format, file_path.as_deref())?;
Expand Down Expand Up @@ -355,7 +355,7 @@ impl PyRdfFormat {
/// :type memo: typing.Any
/// :rtype: RdfFormat
#[allow(unused_variables)]
fn __deepcopy__<'a>(slf: PyRef<'a, Self>, memo: &'_ PyAny) -> PyRef<'a, Self> {
fn __deepcopy__<'a>(slf: PyRef<'a, Self>, memo: &'_ Bound<'_, PyAny>) -> PyRef<'a, Self> {
slf
}
}
Expand Down Expand Up @@ -423,7 +423,7 @@ impl PyWritable {
write: impl FnOnce(BufWriter<Self>, Option<PathBuf>) -> PyResult<BufWriter<Self>>,
output: Option<PyWritableOutput>,
py: Python<'_>,
) -> PyResult<Option<&PyBytes>> {
) -> PyResult<Option<Bound<'_, PyBytes>>> {
let (output, file_path) = match output {
Some(PyWritableOutput::Path(file_path)) => (
Self::File(py.allow_threads(|| File::create(&file_path))?),
Expand All @@ -436,9 +436,9 @@ impl PyWritable {
py.allow_threads(|| writer.into_inner())?.close(py)
}

fn close(self, py: Python<'_>) -> PyResult<Option<&PyBytes>> {
fn close(self, py: Python<'_>) -> PyResult<Option<Bound<'_, PyBytes>>> {
match self {
Self::Bytes(bytes) => Ok(Some(PyBytes::new(py, &bytes))),
Self::Bytes(bytes) => Ok(Some(PyBytes::new_bound(py, &bytes))),
Self::File(mut file) => {
py.allow_threads(|| {
file.flush()?;
Expand Down Expand Up @@ -489,13 +489,18 @@ impl Read for PyIo {
let to_read = max(1, buf.len() / 4); // We divide by 4 because TextIO works with number of characters and not with number of bytes
let read = self
.0
.as_ref(py)
.bind(py)
.call_method1(intern!(py, "read"), (to_read,))?;
let bytes = read
.extract::<&[u8]>()
.or_else(|_| read.extract::<&str>().map(str::as_bytes))?;
buf[..bytes.len()].copy_from_slice(bytes);
Ok(bytes.len())
Ok(if let Ok(bytes) = read.extract::<&[u8]>() {
buf[..bytes.len()].copy_from_slice(bytes);
bytes.len()
} else {
// TODO: Python 3.10+ use directly .extract<&str>
let string = read.extract::<Bound<'_, PyString>>()?;
let str = string.to_cow()?;
buf[..str.len()].copy_from_slice(str.as_bytes());
str.len()
})
})
}
}
Expand All @@ -505,15 +510,15 @@ impl Write for PyIo {
Python::with_gil(|py| {
Ok(self
.0
.as_ref(py)
.call_method1(intern!(py, "write"), (PyBytes::new(py, buf),))?
.bind(py)
.call_method1(intern!(py, "write"), (PyBytes::new_bound(py, buf),))?
.extract::<usize>()?)
})
}

fn flush(&mut self) -> io::Result<()> {
Python::with_gil(|py| {
self.0.as_ref(py).call_method0(intern!(py, "flush"))?;
self.0.bind(py).call_method0(intern!(py, "flush"))?;
Ok(())
})
}
Expand Down Expand Up @@ -629,5 +634,7 @@ pub fn python_version() -> (u8, u8) {
}

pub fn deprecation_warning(message: &str) -> PyResult<()> {
Python::with_gil(|py| PyErr::warn(py, py.get_type::<PyDeprecationWarning>(), message, 0))
Python::with_gil(|py| {
PyErr::warn_bound(py, &py.get_type_bound::<PyDeprecationWarning>(), message, 0)
})
}
2 changes: 1 addition & 1 deletion python/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use pyo3::prelude::*;

/// Oxigraph Python bindings
#[pymodule]
fn pyoxigraph(_py: Python<'_>, module: &PyModule) -> PyResult<()> {
fn pyoxigraph(_py: Python<'_>, module: &Bound<'_, PyModule>) -> PyResult<()> {
module.add("__package__", "pyoxigraph")?;
module.add("__version__", env!("CARGO_PKG_VERSION"))?;
module.add("__author__", env!("CARGO_PKG_AUTHORS").replace(':', "\n"))?;
Expand Down

0 comments on commit c1dba98

Please sign in to comment.