Two default fn less

This commit is contained in:
konstin 2018-08-31 21:11:08 +02:00
parent a2af5fe71d
commit 0101dc8136
4 changed files with 38 additions and 25 deletions

View File

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

View File

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

View File

@ -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())) }

View File

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