diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bef1e2c0..a30d0b38 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,7 @@ ci: repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.1.0 + rev: v5.0.0 hooks: - id: trailing-whitespace - repo: https://github.com/pre-commit/mirrors-mypy @@ -58,6 +58,8 @@ repos: - clippy::all - -W - clippy::pedantic + # - -D + # - warnings - id: check types: diff --git a/python/psqlpy/_internal/__init__.pyi b/python/psqlpy/_internal/__init__.pyi index 73011b45..ddb74de1 100644 --- a/python/psqlpy/_internal/__init__.pyi +++ b/python/psqlpy/_internal/__init__.pyi @@ -815,16 +815,6 @@ class Connection: Return representation of prepared statement. """ - async def commit(self: Self) -> None: - """Commit the transaction. - - Do nothing if there is no active transaction. - """ - async def rollback(self: Self) -> None: - """Rollback the transaction. - - Do nothing if there is no active transaction. - """ async def execute( self: Self, querystring: str, diff --git a/src/connection/impls.rs b/src/connection/impls.rs index 931770aa..795554c2 100644 --- a/src/connection/impls.rs +++ b/src/connection/impls.rs @@ -31,9 +31,9 @@ where ) -> PSQLPyResult<()> { let start_qs = self.build_start_qs(isolation_level, read_variant, deferrable); self.batch_execute(start_qs.as_str()).await.map_err(|err| { - RustPSQLDriverError::TransactionBeginError( - format!("Cannot start transaction due to - {err}").into(), - ) + RustPSQLDriverError::TransactionBeginError(format!( + "Cannot start transaction due to - {err}" + )) })?; Ok(()) @@ -65,7 +65,7 @@ impl Connection for SingleConnection { if !prepared { self.drop_prepared(&prepared_stmt).await?; } - return Ok(prepared_stmt); + Ok(prepared_stmt) } async fn drop_prepared(&self, stmt: &Statement) -> PSQLPyResult<()> { @@ -116,28 +116,27 @@ impl StartTransaction for SingleConnection { read_variant: Option, deferrable: Option, ) -> PSQLPyResult<()> { - let res = self - ._start_transaction(isolation_level, read_variant, deferrable) + self._start_transaction(isolation_level, read_variant, deferrable) .await?; self.in_transaction = true; - Ok(res) + Ok(()) } } impl CloseTransaction for SingleConnection { async fn commit(&mut self) -> PSQLPyResult<()> { - let res = self._commit().await?; + self._commit().await?; self.in_transaction = false; - Ok(res) + Ok(()) } async fn rollback(&mut self) -> PSQLPyResult<()> { - let res = self._rollback().await?; + self._rollback().await?; self.in_transaction = false; - Ok(res) + Ok(()) } } @@ -149,7 +148,7 @@ impl Connection for PoolConnection { let prepared = self.connection.prepare(query).await?; self.drop_prepared(&prepared).await?; - return Ok(prepared); + Ok(prepared) } async fn drop_prepared(&self, stmt: &Statement) -> PSQLPyResult<()> { @@ -208,17 +207,17 @@ impl StartTransaction for PoolConnection { impl CloseTransaction for PoolConnection { async fn commit(&mut self) -> PSQLPyResult<()> { - let res = self._commit().await?; + self._commit().await?; self.in_transaction = false; - Ok(res) + Ok(()) } async fn rollback(&mut self) -> PSQLPyResult<()> { - let res = self._rollback().await?; + self._rollback().await?; self.in_transaction = false; - Ok(res) + Ok(()) } } @@ -407,14 +406,14 @@ impl PSQLPyConnection { for statement in statements { let querystring_result = if prepared { - let prepared_stmt = &self.prepare(&statement.raw_query(), true).await; + let prepared_stmt = &self.prepare(statement.raw_query(), true).await; if let Err(error) = prepared_stmt { return Err(RustPSQLDriverError::ConnectionExecuteError(format!( "Cannot prepare statement in execute_many, operation rolled back {error}", ))); } self.query( - &self.prepare(&statement.raw_query(), true).await?, + &self.prepare(statement.raw_query(), true).await?, &statement.params(), ) .await @@ -429,7 +428,7 @@ impl PSQLPyConnection { } } - return Ok(()); + Ok(()) } pub async fn fetch_row_raw( @@ -447,7 +446,7 @@ impl PSQLPyConnection { let result = if prepared { self.query_one( &self - .prepare(&statement.raw_query(), true) + .prepare(statement.raw_query(), true) .await .map_err(|err| { RustPSQLDriverError::ConnectionExecuteError(format!( @@ -464,7 +463,7 @@ impl PSQLPyConnection { .map_err(|err| RustPSQLDriverError::ConnectionExecuteError(format!("{err}")))? }; - return Ok(result); + Ok(result) } pub async fn fetch_row( @@ -477,7 +476,7 @@ impl PSQLPyConnection { .fetch_row_raw(querystring, parameters, prepared) .await?; - return Ok(PSQLDriverSinglePyQueryResult::new(result)); + Ok(PSQLDriverSinglePyQueryResult::new(result)) } pub async fn fetch_val( @@ -490,10 +489,10 @@ impl PSQLPyConnection { .fetch_row_raw(querystring, parameters, prepared) .await?; - return Python::with_gil(|gil| match result.columns().first() { + Python::with_gil(|gil| match result.columns().first() { Some(first_column) => postgres_to_py(gil, &result, first_column, 0, &None), None => Ok(gil.None()), - }); + }) } pub async fn copy_in(&self, statement: &T) -> PSQLPyResult> diff --git a/src/connection/traits.rs b/src/connection/traits.rs index ccf8f467..1e9d0960 100644 --- a/src/connection/traits.rs +++ b/src/connection/traits.rs @@ -1,5 +1,4 @@ use postgres_types::{ToSql, Type}; -use pyo3::PyAny; use tokio_postgres::{Row, Statement, ToStatement}; use crate::exceptions::rust_errors::PSQLPyResult; diff --git a/src/driver/connection_pool.rs b/src/driver/connection_pool.rs index 16e1fe90..7d7d96e8 100644 --- a/src/driver/connection_pool.rs +++ b/src/driver/connection_pool.rs @@ -238,7 +238,7 @@ impl ConnectionPool { prepare: Option, ) -> Self { ConnectionPool { - pool: pool, + pool, pg_config: Arc::new(pg_config), pool_conf: ConnectionPoolConf::new(ca_file, ssl_mode, prepare.unwrap_or(true)), } diff --git a/src/driver/cursor.rs b/src/driver/cursor.rs index 3a8abe59..1dde4723 100644 --- a/src/driver/cursor.rs +++ b/src/driver/cursor.rs @@ -59,7 +59,7 @@ impl Cursor { let Some(portal) = &self.inner else { return Err(RustPSQLDriverError::TransactionClosedError); }; - transaction.query_portal(&portal, size).await + transaction.query_portal(portal, size).await } } @@ -157,7 +157,7 @@ impl Cursor { fn __anext__(&self) -> PSQLPyResult> { let txid = self.transaction.clone(); let portal = self.inner.clone(); - let size = self.array_size.clone(); + let size = self.array_size; let py_future = Python::with_gil(move |gil| { rustdriver_future(gil, async move { @@ -167,7 +167,7 @@ impl Cursor { let Some(portal) = &portal else { return Err(RustPSQLDriverError::TransactionClosedError); }; - let result = txid.query_portal(&portal, size).await?; + let result = txid.query_portal(portal, size).await?; if result.is_empty() { return Err(PyStopAsyncIteration::new_err( @@ -192,7 +192,7 @@ impl Cursor { let (txid, inner_portal) = match &self.querystring { Some(querystring) => { write_conn_g - .portal(Some(&querystring), &self.parameters, None) + .portal(Some(querystring), &self.parameters, None) .await? } None => { @@ -201,7 +201,7 @@ impl Cursor { "Cannot start cursor".into(), )); }; - write_conn_g.portal(None, &None, Some(&statement)).await? + write_conn_g.portal(None, &None, Some(statement)).await? } }; diff --git a/src/driver/transaction.rs b/src/driver/transaction.rs index 87f1a282..781d95d3 100644 --- a/src/driver/transaction.rs +++ b/src/driver/transaction.rs @@ -78,7 +78,7 @@ impl Transaction { .start_transaction(isolation_level, read_variant, deferrable) .await?; - return Ok(self_); + Ok(self_) } #[allow(clippy::needless_pass_by_value)] @@ -114,7 +114,7 @@ impl Transaction { let mut self_ = self_.borrow_mut(gil); self_.conn = None; }); - return Err(RustPSQLDriverError::RustPyError(py_err)); + Err(RustPSQLDriverError::RustPyError(py_err)) } } @@ -277,7 +277,7 @@ impl Transaction { let mut futures = vec![]; if let Some(queries) = queries { let gil_result = pyo3::Python::with_gil(|gil| -> PyResult<()> { - for single_query in queries.into_bound(gil).iter() { + for single_query in queries.into_bound(gil).try_iter() { let query_tuple = single_query.downcast::().map_err(|err| { RustPSQLDriverError::PyToRustValueConversionError(format!( "Cannot cast to tuple: {err}", diff --git a/src/query_result.rs b/src/query_result.rs index d9dd8848..b17acad9 100644 --- a/src/query_result.rs +++ b/src/query_result.rs @@ -1,9 +1,4 @@ -use pyo3::{ - prelude::*, - pyclass, pymethods, - types::{PyDict, PyTuple}, - Py, PyAny, Python, ToPyObject, -}; +use pyo3::{prelude::*, pyclass, pymethods, types::PyDict, IntoPyObjectExt, Py, PyAny, Python}; use tokio_postgres::Row; use crate::{exceptions::rust_errors::PSQLPyResult, value_converter::to_python::postgres_to_py}; @@ -24,7 +19,7 @@ fn row_to_dict<'a>( let python_dict = PyDict::new(py); for (column_idx, column) in postgres_row.columns().iter().enumerate() { let python_type = postgres_to_py(py, postgres_row, column, column_idx, custom_decoders)?; - python_dict.set_item(column.name().to_object(py), python_type)?; + python_dict.set_item(column.name().into_py_any(py)?, python_type)?; } Ok(python_dict) } @@ -72,7 +67,7 @@ impl PSQLDriverPyQueryResult { for row in &self.inner { result.push(row_to_dict(py, row, &custom_decoders)?); } - Ok(result.to_object(py)) + Ok(result.into_py_any(py)?) } /// Convert result from database to any class passed from Python. @@ -83,14 +78,14 @@ impl PSQLDriverPyQueryResult { /// postgres type to python or create new Python class. #[allow(clippy::needless_pass_by_value)] pub fn as_class<'a>(&'a self, py: Python<'a>, as_class: Py) -> PSQLPyResult> { - let mut res: Vec> = vec![]; + let mut result: Vec> = vec![]; for row in &self.inner { let pydict: pyo3::Bound<'_, PyDict> = row_to_dict(py, row, &None)?; let convert_class_inst = as_class.call(py, (), Some(&pydict))?; - res.push(convert_class_inst); + result.push(convert_class_inst); } - Ok(res.to_object(py)) + Ok(result.into_py_any(py)?) } /// Convert result from database with function passed from Python. @@ -107,13 +102,13 @@ impl PSQLDriverPyQueryResult { row_factory: Py, custom_decoders: Option>, ) -> PSQLPyResult> { - let mut res: Vec> = vec![]; + let mut result: Vec> = vec![]; for row in &self.inner { let pydict: pyo3::Bound<'_, PyDict> = row_to_dict(py, row, &custom_decoders)?; let row_factory_class = row_factory.call(py, (pydict,), None)?; - res.push(row_factory_class); + result.push(row_factory_class); } - Ok(res.to_object(py)) + Ok(result.into_py_any(py)?) } } @@ -154,7 +149,7 @@ impl PSQLDriverSinglePyQueryResult { py: Python<'_>, custom_decoders: Option>, ) -> PSQLPyResult> { - Ok(row_to_dict(py, &self.inner, &custom_decoders)?.to_object(py)) + Ok(row_to_dict(py, &self.inner, &custom_decoders)?.into_py_any(py)?) } /// Convert result from database to any class passed from Python. @@ -184,7 +179,7 @@ impl PSQLDriverSinglePyQueryResult { row_factory: Py, custom_decoders: Option>, ) -> PSQLPyResult> { - let pydict = row_to_dict(py, &self.inner, &custom_decoders)?.to_object(py); + let pydict = row_to_dict(py, &self.inner, &custom_decoders)?.into_py_any(py)?; Ok(row_factory.call(py, (pydict,), None)?) } } diff --git a/src/row_factories.rs b/src/row_factories.rs index e867df0a..e68decd5 100644 --- a/src/row_factories.rs +++ b/src/row_factories.rs @@ -1,7 +1,7 @@ use pyo3::{ pyclass, pyfunction, pymethods, types::{PyDict, PyDictMethods, PyModule, PyModuleMethods, PyTuple}, - wrap_pyfunction, Bound, Py, PyAny, PyResult, Python, ToPyObject, + wrap_pyfunction, Bound, IntoPyObject, Py, PyAny, PyResult, Python, }; use crate::exceptions::rust_errors::{PSQLPyResult, RustPSQLDriverError}; @@ -14,7 +14,10 @@ fn tuple_row(py: Python<'_>, dict_: Py) -> PSQLPyResult> { "as_tuple accepts only dict as a parameter".into(), ) })?; - Ok(PyTuple::new_bound(py, dict_.items()).to_object(py)) + match PyTuple::new(py, dict_.items())?.into_pyobject(py) { + Ok(x) => Ok(x.unbind().into_any()), + _ => unreachable!(), + } } #[pyclass] @@ -24,7 +27,7 @@ struct class_row(Py); #[pymethods] impl class_row { #[new] - fn constract_class(class_: Py) -> Self { + fn construct_class(class_: Py) -> Self { Self(class_) } @@ -35,7 +38,7 @@ impl class_row { "as_tuple accepts only dict as a parameter".into(), ) })?; - Ok(self.0.call_bound(py, (), Some(dict_))?) + Ok(self.0.call(py, (), Some(dict_))?) } } diff --git a/src/statement/cache.rs b/src/statement/cache.rs index 7c07da40..a0f071d8 100644 --- a/src/statement/cache.rs +++ b/src/statement/cache.rs @@ -17,7 +17,7 @@ impl StatementsCache { } pub fn get_cache(&self, querystring: &String) -> Option { - let qs_hash = hash_str(&querystring); + let qs_hash = hash_str(querystring); if let Some(cache_info) = self.0.get(&qs_hash) { return Some(cache_info.clone()); @@ -35,10 +35,10 @@ pub(crate) struct StatementCacheInfo { impl StatementCacheInfo { fn new(query: &QueryString, inner_stmt: &Statement) -> Self { - return Self { + Self { query: query.clone(), inner_stmt: inner_stmt.clone(), - }; + } } pub(crate) fn types(&self) -> Vec { @@ -49,7 +49,7 @@ impl StatementCacheInfo { self.inner_stmt .columns() .iter() - .map(|column| Column::new(column.name().to_string(), column.table_oid().clone())) + .map(|column| Column::new(column.name().to_string(), column.table_oid())) .collect::>() } } diff --git a/src/statement/parameters.rs b/src/statement/parameters.rs index 3aa12160..6b74b902 100644 --- a/src/statement/parameters.rs +++ b/src/statement/parameters.rs @@ -40,7 +40,7 @@ impl Column { #[getter] fn get_table_oid(&self) -> Option { - self.table_oid.clone() + self.table_oid } } @@ -108,9 +108,9 @@ impl ParametersBuilder { return Ok(prepared_parameters); } - return Err(RustPSQLDriverError::PyToRustValueConversionError( + Err(RustPSQLDriverError::PyToRustValueConversionError( "Parameters must be sequence or mapping".into(), - )); + )) } fn as_type FromPyObjectBound<'a, 'py>>(&self, gil: Python<'_>) -> Option { @@ -163,8 +163,8 @@ impl MappingParametersBuilder { parameters_names: Vec, ) -> PSQLPyResult { match self.types.clone() { - Some(types) => return self.prepare_typed(gil, parameters_names, types), - None => return self.prepare_not_typed(gil, parameters_names), + Some(types) => self.prepare_typed(gil, parameters_names, types), + None => self.prepare_not_typed(gil, parameters_names), } } @@ -177,7 +177,7 @@ impl MappingParametersBuilder { let extracted_parameters = self.extract_parameters(gil, parameters_names)?; let zipped_params_types = zip(extracted_parameters, &types); let converted_parameters = zipped_params_types - .map(|(parameter, type_)| from_python_typed(parameter.bind(gil), &type_)) + .map(|(parameter, type_)| from_python_typed(parameter.bind(gil), type_)) .collect::>>()?; Ok(PreparedParameters::new( @@ -216,9 +216,10 @@ impl MappingParametersBuilder { match self.map_parameters.bind(gil).get_item(¶m_name) { Ok(param_value) => params_as_pyobject.push(param_value.unbind()), Err(_) => { - return Err(RustPSQLDriverError::PyToRustValueConversionError( - format!("Cannot find parameter with name <{}>", param_name).into(), - )) + return Err(RustPSQLDriverError::PyToRustValueConversionError(format!( + "Cannot find parameter with name <{}>", + param_name + ))) } } } @@ -236,7 +237,7 @@ pub(crate) struct SequenceParametersBuilder { impl SequenceParametersBuilder { fn new(seq_parameters: Vec, types: Option>, columns: Vec) -> Self { Self { - seq_parameters: seq_parameters, + seq_parameters, types, columns, } @@ -244,15 +245,15 @@ impl SequenceParametersBuilder { fn prepare(self, gil: Python<'_>) -> PSQLPyResult { match self.types.clone() { - Some(types) => return self.prepare_typed(gil, types), - None => return self.prepare_not_typed(gil), + Some(types) => self.prepare_typed(gil, types), + None => self.prepare_not_typed(gil), } } fn prepare_typed(self, gil: Python<'_>, types: Vec) -> PSQLPyResult { let zipped_params_types = zip(self.seq_parameters, &types); let converted_parameters = zipped_params_types - .map(|(parameter, type_)| from_python_typed(parameter.bind(gil), &type_)) + .map(|(parameter, type_)| from_python_typed(parameter.bind(gil), type_)) .collect::>>()?; Ok(PreparedParameters::new( diff --git a/src/statement/query.rs b/src/statement/query.rs index 108fe756..54d78266 100644 --- a/src/statement/query.rs +++ b/src/statement/query.rs @@ -22,10 +22,10 @@ impl Display for QueryString { impl QueryString { pub fn new(initial_qs: &String) -> Self { - return Self { + Self { initial_qs: initial_qs.clone(), converted_qs: None, - }; + } } pub(crate) fn query(&self) -> &str { @@ -33,7 +33,7 @@ impl QueryString { return converted_qs.query(); } - return &self.initial_qs; + &self.initial_qs } pub(crate) fn hash(&self) -> u64 { @@ -42,7 +42,7 @@ impl QueryString { pub(crate) fn process_qs(&mut self) { if !self.is_kwargs_parametrized() { - return (); + return; } let mut counter = 0; diff --git a/src/statement/statement.rs b/src/statement/statement.rs index fc45b3eb..b1f85f53 100644 --- a/src/statement/statement.rs +++ b/src/statement/statement.rs @@ -34,12 +34,10 @@ impl PsqlpyStatement { pub fn statement_query(&self) -> PSQLPyResult<&Statement> { match &self.prepared_statement { - Some(prepared_stmt) => return Ok(prepared_stmt), - None => { - return Err(RustPSQLDriverError::ConnectionExecuteError( - "No prepared parameters".into(), - )) - } + Some(prepared_stmt) => Ok(prepared_stmt), + None => Err(RustPSQLDriverError::ConnectionExecuteError( + "No prepared parameters".into(), + )), } } @@ -52,6 +50,6 @@ impl PsqlpyStatement { } pub fn columns(&self) -> &Vec { - &self.prepared_parameters.columns() + self.prepared_parameters.columns() } } diff --git a/src/statement/statement_builder.rs b/src/statement/statement_builder.rs index 054352a3..9c9b27bd 100644 --- a/src/statement/statement_builder.rs +++ b/src/statement/statement_builder.rs @@ -40,7 +40,7 @@ impl<'a> StatementBuilder<'a> { if !self.prepared { { let stmt_cache_guard = STMTS_CACHE.read().await; - if let Some(cached) = stmt_cache_guard.get_cache(&self.querystring) { + if let Some(cached) = stmt_cache_guard.get_cache(self.querystring) { return self.build_with_cached(cached); } } @@ -52,28 +52,28 @@ impl<'a> StatementBuilder<'a> { fn build_with_cached(self, cached: StatementCacheInfo) -> PSQLPyResult { let raw_parameters = - ParametersBuilder::new(&self.parameters, Some(cached.types()), cached.columns()); + ParametersBuilder::new(self.parameters, Some(cached.types()), cached.columns()); - let parameters_names = if let Some(converted_qs) = &cached.query.converted_qs { - Some(converted_qs.params_names().clone()) - } else { - None - }; + let parameters_names = cached + .query + .converted_qs + .as_ref() + .map(|converted_qs| converted_qs.params_names().clone()); let prepared_parameters = raw_parameters.prepare(parameters_names)?; - return Ok(PsqlpyStatement::new( + Ok(PsqlpyStatement::new( cached.query, prepared_parameters, None, - )); + )) } async fn build_no_cached( self, cache_guard: RwLockWriteGuard<'_, StatementsCache>, ) -> PSQLPyResult { - let mut querystring = QueryString::new(&self.querystring); + let mut querystring = QueryString::new(self.querystring); querystring.process_qs(); let prepared_stmt = self.prepare_query(&querystring, self.prepared).await?; @@ -81,34 +81,31 @@ impl<'a> StatementBuilder<'a> { let columns = prepared_stmt .columns() .iter() - .map(|column| Column::new(column.name().to_string(), column.table_oid().clone())) + .map(|column| Column::new(column.name().to_string(), column.table_oid())) .collect::>(); let parameters_builder = ParametersBuilder::new( - &self.parameters, + self.parameters, Some(prepared_stmt.params().to_vec()), columns, ); - let parameters_names = if let Some(converted_qs) = &querystring.converted_qs { - Some(converted_qs.params_names().clone()) - } else { - None - }; + let parameters_names = querystring + .converted_qs + .as_ref() + .map(|converted_qs| converted_qs.params_names().clone()); let prepared_parameters = parameters_builder.prepare(parameters_names)?; match self.prepared { - true => { - return Ok(PsqlpyStatement::new( - querystring, - prepared_parameters, - Some(prepared_stmt), - )) - } + true => Ok(PsqlpyStatement::new( + querystring, + prepared_parameters, + Some(prepared_stmt), + )), false => { self.write_to_cache(cache_guard, &querystring, &prepared_stmt) .await; - return Ok(PsqlpyStatement::new(querystring, prepared_parameters, None)); + Ok(PsqlpyStatement::new(querystring, prepared_parameters, None)) } } } diff --git a/src/value_converter/additional_types.rs b/src/value_converter/additional_types.rs index 1159939a..2d6bce61 100644 --- a/src/value_converter/additional_types.rs +++ b/src/value_converter/additional_types.rs @@ -7,17 +7,19 @@ use macaddr::{MacAddr6, MacAddr8}; use postgres_protocol::types; use postgres_types::{to_sql_checked, IsNull, ToSql}; use pyo3::{ - types::{PyList, PyTuple}, - IntoPy, Py, PyAny, PyObject, Python, ToPyObject, + types::{PyFloat, PyList, PyTuple}, + Bound, IntoPyObject, PyAny, Python, }; use serde::{Deserialize, Serialize}; use tokio_postgres::types::{FromSql, Type}; +use crate::exceptions::rust_errors::{PSQLPyResult, RustPSQLDriverError}; + pub struct NonePyType; macro_rules! build_additional_rust_type { ($st_name:ident, $rust_type:ty) => { - #[derive(Debug)] + #[derive(Debug, Clone)] pub struct $st_name { inner: $rust_type, } @@ -80,51 +82,118 @@ build_additional_rust_type!(RustRect, Rect); build_additional_rust_type!(RustLineString, LineString); build_additional_rust_type!(RustLineSegment, LineSegment); -impl ToPyObject for RustPoint { - fn to_object(&self, py: Python<'_>) -> PyObject { - self.into_py(py) - } +macro_rules! new_py_any_vec { + ($py_struct:ident, $py:expr, $vec:expr) => { + match $py_struct::new($py, $vec) { + Ok(t) => Ok(t.into_any()), + Err(_) => Err(RustPSQLDriverError::RustToPyValueConversionError( + "TODO".into(), + )), + } + }; +} + +fn coord_to_pytuple_any<'py>(py: Python<'py>, coord: &Coord) -> PSQLPyResult> { + let tuple_vec = vec![ + coord.x.into_pyobject(py).unwrap(), + coord.y.into_pyobject(py).unwrap(), + ]; + new_py_any_vec!(PyTuple, py, tuple_vec) } -impl ToPyObject for RustRect { - fn to_object(&self, py: Python<'_>) -> PyObject { - self.into_py(py) +impl<'py> IntoPyObject<'py> for RustPoint { + type Target = PyAny; + type Output = Bound<'py, Self::Target>; + type Error = RustPSQLDriverError; + + fn into_pyobject(self, py: Python<'py>) -> Result { + let inner_value = self.inner(); + coord_to_pytuple_any(py, &inner_value.0) } } -impl ToPyObject for RustLineString { - fn to_object(&self, py: Python<'_>) -> PyObject { - self.into_py(py) +impl<'py> IntoPyObject<'py> for RustRect { + type Target = PyAny; + type Output = Bound<'py, Self::Target>; + type Error = RustPSQLDriverError; + + fn into_pyobject(self, py: Python<'py>) -> Result { + let inner_value = self.inner(); + + let mut result_vec: Vec> = vec![]; + let coordinates = vec![inner_value.max(), inner_value.min()]; + for one_coordinate in coordinates { + result_vec.push(coord_to_pytuple_any(py, &one_coordinate)?); + } + new_py_any_vec!(PyTuple, py, result_vec) } } -impl ToPyObject for RustLineSegment { - fn to_object(&self, py: Python<'_>) -> PyObject { - self.into_py(py) +impl<'py> IntoPyObject<'py> for RustLineString { + type Target = PyAny; + type Output = Bound<'py, Self::Target>; + type Error = RustPSQLDriverError; + + fn into_pyobject(self, py: Python<'py>) -> Result { + let inner_value = self.inner(); + + let mut result_vec: Vec> = vec![]; + for coordinate in inner_value { + result_vec.push(coord_to_pytuple_any(py, coordinate)?); + } + + if inner_value.is_closed() { + return new_py_any_vec!(PyTuple, py, result_vec); + } + new_py_any_vec!(PyList, py, result_vec) } } -impl ToPyObject for Line { - fn to_object(&self, py: Python<'_>) -> PyObject { - self.into_py(py) +impl<'py> IntoPyObject<'py> for RustLineSegment { + type Target = PyAny; + type Output = Bound<'py, Self::Target>; + type Error = RustPSQLDriverError; + + fn into_pyobject(self, py: Python<'py>) -> Result { + let inner_value = self.inner(); + + let mut result_vec: Vec> = vec![]; + for coordinate in [inner_value.start, inner_value.end] { + result_vec.push(coord_to_pytuple_any(py, &coordinate)?); + } + new_py_any_vec!(PyList, py, result_vec) } } -impl ToPyObject for Circle { - fn to_object(&self, py: Python<'_>) -> PyObject { - self.into_py(py) +impl<'py> IntoPyObject<'py> for Line { + type Target = PyAny; + type Output = Bound<'py, Self::Target>; + type Error = RustPSQLDriverError; + + fn into_pyobject(self, py: Python<'py>) -> Result { + let result_vec: Vec> = vec![ + self.a().into_pyobject(py).unwrap(), + self.b().into_pyobject(py).unwrap(), + self.c().into_pyobject(py).unwrap(), + ]; + + new_py_any_vec!(PyTuple, py, result_vec) } } -impl IntoPy for &RustPoint { - #[inline] - fn into_py(self, py: Python<'_>) -> PyObject { - let inner_value = self.inner(); - PyTuple::new_bound( - py, - vec![inner_value.x().into_py(py), inner_value.y().into_py(py)], - ) - .into() +impl<'py> IntoPyObject<'py> for Circle { + type Target = PyAny; + type Output = Bound<'py, Self::Target>; + type Error = RustPSQLDriverError; + + fn into_pyobject(self, py: Python<'py>) -> Result { + let center = self.center(); + + let result_vec: Vec> = vec![ + coord_to_pytuple_any(py, ¢er)?, + self.radius().into_pyobject(py).unwrap().into_any(), + ]; + new_py_any_vec!(PyTuple, py, result_vec) } } @@ -159,26 +228,6 @@ impl<'a> FromSql<'a> for RustPoint { } } -impl IntoPy for &RustRect { - #[inline] - fn into_py(self, py: Python<'_>) -> PyObject { - let inner_value = self.inner(); - - let mut result_vec: Vec> = vec![]; - let coordinates = vec![inner_value.max(), inner_value.min()]; - for one_coordinate in coordinates { - result_vec.push( - PyTuple::new_bound( - py, - vec![one_coordinate.x.into_py(py), one_coordinate.y.into_py(py)], - ) - .into(), - ); - } - PyTuple::new_bound(py, result_vec).into() - } -} - impl ToSql for RustRect { fn to_sql( &self, @@ -210,26 +259,6 @@ impl<'a> FromSql<'a> for RustRect { } } -impl IntoPy for &RustLineString { - #[inline] - fn into_py(self, py: Python<'_>) -> PyObject { - let inner_value = self.inner(); - - let mut result_vec: Vec> = vec![]; - for coordinate in inner_value { - result_vec.push( - PyTuple::new_bound(py, vec![coordinate.x.into_py(py), coordinate.y.into_py(py)]) - .into(), - ); - } - - if inner_value.is_closed() { - return PyTuple::new_bound(py, result_vec).into(); - } - PyList::new_bound(py, result_vec).into() - } -} - impl ToSql for RustLineString { fn to_sql( &self, @@ -261,23 +290,6 @@ impl<'a> FromSql<'a> for RustLineString { } } -impl IntoPy for &RustLineSegment { - #[inline] - fn into_py(self, py: Python<'_>) -> PyObject { - let inner_value = self.inner(); - - let mut result_vec: Vec> = vec![]; - for coordinate in [inner_value.start, inner_value.end] { - result_vec.push( - PyTuple::new_bound(py, vec![coordinate.x.into_py(py), coordinate.y.into_py(py)]) - .into(), - ); - } - - PyList::new_bound(py, result_vec).into() - } -} - impl ToSql for RustLineSegment { fn to_sql( &self, @@ -447,19 +459,6 @@ impl DivAssign for Line { } } -impl IntoPy for &Line { - #[inline] - fn into_py(self, py: Python<'_>) -> PyObject { - let result_vec: Vec> = vec![ - self.a().into_py(py), - self.b().into_py(py), - self.c().into_py(py), - ]; - - PyTuple::new_bound(py, result_vec).into() - } -} - impl ToSql for Line { fn to_sql( &self, @@ -565,20 +564,6 @@ impl Circle { } } -impl IntoPy for &Circle { - #[inline] - fn into_py(self, py: Python<'_>) -> PyObject { - let center = self.center(); - - let result_vec: Vec> = vec![ - PyTuple::new_bound(py, vec![center.x.into_py(py), center.y.into_py(py)]).into(), - self.radius().into_py(py), - ]; - - PyTuple::new_bound(py, result_vec).into() - } -} - impl ToSql for Circle { fn to_sql( &self, diff --git a/src/value_converter/dto/converter_impls.rs b/src/value_converter/dto/converter_impls.rs index f50529bc..35f7bbde 100644 --- a/src/value_converter/dto/converter_impls.rs +++ b/src/value_converter/dto/converter_impls.rs @@ -67,9 +67,9 @@ impl ToPythonDTO for PyDateTime { return Ok(PythonDTO::PyDateTimeTz(pydatetime_tz)); } - return Err(RustPSQLDriverError::PyToRustValueConversionError( + Err(RustPSQLDriverError::PyToRustValueConversionError( "Can not convert you datetime to rust type".into(), - )); + )) } } @@ -79,9 +79,9 @@ impl ToPythonDTO for PyDelta { if let Some(interval) = Interval::from_duration(duration) { return Ok(PythonDTO::PyInterval(interval)); } - return Err(RustPSQLDriverError::PyToRustValueConversionError( + Err(RustPSQLDriverError::PyToRustValueConversionError( "Cannot convert timedelta from Python to inner Rust type.".to_string(), - )); + )) } } @@ -89,7 +89,7 @@ impl ToPythonDTO for PyDict { fn to_python_dto(python_param: &pyo3::Bound<'_, PyAny>) -> PSQLPyResult { let serde_value = build_serde_value(python_param)?; - return Ok(PythonDTO::PyJsonb(serde_value)); + Ok(PythonDTO::PyJsonb(serde_value)) } } diff --git a/src/value_converter/from_python.rs b/src/value_converter/from_python.rs index fa1d5c60..6c1c0022 100644 --- a/src/value_converter/from_python.rs +++ b/src/value_converter/from_python.rs @@ -426,9 +426,9 @@ fn from_python_array_typed(parameter: &pyo3::Bound<'_, PyAny>) -> PSQLPyResult

::to_python_dto(parameter); } - Err(RustPSQLDriverError::PyToRustValueConversionError(format!( - "Cannot convert parameter in extra types Array", - ))) + Err(RustPSQLDriverError::PyToRustValueConversionError( + "Cannot convert parameter in extra types Array".to_string(), + )) } /// Extract a timezone-aware datetime from a Python object. diff --git a/src/value_converter/models/decimal.rs b/src/value_converter/models/decimal.rs index 44a898a1..ba1e444e 100644 --- a/src/value_converter/models/decimal.rs +++ b/src/value_converter/models/decimal.rs @@ -1,18 +1,30 @@ use postgres_types::{FromSql, Type}; -use pyo3::{types::PyAnyMethods, Bound, IntoPyObject, PyAny, PyObject, Python, ToPyObject}; +use pyo3::{types::PyAnyMethods, Bound, IntoPyObject, IntoPyObjectExt, PyAny, Python}; use rust_decimal::Decimal; -use crate::value_converter::consts::get_decimal_cls; +use crate::{ + exceptions::rust_errors::RustPSQLDriverError, value_converter::consts::get_decimal_cls, +}; +#[derive(Clone)] pub struct InnerDecimal(pub Decimal); -impl ToPyObject for InnerDecimal { - fn to_object(&self, py: Python<'_>) -> PyObject { +impl<'py> IntoPyObject<'py> for InnerDecimal { + type Target = PyAny; + type Output = Bound<'py, Self::Target>; + type Error = RustPSQLDriverError; + + fn into_pyobject(self, py: Python<'py>) -> Result { let dec_cls = get_decimal_cls(py).expect("failed to load decimal.Decimal"); let ret = dec_cls .call1((self.0.to_string(),)) .expect("failed to call decimal.Decimal(value)"); - ret.to_object(py) + match ret.into_py_any(py) { + Ok(result) => Ok(result.bind(py).clone()), + Err(_) => Err(RustPSQLDriverError::RustToPyValueConversionError( + "Cannot convert Rust decimal to Python one".into(), + )), + } } } diff --git a/src/value_converter/models/interval.rs b/src/value_converter/models/interval.rs index 7259e20d..e4aa9ae1 100644 --- a/src/value_converter/models/interval.rs +++ b/src/value_converter/models/interval.rs @@ -2,24 +2,33 @@ use pg_interval::Interval; use postgres_types::{FromSql, Type}; use pyo3::{ types::{PyAnyMethods, PyDict, PyDictMethods}, - PyObject, Python, ToPyObject, + Bound, IntoPyObject, PyAny, Python, }; -use crate::value_converter::consts::get_timedelta_cls; +use crate::{ + exceptions::rust_errors::RustPSQLDriverError, value_converter::consts::get_timedelta_cls, +}; +#[derive(Clone)] pub struct InnerInterval(pub Interval); -impl ToPyObject for InnerInterval { - fn to_object(&self, py: Python<'_>) -> PyObject { +impl<'py> IntoPyObject<'py> for InnerInterval { + type Target = PyAny; + type Output = Bound<'py, Self::Target>; + type Error = RustPSQLDriverError; + fn into_pyobject(self, py: Python<'py>) -> Result { let td_cls = get_timedelta_cls(py).expect("failed to load datetime.timedelta"); - let pydict = PyDict::new_bound(py); + let pydict = PyDict::new(py); let months = self.0.months * 30; let _ = pydict.set_item("days", self.0.days + months); let _ = pydict.set_item("microseconds", self.0.microseconds); let ret = td_cls .call((), Some(&pydict)) .expect("failed to call datetime.timedelta(days=<>, microseconds=<>)"); - ret.to_object(py) + match ret.into_pyobject(py) { + Ok(res) => Ok(res), + Err(_) => unreachable!(), + } } } diff --git a/src/value_converter/models/serde_value.rs b/src/value_converter/models/serde_value.rs index 392e3fd0..8d61d5a8 100644 --- a/src/value_converter/models/serde_value.rs +++ b/src/value_converter/models/serde_value.rs @@ -4,7 +4,7 @@ use serde_json::{json, Map, Value}; use pyo3::{ types::{PyAnyMethods, PyDict, PyDictMethods, PyList, PyTuple}, - Bound, FromPyObject, Py, PyAny, PyObject, PyResult, Python, ToPyObject, + Bound, FromPyObject, IntoPyObject, Py, PyAny, PyResult, Python, }; use tokio_postgres::types::Type; @@ -31,11 +31,15 @@ impl<'a> FromPyObject<'a> for InternalSerdeValue { } } -impl ToPyObject for InternalSerdeValue { - fn to_object(&self, py: Python<'_>) -> PyObject { +impl<'py> IntoPyObject<'py> for InternalSerdeValue { + type Target = PyAny; + type Output = Bound<'py, Self::Target>; + type Error = RustPSQLDriverError; + + fn into_pyobject(self, py: Python<'py>) -> Result { match build_python_from_serde_value(py, self.0.clone()) { - Ok(ok_value) => ok_value, - Err(_) => py.None(), + Ok(ok_value) => Ok(ok_value.bind(py).clone()), + Err(err) => Err(err), } } } @@ -97,7 +101,7 @@ fn serde_value_from_dict(bind_value: &Bound<'_, PyAny>) -> PSQLPyResult { serde_map.insert(key, value.to_serde_value()?); } - return Ok(Value::Object(serde_map)); + Ok(Value::Object(serde_map)) } /// Convert python List of Dict type or just Dict into serde `Value`. @@ -108,7 +112,7 @@ fn serde_value_from_dict(bind_value: &Bound<'_, PyAny>) -> PSQLPyResult { pub fn build_serde_value(value: &Bound<'_, PyAny>) -> PSQLPyResult { Python::with_gil(|gil| { if value.is_instance_of::() { - return serde_value_from_list(gil, value); + serde_value_from_list(gil, value) } else if value.is_instance_of::() { return serde_value_from_dict(value); } else { diff --git a/src/value_converter/models/uuid.rs b/src/value_converter/models/uuid.rs index 100bfbf8..1b4a7794 100644 --- a/src/value_converter/models/uuid.rs +++ b/src/value_converter/models/uuid.rs @@ -2,7 +2,8 @@ use postgres_types::FromSql; use uuid::Uuid; use pyo3::{ - types::PyAnyMethods, Bound, FromPyObject, PyAny, PyObject, PyResult, Python, ToPyObject, + types::{PyAnyMethods, PyString}, + Bound, FromPyObject, IntoPyObject, PyAny, PyResult, Python, }; use tokio_postgres::types::Type; @@ -26,9 +27,17 @@ impl<'a> FromPyObject<'a> for InternalUuid { } } -impl ToPyObject for InternalUuid { - fn to_object(&self, py: Python<'_>) -> PyObject { - self.0.to_string().as_str().to_object(py) +impl<'py> IntoPyObject<'py> for InternalUuid { + type Target = PyString; + type Output = Bound<'py, Self::Target>; + type Error = RustPSQLDriverError; + + /// Performs the conversion. + fn into_pyobject(self, py: Python<'py>) -> Result { + match self.0.to_string().as_str().into_pyobject(py) { + Ok(result) => Ok(result), + _ => unreachable!(), + } } } diff --git a/src/value_converter/to_python.rs b/src/value_converter/to_python.rs index 6ee761bc..a7495775 100644 --- a/src/value_converter/to_python.rs +++ b/src/value_converter/to_python.rs @@ -9,11 +9,8 @@ use tokio_postgres::{Column, Row}; use uuid::Uuid; use pyo3::{ - types::{ - PyAnyMethods, PyBytes, PyDict, PyDictMethods, PyList, PyListMethods, PySet, PyString, - PyTuple, - }, - Bound, IntoPy, Py, PyAny, Python, ToPyObject, + types::{PyAnyMethods, PyBytes, PyDict, PyDictMethods, PyList, PyListMethods, PyString}, + Bound, IntoPyObject, IntoPyObjectExt, Py, PyAny, Python, }; use crate::{ @@ -43,10 +40,10 @@ pub fn build_python_from_serde_value(py: Python<'_>, value: Value) -> PSQLPyResu result_vec.push(build_python_from_serde_value(py, single_record)?); } - Ok(result_vec.to_object(py)) + Ok(result_vec.into_py_any(py)?) } Value::Object(mapping) => { - let py_dict = PyDict::new_bound(py); + let py_dict = PyDict::new(py); for (key, value) in mapping { py_dict.set_item( @@ -54,20 +51,19 @@ pub fn build_python_from_serde_value(py: Python<'_>, value: Value) -> PSQLPyResu build_python_from_serde_value(py, value)?, )?; } - - Ok(py_dict.to_object(py)) + Ok(py_dict.into_py_any(py)?) } - Value::Bool(boolean) => Ok(boolean.to_object(py)), + Value::Bool(boolean) => Ok(boolean.into_py_any(py)?), Value::Number(number) => { if number.is_f64() { - Ok(number.as_f64().to_object(py)) + Ok(number.as_f64().into_py_any(py)?) } else if number.is_i64() { - Ok(number.as_i64().to_object(py)) + Ok(number.as_i64().into_py_any(py)?) } else { - Ok(number.as_u64().to_object(py)) + Ok(number.as_u64().into_py_any(py)?) } } - Value::String(string) => Ok(string.to_object(py)), + Value::String(string) => Ok(string.into_py_any(py)?), Value::Null => Ok(py.None()), } } @@ -94,15 +90,15 @@ fn composite_field_postgres_to_py<'a, T: FromSql<'a>>( /// Convert rust array to python list. /// /// It can convert multidimensional arrays. -fn postgres_array_to_py( - py: Python<'_>, +fn postgres_array_to_py<'py, T: IntoPyObject<'py> + Clone>( + py: Python<'py>, array: Option>, ) -> Option> { array.map(|array| { inner_postgres_array_to_py( py, array.dimensions(), - array.iter().collect::>().as_slice(), + array.iter().cloned().collect::>(), 0, 0, ) @@ -111,15 +107,15 @@ fn postgres_array_to_py( /// Inner postgres array conversion to python list. #[allow(clippy::cast_sign_loss)] -fn inner_postgres_array_to_py( - py: Python<'_>, +fn inner_postgres_array_to_py<'py, T>( + py: Python<'py>, dimensions: &[Dimension], - data: &[T], + data: Vec, dimension_index: usize, mut lower_bound: usize, ) -> Py where - T: ToPyObject, + T: IntoPyObject<'py> + Clone, { let current_dimension = dimensions.get(dimension_index); @@ -127,14 +123,14 @@ where let possible_next_dimension = dimensions.get(dimension_index + 1); match possible_next_dimension { Some(next_dimension) => { - let final_list = PyList::empty_bound(py); + let final_list = PyList::empty(py); for _ in 0..current_dimension.len as usize { if dimensions.get(dimension_index + 1).is_some() { let inner_pylist = inner_postgres_array_to_py( py, dimensions, - &data[lower_bound..next_dimension.len as usize + lower_bound], + data[lower_bound..next_dimension.len as usize + lower_bound].to_vec(), dimension_index + 1, 0, ); @@ -146,12 +142,12 @@ where return final_list.unbind(); } None => { - return PyList::new_bound(py, data).unbind(); + return PyList::new(py, data).unwrap().unbind(); // TODO unwrap is unsafe } } } - PyList::empty_bound(py).unbind() + PyList::empty(py).unbind() } #[allow(clippy::too_many_lines)] @@ -168,83 +164,90 @@ fn postgres_bytes_to_py( let vec_of_bytes = composite_field_postgres_to_py::>>(type_, buf, is_simple)?; if let Some(vec_of_bytes) = vec_of_bytes { - return Ok(PyBytes::new_bound(py, &vec_of_bytes).to_object(py)); + return Ok(PyBytes::new(py, &vec_of_bytes).into_py_any(py)?); } Ok(py.None()) } - Type::OID => { - Ok(composite_field_postgres_to_py::>(type_, buf, is_simple)?.to_object(py)) - } + Type::OID => Ok( + composite_field_postgres_to_py::>(type_, buf, is_simple)? + .into_py_any(py)?, + ), Type::NAME => Ok( - composite_field_postgres_to_py::>(type_, buf, is_simple)?.to_object(py), + composite_field_postgres_to_py::>(type_, buf, is_simple)? + .into_py_any(py)?, ), // // ---------- String Types ---------- // // Convert TEXT and VARCHAR type into String, then into str Type::TEXT | Type::VARCHAR | Type::XML => Ok(composite_field_postgres_to_py::< Option, >(type_, buf, is_simple)? - .to_object(py)), + .into_py_any(py)?), // ---------- Boolean Types ---------- // Convert BOOL type into bool Type::BOOL => Ok( - composite_field_postgres_to_py::>(type_, buf, is_simple)?.to_object(py), + composite_field_postgres_to_py::>(type_, buf, is_simple)? + .into_py_any(py)?, ), // ---------- Number Types ---------- // Convert SmallInt into i16, then into int - Type::INT2 => { - Ok(composite_field_postgres_to_py::>(type_, buf, is_simple)?.to_object(py)) - } + Type::INT2 => Ok( + composite_field_postgres_to_py::>(type_, buf, is_simple)? + .into_py_any(py)?, + ), // Convert Integer into i32, then into int - Type::INT4 => { - Ok(composite_field_postgres_to_py::>(type_, buf, is_simple)?.to_object(py)) - } + Type::INT4 => Ok( + composite_field_postgres_to_py::>(type_, buf, is_simple)? + .into_py_any(py)?, + ), // Convert BigInt into i64, then into int - Type::INT8 | Type::MONEY => { - Ok(composite_field_postgres_to_py::>(type_, buf, is_simple)?.to_object(py)) - } + Type::INT8 | Type::MONEY => Ok(composite_field_postgres_to_py::>( + type_, buf, is_simple, + )? + .into_py_any(py)?), // Convert REAL into f32, then into float - Type::FLOAT4 => { - Ok(composite_field_postgres_to_py::>(type_, buf, is_simple)?.to_object(py)) - } + Type::FLOAT4 => Ok( + composite_field_postgres_to_py::>(type_, buf, is_simple)? + .into_py_any(py)?, + ), // Convert DOUBLE PRECISION into f64, then into float - Type::FLOAT8 => { - Ok(composite_field_postgres_to_py::>(type_, buf, is_simple)?.to_object(py)) - } + Type::FLOAT8 => Ok( + composite_field_postgres_to_py::>(type_, buf, is_simple)? + .into_py_any(py)?, + ), // ---------- Date Types ---------- // Convert DATE into NaiveDate, then into datetime.date Type::DATE => Ok(composite_field_postgres_to_py::>( type_, buf, is_simple, )? - .to_object(py)), + .into_py_any(py)?), // Convert Time into NaiveTime, then into datetime.time Type::TIME => Ok(composite_field_postgres_to_py::>( type_, buf, is_simple, )? - .to_object(py)), + .into_py_any(py)?), // Convert TIMESTAMP into NaiveDateTime, then into datetime.datetime Type::TIMESTAMP => Ok(composite_field_postgres_to_py::>( type_, buf, is_simple, )? - .to_object(py)), + .into_py_any(py)?), // Convert TIMESTAMP into NaiveDateTime, then into datetime.datetime Type::TIMESTAMPTZ => Ok( composite_field_postgres_to_py::>>(type_, buf, is_simple)? - .to_object(py), + .into_py_any(py)?, ), // ---------- UUID Types ---------- // Convert UUID into Uuid type, then into String if possible Type::UUID => { let rust_uuid = composite_field_postgres_to_py::>(type_, buf, is_simple)?; match rust_uuid { - Some(rust_uuid) => { - return Ok(PyString::new_bound(py, &rust_uuid.to_string()).to_object(py)) - } + Some(rust_uuid) => Ok(PyString::new(py, &rust_uuid.to_string()).into_py_any(py)?), None => Ok(py.None()), } } // ---------- IpAddress Types ---------- Type::INET => Ok( - composite_field_postgres_to_py::>(type_, buf, is_simple)?.to_object(py), + composite_field_postgres_to_py::>(type_, buf, is_simple)? + .into_py_any(py)?, ), // Convert JSON/JSONB into Serde Value, then into list or dict Type::JSONB | Type::JSON => { @@ -252,7 +255,7 @@ fn postgres_bytes_to_py( match db_json { Some(value) => Ok(build_python_from_serde_value(py, value)?), - None => Ok(py.None().to_object(py)), + None => Ok(py.None().into_py_any(py)?), } } // Convert MACADDR into inner type for macaddr6, then into str @@ -260,27 +263,27 @@ fn postgres_bytes_to_py( let macaddr_ = composite_field_postgres_to_py::>(type_, buf, is_simple)?; if let Some(macaddr_) = macaddr_ { - Ok(macaddr_.inner().to_string().to_object(py)) + Ok(macaddr_.inner().to_string().into_py_any(py)?) } else { - Ok(py.None().to_object(py)) + Ok(py.None().into_py_any(py)?) } } Type::MACADDR8 => { let macaddr_ = composite_field_postgres_to_py::>(type_, buf, is_simple)?; if let Some(macaddr_) = macaddr_ { - Ok(macaddr_.inner().to_string().to_object(py)) + Ok(macaddr_.inner().to_string().into_py_any(py)?) } else { - Ok(py.None().to_object(py)) + Ok(py.None().into_py_any(py)?) } } Type::NUMERIC => { if let Some(numeric_) = composite_field_postgres_to_py::>(type_, buf, is_simple)? { - return Ok(InnerDecimal(numeric_).to_object(py)); + return Ok(InnerDecimal(numeric_).into_py_any(py)?); } - Ok(py.None().to_object(py)) + Ok(py.None().into_py_any(py)?) } // ---------- Geo Types ---------- Type::POINT => { @@ -288,16 +291,16 @@ fn postgres_bytes_to_py( composite_field_postgres_to_py::>(type_, buf, is_simple)?; match point_ { - Some(point_) => Ok(point_.into_py(py)), - None => Ok(py.None().to_object(py)), + Some(point_) => Ok(point_.into_pyobject(py)?.unbind()), + None => Ok(py.None().into_py_any(py)?), } } Type::BOX => { let box_ = composite_field_postgres_to_py::>(type_, buf, is_simple)?; match box_ { - Some(box_) => Ok(box_.into_py(py)), - None => Ok(py.None().to_object(py)), + Some(box_) => Ok(box_.into_pyobject(py)?.unbind()), + None => Ok(py.None().into_py_any(py)?), } } Type::PATH => { @@ -305,16 +308,16 @@ fn postgres_bytes_to_py( composite_field_postgres_to_py::>(type_, buf, is_simple)?; match path_ { - Some(path_) => Ok(path_.into_py(py)), - None => Ok(py.None().to_object(py)), + Some(path_) => Ok(path_.into_pyobject(py)?.unbind()), + None => Ok(py.None().into_py_any(py)?), } } Type::LINE => { let line_ = composite_field_postgres_to_py::>(type_, buf, is_simple)?; match line_ { - Some(line_) => Ok(line_.into_py(py)), - None => Ok(py.None().to_object(py)), + Some(line_) => Ok(line_.into_pyobject(py)?.unbind()), + None => Ok(py.None().into_py_any(py)?), } } Type::LSEG => { @@ -322,23 +325,23 @@ fn postgres_bytes_to_py( composite_field_postgres_to_py::>(type_, buf, is_simple)?; match lseg_ { - Some(lseg_) => Ok(lseg_.into_py(py)), - None => Ok(py.None().to_object(py)), + Some(lseg_) => Ok(lseg_.into_pyobject(py)?.unbind()), + None => Ok(py.None().into_py_any(py)?), } } Type::CIRCLE => { let circle_ = composite_field_postgres_to_py::>(type_, buf, is_simple)?; match circle_ { - Some(circle_) => Ok(circle_.into_py(py)), - None => Ok(py.None().to_object(py)), + Some(circle_) => Ok(circle_.into_pyobject(py)?.unbind()), + None => Ok(py.None().into_py_any(py)?), } } Type::INTERVAL => { let interval = composite_field_postgres_to_py::>(type_, buf, is_simple)?; if let Some(interval) = interval { - return Ok(InnerInterval(interval).to_object(py)); + return Ok(InnerInterval(interval).into_py_any(py)?); } Ok(py.None()) } @@ -347,67 +350,67 @@ fn postgres_bytes_to_py( py, composite_field_postgres_to_py::>>(type_, buf, is_simple)?, ) - .to_object(py)), + .into_py_any(py)?), Type::OID_ARRAY => Ok(postgres_array_to_py( py, composite_field_postgres_to_py::>>(type_, buf, is_simple)?, ) - .to_object(py)), + .into_py_any(py)?), // Convert ARRAY of TEXT or VARCHAR into Vec, then into list[str] Type::TEXT_ARRAY | Type::VARCHAR_ARRAY | Type::XML_ARRAY => Ok(postgres_array_to_py( py, composite_field_postgres_to_py::>>(type_, buf, is_simple)?, ) - .to_object(py)), + .into_py_any(py)?), // ---------- Array Integer Types ---------- // Convert ARRAY of SmallInt into Vec, then into list[int] Type::INT2_ARRAY => Ok(postgres_array_to_py( py, composite_field_postgres_to_py::>>(type_, buf, is_simple)?, ) - .to_object(py)), + .into_py_any(py)?), // Convert ARRAY of Integer into Vec, then into list[int] Type::INT4_ARRAY => Ok(postgres_array_to_py( py, composite_field_postgres_to_py::>>(type_, buf, is_simple)?, ) - .to_object(py)), + .into_py_any(py)?), // Convert ARRAY of BigInt into Vec, then into list[int] Type::INT8_ARRAY | Type::MONEY_ARRAY => Ok(postgres_array_to_py( py, composite_field_postgres_to_py::>>(type_, buf, is_simple)?, ) - .to_object(py)), + .into_py_any(py)?), // Convert ARRAY of Float4 into Vec, then into list[float] Type::FLOAT4_ARRAY => Ok(postgres_array_to_py( py, composite_field_postgres_to_py::>>(type_, buf, is_simple)?, ) - .to_object(py)), + .into_py_any(py)?), // Convert ARRAY of Float8 into Vec, then into list[float] Type::FLOAT8_ARRAY => Ok(postgres_array_to_py( py, composite_field_postgres_to_py::>>(type_, buf, is_simple)?, ) - .to_object(py)), + .into_py_any(py)?), // Convert ARRAY of Date into Vec, then into list[datetime.date] Type::DATE_ARRAY => Ok(postgres_array_to_py( py, composite_field_postgres_to_py::>>(type_, buf, is_simple)?, ) - .to_object(py)), + .into_py_any(py)?), // Convert ARRAY of Time into Vec, then into list[datetime.date] Type::TIME_ARRAY => Ok(postgres_array_to_py( py, composite_field_postgres_to_py::>>(type_, buf, is_simple)?, ) - .to_object(py)), + .into_py_any(py)?), // Convert ARRAY of TIMESTAMP into Vec, then into list[datetime.date] Type::TIMESTAMP_ARRAY => Ok(postgres_array_to_py( py, composite_field_postgres_to_py::>>(type_, buf, is_simple)?, ) - .to_object(py)), + .into_py_any(py)?), // Convert ARRAY of TIMESTAMPTZ into Vec>, then into list[datetime.date] Type::TIMESTAMPTZ_ARRAY => Ok(postgres_array_to_py( py, @@ -415,76 +418,76 @@ fn postgres_bytes_to_py( type_, buf, is_simple, )?, ) - .to_object(py)), + .into_py_any(py)?), // Convert ARRAY of UUID into Vec>, then into list[UUID] Type::UUID_ARRAY => { let uuid_array = composite_field_postgres_to_py::>>( type_, buf, is_simple, )?; - Ok(postgres_array_to_py(py, uuid_array).to_object(py)) + Ok(postgres_array_to_py(py, uuid_array).into_py_any(py)?) } // Convert ARRAY of INET into Vec, then into list[IPv4Address | IPv6Address] Type::INET_ARRAY => Ok(postgres_array_to_py( py, composite_field_postgres_to_py::>>(type_, buf, is_simple)?, ) - .to_object(py)), + .into_py_any(py)?), Type::JSONB_ARRAY | Type::JSON_ARRAY => { let db_json_array = composite_field_postgres_to_py::>>( type_, buf, is_simple, )?; - Ok(postgres_array_to_py(py, db_json_array).to_object(py)) + Ok(postgres_array_to_py(py, db_json_array).into_py_any(py)?) } Type::NUMERIC_ARRAY => Ok(postgres_array_to_py( py, composite_field_postgres_to_py::>>(type_, buf, is_simple)?, ) - .to_object(py)), + .into_py_any(py)?), // ---------- Array Geo Types ---------- Type::POINT_ARRAY => { let point_array_ = composite_field_postgres_to_py::>>(type_, buf, is_simple)?; - Ok(postgres_array_to_py(py, point_array_).to_object(py)) + Ok(postgres_array_to_py(py, point_array_).into_py_any(py)?) } Type::BOX_ARRAY => { let box_array_ = composite_field_postgres_to_py::>>(type_, buf, is_simple)?; - Ok(postgres_array_to_py(py, box_array_).to_object(py)) + Ok(postgres_array_to_py(py, box_array_).into_py_any(py)?) } Type::PATH_ARRAY => { let path_array_ = composite_field_postgres_to_py::>>( type_, buf, is_simple, )?; - Ok(postgres_array_to_py(py, path_array_).to_object(py)) + Ok(postgres_array_to_py(py, path_array_).into_py_any(py)?) } Type::LINE_ARRAY => { let line_array_ = composite_field_postgres_to_py::>>(type_, buf, is_simple)?; - Ok(postgres_array_to_py(py, line_array_).to_object(py)) + Ok(postgres_array_to_py(py, line_array_).into_py_any(py)?) } Type::LSEG_ARRAY => { let lseg_array_ = composite_field_postgres_to_py::>>( type_, buf, is_simple, )?; - Ok(postgres_array_to_py(py, lseg_array_).to_object(py)) + Ok(postgres_array_to_py(py, lseg_array_).into_py_any(py)?) } Type::CIRCLE_ARRAY => { let circle_array_ = composite_field_postgres_to_py::>>(type_, buf, is_simple)?; - Ok(postgres_array_to_py(py, circle_array_).to_object(py)) + Ok(postgres_array_to_py(py, circle_array_).into_py_any(py)?) } Type::INTERVAL_ARRAY => { let interval_array_ = composite_field_postgres_to_py::>>( type_, buf, is_simple, )?; - Ok(postgres_array_to_py(py, interval_array_).to_object(py)) + Ok(postgres_array_to_py(py, interval_array_).into_py_any(py)?) } _ => other_postgres_bytes_to_py(py, type_, buf, is_simple), } @@ -504,7 +507,7 @@ pub fn other_postgres_bytes_to_py( let vector = composite_field_postgres_to_py::>(type_, buf, is_simple)?; match vector { Some(real_vector) => { - return Ok(real_vector.to_vec().to_object(py)); + return Ok(real_vector.to_vec().into_py_any(py)?); } None => return Ok(py.None()), } @@ -526,7 +529,7 @@ pub fn composite_postgres_to_py( buf: &mut &[u8], custom_decoders: &Option>, ) -> PSQLPyResult> { - let result_py_dict: Bound<'_, PyDict> = PyDict::new_bound(py); + let result_py_dict: Bound<'_, PyDict> = PyDict::new(py); let num_fields = postgres_types::private::read_be_i32(buf).map_err(|err| { RustPSQLDriverError::RustToPyValueConversionError(format!( @@ -558,13 +561,13 @@ pub fn composite_postgres_to_py( Kind::Simple | Kind::Array(_) => { result_py_dict.set_item( field.name(), - postgres_bytes_to_py(py, field.type_(), buf, false)?.to_object(py), + postgres_bytes_to_py(py, field.type_(), buf, false)?, )?; } Kind::Enum(_) => { result_py_dict.set_item( field.name(), - postgres_bytes_to_py(py, &Type::VARCHAR, buf, false)?.to_object(py), + postgres_bytes_to_py(py, &Type::VARCHAR, buf, false)?, )?; } _ => { @@ -572,14 +575,13 @@ pub fn composite_postgres_to_py( *buf = tail; result_py_dict.set_item( field.name(), - raw_bytes_data_process(py, buf, field.name(), field.type_(), custom_decoders)? - .to_object(py), + raw_bytes_data_process(py, buf, field.name(), field.type_(), custom_decoders)?, )?; } } } - Ok(result_py_dict.to_object(py)) + Ok(result_py_dict.into_py_any(py)?) } /// Process raw bytes from `PostgreSQL`.