Skip to content

Commit

Permalink
Implement PyTypeInfo for PyEllipsis, PyNone, and `PyNotImplemen…
Browse files Browse the repository at this point in the history
…ted`
  • Loading branch information
davidhewitt committed Nov 15, 2023
1 parent 1e28ba7 commit ee70af3
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 45 deletions.
1 change: 1 addition & 0 deletions newsfragments/3577.added.md
@@ -0,0 +1 @@
Implement `PyTypeInfo` for `PyEllipsis`, `PyNone` and `PyNotImplemented`.
32 changes: 17 additions & 15 deletions src/types/ellipsis.rs
@@ -1,4 +1,4 @@
use crate::{ffi, PyAny, PyDowncastError, PyTryFrom, Python};
use crate::{ffi, PyAny, PyTypeInfo, Python};

/// Represents the Python `Ellipsis` object.
#[repr(transparent)]
Expand All @@ -15,24 +15,26 @@ impl PyEllipsis {
}
}

impl<'v> PyTryFrom<'v> for PyEllipsis {
fn try_from<V: Into<&'v PyAny>>(value: V) -> Result<&'v Self, crate::PyDowncastError<'v>> {
let value: &PyAny = value.into();
if unsafe { ffi::Py_Ellipsis() == value.as_ptr() } {
return unsafe { Ok(value.downcast_unchecked()) };
}
Err(PyDowncastError::new(value, "ellipsis"))
unsafe impl PyTypeInfo for PyEllipsis {
const NAME: &'static str = "ellipsis";

const MODULE: Option<&'static str> = None;

type AsRefTarget = PyEllipsis;

fn type_object_raw(_py: Python<'_>) -> *mut ffi::PyTypeObject {
unsafe { ffi::Py_TYPE(ffi::Py_Ellipsis()) }
}

fn try_from_exact<V: Into<&'v PyAny>>(
value: V,
) -> Result<&'v Self, crate::PyDowncastError<'v>> {
value.into().downcast()
#[inline]
fn is_type_of(object: &PyAny) -> bool {
// ellipsis is not usable as a base type
Self::is_exact_type_of(object)
}

unsafe fn try_from_unchecked<V: Into<&'v PyAny>>(value: V) -> &'v Self {
let ptr = value.into() as *const _ as *const PyEllipsis;
&*ptr
#[inline]
fn is_exact_type_of(object: &PyAny) -> bool {
object.is(PyEllipsis::get(object.py()))
}
}

Expand Down
32 changes: 17 additions & 15 deletions src/types/none.rs
@@ -1,4 +1,4 @@
use crate::{ffi, IntoPy, PyAny, PyDowncastError, PyObject, PyTryFrom, Python, ToPyObject};
use crate::{ffi, IntoPy, PyAny, PyObject, PyTypeInfo, Python, ToPyObject};

/// Represents the Python `None` object.
#[repr(transparent)]
Expand All @@ -15,24 +15,26 @@ impl PyNone {
}
}

impl<'v> PyTryFrom<'v> for PyNone {
fn try_from<V: Into<&'v PyAny>>(value: V) -> Result<&'v Self, crate::PyDowncastError<'v>> {
let value: &PyAny = value.into();
if value.is_none() {
return unsafe { Ok(value.downcast_unchecked()) };
}
Err(PyDowncastError::new(value, "NoneType"))
unsafe impl PyTypeInfo for PyNone {
const NAME: &'static str = "NoneType";

const MODULE: Option<&'static str> = None;

type AsRefTarget = PyNone;

fn type_object_raw(_py: Python<'_>) -> *mut ffi::PyTypeObject {
unsafe { ffi::Py_TYPE(ffi::Py_None()) }
}

fn try_from_exact<V: Into<&'v PyAny>>(
value: V,
) -> Result<&'v Self, crate::PyDowncastError<'v>> {
value.into().downcast()
#[inline]
fn is_type_of(object: &PyAny) -> bool {
// NoneType is not usable as a base type
Self::is_exact_type_of(object)
}

unsafe fn try_from_unchecked<V: Into<&'v PyAny>>(value: V) -> &'v Self {
let ptr = value.into() as *const _ as *const PyNone;
&*ptr
#[inline]
fn is_exact_type_of(object: &PyAny) -> bool {
object.is_none()
}
}

Expand Down
32 changes: 17 additions & 15 deletions src/types/notimplemented.rs
@@ -1,4 +1,4 @@
use crate::{ffi, PyAny, PyDowncastError, PyTryFrom, Python};
use crate::{ffi, PyAny, PyTypeInfo, Python};

/// Represents the Python `NotImplemented` object.
#[repr(transparent)]
Expand All @@ -15,24 +15,26 @@ impl PyNotImplemented {
}
}

impl<'v> PyTryFrom<'v> for PyNotImplemented {
fn try_from<V: Into<&'v PyAny>>(value: V) -> Result<&'v Self, crate::PyDowncastError<'v>> {
let value: &PyAny = value.into();
if unsafe { ffi::Py_NotImplemented() == value.as_ptr() } {
return unsafe { Ok(value.downcast_unchecked()) };
}
Err(PyDowncastError::new(value, "NotImplementedType"))
unsafe impl PyTypeInfo for PyNotImplemented {
const NAME: &'static str = "NotImplementedType";

const MODULE: Option<&'static str> = None;

type AsRefTarget = PyNotImplemented;

fn type_object_raw(_py: Python<'_>) -> *mut ffi::PyTypeObject {
unsafe { ffi::Py_TYPE(ffi::Py_NotImplemented()) }
}

fn try_from_exact<V: Into<&'v PyAny>>(
value: V,
) -> Result<&'v Self, crate::PyDowncastError<'v>> {
value.into().downcast()
#[inline]
fn is_type_of(object: &PyAny) -> bool {
// NoneType is not usable as a base type
Self::is_exact_type_of(object)
}

unsafe fn try_from_unchecked<V: Into<&'v PyAny>>(value: V) -> &'v Self {
let ptr = value.into() as *const _ as *const PyNotImplemented;
&*ptr
#[inline]
fn is_exact_type_of(object: &PyAny) -> bool {
object.is(PyNotImplemented::get(object.py()))
}
}

Expand Down

0 comments on commit ee70af3

Please sign in to comment.