Skip to content

Commit

Permalink
feat : upgraded pyo3 and removed deprecated code incompatible with py…
Browse files Browse the repository at this point in the history
…o3 newest version
  • Loading branch information
Senhaji-Rhazi-Hamza committed Dec 16, 2024
1 parent 9855f93 commit d3bc337
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 47 deletions.
8 changes: 7 additions & 1 deletion .github/workflows/release-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,10 @@ jobs:
twine check artifacts/**/*.tar.gz
twine upload artifacts/**/*.tar.gz
twine check artifacts/**/*.whl
twine upload artifacts/**/*.whl
for file in artifacts/**/*.whl; do
if [[ -f "$file" ]]; then
echo "Uploading $file..."
twine upload "$file" || echo "Failed to upload $file"
fi
done
# twine upload artifacts/**/*.whl
2 changes: 1 addition & 1 deletion 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
@@ -1,6 +1,6 @@
[package]
name = "polodb_python" # Must match the Python package name
version = "0.1.16"
version = "0.1.17"
edition = "2021"
description = "Python bindings for PoloDB"
license = "Apache License"
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "polodb-python"
version = "0.1.16"
version = "0.1.17"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.9"
Expand Down
51 changes: 36 additions & 15 deletions src/helper_type_translator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ pub fn convert_py_list_to_vec_document<'a>(py_list_obj: &'a Py<PyAny>) -> Vec<Do
if let Ok(py_list) = py_list_obj.downcast_bound::<PyList>(py) {
// If downcast is successful, return an iterator over the list's items
let iter = py_list.iter().map(|item| {
let py_obj: Py<PyAny> = item.to_object(item.py());
// let py_obj: Py<PyAny> = item.to_object(item.py());
let py_obj2 = item.into_pyobject(py).unwrap();
// Convert each item (expected to be a dictionary) into a BSON document

convert_py_obj_to_document(&py_obj).unwrap()
convert_py_obj_to_document(py_obj2.as_unbound()).unwrap()
});
Vec::from_iter(iter)
} else {
Expand All @@ -32,7 +33,8 @@ pub fn convert_py_obj_to_document(py_obj: &Py<PyAny>) -> PyResult<Document> {
for (key, value) in dict.iter() {
// Use `iter()` on the `PyDict`
let key: String = key.extract()?; // Extract the key as a string
let bson_value = convert_py_obj_to_bson(value.to_object(py).as_any())?; // Convert value to BSON
let bson_value =
convert_py_obj_to_bson(value.into_pyobject(py).unwrap().as_unbound())?; // Convert value to BSON
doc.insert(key, bson_value);
}
Ok(doc)
Expand Down Expand Up @@ -70,7 +72,8 @@ pub fn convert_py_obj_to_bson(py_obj: &Py<PyAny>) -> PyResult<Bson> {
for (key, value) in dict.iter() {
let key_str: String = key.extract::<String>()?;

let bson_value = convert_py_obj_to_bson(value.to_object(py).as_any())?;
let bson_value =
convert_py_obj_to_bson(value.into_pyobject(py).unwrap().as_unbound())?;
bson_doc.insert(key_str, bson_value);
}
Ok(Bson::Document(bson_doc))
Expand All @@ -79,7 +82,8 @@ pub fn convert_py_obj_to_bson(py_obj: &Py<PyAny>) -> PyResult<Bson> {
else if let Ok(list) = py_obj.downcast_bound::<PyList>(py) {
let mut bson_array = Vec::new();
for item in list.iter() {
let bson_item = convert_py_obj_to_bson(item.to_object(py).as_any())?;
let bson_item =
convert_py_obj_to_bson(item.into_pyobject(py).unwrap().as_unbound())?;
bson_array.push(bson_item);
}
Ok(Bson::Array(bson_array))
Expand Down Expand Up @@ -133,7 +137,15 @@ pub fn bson_to_py_obj(py: Python, bson: &Bson) -> PyObject {
Bson::Int64(i) => i.into_pyobject(py).unwrap().into(),
Bson::Double(f) => PyFloat::new(py, *f).into_pyobject(py).unwrap().into(),
Bson::String(s) => PyString::new(py, s).into_pyobject(py).unwrap().into(),
Bson::Boolean(b) => PyBool::new(py, *b).into_py(py),
// Bson::Boolean(b) => {
// // PyBool::new(py, *b) -> &PyBool (borrowed), convert it with Py::from
// // Create a &PyBool
// let py_bool_ref = PyBool::new(py, *b).as_unbound().clone_ref(py);
// // Coerce &PyBool to &PyAny by assignment
// let py_any: &PyAny = py_bool_ref ;
// py_bool_ref
// }
Bson::Boolean(b) => PyBool::new(py, *b).as_unbound().clone_ref(py).into_any(),
Bson::Array(arr) => {
// Create an empty PyList without specifying a slice
let py_list = PyList::empty(py); // Use empty method instead of new
Expand All @@ -150,25 +162,34 @@ pub fn bson_to_py_obj(py: Python, bson: &Bson) -> PyObject {
py_dict.into_pyobject(py).unwrap().into()
}
Bson::RegularExpression(regex) => {
let re_module = py.import_bound("re").unwrap();
let re_module = py.import("re").unwrap();
re_module
.call_method1("compile", (regex.pattern.as_str(),))
.unwrap()
.to_object(py)
.into_pyobject(py)
.unwrap()
.into()
}
// Handle JavaScript code
Bson::JavaScriptCode(code) => PyString::new(py, code).into_pyobject(py).unwrap().into(),
Bson::Timestamp(ts) => (ts.time, ts.increment).into_pyobject(py).unwrap().into(),
Bson::Binary(bin) => PyBytes::new(py, &bin.bytes).into_pyobject(py).unwrap().into(),
Bson::ObjectId(oid) => PyString::new(py, &oid.to_hex()).into_pyobject(py).unwrap().into(),
Bson::Binary(bin) => PyBytes::new(py, &bin.bytes)
.into_pyobject(py)
.unwrap()
.into(),
Bson::ObjectId(oid) => PyString::new(py, &oid.to_hex())
.into_pyobject(py)
.unwrap()
.into(),
Bson::DateTime(dt) => {
let timestamp = dt.timestamp_millis() / 1000;
let datetime = py
.import_bound("datetime")
let datetime = py.import("datetime").unwrap().getattr("datetime").unwrap();
datetime
.call1((timestamp,))
.unwrap()
.into_pyobject(py)
.unwrap()
.getattr("datetime")
.unwrap();
datetime.call1((timestamp,)).unwrap().to_object(py)
.into()
}
Bson::Symbol(s) => PyString::new(py, s).into_pyobject(py).unwrap().into(),

Expand Down
56 changes: 28 additions & 28 deletions src/py_database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use polodb_core::options::UpdateOptions;
use polodb_core::{Collection, CollectionT, Database};
use pyo3::exceptions::PyOSError;
use pyo3::exceptions::PyRuntimeError; // Import PyRuntimeError for error handling
use pyo3::prelude::*;
use pyo3::{prelude::*, IntoPyObjectExt};
use pyo3::types::{PyDict, PyList};
use std::borrow::Borrow;
use std::path::Path;
Expand All @@ -31,7 +31,7 @@ impl PyCollection {

// Example: Create a Python object or interact with the Python runtime.
let bson_vec_docs: Vec<Document> =
convert_py_list_to_vec_document(doc.to_object(py).as_any());
convert_py_list_to_vec_document(&doc.into_py_any(py).unwrap());
// let bson_doc = convert_py_to_bson(doc);
match self.inner.insert_many(bson_vec_docs) {
Ok(result) => {
Expand All @@ -42,7 +42,7 @@ impl PyCollection {
dict.set_item(key, bson_to_py_obj(py, value)).unwrap();
}

Ok(dict.to_object(py))
Ok(dict.into_py_any(py).unwrap())
}
Err(e) => {
// Raise a Python exception on error
Expand All @@ -55,7 +55,7 @@ impl PyCollection {
pub fn insert_one(&self, doc: Py<PyDict>) -> PyResult<PyObject> {
// Acquire the Python GIL (Global Interpreter Lock)
Python::with_gil(|py| {
let bson_doc: Document = match convert_py_obj_to_document(doc.to_object(py).as_any()) {
let bson_doc: Document = match convert_py_obj_to_document(&doc.into_py_any(py).unwrap()) {
Ok(d) => d,
Err(e) => return Err(PyRuntimeError::new_err(format!("Insert many error: {}", e))),
};
Expand All @@ -67,7 +67,7 @@ impl PyCollection {
let dict = PyDict::new(py);
let dict_ref = dict.borrow();
dict_ref.set_item("inserted_id", py_inserted_id)?;
Ok(dict.to_object(py))
Ok(dict.into_py_any(py).unwrap())

// Ok(Py::new(py, result)?.to_object(py))
}
Expand All @@ -86,15 +86,15 @@ impl PyCollection {
update: Py<PyDict>,
) -> PyResult<Option<PyObject>> {
// Convert PyDict to BSON Document
let filter_doc = convert_py_obj_to_document(filter.to_object(py).as_any())?;
let update_doc = convert_py_obj_to_document(update.to_object(py).as_any())?;
let filter_doc = convert_py_obj_to_document(&filter.into_py_any(py).unwrap())?;
let update_doc = convert_py_obj_to_document(&update.into_py_any(py).unwrap())?;

// Call the Rust method `find_one`
match self.inner.update_one(filter_doc, update_doc) {
Ok(update_result) => {
// Convert BSON Document to Python Dict
let py_result = update_result_to_pydict(py, update_result).unwrap();
Ok(Some(py_result.to_object(py)))
Ok(Some(py_result.into_py_any(py).unwrap()))
}
Err(err) => Err(PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(format!(
"Update one error: {}",
Expand All @@ -110,15 +110,15 @@ impl PyCollection {
update: Py<PyDict>,
) -> PyResult<Option<PyObject>> {
// Convert PyDict to BSON Document
let filter_doc = convert_py_obj_to_document(filter.to_object(py).as_any())?;
let update_doc = convert_py_obj_to_document(update.to_object(py).as_any())?;
let filter_doc = convert_py_obj_to_document(&filter.into_py_any(py).unwrap())?;
let update_doc = convert_py_obj_to_document(&update.into_py_any(py).unwrap())?;

// Call the Rust method `find_one`
match self.inner.update_many(filter_doc, update_doc) {
Ok(update_result) => {
// Convert BSON Document to Python Dict
let py_result = update_result_to_pydict(py, update_result).unwrap();
Ok(Some(py_result.to_object(py)))
Ok(Some(py_result.into_py_any(py).unwrap()))
}
Err(err) => Err(PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(format!(
"Update many error: {}",
Expand All @@ -134,8 +134,8 @@ impl PyCollection {
update: Py<PyDict>,
) -> PyResult<Option<PyObject>> {
// Convert PyDict to BSON Document
let filter_doc = convert_py_obj_to_document(filter.to_object(py).as_any())?;
let update_doc = convert_py_obj_to_document(update.to_object(py).as_any())?;
let filter_doc = convert_py_obj_to_document(&filter.into_py_any(py).unwrap())?;
let update_doc = convert_py_obj_to_document(&update.into_py_any(py).unwrap())?;

match self.inner.update_one_with_options(
filter_doc,
Expand All @@ -145,7 +145,7 @@ impl PyCollection {
Ok(update_result) => {
// Convert BSON Document to Python Dict
let py_result = update_result_to_pydict(py, update_result).unwrap();
Ok(Some(py_result.to_object(py)))
Ok(Some(py_result.into_py_any(py).unwrap()))
}
Err(err) => Err(PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(format!(
"Upsert one error: {}",
Expand All @@ -158,7 +158,7 @@ impl PyCollection {
Python::with_gil(|py| {

let bson_vec_pipeline: Vec<Document> =
convert_py_list_to_vec_document(pipeline.to_object(py).as_any());
convert_py_list_to_vec_document(&pipeline.into_py_any(py).unwrap());
match self.inner.aggregate(bson_vec_pipeline).run() {
Ok(result) => {
let vec_result = result.collect::<Result<Vec<Document>, _>>().unwrap();
Expand All @@ -167,7 +167,7 @@ impl PyCollection {
.into_iter()
.map(|x| document_to_pydict(py, x).unwrap())
.collect();
Ok(py_result.to_object(py))
Ok(py_result.into_py_any(py).unwrap())
}
Err(e) => {
// Raise a Python exception on error
Expand All @@ -184,8 +184,8 @@ impl PyCollection {
update: Py<PyDict>,
) -> PyResult<Option<PyObject>> {
// Convert PyDict to BSON Document
let filter_doc = convert_py_obj_to_document(filter.to_object(py).as_any())?;
let update_doc = convert_py_obj_to_document(update.to_object(py).as_any())?;
let filter_doc = convert_py_obj_to_document(&filter.into_py_any(py).unwrap())?;
let update_doc = convert_py_obj_to_document(&update.into_py_any(py).unwrap())?;

// Call the Rust method `find_one`
match self.inner.update_many_with_options(
Expand All @@ -196,7 +196,7 @@ impl PyCollection {
Ok(update_result) => {
// Convert BSON Document to Python Dict
let py_result = update_result_to_pydict(py, update_result).unwrap();
Ok(Some(py_result.to_object(py)))
Ok(Some(py_result.into_py_any(py).unwrap()))
}
Err(err) => Err(PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(format!(
"Upsert many error: {}",
Expand All @@ -207,9 +207,9 @@ impl PyCollection {

pub fn delete_one(&self, filter: Py<PyDict>) -> PyResult<PyObject> {
// Acquire the Python GIL (Global Interpreter Lock)
// let filter_doc = convert_py_obj_to_document(filter.to_object(py).as_any())?;
// let filter_doc = convert_py_obj_to_document(&filter.into_py_any(py).unwrap())?;
Python::with_gil(|py| {
let bson_doc: Document = match convert_py_obj_to_document(filter.to_object(py).as_any())
let bson_doc: Document = match convert_py_obj_to_document(&filter.into_py_any(py).unwrap())
{
Ok(d) => d,
Err(e) => return Err(PyRuntimeError::new_err(format!("Delete one : {}", e))),
Expand All @@ -219,7 +219,7 @@ impl PyCollection {
Ok(delete_result) => {
// Create a Python object from the Rust result and return it
let py_result = delete_result_to_pydict(py, delete_result).unwrap();
Ok(py_result.to_object(py))
Ok(py_result.into_py_any(py).unwrap())

// Ok(Py::new(py, result)?.to_object(py))
}
Expand All @@ -234,7 +234,7 @@ impl PyCollection {
pub fn delete_many(&self, filter: Py<PyDict>) -> PyResult<PyObject> {
// Acquire the Python GIL (Global Interpreter Lock)
Python::with_gil(|py| {
let bson_doc: Document = match convert_py_obj_to_document(filter.to_object(py).as_any())
let bson_doc: Document = match convert_py_obj_to_document(&filter.into_py_any(py).unwrap())
{
Ok(d) => d,
Err(e) => return Err(PyRuntimeError::new_err(format!("Delete many : {}", e))),
Expand All @@ -244,7 +244,7 @@ impl PyCollection {
Ok(delete_result) => {
// Create a Python object from the Rust result and return it
let py_result = delete_result_to_pydict(py, delete_result).unwrap();
Ok(py_result.to_object(py))
Ok(py_result.into_py_any(py).unwrap())

// Ok(Py::new(py, result)?.to_object(py))
}
Expand Down Expand Up @@ -274,14 +274,14 @@ impl PyCollection {

pub fn find_one(&self, py: Python, filter: Py<PyDict>) -> PyResult<Option<PyObject>> {
// Convert PyDict to BSON Document
let filter_doc = convert_py_obj_to_document(filter.to_object(py).as_any())?;
let filter_doc = convert_py_obj_to_document(&filter.into_py_any(py).unwrap())?;

// Call the Rust method `find_one`
match self.inner.find_one(filter_doc) {
Ok(Some(result_doc)) => {
// Convert BSON Document to Python Dict
let py_result = document_to_pydict(py, result_doc).unwrap();
Ok(Some(py_result.to_object(py)))
Ok(Some(py_result.into_py_any(py).unwrap()))
}
Ok(None) => Ok(None), // Return None if no document is found
Err(err) => Err(PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(format!(
Expand All @@ -292,7 +292,7 @@ impl PyCollection {
}
pub fn find(&self, py: Python, filter: Py<PyDict>) -> PyResult<Option<PyObject>> {
// Convert PyDict to BSON Document
let filter_doc = convert_py_obj_to_document(filter.to_object(py).as_any())?;
let filter_doc = convert_py_obj_to_document(&filter.into_py_any(py).unwrap())?;

// Call the Rust method `find_one`
match self.inner.find(filter_doc).run() {
Expand All @@ -302,7 +302,7 @@ impl PyCollection {
.map(|x| document_to_pydict(py, x.unwrap()).unwrap())
.collect();
// let py_result = document_to_pydict(py, result_doc).unwrap();
Ok(Some(py_result.to_object(py)))
Ok(Some(py_result.into_py_any(py).unwrap()))
}
// Ok(None) => Ok(None), // Return None if no document is found
Err(err) => Err(PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(format!(
Expand Down

0 comments on commit d3bc337

Please sign in to comment.