remove True and False python methods

This commit is contained in:
Nikolay Kim 2017-06-23 13:42:46 -07:00
parent b1e6f07060
commit 3e3fed9c18
3 changed files with 66 additions and 54 deletions

View file

@ -32,8 +32,7 @@ impl ToPyObject for bool {
fn to_object(&self, py: Python) -> PyObject {
unsafe {
PyObject::from_borrowed_ptr(
py,
if *self { ffi::Py_True() } else { ffi::Py_False() })
py, if *self { ffi::Py_True() } else { ffi::Py_False() })
}
}
@ -64,7 +63,7 @@ pyobject_extract!(py, obj to bool => {
#[cfg(test)]
mod test {
use python::Python;
use objects::PyInstance;
use objects::{PyBool, PyInstance};
use conversion::ToPyObject;
use objectprotocol::ObjectProtocol;
@ -72,19 +71,19 @@ mod test {
fn test_true() {
let gil = Python::acquire_gil();
let py = gil.python();
assert!(py.True().is_true());
let t: &PyInstance = py.True().into();
assert!(PyBool::new(py, true).is_true());
let t: &PyInstance = PyBool::new(py, true).into();
assert_eq!(true, t.extract().unwrap());
assert!(true.to_object(py) == py.True().into());
assert!(true.to_object(py) == PyBool::new(py, true).into());
}
#[test]
fn test_false() {
let gil = Python::acquire_gil();
let py = gil.python();
assert!(!py.False().is_true());
let t: &PyInstance = py.False().into();
assert!(!PyBool::new(py, false).is_true());
let t: &PyInstance = PyBool::new(py, false).into();
assert_eq!(false, t.extract().unwrap());
assert!(false.to_object(py) == py.False().into());
assert!(false.to_object(py) == PyBool::new(py, false).into());
}
}

View file

@ -11,7 +11,7 @@ use ffi;
use typeob::{PyTypeInfo, PyTypeObject, PyObjectAlloc};
use instance::{Py, PyToken};
use pointer::PyObject;
use objects::{PyInstance, PyType, PyBool, PyDict, PyModule};
use objects::{PyInstance, PyType, PyDict, PyModule};
use err::{PyErr, PyResult, PyDowncastError, ToPyErr};
use pythonrun::{self, GILGuard};
@ -213,20 +213,6 @@ impl<'p> Python<'p> {
unsafe { PyObject::from_borrowed_ptr(self, ffi::Py_None()) }
}
/// Gets the Python builtin value `True`.
#[allow(non_snake_case)] // the Python keyword starts with uppercase
#[inline]
pub fn True(self) -> &'p PyBool {
PyBool::new(self, true)
}
/// Gets the Python builtin value `False`.
#[allow(non_snake_case)] // the Python keyword starts with uppercase
#[inline]
pub fn False(self) -> &'p PyBool {
PyBool::new(self, false)
}
/// Gets the Python builtin value `NotImplemented`.
#[allow(non_snake_case)] // the Python keyword starts with uppercase
#[inline]
@ -281,7 +267,7 @@ impl<'p> Python<'p> {
where D: PyDowncastFrom
{
unsafe {
let p = pythonrun::register(self, obj);
let p = pythonrun::register_owned(self, obj);
<D as PyDowncastFrom>::downcast_from(p)
}
}
@ -289,7 +275,7 @@ impl<'p> Python<'p> {
pub unsafe fn cast_as<D>(self, obj: PyObject) -> &'p D
where D: PyDowncastFrom
{
let p = pythonrun::register(self, obj);
let p = pythonrun::register_owned(self, obj);
<D as PyDowncastFrom>::unchecked_downcast_from(p)
}
@ -297,7 +283,7 @@ impl<'p> Python<'p> {
where D: PyDowncastFrom
{
let obj = PyObject::from_owned_ptr_or_panic(self, ptr);
let p = pythonrun::register(self, obj);
let p = pythonrun::register_owned(self, obj);
<D as PyDowncastFrom>::unchecked_downcast_from(p)
}
@ -306,7 +292,7 @@ impl<'p> Python<'p> {
{
let obj = PyObject::from_owned_ptr_or_err(self, ptr)?;
unsafe {
let p = pythonrun::register(self, obj);
let p = pythonrun::register_owned(self, obj);
Ok(<D as PyDowncastFrom>::unchecked_downcast_from(p))
}
}
@ -319,7 +305,7 @@ impl<'p> Python<'p> {
} else {
unsafe {
let obj = PyObject::from_owned_ptr(self, ptr);
let p = pythonrun::register(self, obj);
let p = pythonrun::register_owned(self, obj);
Some(<D as PyDowncastFrom>::unchecked_downcast_from(p))
}
}
@ -329,7 +315,7 @@ impl<'p> Python<'p> {
where D: PyDowncastFrom
{
let obj = PyObject::from_borrowed_ptr(self, ptr);
let p = pythonrun::register(self, obj);
let p = pythonrun::register_borrowed(self, obj);
<D as PyDowncastFrom>::unchecked_downcast_from(p)
}
@ -338,7 +324,7 @@ impl<'p> Python<'p> {
where D: PyDowncastFrom
{
let obj = PyObject::from_borrowed_ptr_or_err(self, ptr)?;
let p = pythonrun::register(self, obj);
let p = pythonrun::register_borrowed(self, obj);
Ok(<D as PyDowncastFrom>::unchecked_downcast_from(p))
}
@ -350,7 +336,7 @@ impl<'p> Python<'p> {
None
} else {
let obj = PyObject::from_borrowed_ptr(self, ptr);
let p = pythonrun::register(self, obj);
let p = pythonrun::register_borrowed(self, obj);
Some(<D as PyDowncastFrom>::unchecked_downcast_from(p))
}
}
@ -359,13 +345,13 @@ impl<'p> Python<'p> {
where D: PyDowncastFrom
{
let obj = PyObject::from_borrowed_ptr(self, ptr);
let p = pythonrun::register(self, obj);
let p = pythonrun::register_borrowed(self, obj);
<D as PyDowncastFrom>::unchecked_mut_downcast_from(p)
}
pub fn track_object(self, obj: PyObject) -> &'p PyInstance
{
unsafe { pythonrun::register(self, obj) }
unsafe { pythonrun::register_owned(self, obj) }
}
}
@ -405,7 +391,7 @@ mod test {
fn test_is_instance() {
let gil = Python::acquire_gil();
let py = gil.python();
assert!(py.is_instance::<PyBool, PyInstance>(py.True().into()).unwrap());
assert!(py.is_instance::<PyBool, PyInstance>(PyBool::new(py, true).into()).unwrap());
let list = PyList::new(py, &[1, 2, 3, 4]);
assert!(!py.is_instance::<PyBool, _>(list.as_ref()).unwrap());
assert!(py.is_instance::<PyList, _>(list.as_ref()).unwrap());

View file

@ -69,7 +69,8 @@ pub fn prepare_freethreaded_python() {
pub fn prepare_pyo3_library() {
START_PYO3.call_once(|| unsafe {
// initialize release pool
POOL = Box::into_raw(Box::new(Vec::with_capacity(250)));
OWNED = Box::into_raw(Box::new(Vec::with_capacity(250)));
BORROWED = Box::into_raw(Box::new(Vec::with_capacity(250)));
});
}
@ -86,7 +87,8 @@ pub fn prepare_pyo3_library() {
/// ```
#[must_use]
pub struct GILGuard {
pos: usize,
owned: usize,
borrowed: usize,
gstate: ffi::PyGILState_STATE,
// hack to opt out of Send on stable rust, which doesn't
// have negative impls
@ -97,25 +99,30 @@ pub struct GILGuard {
impl Drop for GILGuard {
fn drop(&mut self) {
unsafe {
drain(self.pos);
drain(self.owned, self.borrowed);
ffi::PyGILState_Release(self.gstate);
}
}
}
static mut POOL: *mut Vec<PyObject> = 0 as *mut _;
static mut OWNED: *mut Vec<PyObject> = 0 as *mut _;
static mut BORROWED: *mut Vec<PyObject> = 0 as *mut _;
pub struct Pool {
pos: usize,
owned: usize,
borrowed: usize,
no_send: marker::PhantomData<rc::Rc<()>>,
}
impl Pool {
#[inline]
pub unsafe fn new() -> Pool {
let pool: &'static mut Vec<PyInstance> = mem::transmute(POOL);
Pool{ pos: pool.len(), no_send: marker::PhantomData }
let owned: &'static mut Vec<PyObject> = mem::transmute(OWNED);
let borrowed: &'static mut Vec<PyObject> = mem::transmute(BORROWED);
Pool{ owned: owned.len(),
borrowed: borrowed.len(),
no_send: marker::PhantomData }
}
// /// Retrieves the marker type that proves that the GIL was acquired.
// #[inline]
@ -127,27 +134,43 @@ impl Pool {
impl Drop for Pool {
fn drop(&mut self) {
unsafe {
drain(self.pos);
drain(self.owned, self.borrowed);
}
}
}
pub unsafe fn register<'p>(_py: Python<'p>, obj: PyObject) -> &'p PyInstance {
let pool: &'static mut Vec<PyObject> = mem::transmute(POOL);
pub unsafe fn register_owned<'p>(_py: Python<'p>, obj: PyObject) -> &'p PyInstance {
let pool: &'static mut Vec<PyObject> = mem::transmute(OWNED);
pool.push(obj);
mem::transmute(&pool[pool.len()-1])
}
pub unsafe fn drain(pos: usize) {
let pool: &'static mut Vec<PyObject> = mem::transmute(POOL);
pub unsafe fn register_borrowed<'p>(_py: Python<'p>, obj: PyObject) -> &'p PyInstance {
let pool: &'static mut Vec<PyObject> = mem::transmute(BORROWED);
pool.push(obj);
mem::transmute(&pool[pool.len()-1])
}
let len = pool.len();
if pos < len {
for ob in &mut pool[pos..len] {
pub unsafe fn drain(owned: usize, borrowed: usize) {
let owned_pool: &'static mut Vec<PyObject> = mem::transmute(OWNED);
let len = owned_pool.len();
if owned < len {
for ob in &mut owned_pool[owned..len] {
ffi::Py_DECREF(ob.as_ptr());
}
pool.set_len(pos);
owned_pool.set_len(owned);
}
let borrowed_pool: &'static mut Vec<PyObject> = mem::transmute(BORROWED);
let len = borrowed_pool.len();
if borrowed < len {
for ob in &mut borrowed_pool[borrowed..len] {
ffi::Py_DECREF(ob.as_ptr());
}
borrowed_pool.set_len(borrowed);
}
}
@ -157,13 +180,17 @@ impl GILGuard {
/// If the Python runtime is not already initialized, this function will initialize it.
/// See [prepare_freethreaded_python()](fn.prepare_freethreaded_python.html) for details.
pub fn acquire() -> GILGuard {
::pythonrun::prepare_freethreaded_python();
prepare_freethreaded_python();
unsafe {
let gstate = ffi::PyGILState_Ensure(); // acquire GIL
let pool: &'static mut Vec<PyInstance> = mem::transmute(POOL);
let owned: &'static mut Vec<PyObject> = mem::transmute(OWNED);
let borrowed: &'static mut Vec<PyObject> = mem::transmute(BORROWED);
GILGuard { pos: pool.len(), gstate: gstate, no_send: marker::PhantomData }
GILGuard { owned: owned.len(),
borrowed: borrowed.len(),
gstate: gstate,
no_send: marker::PhantomData }
}
}