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

types: clean up types macros #1592

Merged
merged 1 commit into from May 3, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 3 additions & 8 deletions src/exceptions.rs
Expand Up @@ -2,7 +2,6 @@

//! Exception types defined by Python.

use crate::type_object::PySizedLayout;
use crate::{ffi, PyResult, Python};
use std::ffi::CStr;
use std::ops;
Expand Down Expand Up @@ -78,9 +77,8 @@ macro_rules! import_exception {

$crate::pyobject_native_type_core!(
$name,
$crate::ffi::PyBaseExceptionObject,
*$name::type_object_raw($crate::Python::assume_gil_acquired()),
Some(stringify!($module))
#module=Some(stringify!($module))
);

impl $name {
Expand Down Expand Up @@ -164,9 +162,8 @@ macro_rules! create_exception_type_object {
($module: ident, $name: ident, $base: ty) => {
$crate::pyobject_native_type_core!(
$name,
$crate::ffi::PyBaseExceptionObject,
*$name::type_object_raw($crate::Python::assume_gil_acquired()),
Some(stringify!($module))
#module=Some(stringify!($module))
);

impl $name {
Expand Down Expand Up @@ -201,15 +198,13 @@ macro_rules! impl_native_exception (
pub struct $name($crate::PyAny);

$crate::impl_exception_boilerplate!($name);
$crate::pyobject_native_type_core!($name, $layout, *(ffi::$exc_name as *mut ffi::PyTypeObject), Some("builtins"));
$crate::pyobject_native_type!($name, $layout, *(ffi::$exc_name as *mut ffi::PyTypeObject));
);
($name:ident, $exc_name:ident) => (
impl_native_exception!($name, $exc_name, ffi::PyBaseExceptionObject);
)
);

impl PySizedLayout<PyBaseException> for ffi::PyBaseExceptionObject {}

impl_native_exception!(PyBaseException, PyExc_BaseException);
impl_native_exception!(PyException, PyExc_Exception);
impl_native_exception!(PyStopAsyncIteration, PyExc_StopAsyncIteration);
Expand Down
2 changes: 1 addition & 1 deletion src/types/any.rs
Expand Up @@ -61,7 +61,7 @@ pyobject_native_type_info!(
ffi::PyObject,
ffi::PyBaseObject_Type,
Some("builtins"),
PyObject_Check
#checkfunction=PyObject_Check
);

pyobject_native_type_extract!(PyAny);
Expand Down
2 changes: 1 addition & 1 deletion src/types/boolobject.rs
Expand Up @@ -8,7 +8,7 @@ use crate::{
#[repr(transparent)]
pub struct PyBool(PyAny);

pyobject_native_type!(PyBool, ffi::PyObject, ffi::PyBool_Type, ffi::PyBool_Check);
pyobject_native_type!(PyBool, ffi::PyObject, ffi::PyBool_Type, #checkfunction=ffi::PyBool_Check);

impl PyBool {
/// Depending on `val`, returns `true` or `false`.
Expand Down
2 changes: 1 addition & 1 deletion src/types/bytearray.rs
Expand Up @@ -9,7 +9,7 @@ use std::slice;
#[repr(transparent)]
pub struct PyByteArray(PyAny);

pyobject_native_var_type!(PyByteArray, ffi::PyByteArray_Type, ffi::PyByteArray_Check);
pyobject_native_type_core!(PyByteArray, ffi::PyByteArray_Type, #checkfunction=ffi::PyByteArray_Check);

impl PyByteArray {
/// Creates a new Python bytearray object.
Expand Down
2 changes: 1 addition & 1 deletion src/types/bytes.rs
Expand Up @@ -13,7 +13,7 @@ use std::str;
#[repr(transparent)]
pub struct PyBytes(PyAny);

pyobject_native_var_type!(PyBytes, ffi::PyBytes_Type, ffi::PyBytes_Check);
pyobject_native_type_core!(PyBytes, ffi::PyBytes_Type, #checkfunction=ffi::PyBytes_Check);

impl PyBytes {
/// Creates a new Python bytestring object.
Expand Down
2 changes: 1 addition & 1 deletion src/types/complex.rs
Expand Up @@ -13,7 +13,7 @@ pyobject_native_type!(
PyComplex,
ffi::PyComplexObject,
ffi::PyComplex_Type,
ffi::PyComplex_Check
#checkfunction=ffi::PyComplex_Check
);

impl PyComplex {
Expand Down
20 changes: 10 additions & 10 deletions src/types/datetime.rs
Expand Up @@ -66,8 +66,8 @@ pyobject_native_type!(
PyDate,
crate::ffi::PyDateTime_Date,
*PyDateTimeAPI.DateType,
Some("datetime"),
PyDate_Check
#module=Some("datetime"),
#checkfunction=PyDate_Check
);

impl PyDate {
Expand Down Expand Up @@ -123,8 +123,8 @@ pyobject_native_type!(
PyDateTime,
crate::ffi::PyDateTime_DateTime,
*PyDateTimeAPI.DateTimeType,
Some("datetime"),
PyDateTime_Check
#module=Some("datetime"),
#checkfunction=PyDateTime_Check
);

impl PyDateTime {
Expand Down Expand Up @@ -268,8 +268,8 @@ pyobject_native_type!(
PyTime,
crate::ffi::PyDateTime_Time,
*PyDateTimeAPI.TimeType,
Some("datetime"),
PyTime_Check
#module=Some("datetime"),
#checkfunction=PyTime_Check
);

impl PyTime {
Expand Down Expand Up @@ -352,8 +352,8 @@ pyobject_native_type!(
PyTzInfo,
crate::ffi::PyObject,
*PyDateTimeAPI.TZInfoType,
Some("datetime"),
PyTZInfo_Check
#module=Some("datetime"),
#checkfunction=PyTZInfo_Check
);

/// Bindings for `datetime.timedelta`
Expand All @@ -363,8 +363,8 @@ pyobject_native_type!(
PyDelta,
crate::ffi::PyDateTime_Delta,
*PyDateTimeAPI.DeltaType,
Some("datetime"),
PyDelta_Check
#module=Some("datetime"),
#checkfunction=PyDelta_Check
);

impl PyDelta {
Expand Down
2 changes: 1 addition & 1 deletion src/types/dict.rs
Expand Up @@ -20,7 +20,7 @@ pyobject_native_type!(
PyDict,
ffi::PyDictObject,
ffi::PyDict_Type,
ffi::PyDict_Check
#checkfunction=ffi::PyDict_Check
);

impl PyDict {
Expand Down
2 changes: 1 addition & 1 deletion src/types/floatob.rs
Expand Up @@ -20,7 +20,7 @@ pyobject_native_type!(
PyFloat,
ffi::PyFloatObject,
ffi::PyFloat_Type,
ffi::PyFloat_Check
#checkfunction=ffi::PyFloat_Check
);

impl PyFloat {
Expand Down
4 changes: 2 additions & 2 deletions src/types/function.rs
Expand Up @@ -10,7 +10,7 @@ use crate::{
#[repr(transparent)]
pub struct PyCFunction(PyAny);

pyobject_native_var_type!(PyCFunction, ffi::PyCFunction_Type, ffi::PyCFunction_Check);
pyobject_native_type_core!(PyCFunction, ffi::PyCFunction_Type, #checkfunction=ffi::PyCFunction_Check);

impl PyCFunction {
/// Create a new built-in function with keywords.
Expand Down Expand Up @@ -73,4 +73,4 @@ impl PyCFunction {
pub struct PyFunction(PyAny);

#[cfg(not(Py_LIMITED_API))]
pyobject_native_var_type!(PyFunction, ffi::PyFunction_Type, ffi::PyFunction_Check);
pyobject_native_type_core!(PyFunction, ffi::PyFunction_Type, #checkfunction=ffi::PyFunction_Check);
2 changes: 1 addition & 1 deletion src/types/list.rs
Expand Up @@ -13,7 +13,7 @@ use crate::{
#[repr(transparent)]
pub struct PyList(PyAny);

pyobject_native_var_type!(PyList, ffi::PyList_Type, ffi::PyList_Check);
pyobject_native_type_core!(PyList, ffi::PyList_Type, #checkfunction=ffi::PyList_Check);

impl PyList {
/// Constructs a new list with the given elements.
Expand Down
133 changes: 64 additions & 69 deletions src/types/mod.rs
Expand Up @@ -29,7 +29,7 @@ pub use self::typeobject::PyType;
// Implementations core to all native types
#[macro_export]
macro_rules! pyobject_native_type_base(
($name: ty $(;$generics: ident)* ) => {
($name:ty $(;$generics:ident)* ) => {
unsafe impl<$($generics,)*> $crate::PyNativeType for $name {}

impl<$($generics,)*> std::fmt::Debug for $name {
Expand Down Expand Up @@ -74,7 +74,7 @@ macro_rules! pyobject_native_type_base(
// make sense on PyAny / have different implementations).
#[macro_export]
macro_rules! pyobject_native_type_named (
($name: ty $(;$generics: ident)*) => {
($name:ty $(;$generics:ident)*) => {
$crate::pyobject_native_type_base!($name $(;$generics)*);

impl<$($generics,)*> std::convert::AsRef<$crate::PyAny> for $name {
Expand Down Expand Up @@ -126,75 +126,10 @@ macro_rules! pyobject_native_type_named (
};
);

#[macro_export]
macro_rules! pyobject_native_type_core {
($name: ty, $layout: path, $typeobject: expr, $module: expr $(, $checkfunction:path)? $(;$generics: ident)*) => {
unsafe impl $crate::type_object::PyLayout<$name> for $layout {}
$crate::pyobject_native_type_named!($name $(;$generics)*);
$crate::pyobject_native_type_info!($name, $layout, $typeobject, $module $(, $checkfunction)? $(;$generics)*);
$crate::pyobject_native_type_extract!($name $(;$generics)*);
}
}

#[macro_export]
macro_rules! pyobject_native_type_sized {
($name: ty, $layout: path $(;$generics: ident)*) => {
// To prevent inheriting native types with ABI3
#[cfg(not(Py_LIMITED_API))]
impl $crate::type_object::PySizedLayout<$name> for $layout {}
impl<'a, $($generics,)*> $crate::derive_utils::PyBaseTypeUtils for $name {
type Dict = $crate::pyclass_slots::PyClassDummySlot;
type WeakRef = $crate::pyclass_slots::PyClassDummySlot;
type LayoutAsBase = $crate::pycell::PyCellBase<$name>;
type BaseNativeType = $name;
type ThreadChecker = $crate::class::impl_::ThreadCheckerStub<$crate::PyObject>;
}
}
}

#[macro_export]
macro_rules! pyobject_native_type {
($name: ty, $layout: path, $typeobject: expr, $module: expr, $checkfunction:path $(;$generics: ident)*) => {
$crate::pyobject_native_type_core!($name, $layout, $typeobject, $module, $checkfunction $(;$generics)*);
$crate::pyobject_native_type_sized!($name, $layout $(;$generics)*);
};
($name: ty, $layout: path, $typeobject: expr, $checkfunction:path $(;$generics: ident)*) => {
$crate::pyobject_native_type! {
$name, $layout, $typeobject, Some("builtins"), $checkfunction $(;$generics)*
}
};
}

#[macro_export]
macro_rules! pyobject_native_var_type {
($name: ty, $typeobject: expr, $module: expr, $checkfunction:path $(;$generics: ident)*) => {
$crate::pyobject_native_type_core!(
$name, $crate::ffi::PyObject, $typeobject, Some("builtins"), $checkfunction $(;$generics)*);
};
($name: ty, $typeobject: expr, $checkfunction: path $(;$generics: ident)*) => {
$crate::pyobject_native_var_type! {
$name, $typeobject, Some("builtins"), $checkfunction $(;$generics)*
}
};
}

// NOTE: This macro is not included in pyobject_native_type_base!
// because rust-numpy has a special implementation.
#[macro_export]
macro_rules! pyobject_native_type_extract {
($name: ty $(;$generics: ident)*) => {
impl<'py, $($generics,)*> $crate::FromPyObject<'py> for &'py $name {
fn extract(obj: &'py $crate::PyAny) -> $crate::PyResult<Self> {
$crate::PyTryFrom::try_from(obj).map_err(Into::into)
}
}
}
}

#[macro_export]
macro_rules! pyobject_native_type_info(
($name: ty, $layout: path, $typeobject: expr,
$module: expr $(, $checkfunction:path)? $(;$generics: ident)*) => {
($name:ty, $layout:path, $typeobject:expr,
$module:expr $(, #checkfunction=$checkfunction:path)? $(;$generics:ident)*) => {
unsafe impl<$($generics,)*> $crate::type_object::PyTypeInfo for $name {
type BaseType = $crate::PyAny;
type Layout = $layout;
Expand Down Expand Up @@ -224,6 +159,66 @@ macro_rules! pyobject_native_type_info(
};
);

// NOTE: This macro is not included in pyobject_native_type_base!
// because rust-numpy has a special implementation.
#[macro_export]
macro_rules! pyobject_native_type_extract {
($name:ty $(;$generics:ident)*) => {
impl<'py, $($generics,)*> $crate::FromPyObject<'py> for &'py $name {
fn extract(obj: &'py $crate::PyAny) -> $crate::PyResult<Self> {
$crate::PyTryFrom::try_from(obj).map_err(Into::into)
}
}
}
}

/// Declares all of the boilerplate for Python types.
#[macro_export]
macro_rules! pyobject_native_type_core {
($name:ty, $typeobject:expr, #module=$module:expr $(, #checkfunction=$checkfunction:path)? $(;$generics:ident)*) => {
$crate::pyobject_native_type_core!(@impl $name, $crate::PyAny, $typeobject, #module=$module $(, #checkfunction=$checkfunction)? $(;$generics)*);
};
($name:ty, $typeobject:expr $(, #checkfunction=$checkfunction:path)? $(;$generics:ident)*) => {
$crate::pyobject_native_type_core!(@impl $name, $crate::PyAny, $typeobject, #module=Some("builtins") $(, #checkfunction=$checkfunction)? $(;$generics)*);
};

(@impl $name:ty, $layout:path, $typeobject:expr, #module=$module:expr $(, #checkfunction=$checkfunction:path)? $(;$generics:ident)*) => {
unsafe impl $crate::type_object::PyLayout<$name> for $layout {}
$crate::pyobject_native_type_named!($name $(;$generics)*);
$crate::pyobject_native_type_info!($name, $layout, $typeobject, $module $(, #checkfunction=$checkfunction)? $(;$generics)*);
$crate::pyobject_native_type_extract!($name $(;$generics)*);
};
(@impl $name:ty, $layout:path, $typeobject:expr $(, #checkfunction=$checkfunction:path)? $(;$generics:ident)*) => {
$crate::pyobject_native_type_core!(@impl $name, $layout, $typeobject, #module=Some("builtins") $(, #checkfunction=$checkfunction)? $(;$generics)*);
};
}

#[macro_export]
macro_rules! pyobject_native_type_sized {
($name:ty, $layout:path $(;$generics:ident)*) => {
// To prevent inheriting native types with ABI3
#[cfg(not(Py_LIMITED_API))]
impl $crate::type_object::PySizedLayout<$name> for $layout {}
impl<'a, $($generics,)*> $crate::derive_utils::PyBaseTypeUtils for $name {
type Dict = $crate::pyclass_slots::PyClassDummySlot;
type WeakRef = $crate::pyclass_slots::PyClassDummySlot;
type LayoutAsBase = $crate::pycell::PyCellBase<$name>;
type BaseNativeType = $name;
type ThreadChecker = $crate::class::impl_::ThreadCheckerStub<$crate::PyObject>;
}
}
}

/// Declares all of the boilerplate for Python types which can be inherited from (because the exact
/// Python layout is known).
#[macro_export]
macro_rules! pyobject_native_type {
($name:ty, $layout:path, $typeobject:expr $(, #module=$module:expr)? $(, #checkfunction=$checkfunction:path)? $(;$generics:ident)*) => {
$crate::pyobject_native_type_core!(@impl $name, $layout, $typeobject $(, #module=$module)? $(, #checkfunction=$checkfunction)? $(;$generics)*);
$crate::pyobject_native_type_sized!($name, $layout $(;$generics)*);
};
}

mod any;
mod boolobject;
mod bytearray;
Expand Down
2 changes: 1 addition & 1 deletion src/types/module.rs
Expand Up @@ -19,7 +19,7 @@ use std::str;
#[repr(transparent)]
pub struct PyModule(PyAny);

pyobject_native_var_type!(PyModule, ffi::PyModule_Type, ffi::PyModule_Check);
pyobject_native_type_core!(PyModule, ffi::PyModule_Type, #checkfunction=ffi::PyModule_Check);

impl PyModule {
/// Creates a new module object with the `__name__` attribute set to name.
Expand Down
2 changes: 1 addition & 1 deletion src/types/num.rs
Expand Up @@ -55,7 +55,7 @@ macro_rules! int_fits_larger_int {
#[repr(transparent)]
pub struct PyLong(PyAny);

pyobject_native_var_type!(PyLong, ffi::PyLong_Type, ffi::PyLong_Check);
pyobject_native_type_core!(PyLong, ffi::PyLong_Type, #checkfunction=ffi::PyLong_Check);

macro_rules! int_fits_c_long {
($rust_type:ty) => {
Expand Down
4 changes: 2 additions & 2 deletions src/types/set.rs
Expand Up @@ -20,12 +20,12 @@ pub struct PySet(PyAny);
#[repr(transparent)]
pub struct PyFrozenSet(PyAny);

pyobject_native_type!(PySet, ffi::PySetObject, ffi::PySet_Type, ffi::PySet_Check);
pyobject_native_type!(PySet, ffi::PySetObject, ffi::PySet_Type, #checkfunction=ffi::PySet_Check);
pyobject_native_type!(
PyFrozenSet,
ffi::PySetObject,
ffi::PyFrozenSet_Type,
ffi::PyFrozenSet_Check
#checkfunction=ffi::PyFrozenSet_Check
);

impl PySet {
Expand Down
2 changes: 1 addition & 1 deletion src/types/slice.rs
Expand Up @@ -16,7 +16,7 @@ pyobject_native_type!(
PySlice,
ffi::PySliceObject,
ffi::PySlice_Type,
ffi::PySlice_Check
#checkfunction=ffi::PySlice_Check
);

/// Represents Python `slice` indices.
Expand Down