Skip to content

Commit

Permalink
deps: upgrade PyO3 to 0.21 (#275)
Browse files Browse the repository at this point in the history
  • Loading branch information
cjrh authored May 7, 2024
1 parent 14827d9 commit cc7e785
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 68 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,20 @@ jobs:
run: cargo fmt --check

Test:
continue-on-error: ${{ matrix.python-version == '3.13' }}
env:
UNSAFE_PYO3_SKIP_VERSION_CHECK: ${{ matrix.unsafe-pyo3-skip-version-check }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.12"]
allow-prereleases: [false]
unsafe-pyo3-skip-version-check: [0]
include:
- os: ubuntu-latest
python-version: "3.13"
allow-prereleases: true
unsafe-pyo3-skip-version-check: 1
- os: ubuntu-latest
python-version: "3.11"
allow-prereleases: false
Expand Down
32 changes: 20 additions & 12 deletions Cargo.lock

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

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@ name = "tantivy"
crate-type = ["cdylib"]

[build-dependencies]
pyo3-build-config = "0.20.0"
pyo3-build-config = "0.21.0"

[dependencies]
base64 = "0.22"
chrono = "0.4.38"
tantivy = "0.22.0"
itertools = "0.12.1"
futures = "0.3.30"
pythonize = "0.20.0"
pythonize = "0.21.0"
serde = "1.0"
serde_json = "1.0.116"

[dependencies.pyo3]
version = "0.20.0"
version = "0.21.0"
features = ["chrono", "extension-module"]
77 changes: 46 additions & 31 deletions src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use std::{
str::FromStr,
};

pub(crate) fn extract_value(any: &PyAny) -> PyResult<Value> {
pub(crate) fn extract_value(any: &Bound<PyAny>) -> PyResult<Value> {
if let Ok(s) = any.extract::<String>() {
return Ok(Value::Str(s));
}
Expand All @@ -42,7 +42,7 @@ pub(crate) fn extract_value(any: &PyAny) -> PyResult<Value> {
}
if let Ok(datetime) = any.extract::<NaiveDateTime>() {
return Ok(Value::Date(tv::DateTime::from_timestamp_secs(
datetime.timestamp(),
datetime.and_utc().timestamp(),
)));
}
if let Ok(facet) = any.extract::<Facet>() {
Expand All @@ -52,23 +52,24 @@ pub(crate) fn extract_value(any: &PyAny) -> PyResult<Value> {
return Ok(Value::Bytes(b));
}
if let Ok(dict) = any.downcast::<PyDict>() {
if let Ok(json) = pythonize::depythonize(dict) {
if let Ok(json) = pythonize::depythonize_bound(dict.clone().into_any())
{
return Ok(Value::Object(json));
}
}
Err(to_pyerr(format!("Value unsupported {any:?}")))
}

pub(crate) fn extract_value_for_type(
any: &PyAny,
any: &Bound<PyAny>,
tv_type: tv::schema::Type,
field_name: &str,
) -> PyResult<Value> {
// Helper function to create `PyErr`s returned by this function.
fn to_pyerr_for_type<'a, E: std::error::Error>(
type_name: &'a str,
field_name: &'a str,
any: &'a PyAny,
any: &'a Bound<PyAny>,
) -> impl Fn(E) -> PyErr + 'a {
move |_| {
to_pyerr(format!(
Expand Down Expand Up @@ -104,7 +105,9 @@ pub(crate) fn extract_value_for_type(
.extract::<NaiveDateTime>()
.map_err(to_pyerr_for_type("DateTime", field_name, any))?;

Value::Date(tv::DateTime::from_timestamp_secs(datetime.timestamp()))
Value::Date(tv::DateTime::from_timestamp_secs(
datetime.and_utc().timestamp(),
))
}
tv::schema::Type::Facet => Value::Facet(
any.extract::<Facet>()
Expand All @@ -124,9 +127,11 @@ pub(crate) fn extract_value_for_type(

Value::Object(
any.downcast::<PyDict>()
.map(|dict| pythonize::depythonize(dict))
.map_err(to_pyerr_for_type("Json", field_name, any))?
.map_err(to_pyerr_for_type("Json", field_name, any))?,
.map_err(to_pyerr_for_type("Json", field_name, any))
.and_then(|dict| {
pythonize::depythonize_bound(dict.clone().into_any())
.map_err(to_pyerr_for_type("Json", field_name, any))
})?,
)
}
tv::schema::Type::IpAddr => {
Expand All @@ -147,16 +152,16 @@ pub(crate) fn extract_value_for_type(
Ok(value)
}

fn extract_value_single_or_list(any: &PyAny) -> PyResult<Vec<Value>> {
fn extract_value_single_or_list(any: &Bound<PyAny>) -> PyResult<Vec<Value>> {
if let Ok(values) = any.downcast::<PyList>() {
values.iter().map(extract_value).collect()
values.iter().map(|v| extract_value(&v)).collect()
} else {
Ok(vec![extract_value(any)?])
}
}

fn extract_value_single_or_list_for_type(
any: &PyAny,
any: &Bound<PyAny>,
field_type: &tv::schema::FieldType,
field_name: &str,
) -> PyResult<Vec<Value>> {
Expand All @@ -179,7 +184,11 @@ fn extract_value_single_or_list_for_type(
values
.iter()
.map(|any| {
extract_value_for_type(any, field_type.value_type(), field_name)
extract_value_for_type(
&any,
field_type.value_type(),
field_name,
)
})
.collect()
} else {
Expand All @@ -195,7 +204,7 @@ fn object_to_py(
py: Python,
obj: &BTreeMap<String, Value>,
) -> PyResult<PyObject> {
let dict = PyDict::new(py);
let dict = PyDict::new_bound(py);
for (k, v) in obj.iter() {
dict.set_item(k, value_to_py(py, v)?)?;
}
Expand All @@ -216,7 +225,7 @@ fn value_to_py(py: Python, value: &Value) -> PyResult<PyObject> {
}
Value::Date(d) => {
let utc = d.into_utc();
PyDateTime::new(
PyDateTime::new_bound(
py,
utc.year(),
utc.month() as u8,
Expand Down Expand Up @@ -538,7 +547,7 @@ impl Document {
/// [`extend()`], or `add_<type>()` functions.
#[new]
#[pyo3(signature = (**kwargs))]
fn new(kwargs: Option<&PyDict>) -> PyResult<Self> {
fn new(kwargs: Option<&Bound<PyDict>>) -> PyResult<Self> {
let mut document = Document::default();
if let Some(field_dict) = kwargs {
document.extend(field_dict, None)?;
Expand All @@ -548,7 +557,7 @@ impl Document {

fn extend(
&mut self,
py_dict: &PyDict,
py_dict: &Bound<PyDict>,
schema: Option<&Schema>,
) -> PyResult<()> {
Document::extract_py_values_from_dict(
Expand All @@ -560,7 +569,7 @@ impl Document {

#[staticmethod]
fn from_dict(
py_dict: &PyDict,
py_dict: &Bound<PyDict>,
schema: Option<&Schema>,
) -> PyResult<Document> {
let mut field_values: BTreeMap<String, Vec<Value>> = BTreeMap::new();
Expand All @@ -581,7 +590,7 @@ impl Document {
/// For this reason, the dictionary, will associate
/// a list of value for every field.
fn to_dict(&self, py: Python) -> PyResult<PyObject> {
let dict = PyDict::new(py);
let dict = PyDict::new_bound(py);
for (key, values) in &self.field_values {
let values_py: Vec<PyObject> = values
.iter()
Expand Down Expand Up @@ -642,7 +651,7 @@ impl Document {
/// Args:
/// field_name (str): The field name for which we are adding the date.
/// value (datetime): The date that will be added to the document.
fn add_date(&mut self, field_name: String, value: &PyDateTime) {
fn add_date(&mut self, field_name: String, value: &Bound<PyDateTime>) {
let datetime = Utc
.with_ymd_and_hms(
value.get_year(),
Expand Down Expand Up @@ -685,15 +694,21 @@ impl Document {
/// to the document.
///
/// Raises a ValueError if the JSON is invalid.
fn add_json(&mut self, field_name: String, value: &PyAny) -> PyResult<()> {
fn add_json(
&mut self,
field_name: String,
value: &Bound<PyAny>,
) -> PyResult<()> {
type JsonMap = serde_json::Map<String, serde_json::Value>;

if let Ok(json_str) = value.extract::<&str>() {
let json_map: JsonMap =
serde_json::from_str(json_str).map_err(to_pyerr)?;
self.add_value(field_name, json_map);
Ok(())
} else if let Ok(json_map) = pythonize::depythonize::<JsonMap>(value) {
} else if let Ok(json_map) =
pythonize::depythonize_bound::<JsonMap>(value.clone())
{
self.add_value(field_name, json_map);
Ok(())
} else {
Expand Down Expand Up @@ -760,7 +775,7 @@ impl Document {
self.clone()
}

fn __deepcopy__(&self, _memo: &PyDict) -> Self {
fn __deepcopy__(&self, _memo: &Bound<PyDict>) -> Self {
self.clone()
}

Expand All @@ -778,21 +793,21 @@ impl Document {
}

#[staticmethod]
fn _internal_from_pythonized(serialized: &PyAny) -> PyResult<Self> {
pythonize::depythonize(serialized).map_err(to_pyerr)
fn _internal_from_pythonized(serialized: &Bound<PyAny>) -> PyResult<Self> {
pythonize::depythonize_bound(serialized.clone()).map_err(to_pyerr)
}

fn __reduce__<'a>(
slf: PyRef<'a, Self>,
py: Python<'a>,
) -> PyResult<&'a PyTuple> {
) -> PyResult<Bound<'a, PyTuple>> {
let serialized = pythonize::pythonize(py, &*slf).map_err(to_pyerr)?;

Ok(PyTuple::new(
Ok(PyTuple::new_bound(
py,
[
slf.into_py(py).getattr(py, "_internal_from_pythonized")?,
PyTuple::new(py, [serialized]).to_object(py),
PyTuple::new_bound(py, [serialized]).to_object(py),
],
))
}
Expand All @@ -810,7 +825,7 @@ impl Document {
}

fn extract_py_values_from_dict(
py_dict: &PyDict,
py_dict: &Bound<PyDict>,
schema: Option<&Schema>,
out_field_values: &mut BTreeMap<String, Vec<Value>>,
) -> PyResult<()> {
Expand Down Expand Up @@ -847,12 +862,12 @@ impl Document {

let value_list = if let Some(field_type) = field_type {
extract_value_single_or_list_for_type(
key_value.get_item(1)?,
&key_value.get_item(1)?,
field_type,
key.as_str(),
)?
} else {
extract_value_single_or_list(key_value.get_item(1)?)?
extract_value_single_or_list(&key_value.get_item(1)?)?
};

out_field_values.insert(key, value_list);
Expand Down
Loading

0 comments on commit cc7e785

Please sign in to comment.