Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make Bound and Borrowed types public API #3686

Merged
merged 8 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions newsfragments/3686.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add `Bound<T>` and `Borrowed<T>` smart pointers as a new API for accessing Python objects.
48 changes: 24 additions & 24 deletions src/err/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::instance::Py2;
use crate::instance::Bound;
use crate::panic::PanicException;
use crate::type_object::PyTypeInfo;
use crate::types::any::PyAnyMethods;
Expand Down Expand Up @@ -65,16 +65,16 @@ impl<'a> PyDowncastError<'a> {

/// Error that indicates a failure to convert a PyAny to a more specific Python type.
#[derive(Debug)]
pub(crate) struct PyDowncastError2<'a, 'py> {
from: &'a Py2<'py, PyAny>,
pub struct DowncastError<'a, 'py> {
from: &'a Bound<'py, PyAny>,
to: Cow<'static, str>,
}

impl<'a, 'py> PyDowncastError2<'a, 'py> {
impl<'a, 'py> DowncastError<'a, 'py> {
/// Create a new `PyDowncastError` representing a failure to convert the object
/// `from` into the type named in `to`.
pub fn new(from: &'a Py2<'py, PyAny>, to: impl Into<Cow<'static, str>>) -> Self {
PyDowncastError2 {
pub fn new(from: &'a Bound<'py, PyAny>, to: impl Into<Cow<'static, str>>) -> Self {
DowncastError {
from,
to: to.into(),
}
Expand All @@ -83,16 +83,16 @@ impl<'a, 'py> PyDowncastError2<'a, 'py> {

/// Error that indicates a failure to convert a PyAny to a more specific Python type.
#[derive(Debug)]
pub(crate) struct PyDowncastIntoError<'py> {
from: Py2<'py, PyAny>,
pub struct DowncastIntoError<'py> {
from: Bound<'py, PyAny>,
to: Cow<'static, str>,
}

impl<'py> PyDowncastIntoError<'py> {
/// Create a new `PyDowncastIntoError` representing a failure to convert the object
impl<'py> DowncastIntoError<'py> {
/// Create a new `DowncastIntoError` representing a failure to convert the object
/// `from` into the type named in `to`.
pub fn new(from: Py2<'py, PyAny>, to: impl Into<Cow<'static, str>>) -> Self {
PyDowncastIntoError {
pub fn new(from: Bound<'py, PyAny>, to: impl Into<Cow<'static, str>>) -> Self {
DowncastIntoError {
from,
to: to.into(),
}
Expand Down Expand Up @@ -811,13 +811,13 @@ impl<'a> std::error::Error for PyDowncastError<'a> {}

impl<'a> std::fmt::Display for PyDowncastError<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
display_downcast_error(f, Py2::borrowed_from_gil_ref(&self.from), &self.to)
display_downcast_error(f, Bound::borrowed_from_gil_ref(&self.from), &self.to)
}
}

/// Convert `PyDowncastError2` to Python `TypeError`.
impl std::convert::From<PyDowncastError2<'_, '_>> for PyErr {
fn from(err: PyDowncastError2<'_, '_>) -> PyErr {
/// Convert `DowncastError` to Python `TypeError`.
impl std::convert::From<DowncastError<'_, '_>> for PyErr {
fn from(err: DowncastError<'_, '_>) -> PyErr {
let args = PyDowncastErrorArguments {
from: err.from.get_type().into(),
to: err.to,
Expand All @@ -827,17 +827,17 @@ impl std::convert::From<PyDowncastError2<'_, '_>> for PyErr {
}
}

impl std::error::Error for PyDowncastError2<'_, '_> {}
impl std::error::Error for DowncastError<'_, '_> {}

impl std::fmt::Display for PyDowncastError2<'_, '_> {
impl std::fmt::Display for DowncastError<'_, '_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
display_downcast_error(f, self.from, &self.to)
}
}

/// Convert `PyDowncastIntoError` to Python `TypeError`.
impl std::convert::From<PyDowncastIntoError<'_>> for PyErr {
fn from(err: PyDowncastIntoError<'_>) -> PyErr {
/// Convert `DowncastIntoError` to Python `TypeError`.
impl std::convert::From<DowncastIntoError<'_>> for PyErr {
fn from(err: DowncastIntoError<'_>) -> PyErr {
let args = PyDowncastErrorArguments {
from: err.from.get_type().into(),
to: err.to,
Expand All @@ -847,17 +847,17 @@ impl std::convert::From<PyDowncastIntoError<'_>> for PyErr {
}
}

impl std::error::Error for PyDowncastIntoError<'_> {}
impl std::error::Error for DowncastIntoError<'_> {}

impl std::fmt::Display for PyDowncastIntoError<'_> {
impl std::fmt::Display for DowncastIntoError<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
display_downcast_error(f, &self.from, &self.to)
}
}

fn display_downcast_error(
f: &mut std::fmt::Formatter<'_>,
from: &Py2<'_, PyAny>,
from: &Bound<'_, PyAny>,
to: &str,
) -> std::fmt::Result {
write!(
Expand Down
48 changes: 20 additions & 28 deletions src/ffi_ptr_ext.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
ffi,
instance::{Py2, Py2Borrowed},
instance::{Borrowed, Bound},
PyAny, PyResult, Python,
};

Expand All @@ -15,65 +15,57 @@ mod sealed {
use sealed::Sealed;

pub(crate) trait FfiPtrExt: Sealed {
unsafe fn assume_owned_or_err(self, py: Python<'_>) -> PyResult<Py2<'_, PyAny>>;
unsafe fn assume_owned(self, py: Python<'_>) -> Py2<'_, PyAny>;
unsafe fn assume_owned_or_err(self, py: Python<'_>) -> PyResult<Bound<'_, PyAny>>;
unsafe fn assume_owned(self, py: Python<'_>) -> Bound<'_, PyAny>;

/// Assumes this pointer is borrowed from a parent object.
///
/// Warning: the lifetime `'a` is not bounded by the function arguments; the caller is
/// responsible to ensure this is tied to some appropriate lifetime.
unsafe fn assume_borrowed_or_err<'a>(
self,
py: Python<'_>,
) -> PyResult<Py2Borrowed<'a, '_, PyAny>>;
unsafe fn assume_borrowed_or_err<'a>(self, py: Python<'_>)
-> PyResult<Borrowed<'a, '_, PyAny>>;

/// Same as `assume_borrowed_or_err`, but doesn't fetch an error on NULL.
unsafe fn assume_borrowed_or_opt<'a>(
self,
py: Python<'_>,
) -> Option<Py2Borrowed<'a, '_, PyAny>>;
unsafe fn assume_borrowed_or_opt<'a>(self, py: Python<'_>) -> Option<Borrowed<'a, '_, PyAny>>;

/// Same as `assume_borrowed_or_err`, but panics on NULL.
unsafe fn assume_borrowed<'a>(self, py: Python<'_>) -> Py2Borrowed<'a, '_, PyAny>;
unsafe fn assume_borrowed<'a>(self, py: Python<'_>) -> Borrowed<'a, '_, PyAny>;

/// Same as `assume_borrowed_or_err`, but does not check for NULL.
unsafe fn assume_borrowed_unchecked<'a>(self, py: Python<'_>) -> Py2Borrowed<'a, '_, PyAny>;
unsafe fn assume_borrowed_unchecked<'a>(self, py: Python<'_>) -> Borrowed<'a, '_, PyAny>;
}

impl FfiPtrExt for *mut ffi::PyObject {
#[inline]
unsafe fn assume_owned_or_err(self, py: Python<'_>) -> PyResult<Py2<'_, PyAny>> {
Py2::from_owned_ptr_or_err(py, self)
unsafe fn assume_owned_or_err(self, py: Python<'_>) -> PyResult<Bound<'_, PyAny>> {
Bound::from_owned_ptr_or_err(py, self)
}

#[inline]
unsafe fn assume_owned(self, py: Python<'_>) -> Py2<'_, PyAny> {
Py2::from_owned_ptr(py, self)
unsafe fn assume_owned(self, py: Python<'_>) -> Bound<'_, PyAny> {
Bound::from_owned_ptr(py, self)
}

#[inline]
unsafe fn assume_borrowed_or_err<'a>(
self,
py: Python<'_>,
) -> PyResult<Py2Borrowed<'a, '_, PyAny>> {
Py2Borrowed::from_ptr_or_err(py, self)
) -> PyResult<Borrowed<'a, '_, PyAny>> {
Borrowed::from_ptr_or_err(py, self)
}

#[inline]
unsafe fn assume_borrowed_or_opt<'a>(
self,
py: Python<'_>,
) -> Option<Py2Borrowed<'a, '_, PyAny>> {
Py2Borrowed::from_ptr_or_opt(py, self)
unsafe fn assume_borrowed_or_opt<'a>(self, py: Python<'_>) -> Option<Borrowed<'a, '_, PyAny>> {
Borrowed::from_ptr_or_opt(py, self)
}

#[inline]
unsafe fn assume_borrowed<'a>(self, py: Python<'_>) -> Py2Borrowed<'a, '_, PyAny> {
Py2Borrowed::from_ptr(py, self)
unsafe fn assume_borrowed<'a>(self, py: Python<'_>) -> Borrowed<'a, '_, PyAny> {
Borrowed::from_ptr(py, self)
}

#[inline]
unsafe fn assume_borrowed_unchecked<'a>(self, py: Python<'_>) -> Py2Borrowed<'a, '_, PyAny> {
Py2Borrowed::from_ptr_unchecked(py, self)
unsafe fn assume_borrowed_unchecked<'a>(self, py: Python<'_>) -> Borrowed<'a, '_, PyAny> {
Borrowed::from_ptr_unchecked(py, self)
}
}
Loading
Loading