Two default fn less
This commit is contained in:
parent
a2af5fe71d
commit
0101dc8136
|
@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||
* `as_mut` and friends take and `&mut self` instead of `&self`
|
||||
* `ObjectProtocol::call` now takes an `Option<PyDict>` for the kwargs instead of an `IntoPyDictPointer`.
|
||||
* `IntoPyDictPointer` was replace by `IntoPyDict` which doesn't convert `PyDict` itself anymore and returns a `PyDict` instead of `*mut PyObject`.
|
||||
* `PyTuple::new` now takes an `IntoIterator` instead of a slice
|
||||
|
||||
### Fixed
|
||||
|
||||
|
|
|
@ -210,19 +210,15 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> AsPyRef<T> for Py<T>
|
||||
where
|
||||
T: PyTypeInfo,
|
||||
{
|
||||
#[inline]
|
||||
default fn as_ref(&self, _py: Python) -> &T {
|
||||
/// Specialization workaround
|
||||
trait AsPyRefDispatch<T: PyTypeInfo>: ToPyPointer {
|
||||
fn as_ref_dispatch(&self, _py: Python) -> &T {
|
||||
unsafe {
|
||||
let ptr = (self.as_ptr() as *mut u8).offset(T::OFFSET) as *mut T;
|
||||
ptr.as_ref().unwrap()
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
default fn as_mut(&mut self, _py: Python) -> &mut T {
|
||||
fn as_mut_dispatch(&mut self, _py: Python) -> &mut T {
|
||||
unsafe {
|
||||
let ptr = (self.as_ptr() as *mut u8).offset(T::OFFSET) as *mut T;
|
||||
ptr.as_mut().unwrap()
|
||||
|
@ -230,20 +226,29 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> AsPyRef<T> for Py<T>
|
||||
where
|
||||
T: PyTypeInfo + PyNativeType,
|
||||
{
|
||||
#[inline]
|
||||
fn as_ref(&self, _py: Python) -> &T {
|
||||
impl<T: PyTypeInfo> AsPyRefDispatch<T> for Py<T> {}
|
||||
|
||||
impl<T: PyTypeInfo + PyNativeType> AsPyRefDispatch<T> for Py<T> {
|
||||
fn as_ref_dispatch(&self, _py: Python) -> &T {
|
||||
unsafe { &*(self as *const instance::Py<T> as *const T) }
|
||||
}
|
||||
#[inline]
|
||||
fn as_mut(&mut self, _py: Python) -> &mut T {
|
||||
fn as_mut_dispatch(&mut self, _py: Python) -> &mut T {
|
||||
unsafe { &mut *(self as *const _ as *mut T) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AsPyRef<T> for Py<T>
|
||||
where
|
||||
T: PyTypeInfo,
|
||||
{
|
||||
fn as_ref(&self, py: Python) -> &T {
|
||||
self.as_ref_dispatch(py)
|
||||
}
|
||||
fn as_mut(&mut self, py: Python) -> &mut T {
|
||||
self.as_mut_dispatch(py)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ToPyObject for Py<T> {
|
||||
/// Converts `Py` instance -> PyObject.
|
||||
fn to_object(&self, py: Python) -> PyObject {
|
||||
|
|
|
@ -22,8 +22,6 @@ pyobject_native_type!(PyFrozenSet, ffi::PyFrozenSet_Type, ffi::PyFrozenSet_Check
|
|||
|
||||
impl PySet {
|
||||
/// Creates a new set.
|
||||
///
|
||||
/// May panic when running out of memory.
|
||||
pub fn new<T: ToPyObject>(py: Python, elements: &[T]) -> Py<PySet> {
|
||||
let list = elements.to_object(py);
|
||||
unsafe { Py::from_owned_ptr_or_panic(ffi::PySet_New(list.as_ptr())) }
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
use std;
|
||||
use std::slice;
|
||||
|
||||
use super::exc;
|
||||
use conversion::{FromPyObject, IntoPyObject, IntoPyTuple, PyTryFrom, ToPyObject};
|
||||
use err::{PyErr, PyResult};
|
||||
|
@ -11,6 +8,7 @@ use instance::{AsPyRef, Py, PyObjectWithToken};
|
|||
use object::PyObject;
|
||||
use objects::PyObjectRef;
|
||||
use python::{IntoPyPointer, Python, ToPyPointer};
|
||||
use std::slice;
|
||||
|
||||
/// Represents a Python `tuple` object.
|
||||
#[repr(transparent)]
|
||||
|
@ -20,11 +18,16 @@ pyobject_native_type!(PyTuple, ffi::PyTuple_Type, ffi::PyTuple_Check);
|
|||
|
||||
impl PyTuple {
|
||||
/// Construct a new tuple with the given elements.
|
||||
pub fn new<T: ToPyObject>(py: Python, elements: &[T]) -> Py<PyTuple> {
|
||||
pub fn new<T, U>(py: Python, elements: impl IntoIterator<Item = T, IntoIter = U>) -> Py<PyTuple>
|
||||
where
|
||||
T: ToPyObject,
|
||||
U: ExactSizeIterator<Item = T>,
|
||||
{
|
||||
let elements_iter = elements.into_iter();
|
||||
let len = elements_iter.len();
|
||||
unsafe {
|
||||
let len = elements.len();
|
||||
let ptr = ffi::PyTuple_New(len as Py_ssize_t);
|
||||
for (i, e) in elements.iter().enumerate() {
|
||||
for (i, e) in elements_iter.enumerate() {
|
||||
ffi::PyTuple_SetItem(ptr, i as Py_ssize_t, e.to_object(py).into_ptr());
|
||||
}
|
||||
Py::from_owned_ptr_or_panic(ptr)
|
||||
|
@ -119,7 +122,7 @@ impl<'a> Iterator for PyTupleIterator<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> std::iter::IntoIterator for &'a PyTuple {
|
||||
impl<'a> IntoIterator for &'a PyTuple {
|
||||
type Item = &'a PyObjectRef;
|
||||
type IntoIter = PyTupleIterator<'a>;
|
||||
|
||||
|
@ -267,6 +270,7 @@ mod test {
|
|||
use objectprotocol::ObjectProtocol;
|
||||
use objects::PyObjectRef;
|
||||
use python::Python;
|
||||
use std::collections::HashSet;
|
||||
use PyTuple;
|
||||
|
||||
#[test]
|
||||
|
@ -278,6 +282,11 @@ mod test {
|
|||
assert_eq!(3, ob.len());
|
||||
let ob: &PyObjectRef = ob.into();
|
||||
assert_eq!((1, 2, 3), ob.extract().unwrap());
|
||||
|
||||
let mut map = HashSet::new();
|
||||
map.insert(1);
|
||||
map.insert(2);
|
||||
PyTuple::new(py, &map);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in New Issue