Merge pull request #1592 from davidhewitt/tidy-types-macros

types: clean up types macros
This commit is contained in:
David Hewitt 2021-05-03 17:35:59 +01:00 committed by GitHub
commit 20e10b3693
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 95 additions and 105 deletions

View File

@ -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;
@ -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 {
@ -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 {
@ -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);

View File

@ -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);

View File

@ -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`.

View File

@ -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.

View File

@ -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.

View File

@ -13,7 +13,7 @@ pyobject_native_type!(
PyComplex,
ffi::PyComplexObject,
ffi::PyComplex_Type,
ffi::PyComplex_Check
#checkfunction=ffi::PyComplex_Check
);
impl PyComplex {

View File

@ -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 {
@ -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 {
@ -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 {
@ -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`
@ -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 {

View File

@ -20,7 +20,7 @@ pyobject_native_type!(
PyDict,
ffi::PyDictObject,
ffi::PyDict_Type,
ffi::PyDict_Check
#checkfunction=ffi::PyDict_Check
);
impl PyDict {

View File

@ -20,7 +20,7 @@ pyobject_native_type!(
PyFloat,
ffi::PyFloatObject,
ffi::PyFloat_Type,
ffi::PyFloat_Check
#checkfunction=ffi::PyFloat_Check
);
impl PyFloat {

View File

@ -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.
@ -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);

View File

@ -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.

View File

@ -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 {
@ -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 {
@ -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;
@ -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;

View File

@ -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.

View File

@ -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) => {

View File

@ -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 {

View File

@ -16,7 +16,7 @@ pyobject_native_type!(
PySlice,
ffi::PySliceObject,
ffi::PySlice_Type,
ffi::PySlice_Check
#checkfunction=ffi::PySlice_Check
);
/// Represents Python `slice` indices.

View File

@ -15,7 +15,7 @@ use std::str;
#[repr(transparent)]
pub struct PyString(PyAny);
pyobject_native_var_type!(PyString, ffi::PyUnicode_Type, ffi::PyUnicode_Check);
pyobject_native_type_core!(PyString, ffi::PyUnicode_Type, #checkfunction=ffi::PyUnicode_Check);
impl PyString {
/// Creates a new Python string object.

View File

@ -12,7 +12,7 @@ use crate::{
#[repr(transparent)]
pub struct PyTuple(PyAny);
pyobject_native_var_type!(PyTuple, ffi::PyTuple_Type, ffi::PyTuple_Check);
pyobject_native_type_core!(PyTuple, ffi::PyTuple_Type, #checkfunction=ffi::PyTuple_Check);
impl PyTuple {
/// Constructs a new tuple with the given elements.

View File

@ -11,7 +11,7 @@ use crate::{ffi, AsPyPointer, PyAny, Python};
#[repr(transparent)]
pub struct PyType(PyAny);
pyobject_native_var_type!(PyType, ffi::PyType_Type, ffi::PyType_Check);
pyobject_native_type_core!(PyType, ffi::PyType_Type, #checkfunction=ffi::PyType_Check);
impl PyType {
/// Creates a new type object.