Big refactoring to shrink the prelude

This commit is contained in:
konstin 2018-09-21 23:32:48 +02:00
parent 0dc697feac
commit 302c099a76
64 changed files with 585 additions and 534 deletions

View File

@ -9,15 +9,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added ### Added
* `#[pyclass]` objects can now be returned from rust functions * `#[pyclass]` objects can now be returned from rust functions
* `PyComplex` by kngwyu in [#226](https://github.com/PyO3/pyo3/pull/226)
### Removed
* Removed most entries from the prelude. The new prelude is small and clear.
* Slowly removing specialization uses
### Changed ### Changed
* Removes the types from the root module and the prelude. They now live in `pyo3::types` instead.
* Slowly removing specialization uses
* All exceptions are consturcted with `py_err` instead of `new`, as they return `PyErr` and not `Self`. * All exceptions are consturcted with `py_err` instead of `new`, as they return `PyErr` and not `Self`.
* `as_mut` and friends take and `&mut self` instead of `&self` * `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`. * `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`. * `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 * `PyTuple::new` now takes an `IntoIterator` instead of a slice
* Updated to syn 0.15
### Fixed ### Fixed

View File

@ -94,6 +94,7 @@ Example program displaying the value of `sys.version`:
extern crate pyo3; extern crate pyo3;
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::types::PyDict;
fn main() -> PyResult<()> { fn main() -> PyResult<()> {
let gil = Python::acquire_gil(); let gil = Python::acquire_gil();

View File

@ -3,15 +3,11 @@
#[macro_use] #[macro_use]
extern crate pyo3; extern crate pyo3;
use pyo3::prelude::PyDeltaAccess; use pyo3::prelude::*;
use pyo3::prelude::PyModule; use pyo3::types::{
use pyo3::prelude::PyObject; PyDate, PyDateAccess, PyDateTime, PyDelta, PyDeltaAccess, PyDict, PyTime, PyTimeAccess,
use pyo3::prelude::{pyfunction, pymodinit}; PyTuple, PyTzInfo,
use pyo3::prelude::{PyDate, PyDateTime, PyDelta, PyTime, PyTzInfo}; };
use pyo3::prelude::{PyDateAccess, PyTimeAccess};
use pyo3::prelude::{PyDict, PyTuple};
use pyo3::{ObjectProtocol, ToPyObject};
use pyo3::{Py, PyResult, Python};
#[pyfunction] #[pyfunction]
fn make_date(py: Python, year: i32, month: u8, day: u8) -> PyResult<Py<PyDate>> { fn make_date(py: Python, year: i32, month: u8, day: u8) -> PyResult<Py<PyDate>> {
@ -195,7 +191,7 @@ fn datetime_from_timestamp(py: Python, ts: f64, tz: Option<&PyTzInfo>) -> PyResu
#[pyfunction] #[pyfunction]
fn issue_219() -> PyResult<()> { fn issue_219() -> PyResult<()> {
let gil = Python::acquire_gil(); let gil = Python::acquire_gil();
let py = gil.python(); let _py = gil.python();
Ok(()) Ok(())
} }

View File

@ -48,7 +48,7 @@ attribute. Only the python `__new__` method can be specified, `__init__` is not
# #
# extern crate pyo3; # extern crate pyo3;
# use pyo3::prelude::*; # use pyo3::prelude::*;
# use pyo3::PyRawObject;
#[pyclass] #[pyclass]
struct MyClass { struct MyClass {
@ -92,7 +92,7 @@ with value of custom class struct. Subclass must call parent's `__new__` method.
# #![feature(specialization)] # #![feature(specialization)]
# extern crate pyo3; # extern crate pyo3;
# use pyo3::prelude::*; # use pyo3::prelude::*;
# # use pyo3::PyRawObject;
#[pyclass] #[pyclass]
struct BaseClass { struct BaseClass {
val1: usize, val1: usize,

View File

@ -7,7 +7,7 @@ You can use the `py_exception!` macro to define a new exception type:
```rust ```rust
#[macro_use] extern crate pyo3; #[macro_use] extern crate pyo3;
py_exception!(module, MyError, pyo3::exc::Exception); py_exception!(module, MyError, pyo3::exceptions::Exception);
``` ```
* `module` is the name of the containing module. * `module` is the name of the containing module.
@ -18,9 +18,10 @@ For example:
```rust ```rust
#[macro_use] extern crate pyo3; #[macro_use] extern crate pyo3;
use pyo3::{Python, PyDict}; use pyo3::Python;
use pyo3::types::PyDict;
py_exception!(mymodule, CustomError, pyo3::exc::Exception); py_exception!(mymodule, CustomError, pyo3::exceptions::Exception);
fn main() { fn main() {
let gil = Python::acquire_gil(); let gil = Python::acquire_gil();
@ -46,7 +47,7 @@ use pyo3::{Python, PyErr, exc};
fn main() { fn main() {
let gil = Python::acquire_gil(); let gil = Python::acquire_gil();
let py = gil.python(); let py = gil.python();
PyErr::new::<exc::TypeError, _>("Error").restore(py); PyErr::new::<exceptions::TypeError, _>("Error").restore(py);
assert!(PyErr::occurred(py)); assert!(PyErr::occurred(py));
drop(PyErr::fetch(py)); drop(PyErr::fetch(py));
} }
@ -69,7 +70,7 @@ have rust type as well.
# fn check_for_error() -> bool {false} # fn check_for_error() -> bool {false}
fn my_func(arg: PyObject) -> PyResult<()> { fn my_func(arg: PyObject) -> PyResult<()> {
if check_for_error() { if check_for_error() {
Err(exc::ValueError::py_err("argument is wrong")) Err(exceptions::ValueError::py_err("argument is wrong"))
} else { } else {
Ok(()) Ok(())
} }
@ -106,8 +107,8 @@ To check the type of an exception, you can simply do:
# fn main() { # fn main() {
# let gil = Python::acquire_gil(); # let gil = Python::acquire_gil();
# let py = gil.python(); # let py = gil.python();
# let err = exc::TypeError::py_err(NoArgs); # let err = exceptions::TypeError::py_err(NoArgs);
err.is_instance::<exc::TypeError>(py); err.is_instance::<exceptions::TypeError>(py);
# } # }
``` ```
@ -139,7 +140,7 @@ use pyo3::{PyErr, PyResult, exc};
impl std::convert::From<std::io::Error> for PyErr { impl std::convert::From<std::io::Error> for PyErr {
fn from(err: std::io::Error) -> PyErr { fn from(err: std::io::Error) -> PyErr {
exc::OSError.into() exceptions::OSError.into()
} }
} }
@ -179,7 +180,7 @@ use pyo3::prelude::*;
import_exception!(io, UnsupportedOperation); import_exception!(io, UnsupportedOperation);
fn tell(file: PyObject) -> PyResult<u64> { fn tell(file: PyObject) -> PyResult<u64> {
use pyo3::exc::*; use pyo3::exceptions::*;
let gil = Python::acquire_gil(); let gil = Python::acquire_gil();
let py = gil.python(); let py = gil.python();

View File

@ -84,6 +84,7 @@ Example program displaying the value of `sys.version`:
extern crate pyo3; extern crate pyo3;
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::types::PyDict;
fn main() -> PyResult<()> { fn main() -> PyResult<()> {
let gil = Python::acquire_gil(); let gil = Python::acquire_gil();

View File

@ -30,7 +30,7 @@ py_class!(class MyClass |py| {
extern crate pyo3; extern crate pyo3;
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::PyRawObject;
#[pyclass] #[pyclass]
struct MyClass { struct MyClass {

View File

@ -20,7 +20,7 @@ pub fn py3_init(fnname: &syn::Ident, name: &syn::Ident, doc: syn::Lit) -> TokenS
/// This autogenerated function is called by the python interpreter when importing /// This autogenerated function is called by the python interpreter when importing
/// the module. /// the module.
pub unsafe extern "C" fn #cb_name() -> *mut ::pyo3::ffi::PyObject { pub unsafe extern "C" fn #cb_name() -> *mut ::pyo3::ffi::PyObject {
::pyo3::make_module(concat!(stringify!(#name), "\0"), #doc, #fnname) ::pyo3::derive_utils::make_module(concat!(stringify!(#name), "\0"), #doc, #fnname)
} }
} }
} }
@ -32,7 +32,7 @@ pub fn py2_init(fnname: &syn::Ident, name: &syn::Ident, doc: syn::Lit) -> TokenS
#[no_mangle] #[no_mangle]
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub unsafe extern "C" fn #cb_name() { pub unsafe extern "C" fn #cb_name() {
::pyo3::make_module(concat!(stringify!(#name), "\0"), #doc, #fnname) ::pyo3::derive_utils::make_module(concat!(stringify!(#name), "\0"), #doc, #fnname)
} }
} }
} }
@ -243,8 +243,8 @@ fn function_c_wrapper(name: &syn::Ident, spec: &method::FnSpec) -> TokenStream {
let _pool = ::pyo3::GILPool::new(); let _pool = ::pyo3::GILPool::new();
let _py = ::pyo3::Python::assume_gil_acquired(); let _py = ::pyo3::Python::assume_gil_acquired();
let _args = _py.from_borrowed_ptr::<::pyo3::PyTuple>(_args); let _args = _py.from_borrowed_ptr::<::pyo3::types::PyTuple>(_args);
let _kwargs: Option<&PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); let _kwargs: Option<&::pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
#body_to_result #body_to_result
::pyo3::callback::cb_convert( ::pyo3::callback::cb_convert(

View File

@ -236,6 +236,7 @@ fn impl_class(
impl ::pyo3::ToPyObject for #cls { impl ::pyo3::ToPyObject for #cls {
fn to_object(&self, py: ::pyo3::Python) -> ::pyo3::PyObject { fn to_object(&self, py: ::pyo3::Python) -> ::pyo3::PyObject {
use ::pyo3::python::ToPyPointer;
unsafe { ::pyo3::PyObject::from_borrowed_ptr(py, self.as_ptr()) } unsafe { ::pyo3::PyObject::from_borrowed_ptr(py, self.as_ptr()) }
} }
} }
@ -251,6 +252,7 @@ fn impl_class(
impl<'a> ::pyo3::ToPyObject for &'a mut #cls { impl<'a> ::pyo3::ToPyObject for &'a mut #cls {
fn to_object(&self, py: ::pyo3::Python) -> ::pyo3::PyObject { fn to_object(&self, py: ::pyo3::Python) -> ::pyo3::PyObject {
use ::pyo3::python::ToPyPointer;
unsafe { ::pyo3::PyObject::from_borrowed_ptr(py, self.as_ptr()) } unsafe { ::pyo3::PyObject::from_borrowed_ptr(py, self.as_ptr()) }
} }
} }
@ -259,6 +261,7 @@ fn impl_class(
fn with_borrowed_ptr<F, R>(&self, _py: ::pyo3::Python, f: F) -> R fn with_borrowed_ptr<F, R>(&self, _py: ::pyo3::Python, f: F) -> R
where F: FnOnce(*mut ::pyo3::ffi::PyObject) -> R where F: FnOnce(*mut ::pyo3::ffi::PyObject) -> R
{ {
use ::pyo3::python::ToPyPointer;
f(self.as_ptr()) f(self.as_ptr())
} }
} }
@ -267,6 +270,7 @@ fn impl_class(
fn with_borrowed_ptr<F, R>(&self, _py: ::pyo3::Python, f: F) -> R fn with_borrowed_ptr<F, R>(&self, _py: ::pyo3::Python, f: F) -> R
where F: FnOnce(*mut ::pyo3::ffi::PyObject) -> R where F: FnOnce(*mut ::pyo3::ffi::PyObject) -> R
{ {
use ::pyo3::python::ToPyPointer;
f(self.as_ptr()) f(self.as_ptr())
} }
} }
@ -393,7 +397,7 @@ fn parse_attribute(
// We need the 0 as value for the constant we're later building using quote for when there // We need the 0 as value for the constant we're later building using quote for when there
// are no other flags // are no other flags
let mut flags = vec![parse_quote! {0}]; let mut flags = vec![parse_quote! {0}];
let mut base: syn::TypePath = parse_quote! {::pyo3::PyObjectRef}; let mut base: syn::TypePath = parse_quote! {::pyo3::types::PyObjectRef};
for expr in args.iter() { for expr in args.iter() {
match expr { match expr {

View File

@ -88,8 +88,8 @@ pub fn impl_wrap(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec, noargs: bool
let _pool = ::pyo3::GILPool::new(); let _pool = ::pyo3::GILPool::new();
let _py = ::pyo3::Python::assume_gil_acquired(); let _py = ::pyo3::Python::assume_gil_acquired();
let _slf = _py.mut_from_borrowed_ptr::<#cls>(_slf); let _slf = _py.mut_from_borrowed_ptr::<#cls>(_slf);
let _args = _py.from_borrowed_ptr::<::pyo3::PyTuple>(_args); let _args = _py.from_borrowed_ptr::<::pyo3::types::PyTuple>(_args);
let _kwargs: Option<&PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); let _kwargs: Option<&::pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
#body_to_result #body_to_result
::pyo3::callback::cb_convert( ::pyo3::callback::cb_convert(
@ -115,8 +115,8 @@ pub fn impl_proto_wrap(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec) -> Tok
let _pool = ::pyo3::GILPool::new(); let _pool = ::pyo3::GILPool::new();
let _py = ::pyo3::Python::assume_gil_acquired(); let _py = ::pyo3::Python::assume_gil_acquired();
let _slf = _py.mut_from_borrowed_ptr::<#cls>(_slf); let _slf = _py.mut_from_borrowed_ptr::<#cls>(_slf);
let _args = _py.from_borrowed_ptr::<::pyo3::PyTuple>(_args); let _args = _py.from_borrowed_ptr::<::pyo3::types::PyTuple>(_args);
let _kwargs: Option<&PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); let _kwargs: Option<&::pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
let _result = { let _result = {
#body #body
@ -161,13 +161,13 @@ pub fn impl_wrap_new(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec) -> Token
let _py = ::pyo3::Python::assume_gil_acquired(); let _py = ::pyo3::Python::assume_gil_acquired();
match ::pyo3::typeob::PyRawObject::new(_py, #cls::type_object(), _cls) { match ::pyo3::typeob::PyRawObject::new(_py, #cls::type_object(), _cls) {
Ok(_obj) => { Ok(_obj) => {
let _args = _py.from_borrowed_ptr::<::pyo3::PyTuple>(_args); let _args = _py.from_borrowed_ptr::<::pyo3::types::PyTuple>(_args);
let _kwargs: Option<&PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); let _kwargs: Option<&::pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
#body_to_result #body_to_result
match _result { match _result {
Ok(_) => _obj.into_ptr(), Ok(_) => ::pyo3::IntoPyPointer::into_ptr(_obj),
Err(e) => { Err(e) => {
e.restore(_py); e.restore(_py);
::std::ptr::null_mut() ::std::ptr::null_mut()
@ -207,8 +207,8 @@ fn impl_wrap_init(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec) -> TokenStr
let _pool = ::pyo3::GILPool::new(); let _pool = ::pyo3::GILPool::new();
let _py = ::pyo3::Python::assume_gil_acquired(); let _py = ::pyo3::Python::assume_gil_acquired();
let _slf = _py.mut_from_borrowed_ptr::<#cls>(_slf); let _slf = _py.mut_from_borrowed_ptr::<#cls>(_slf);
let _args = _py.from_borrowed_ptr::<::pyo3::PyTuple>(_args); let _args = _py.from_borrowed_ptr::<::pyo3::types::PyTuple>(_args);
let _kwargs: Option<&PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); let _kwargs: Option<&::pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
#body_to_result #body_to_result
match _result { match _result {
@ -252,9 +252,9 @@ pub fn impl_wrap_class(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec) -> Tok
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()"); const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
let _pool = ::pyo3::GILPool::new(); let _pool = ::pyo3::GILPool::new();
let _py = ::pyo3::Python::assume_gil_acquired(); let _py = ::pyo3::Python::assume_gil_acquired();
let _cls = ::pyo3::PyType::from_type_ptr(_py, _cls as *mut ::pyo3::ffi::PyTypeObject); let _cls = ::pyo3::types::PyType::from_type_ptr(_py, _cls as *mut ::pyo3::ffi::PyTypeObject);
let _args = _py.from_borrowed_ptr::<::pyo3::PyTuple>(_args); let _args = _py.from_borrowed_ptr::<::pyo3::types::PyTuple>(_args);
let _kwargs: Option<&PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); let _kwargs: Option<&::pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
#body_to_result #body_to_result
::pyo3::callback::cb_convert( ::pyo3::callback::cb_convert(
@ -293,8 +293,8 @@ pub fn impl_wrap_static(cls: &syn::Type, name: &syn::Ident, spec: &FnSpec) -> To
const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()"); const _LOCATION: &'static str = concat!(stringify!(#cls),".",stringify!(#name),"()");
let _pool = ::pyo3::GILPool::new(); let _pool = ::pyo3::GILPool::new();
let _py = ::pyo3::Python::assume_gil_acquired(); let _py = ::pyo3::Python::assume_gil_acquired();
let _args = _py.from_borrowed_ptr::<::pyo3::PyTuple>(_args); let _args = _py.from_borrowed_ptr::<::pyo3::types::PyTuple>(_args);
let _kwargs: Option<&PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs); let _kwargs: Option<&::pyo3::types::PyDict> = _py.from_borrowed_ptr_or_opt(_kwargs);
#body_to_result #body_to_result
::pyo3::callback::cb_convert( ::pyo3::callback::cb_convert(
@ -317,7 +317,7 @@ pub(crate) fn impl_wrap_getter(cls: &syn::Type, name: &syn::Ident) -> TokenStrea
match _slf.#name() { match _slf.#name() {
Ok(val) => { Ok(val) => {
val.into_object(_py).into_ptr() ::pyo3::IntoPyPointer::into_ptr(val.into_object(_py))
} }
Err(e) => { Err(e) => {
e.restore(_py); e.restore(_py);
@ -413,7 +413,7 @@ pub fn impl_arg_params(spec: &FnSpec, body: TokenStream) -> TokenStream {
}; };
params.push(quote! { params.push(quote! {
::pyo3::argparse::ParamDescription{ ::pyo3::derive_utils::ParamDescription{
name: stringify!(#name), is_optional: #opt, kw_only: #kwonly} name: stringify!(#name), is_optional: #opt, kw_only: #kwonly}
}); });
} }
@ -448,12 +448,12 @@ pub fn impl_arg_params(spec: &FnSpec, body: TokenStream) -> TokenStream {
// create array of arguments, and then parse // create array of arguments, and then parse
quote! { quote! {
const _PARAMS: &'static [::pyo3::argparse::ParamDescription<'static>] = &[ const _PARAMS: &'static [::pyo3::derive_utils::ParamDescription<'static>] = &[
#(#params),* #(#params),*
]; ];
let mut _output = [#(#placeholders),*]; let mut _output = [#(#placeholders),*];
match ::pyo3::argparse::parse_args(Some(_LOCATION), _PARAMS, &_args, match ::pyo3::derive_utils::parse_fn_args(Some(_LOCATION), _PARAMS, &_args,
_kwargs, #accept_args, #accept_kwargs, &mut _output) _kwargs, #accept_args, #accept_kwargs, &mut _output)
{ {
Ok(_) => { Ok(_) => {

View File

@ -23,10 +23,10 @@ use std::os::raw;
use std::{cell, mem, slice}; use std::{cell, mem, slice};
use err::{self, PyResult}; use err::{self, PyResult};
use exc; use exceptions;
use ffi; use ffi;
use objects::PyObjectRef;
use python::{Python, ToPyPointer}; use python::{Python, ToPyPointer};
use types::PyObjectRef;
/// Allows access to the underlying buffer used by a python object such as `bytes`, `bytearray` or `array.array`. /// Allows access to the underlying buffer used by a python object such as `bytes`, `bytearray` or `array.array`.
#[repr(transparent)] #[repr(transparent)]
@ -460,7 +460,7 @@ impl PyBuffer {
fort: u8, fort: u8,
) -> PyResult<()> { ) -> PyResult<()> {
if mem::size_of_val(target) != self.len_bytes() { if mem::size_of_val(target) != self.len_bytes() {
return Err(exc::BufferError::py_err( return Err(exceptions::BufferError::py_err(
"Slice length does not match buffer length.", "Slice length does not match buffer length.",
)); ));
} }
@ -563,7 +563,7 @@ impl PyBuffer {
return buffer_readonly_error(); return buffer_readonly_error();
} }
if mem::size_of_val(source) != self.len_bytes() { if mem::size_of_val(source) != self.len_bytes() {
return Err(exc::BufferError::py_err( return Err(exceptions::BufferError::py_err(
"Slice length does not match buffer length.", "Slice length does not match buffer length.",
)); ));
} }
@ -593,13 +593,13 @@ impl PyBuffer {
} }
fn incompatible_format_error() -> PyResult<()> { fn incompatible_format_error() -> PyResult<()> {
Err(exc::BufferError::py_err( Err(exceptions::BufferError::py_err(
"Slice type is incompatible with buffer format.", "Slice type is incompatible with buffer format.",
)) ))
} }
fn buffer_readonly_error() -> PyResult<()> { fn buffer_readonly_error() -> PyResult<()> {
Err(exc::BufferError::py_err( Err(exceptions::BufferError::py_err(
"Cannot write to read-only buffer.", "Cannot write to read-only buffer.",
)) ))
} }

View File

@ -8,8 +8,8 @@ use std::{isize, ptr};
use conversion::IntoPyObject; use conversion::IntoPyObject;
use err::PyResult; use err::PyResult;
use ffi::{self, Py_hash_t}; use ffi::{self, Py_hash_t};
use objects::exc::OverflowError;
use python::{IntoPyPointer, Python}; use python::{IntoPyPointer, Python};
use types::exceptions::OverflowError;
pub trait CallbackConverter<S> { pub trait CallbackConverter<S> {
type R; type R;

View File

@ -17,9 +17,9 @@ use conversion::{FromPyObject, IntoPyObject};
use err::{PyErr, PyResult}; use err::{PyErr, PyResult};
use ffi; use ffi;
use objectprotocol::ObjectProtocol; use objectprotocol::ObjectProtocol;
use objects::{exc, PyObjectRef};
use python::{IntoPyPointer, Python}; use python::{IntoPyPointer, Python};
use typeob::PyTypeInfo; use typeob::PyTypeInfo;
use types::{exceptions, PyObjectRef};
use CompareOp; use CompareOp;
/// Basic python class customization /// Basic python class customization
@ -458,7 +458,7 @@ fn extract_op(op: c_int) -> PyResult<CompareOp> {
ffi::Py_NE => Ok(CompareOp::Ne), ffi::Py_NE => Ok(CompareOp::Ne),
ffi::Py_GT => Ok(CompareOp::Gt), ffi::Py_GT => Ok(CompareOp::Gt),
ffi::Py_GE => Ok(CompareOp::Ge), ffi::Py_GE => Ok(CompareOp::Ge),
_ => Err(PyErr::new::<exc::ValueError, _>( _ => Err(PyErr::new::<exceptions::ValueError, _>(
"tp_richcompare called with invalid comparison operator", "tp_richcompare called with invalid comparison operator",
)), )),
} }

View File

@ -12,8 +12,8 @@ use class::methods::PyMethodDef;
use conversion::{FromPyObject, IntoPyObject}; use conversion::{FromPyObject, IntoPyObject};
use err::PyResult; use err::PyResult;
use ffi; use ffi;
use objects::{PyObjectRef, PyType};
use typeob::PyTypeInfo; use typeob::PyTypeInfo;
use types::{PyObjectRef, PyType};
/// Descriptor interface /// Descriptor interface
#[allow(unused_variables)] #[allow(unused_variables)]

View File

@ -87,7 +87,7 @@ macro_rules! py_binary_func {
let _pool = $crate::GILPool::new(); let _pool = $crate::GILPool::new();
let py = $crate::Python::assume_gil_acquired(); let py = $crate::Python::assume_gil_acquired();
let slf = py.mut_from_borrowed_ptr::<T>(slf); let slf = py.mut_from_borrowed_ptr::<T>(slf);
let arg = py.from_borrowed_ptr::<$crate::PyObjectRef>(arg); let arg = py.from_borrowed_ptr::<$crate::types::PyObjectRef>(arg);
let result = match arg.extract() { let result = match arg.extract() {
Ok(arg) => slf.$f(arg).into(), Ok(arg) => slf.$f(arg).into(),
@ -114,8 +114,8 @@ macro_rules! py_binary_num_func {
use $crate::ObjectProtocol; use $crate::ObjectProtocol;
let _pool = $crate::GILPool::new(); let _pool = $crate::GILPool::new();
let py = $crate::Python::assume_gil_acquired(); let py = $crate::Python::assume_gil_acquired();
let lhs = py.from_borrowed_ptr::<$crate::PyObjectRef>(lhs); let lhs = py.from_borrowed_ptr::<$crate::types::PyObjectRef>(lhs);
let rhs = py.from_borrowed_ptr::<$crate::PyObjectRef>(rhs); let rhs = py.from_borrowed_ptr::<$crate::types::PyObjectRef>(rhs);
let result = match lhs.extract() { let result = match lhs.extract() {
Ok(lhs) => match rhs.extract() { Ok(lhs) => match rhs.extract() {
@ -147,7 +147,7 @@ macro_rules! py_binary_self_func {
let _pool = $crate::GILPool::new(); let _pool = $crate::GILPool::new();
let py = $crate::Python::assume_gil_acquired(); let py = $crate::Python::assume_gil_acquired();
let slf1 = py.mut_from_borrowed_ptr::<T>(slf); let slf1 = py.mut_from_borrowed_ptr::<T>(slf);
let arg = py.from_borrowed_ptr::<$crate::PyObjectRef>(arg); let arg = py.from_borrowed_ptr::<$crate::types::PyObjectRef>(arg);
let result = match arg.extract() { let result = match arg.extract() {
Ok(arg) => slf1.$f(arg).into(), Ok(arg) => slf1.$f(arg).into(),
@ -216,8 +216,8 @@ macro_rules! py_ternary_func {
let _pool = $crate::GILPool::new(); let _pool = $crate::GILPool::new();
let py = $crate::Python::assume_gil_acquired(); let py = $crate::Python::assume_gil_acquired();
let slf = py.mut_from_borrowed_ptr::<T>(slf); let slf = py.mut_from_borrowed_ptr::<T>(slf);
let arg1 = py.from_borrowed_ptr::<$crate::PyObjectRef>(arg1); let arg1 = py.from_borrowed_ptr::<$crate::types::PyObjectRef>(arg1);
let arg2 = py.from_borrowed_ptr::<$crate::PyObjectRef>(arg2); let arg2 = py.from_borrowed_ptr::<$crate::types::PyObjectRef>(arg2);
let result = match arg1.extract() { let result = match arg1.extract() {
Ok(arg1) => match arg2.extract() { Ok(arg1) => match arg2.extract() {
@ -249,9 +249,9 @@ macro_rules! py_ternary_num_func {
let _pool = $crate::GILPool::new(); let _pool = $crate::GILPool::new();
let py = $crate::Python::assume_gil_acquired(); let py = $crate::Python::assume_gil_acquired();
let arg1 = py.from_borrowed_ptr::<$crate::PyObjectRef>(arg1); let arg1 = py.from_borrowed_ptr::<$crate::types::PyObjectRef>(arg1);
let arg2 = py.from_borrowed_ptr::<$crate::PyObjectRef>(arg2); let arg2 = py.from_borrowed_ptr::<$crate::types::PyObjectRef>(arg2);
let arg3 = py.from_borrowed_ptr::<$crate::PyObjectRef>(arg3); let arg3 = py.from_borrowed_ptr::<$crate::types::PyObjectRef>(arg3);
let result = match arg1.extract() { let result = match arg1.extract() {
Ok(arg1) => match arg2.extract() { Ok(arg1) => match arg2.extract() {
@ -287,8 +287,8 @@ macro_rules! py_ternary_self_func {
let _pool = $crate::GILPool::new(); let _pool = $crate::GILPool::new();
let py = $crate::Python::assume_gil_acquired(); let py = $crate::Python::assume_gil_acquired();
let slf1 = py.mut_from_borrowed_ptr::<T>(slf); let slf1 = py.mut_from_borrowed_ptr::<T>(slf);
let arg1 = py.from_borrowed_ptr::<$crate::PyObjectRef>(arg1); let arg1 = py.from_borrowed_ptr::<$crate::types::PyObjectRef>(arg1);
let arg2 = py.from_borrowed_ptr::<$crate::PyObjectRef>(arg2); let arg2 = py.from_borrowed_ptr::<$crate::types::PyObjectRef>(arg2);
let result = match arg1.extract() { let result = match arg1.extract() {
Ok(arg1) => match arg2.extract() { Ok(arg1) => match arg2.extract() {
@ -328,13 +328,15 @@ macro_rules! py_func_set {
let slf = py.mut_from_borrowed_ptr::<$generic>(slf); let slf = py.mut_from_borrowed_ptr::<$generic>(slf);
let result = if value.is_null() { let result = if value.is_null() {
Err($crate::PyErr::new::<exc::NotImplementedError, _>(format!( Err($crate::PyErr::new::<exceptions::NotImplementedError, _>(
format!(
"Subscript deletion not supported by {:?}", "Subscript deletion not supported by {:?}",
stringify!($generic) stringify!($generic)
))) ),
))
} else { } else {
let name = py.mut_from_borrowed_ptr::<$crate::PyObjectRef>(name); let name = py.mut_from_borrowed_ptr::<$crate::types::PyObjectRef>(name);
let value = py.from_borrowed_ptr::<$crate::PyObjectRef>(value); let value = py.from_borrowed_ptr::<$crate::types::PyObjectRef>(value);
match name.extract() { match name.extract() {
Ok(name) => match value.extract() { Ok(name) => match value.extract() {
Ok(value) => slf.$fn_set(name, value).into(), Ok(value) => slf.$fn_set(name, value).into(),
@ -374,14 +376,14 @@ macro_rules! py_func_del {
let result = if value.is_null() { let result = if value.is_null() {
let slf = py.mut_from_borrowed_ptr::<U>(slf); let slf = py.mut_from_borrowed_ptr::<U>(slf);
let name = py.from_borrowed_ptr::<$crate::PyObjectRef>(name); let name = py.from_borrowed_ptr::<$crate::types::PyObjectRef>(name);
match name.extract() { match name.extract() {
Ok(name) => slf.$fn_del(name).into(), Ok(name) => slf.$fn_del(name).into(),
Err(e) => Err(e.into()), Err(e) => Err(e.into()),
} }
} else { } else {
Err(PyErr::new::<exc::NotImplementedError, _>( Err(PyErr::new::<exceptions::NotImplementedError, _>(
"Subscript assignment not supported", "Subscript assignment not supported",
)) ))
}; };
@ -414,7 +416,7 @@ macro_rules! py_func_set_del {
let _pool = $crate::GILPool::new(); let _pool = $crate::GILPool::new();
let py = $crate::Python::assume_gil_acquired(); let py = $crate::Python::assume_gil_acquired();
let slf = py.mut_from_borrowed_ptr::<$generic>(slf); let slf = py.mut_from_borrowed_ptr::<$generic>(slf);
let name = py.from_borrowed_ptr::<$crate::PyObjectRef>(name); let name = py.from_borrowed_ptr::<$crate::types::PyObjectRef>(name);
let result = if value.is_null() { let result = if value.is_null() {
match name.extract() { match name.extract() {
@ -422,7 +424,7 @@ macro_rules! py_func_set_del {
Err(e) => Err(e.into()), Err(e) => Err(e.into()),
} }
} else { } else {
let value = py.from_borrowed_ptr::<$crate::PyObjectRef>(value); let value = py.from_borrowed_ptr::<$crate::types::PyObjectRef>(value);
match name.extract() { match name.extract() {
Ok(name) => match value.extract() { Ok(name) => match value.extract() {
Ok(value) => slf.$fn_set(name, value).into(), Ok(value) => slf.$fn_set(name, value).into(),

View File

@ -8,9 +8,9 @@ use class::methods::PyMethodDef;
use conversion::{FromPyObject, IntoPyObject}; use conversion::{FromPyObject, IntoPyObject};
use err::{PyErr, PyResult}; use err::{PyErr, PyResult};
use ffi; use ffi;
use objects::exc;
use python::Python; use python::Python;
use typeob::PyTypeInfo; use typeob::PyTypeInfo;
use types::exceptions;
/// Mapping interface /// Mapping interface
#[allow(unused_variables)] #[allow(unused_variables)]

View File

@ -8,10 +8,10 @@ use conversion::{FromPyObject, IntoPyObject};
use err::{PyErr, PyResult}; use err::{PyErr, PyResult};
use ffi; use ffi;
use objectprotocol::ObjectProtocol; use objectprotocol::ObjectProtocol;
use objects::{exc, PyObjectRef};
use python::Python; use python::Python;
use std::os::raw::c_int; use std::os::raw::c_int;
use typeob::PyTypeInfo; use typeob::PyTypeInfo;
use types::{exceptions, PyObjectRef};
/// Sequece interface /// Sequece interface
#[allow(unused_variables)] #[allow(unused_variables)]
@ -235,7 +235,7 @@ where
let slf = py.mut_from_borrowed_ptr::<T>(slf); let slf = py.mut_from_borrowed_ptr::<T>(slf);
let result = if value.is_null() { let result = if value.is_null() {
Err(PyErr::new::<exc::NotImplementedError, _>(format!( Err(PyErr::new::<exceptions::NotImplementedError, _>(format!(
"Item deletion not supported by {:?}", "Item deletion not supported by {:?}",
stringify!(T) stringify!(T)
))) )))
@ -311,7 +311,7 @@ mod sq_ass_item_impl {
let result = if value.is_null() { let result = if value.is_null() {
slf.__delitem__(key as isize).into() slf.__delitem__(key as isize).into()
} else { } else {
Err(PyErr::new::<exc::NotImplementedError, _>(format!( Err(PyErr::new::<exceptions::NotImplementedError, _>(format!(
"Item assignment not supported by {:?}", "Item assignment not supported by {:?}",
stringify!(T) stringify!(T)
))) )))

View File

@ -6,9 +6,9 @@ use err::{PyDowncastError, PyResult};
use ffi; use ffi;
use instance::Py; use instance::Py;
use object::PyObject; use object::PyObject;
use objects::{PyObjectRef, PyTuple};
use python::{IntoPyPointer, Python, ToPyPointer}; use python::{IntoPyPointer, Python, ToPyPointer};
use typeob::PyTypeInfo; use typeob::PyTypeInfo;
use types::{PyObjectRef, PyTuple};
/// Conversion trait that allows various objects to be converted into `PyObject` /// Conversion trait that allows various objects to be converted into `PyObject`
pub trait ToPyObject { pub trait ToPyObject {

View File

@ -2,10 +2,18 @@
// //
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython // based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
//! Python argument parsing //! Functionality for the code generated by the derive backend
use conversion::PyTryFrom; use conversion::PyTryFrom;
use err::PyResult; use err::PyResult;
use objects::{exc, PyDict, PyObjectRef, PyString, PyTuple}; use exceptions::TypeError;
use ffi;
use init_once;
use std::ptr;
use types::PyModule;
use types::{PyDict, PyObjectRef, PyString, PyTuple};
use GILPool;
use Python;
#[derive(Debug)] #[derive(Debug)]
/// Description of a python parameter; used for `parse_args()`. /// Description of a python parameter; used for `parse_args()`.
@ -26,7 +34,7 @@ pub struct ParamDescription<'a> {
/// * kwargs: Keyword arguments /// * kwargs: Keyword arguments
/// * output: Output array that receives the arguments. /// * output: Output array that receives the arguments.
/// Must have same length as `params` and must be initialized to `None`. /// Must have same length as `params` and must be initialized to `None`.
pub fn parse_args<'p>( pub fn parse_fn_args<'p>(
fname: Option<&str>, fname: Option<&str>,
params: &[ParamDescription], params: &[ParamDescription],
args: &'p PyTuple, args: &'p PyTuple,
@ -38,7 +46,7 @@ pub fn parse_args<'p>(
let nargs = args.len(); let nargs = args.len();
let nkeywords = kwargs.map_or(0, |d| d.len()); let nkeywords = kwargs.map_or(0, |d| d.len());
if !accept_args && (nargs + nkeywords > params.len()) { if !accept_args && (nargs + nkeywords > params.len()) {
return Err(exc::TypeError::py_err(format!( return Err(TypeError::py_err(format!(
"{}{} takes at most {} argument{} ({} given)", "{}{} takes at most {} argument{} ({} given)",
fname.unwrap_or("function"), fname.unwrap_or("function"),
if fname.is_some() { "()" } else { "" }, if fname.is_some() { "()" } else { "" },
@ -55,7 +63,7 @@ pub fn parse_args<'p>(
*out = Some(kwarg); *out = Some(kwarg);
used_keywords += 1; used_keywords += 1;
if i < nargs { if i < nargs {
return Err(exc::TypeError::py_err(format!( return Err(TypeError::py_err(format!(
"Argument given by name ('{}') and position ({})", "Argument given by name ('{}') and position ({})",
p.name, p.name,
i + 1 i + 1
@ -65,7 +73,7 @@ pub fn parse_args<'p>(
None => { None => {
if p.kw_only { if p.kw_only {
if !p.is_optional { if !p.is_optional {
return Err(exc::TypeError::py_err(format!( return Err(TypeError::py_err(format!(
"Required argument ('{}') is keyword only argument", "Required argument ('{}') is keyword only argument",
p.name p.name
))); )));
@ -76,7 +84,7 @@ pub fn parse_args<'p>(
} else { } else {
*out = None; *out = None;
if !p.is_optional { if !p.is_optional {
return Err(exc::TypeError::py_err(format!( return Err(TypeError::py_err(format!(
"Required argument ('{}') (pos {}) not found", "Required argument ('{}') (pos {}) not found",
p.name, p.name,
i + 1 i + 1
@ -92,7 +100,7 @@ pub fn parse_args<'p>(
let item = <PyTuple as PyTryFrom>::try_from(item)?; let item = <PyTuple as PyTryFrom>::try_from(item)?;
let key = <PyString as PyTryFrom>::try_from(item.get_item(0))?.to_string()?; let key = <PyString as PyTryFrom>::try_from(item.get_item(0))?.to_string()?;
if !params.iter().any(|p| p.name == key) { if !params.iter().any(|p| p.name == key) {
return Err(exc::TypeError::py_err(format!( return Err(TypeError::py_err(format!(
"'{}' is an invalid keyword argument for this function", "'{}' is an invalid keyword argument for this function",
key key
))); )));
@ -101,3 +109,90 @@ pub fn parse_args<'p>(
} }
Ok(()) Ok(())
} }
#[cfg(Py_3)]
#[doc(hidden)]
/// Builds a module (or null) from a user given initializer. Used for `#[pymodinit]`.
pub unsafe fn make_module(
name: &str,
doc: &str,
initializer: impl Fn(Python, &PyModule) -> PyResult<()>,
) -> *mut ffi::PyObject {
use python::IntoPyPointer;
init_once();
#[cfg(py_sys_config = "WITH_THREAD")]
// > Changed in version 3.7: This function is now called by Py_Initialize(), so you dont have
// > to call it yourself anymore.
#[cfg(not(Py_3_7))]
ffi::PyEval_InitThreads();
static mut MODULE_DEF: ffi::PyModuleDef = ffi::PyModuleDef_INIT;
// We can't convert &'static str to *const c_char within a static initializer,
// so we'll do it here in the module initialization:
MODULE_DEF.m_name = name.as_ptr() as *const _;
let module = ffi::PyModule_Create(&mut MODULE_DEF);
if module.is_null() {
return module;
}
let _pool = GILPool::new();
let py = Python::assume_gil_acquired();
let module = match py.from_owned_ptr_or_err::<PyModule>(module) {
Ok(m) => m,
Err(e) => {
e.restore(py);
return ptr::null_mut();
}
};
module
.add("__doc__", doc)
.expect("Failed to add doc for module");
match initializer(py, module) {
Ok(_) => module.into_ptr(),
Err(e) => {
e.restore(py);
ptr::null_mut()
}
}
}
#[cfg(not(Py_3))]
#[doc(hidden)]
/// Builds a module (or null) from a user given initializer. Used for `#[pymodinit]`.
pub unsafe fn make_module(
name: &str,
doc: &str,
initializer: impl Fn(Python, &PyModule) -> PyResult<()>,
) {
init_once();
#[cfg(py_sys_config = "WITH_THREAD")]
ffi::PyEval_InitThreads();
let _name = name.as_ptr() as *const _;
let _pool = GILPool::new();
let py = Python::assume_gil_acquired();
let _module = ffi::Py_InitModule(_name, ptr::null_mut());
if _module.is_null() {
return;
}
let _module = match py.from_borrowed_ptr_or_err::<PyModule>(_module) {
Ok(m) => m,
Err(e) => {
e.restore(py);
return;
}
};
_module
.add("__doc__", doc)
.expect("Failed to add doc for module");
if let Err(e) = initializer(py, _module) {
e.restore(py)
}
}

View File

@ -10,27 +10,28 @@ use conversion::{IntoPyObject, ToBorrowedObject, ToPyObject};
use ffi; use ffi;
use instance::Py; use instance::Py;
use object::PyObject; use object::PyObject;
use objects::{exc, PyObjectRef, PyType};
use python::{IntoPyPointer, Python, ToPyPointer}; use python::{IntoPyPointer, Python, ToPyPointer};
use typeob::PyTypeObject; use typeob::PyTypeObject;
use types::{exceptions, PyObjectRef, PyType};
/// Defines a new exception type. /// Defines a new exception type.
/// ///
/// # Syntax /// # Syntax
/// `py_exception!(module, MyError, pyo3::exc::Exception)` /// `py_exception!(module, MyError, pyo3::exceptions::Exception)`
/// ///
/// * `module` is the name of the containing module. /// * `module` is the name of the containing module.
/// * `MyError` is the name of the new exception type. /// * `MyError` is the name of the new exception type.
/// * `pyo3::exc::Exception` is the name of the base type /// * `pyo3::exceptions::Exception` is the name of the base type
/// ///
/// # Example /// # Example
/// ``` /// ```
/// #[macro_use] /// #[macro_use]
/// extern crate pyo3; /// extern crate pyo3;
/// ///
/// use pyo3::{Python, PyDict}; /// use pyo3::Python;
/// use pyo3::types::PyDict;
/// ///
/// py_exception!(mymodule, CustomError, pyo3::exc::Exception); /// py_exception!(mymodule, CustomError, pyo3::exceptions::Exception);
/// ///
/// fn main() { /// fn main() {
/// let gil = Python::acquire_gil(); /// let gil = Python::acquire_gil();
@ -97,7 +98,7 @@ macro_rules! py_exception {
} }
#[inline] #[inline]
fn type_object() -> $crate::Py<$crate::PyType> { fn type_object() -> $crate::Py<$crate::types::PyType> {
unsafe { unsafe {
$crate::Py::from_borrowed_ptr( $crate::Py::from_borrowed_ptr(
$name::type_object() as *const _ as *mut $crate::ffi::PyObject $name::type_object() as *const _ as *mut $crate::ffi::PyObject
@ -156,7 +157,7 @@ impl PyErr {
/// Panics if `T` is not a python class derived from `BaseException`. /// Panics if `T` is not a python class derived from `BaseException`.
/// ///
/// Example: /// Example:
/// `return Err(PyErr::new::<exc::TypeError, _>("Error message"));` /// `return Err(PyErr::new::<exceptions::TypeError, _>("Error message"));`
pub fn new<T, V>(value: V) -> PyErr pub fn new<T, V>(value: V) -> PyErr
where where
T: PyTypeObject, T: PyTypeObject,
@ -174,7 +175,7 @@ impl PyErr {
/// Construct a new error, with the usual lazy initialization of Python exceptions. /// Construct a new error, with the usual lazy initialization of Python exceptions.
/// `exc` is the exception type; usually one of the standard exceptions /// `exc` is the exception type; usually one of the standard exceptions
/// like `exc::RuntimeError`. /// like `exceptions::RuntimeError`.
/// `args` is the a tuple of arguments to pass to the exception constructor. /// `args` is the a tuple of arguments to pass to the exception constructor.
pub fn from_type<A>(exc: Py<PyType>, args: A) -> PyErr pub fn from_type<A>(exc: Py<PyType>, args: A) -> PyErr
where where
@ -225,7 +226,7 @@ impl PyErr {
} }
} else { } else {
PyErr { PyErr {
ptype: exc::TypeError::type_object(), ptype: exceptions::TypeError::type_object(),
pvalue: PyErrValue::ToObject(Box::new("exceptions must derive from BaseException")), pvalue: PyErrValue::ToObject(Box::new("exceptions must derive from BaseException")),
ptraceback: None, ptraceback: None,
} }
@ -297,7 +298,7 @@ impl PyErr {
}; };
let ptype = if ptype.is_null() { let ptype = if ptype.is_null() {
<exc::SystemError as PyTypeObject>::type_object() <exceptions::SystemError as PyTypeObject>::type_object()
} else { } else {
Py::from_owned_ptr(ptype) Py::from_owned_ptr(ptype)
}; };
@ -479,7 +480,7 @@ impl<'a> IntoPyObject for &'a PyErr {
/// Converts `PyDowncastError` to Python `TypeError`. /// Converts `PyDowncastError` to Python `TypeError`.
impl std::convert::From<PyDowncastError> for PyErr { impl std::convert::From<PyDowncastError> for PyErr {
fn from(_err: PyDowncastError) -> PyErr { fn from(_err: PyDowncastError) -> PyErr {
exc::TypeError.into() exceptions::TypeError.into()
} }
} }
@ -528,30 +529,32 @@ impl std::convert::From<io::Error> for PyErr {
fn from(err: io::Error) -> PyErr { fn from(err: io::Error) -> PyErr {
match err.kind() { match err.kind() {
io::ErrorKind::BrokenPipe => { io::ErrorKind::BrokenPipe => {
PyErr::from_value::<exc::BrokenPipeError>(PyErrValue::ToArgs(Box::new(err))) PyErr::from_value::<exceptions::BrokenPipeError>(PyErrValue::ToArgs(Box::new(err)))
}
io::ErrorKind::ConnectionRefused => {
PyErr::from_value::<exc::ConnectionRefusedError>(PyErrValue::ToArgs(Box::new(err)))
}
io::ErrorKind::ConnectionAborted => {
PyErr::from_value::<exc::ConnectionAbortedError>(PyErrValue::ToArgs(Box::new(err)))
} }
io::ErrorKind::ConnectionRefused => PyErr::from_value::<
exceptions::ConnectionRefusedError,
>(PyErrValue::ToArgs(Box::new(err))),
io::ErrorKind::ConnectionAborted => PyErr::from_value::<
exceptions::ConnectionAbortedError,
>(PyErrValue::ToArgs(Box::new(err))),
io::ErrorKind::ConnectionReset => { io::ErrorKind::ConnectionReset => {
PyErr::from_value::<exc::ConnectionResetError>(PyErrValue::ToArgs(Box::new(err))) PyErr::from_value::<exceptions::ConnectionResetError>(PyErrValue::ToArgs(Box::new(
err,
)))
} }
io::ErrorKind::Interrupted => { io::ErrorKind::Interrupted => {
PyErr::from_value::<exc::InterruptedError>(PyErrValue::ToArgs(Box::new(err))) PyErr::from_value::<exceptions::InterruptedError>(PyErrValue::ToArgs(Box::new(err)))
}
io::ErrorKind::NotFound => {
PyErr::from_value::<exc::FileNotFoundError>(PyErrValue::ToArgs(Box::new(err)))
} }
io::ErrorKind::NotFound => PyErr::from_value::<exceptions::FileNotFoundError>(
PyErrValue::ToArgs(Box::new(err)),
),
io::ErrorKind::WouldBlock => { io::ErrorKind::WouldBlock => {
PyErr::from_value::<exc::BlockingIOError>(PyErrValue::ToArgs(Box::new(err))) PyErr::from_value::<exceptions::BlockingIOError>(PyErrValue::ToArgs(Box::new(err)))
} }
io::ErrorKind::TimedOut => { io::ErrorKind::TimedOut => {
PyErr::from_value::<exc::TimeoutError>(PyErrValue::ToArgs(Box::new(err))) PyErr::from_value::<exceptions::TimeoutError>(PyErrValue::ToArgs(Box::new(err)))
} }
_ => PyErr::from_value::<exc::OSError>(PyErrValue::ToArgs(Box::new(err))), _ => PyErr::from_value::<exceptions::OSError>(PyErrValue::ToArgs(Box::new(err))),
} }
} }
} }
@ -560,7 +563,7 @@ impl std::convert::From<io::Error> for PyErr {
/// Create `OSError` from `io::Error` /// Create `OSError` from `io::Error`
impl std::convert::From<io::Error> for PyErr { impl std::convert::From<io::Error> for PyErr {
fn from(err: io::Error) -> PyErr { fn from(err: io::Error) -> PyErr {
PyErr::from_value::<exc::OSError>(PyErrValue::ToArgs(Box::new(err))) PyErr::from_value::<exceptions::OSError>(PyErrValue::ToArgs(Box::new(err)))
} }
} }
@ -573,7 +576,7 @@ impl PyErrArguments for io::Error {
impl<W: 'static + Send + std::fmt::Debug> std::convert::From<std::io::IntoInnerError<W>> for PyErr { impl<W: 'static + Send + std::fmt::Debug> std::convert::From<std::io::IntoInnerError<W>> for PyErr {
fn from(err: std::io::IntoInnerError<W>) -> PyErr { fn from(err: std::io::IntoInnerError<W>) -> PyErr {
PyErr::from_value::<exc::OSError>(PyErrValue::ToArgs(Box::new(err))) PyErr::from_value::<exceptions::OSError>(PyErrValue::ToArgs(Box::new(err)))
} }
} }
@ -583,17 +586,17 @@ impl<W: Send + std::fmt::Debug> PyErrArguments for std::io::IntoInnerError<W> {
} }
} }
impl_to_pyerr!(std::num::ParseIntError, exc::ValueError); impl_to_pyerr!(std::num::ParseIntError, exceptions::ValueError);
impl_to_pyerr!(std::num::ParseFloatError, exc::ValueError); impl_to_pyerr!(std::num::ParseFloatError, exceptions::ValueError);
impl_to_pyerr!(std::string::ParseError, exc::ValueError); impl_to_pyerr!(std::string::ParseError, exceptions::ValueError);
impl_to_pyerr!(std::str::ParseBoolError, exc::ValueError); impl_to_pyerr!(std::str::ParseBoolError, exceptions::ValueError);
impl_to_pyerr!(std::ffi::IntoStringError, exc::UnicodeDecodeError); impl_to_pyerr!(std::ffi::IntoStringError, exceptions::UnicodeDecodeError);
impl_to_pyerr!(std::ffi::NulError, exc::ValueError); impl_to_pyerr!(std::ffi::NulError, exceptions::ValueError);
impl_to_pyerr!(std::str::Utf8Error, exc::UnicodeDecodeError); impl_to_pyerr!(std::str::Utf8Error, exceptions::UnicodeDecodeError);
impl_to_pyerr!(std::string::FromUtf8Error, exc::UnicodeDecodeError); impl_to_pyerr!(std::string::FromUtf8Error, exceptions::UnicodeDecodeError);
impl_to_pyerr!(std::string::FromUtf16Error, exc::UnicodeDecodeError); impl_to_pyerr!(std::string::FromUtf16Error, exceptions::UnicodeDecodeError);
impl_to_pyerr!(std::char::DecodeUtf16Error, exc::UnicodeDecodeError); impl_to_pyerr!(std::char::DecodeUtf16Error, exceptions::UnicodeDecodeError);
impl_to_pyerr!(std::net::AddrParseError, exc::ValueError); impl_to_pyerr!(std::net::AddrParseError, exceptions::ValueError);
pub fn panic_after_error() -> ! { pub fn panic_after_error() -> ! {
unsafe { unsafe {
@ -614,14 +617,14 @@ pub fn error_on_minusone(py: Python, result: libc::c_int) -> PyResult<()> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use objects::exc; use types::exceptions;
use {PyErr, Python}; use {PyErr, Python};
#[test] #[test]
fn set_typeerror() { fn set_typeerror() {
let gil = Python::acquire_gil(); let gil = Python::acquire_gil();
let py = gil.python(); let py = gil.python();
let err: PyErr = exc::TypeError.into(); let err: PyErr = exceptions::TypeError.into();
err.restore(py); err.restore(py);
assert!(PyErr::occurred(py)); assert!(PyErr::occurred(py));
drop(PyErr::fetch(py)); drop(PyErr::fetch(py));

View File

@ -10,10 +10,10 @@ use ffi;
use instance; use instance;
use object::PyObject; use object::PyObject;
use objectprotocol::ObjectProtocol; use objectprotocol::ObjectProtocol;
use objects::PyObjectRef;
use python::{IntoPyPointer, Python, ToPyPointer}; use python::{IntoPyPointer, Python, ToPyPointer};
use pythonrun; use pythonrun;
use typeob::{PyTypeInfo, PyTypeObject}; use typeob::{PyTypeInfo, PyTypeObject};
use types::PyObjectRef;
pub struct PyToken(PhantomData<Rc<()>>); pub struct PyToken(PhantomData<Rc<()>>);

View File

@ -34,6 +34,7 @@
//! extern crate pyo3; //! extern crate pyo3;
//! //!
//! use pyo3::prelude::*; //! use pyo3::prelude::*;
//! use pyo3::types::PyDict;
//! //!
//! fn main() -> PyResult<()> { //! fn main() -> PyResult<()> {
//! let gil = Python::acquire_gil(); //! let gil = Python::acquire_gil();
@ -123,14 +124,29 @@
// We need those types in the macro exports // We need those types in the macro exports
#[doc(hidden)] #[doc(hidden)]
pub extern crate libc; pub extern crate libc;
extern crate pyo3cls;
extern crate spin;
// We need that reexport for wrap_function // We need that reexport for wrap_function
#[doc(hidden)] #[doc(hidden)]
pub extern crate mashup; pub extern crate mashup;
#[cfg(test)] #[cfg(test)]
#[macro_use] #[macro_use]
extern crate assert_approx_eq; extern crate assert_approx_eq;
extern crate pyo3cls;
extern crate spin;
pub use class::*;
pub use conversion::{
FromPyObject, IntoPyObject, IntoPyTuple, PyTryFrom, PyTryInto, ReturnTypeIntoPyResult,
ToBorrowedObject, ToPyObject,
};
pub use err::{PyDowncastError, PyErr, PyErrArguments, PyErrValue, PyResult};
pub use instance::{AsPyRef, Py, PyNativeType, PyObjectWithToken, PyToken};
pub use noargs::NoArgs;
pub use object::PyObject;
pub use objectprotocol::ObjectProtocol;
pub use python::{IntoPyPointer, Python, ToPyPointer};
pub use pythonrun::{init_once, prepare_freethreaded_python, GILGuard, GILPool};
pub use typeob::{PyObjectAlloc, PyRawObject, PyTypeInfo};
pub use types::exceptions;
/// Rust FFI declarations for Python /// Rust FFI declarations for Python
pub mod ffi; pub mod ffi;
@ -141,32 +157,7 @@ mod ffi2;
#[cfg(Py_3)] #[cfg(Py_3)]
mod ffi3; mod ffi3;
pub use conversion::{
FromPyObject, IntoPyObject, IntoPyTuple, PyTryFrom, PyTryInto, ReturnTypeIntoPyResult,
ToBorrowedObject, ToPyObject,
};
pub use err::{PyDowncastError, PyErr, PyErrArguments, PyErrValue, PyResult};
pub use instance::{AsPyRef, Py, PyNativeType, PyObjectWithToken, PyToken};
pub use noargs::NoArgs;
pub use object::PyObject;
pub use objectprotocol::ObjectProtocol;
pub use objects::*;
pub use python::{IntoPyPointer, Python, ToPyPointer};
pub use pythonrun::{init_once, prepare_freethreaded_python, GILGuard, GILPool};
pub use typeob::{PyObjectAlloc, PyRawObject, PyTypeInfo};
pub mod class; pub mod class;
pub use class::*;
/// The proc macro attributes
pub mod proc_macro {
pub use pyo3cls::{pyclass, pyfunction, pymethods, pyproto};
#[cfg(Py_3)]
pub use pyo3cls::mod3init as pymodinit;
#[cfg(not(Py_3))]
pub use pyo3cls::mod2init as pymodinit;
}
/// Constructs a `&'static CStr` literal. /// Constructs a `&'static CStr` literal.
macro_rules! cstr { macro_rules! cstr {
@ -176,9 +167,37 @@ macro_rules! cstr {
}; };
} }
pub mod buffer;
#[doc(hidden)]
pub mod callback;
mod conversion;
#[doc(hidden)]
pub mod derive_utils;
mod err;
pub mod freelist;
mod instance;
mod noargs;
mod object;
mod objectprotocol;
pub mod prelude;
pub mod python;
mod pythonrun;
pub mod typeob;
pub mod types;
/// The proc macros, which are also part of the prelude
pub mod proc_macro {
#[cfg(not(Py_3))]
pub use pyo3cls::mod2init as pymodinit;
#[cfg(Py_3)]
pub use pyo3cls::mod3init as pymodinit;
/// The proc macro attributes
pub use pyo3cls::{pyclass, pyfunction, pymethods, pyproto};
}
/// Returns a function that takes a [Python] instance and returns a python function. /// Returns a function that takes a [Python] instance and returns a python function.
/// ///
/// Use this together with `#[function]` and [PyModule::add_function]. /// Use this together with `#[function]` and [types::PyModule::add_function].
#[macro_export] #[macro_export]
macro_rules! wrap_function { macro_rules! wrap_function {
($function_name:ident) => {{ ($function_name:ident) => {{
@ -195,21 +214,3 @@ macro_rules! wrap_function {
} }
}}; }};
} }
#[doc(hidden)]
pub mod argparse;
pub mod buffer;
#[doc(hidden)]
pub mod callback;
mod conversion;
mod err;
pub mod freelist;
mod instance;
mod noargs;
mod object;
mod objectprotocol;
mod objects;
pub mod prelude;
pub mod python;
mod pythonrun;
pub mod typeob;

View File

@ -3,8 +3,8 @@
use conversion::{IntoPyObject, IntoPyTuple, ToPyObject}; use conversion::{IntoPyObject, IntoPyTuple, ToPyObject};
use instance::Py; use instance::Py;
use object::PyObject; use object::PyObject;
use objects::PyTuple;
use python::Python; use python::Python;
use types::PyTuple;
/// An empty struct that represents the empty argument list. /// An empty struct that represents the empty argument list.
/// Corresponds to the empty tuple `()` in Python. /// Corresponds to the empty tuple `()` in Python.

View File

@ -8,10 +8,9 @@ use conversion::{
use err::{PyDowncastError, PyErr, PyResult}; use err::{PyDowncastError, PyErr, PyResult};
use ffi; use ffi;
use instance::{AsPyRef, PyObjectWithToken}; use instance::{AsPyRef, PyObjectWithToken};
use objects::PyDict;
use objects::{PyObjectRef, PyTuple};
use python::{IntoPyPointer, Python, ToPyPointer}; use python::{IntoPyPointer, Python, ToPyPointer};
use pythonrun; use pythonrun;
use types::{PyDict, PyObjectRef, PyTuple};
/// Safe wrapper around unsafe `*mut ffi::PyObject` pointer. /// Safe wrapper around unsafe `*mut ffi::PyObject` pointer.
#[derive(Debug)] #[derive(Debug)]

View File

@ -5,13 +5,12 @@ use err::{self, PyDowncastError, PyErr, PyResult};
use ffi; use ffi;
use instance::PyObjectWithToken; use instance::PyObjectWithToken;
use object::PyObject; use object::PyObject;
use objects::PyDict;
use objects::{PyIterator, PyObjectRef, PyString, PyTuple, PyType};
use python::{IntoPyPointer, Python, ToPyPointer}; use python::{IntoPyPointer, Python, ToPyPointer};
use std; use std;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::os::raw::c_int; use std::os::raw::c_int;
use typeob::PyTypeInfo; use typeob::PyTypeInfo;
use types::{PyDict, PyIterator, PyObjectRef, PyString, PyTuple, PyType};
/// Python object model helper methods /// Python object model helper methods
pub trait ObjectProtocol { pub trait ObjectProtocol {
@ -269,7 +268,7 @@ where
} else if result < 0 { } else if result < 0 {
return Err(PyErr::fetch(py)); return Err(PyErr::fetch(py));
} }
Err(::exc::TypeError::py_err( Err(::exceptions::TypeError::py_err(
"ObjectProtocol::compare(): All comparisons returned false", "ObjectProtocol::compare(): All comparisons returned false",
)) ))
} }
@ -482,8 +481,8 @@ mod test {
use super::*; use super::*;
use conversion::{PyTryFrom, ToPyObject}; use conversion::{PyTryFrom, ToPyObject};
use instance::AsPyRef; use instance::AsPyRef;
use objects::PyString;
use python::Python; use python::Python;
use types::PyString;
#[test] #[test]
fn test_debug_string() { fn test_debug_string() {

View File

@ -1,160 +0,0 @@
// Copyright (c) 2017-present PyO3 Project and Contributors
/// Stringify a dotted path.
#[macro_export]
macro_rules! dot_stringify {
($e:ident) => (
stringify!($e)
);
($e:ident. $($es:ident).+) => (
concat!(stringify!($e), ".", dot_stringify!($($es).*))
);
}
/// Defines rust type for exception defined in Python code.
///
/// # Syntax
/// `import_exception!(module, MyError)`
///
/// * `module` is the name of the containing module.
/// * `MyError` is the name of the new exception type.
///
/// # Example
/// ```
/// #[macro_use] extern crate pyo3;
///
/// use pyo3::{Python, PyDict};
///
/// import_exception!(socket, gaierror);
///
/// fn main() {
/// let gil = Python::acquire_gil();
/// let py = gil.python();
/// let ctx = PyDict::new(py);
///
/// ctx.set_item("gaierror", py.get_type::<gaierror>()).unwrap();
/// py.run("import socket; assert gaierror is socket.gaierror", None, Some(ctx)).unwrap();
/// }
/// ```
#[macro_export]
macro_rules! import_exception {
($($module:ident).+ , $name: ident) => {
#[allow(non_camel_case_types)]
pub struct $name;
impl ::std::convert::From<$name> for $crate::PyErr {
fn from(_err: $name) -> $crate::PyErr {
$crate::PyErr::new::<$name, _>(())
}
}
impl<T> ::std::convert::Into<$crate::PyResult<T>> for $name {
fn into(self) -> $crate::PyResult<T> {
$crate::PyErr::new::<$name, _>(()).into()
}
}
impl $name {
pub fn py_err<T: $crate::ToPyObject + 'static>(args: T) -> $crate::PyErr
where Self: $crate::typeob::PyTypeObject + Sized
{
$crate::PyErr::new::<Self, T>(args)
}
pub fn into<R, T: $crate::ToPyObject + 'static>(args: T) -> $crate::PyResult<R>
where Self: $crate::typeob::PyTypeObject + Sized
{
$crate::PyErr::new::<Self, T>(args).into()
}
}
impl $crate::typeob::PyTypeObject for $name {
#[inline]
fn init_type() {}
#[inline]
fn type_object() -> $crate::Py<$crate::PyType> {
use $crate::IntoPyPointer;
static mut TYPE_OBJECT: *mut $crate::ffi::PyTypeObject = ::std::ptr::null_mut();
unsafe {
if TYPE_OBJECT.is_null() {
let gil = $crate::Python::acquire_gil();
let py = gil.python();
let imp = py.import(dot_stringify!($($module).*))
.expect(concat!(
"Can not import module: ", dot_stringify!($($module).*)));
let cls = imp.get(stringify!($name))
.expect(concat!(
"Can not load exception class: {}.{}", dot_stringify!($($module).*),
".", stringify!($name)));
TYPE_OBJECT = cls.into_ptr() as *mut $crate::ffi::PyTypeObject;
}
$crate::Py::from_borrowed_ptr(
TYPE_OBJECT as *const _ as *mut $crate::ffi::PyObject)
}
}
}
};
}
#[cfg(test)]
mod test {
use objects::PyDict;
use {PyErr, Python};
import_exception!(socket, gaierror);
import_exception!(email.errors, MessageError);
#[test]
fn test_check_exception() {
let gil = Python::acquire_gil();
let py = gil.python();
let err: PyErr = gaierror.into();
let socket = py
.import("socket")
.map_err(|e| e.print(py))
.expect("could not import socket");
let d = PyDict::new(py);
d.set_item("socket", socket)
.map_err(|e| e.print(py))
.expect("could not setitem");
d.set_item("exc", err)
.map_err(|e| e.print(py))
.expect("could not setitem");
py.run("assert isinstance(exc, socket.gaierror)", None, Some(d))
.map_err(|e| e.print(py))
.expect("assertion failed");
}
#[test]
fn test_check_exception_nested() {
let gil = Python::acquire_gil();
let py = gil.python();
let err: PyErr = MessageError.into();
let email = py
.import("email")
.map_err(|e| e.print(py))
.expect("could not import email");
let d = PyDict::new(py);
d.set_item("email", email)
.map_err(|e| e.print(py))
.expect("could not setitem");
d.set_item("exc", err)
.map_err(|e| e.print(py))
.expect("could not setitem");
py.run(
"assert isinstance(exc, email.errors.MessageError)",
None,
Some(d),
).map_err(|e| e.print(py))
.expect("assertion failed");
}
}

View File

@ -10,19 +10,18 @@
//! use pyo3::prelude::*; //! use pyo3::prelude::*;
//! ``` //! ```
pub use class::*; pub use conversion::{FromPyObject, IntoPyObject, PyTryFrom, PyTryInto, ToPyObject};
pub use conversion::{ pub use err::{PyErr, PyResult};
FromPyObject, IntoPyObject, IntoPyTuple, PyTryFrom, PyTryInto, ToBorrowedObject, ToPyObject, pub use instance::{AsPyRef, Py, PyToken};
};
pub use err::{PyDowncastError, PyErr, PyErrArguments, PyErrValue, PyResult};
pub use instance::{AsPyRef, Py, PyNativeType, PyObjectWithToken, PyToken};
pub use noargs::NoArgs; pub use noargs::NoArgs;
pub use object::PyObject; pub use object::PyObject;
pub use objectprotocol::ObjectProtocol; pub use objectprotocol::ObjectProtocol;
pub use objects::*; pub use python::Python;
pub use python::{IntoPyPointer, Python, ToPyPointer};
pub use pythonrun::GILGuard; pub use pythonrun::GILGuard;
pub use typeob::PyRawObject; // This is only part of the prelude because we need it for the pymodinit function
pub use types::PyModule;
// This is required for the constructor
pub use PyRawObject;
pub use pyo3cls::{pyclass, pyfunction, pymethods, pyproto}; pub use pyo3cls::{pyclass, pyfunction, pymethods, pyproto};

View File

@ -7,13 +7,13 @@ use err::{PyDowncastError, PyErr, PyResult};
use ffi; use ffi;
use instance::{AsPyRef, Py, PyToken}; use instance::{AsPyRef, Py, PyToken};
use object::PyObject; use object::PyObject;
use objects::{PyDict, PyModule, PyObjectRef, PyType};
use pythonrun::{self, GILGuard}; use pythonrun::{self, GILGuard};
use std; use std;
use std::ffi::CString; use std::ffi::CString;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::os::raw::c_int; use std::os::raw::c_int;
use typeob::{PyObjectAlloc, PyTypeInfo, PyTypeObject}; use typeob::{PyObjectAlloc, PyTypeInfo, PyTypeObject};
use types::{PyDict, PyModule, PyObjectRef, PyType};
/// Marker type that indicates that the GIL is currently held. /// Marker type that indicates that the GIL is currently held.
/// ///
@ -482,7 +482,7 @@ impl<'p> Python<'p> {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use objectprotocol::ObjectProtocol; use objectprotocol::ObjectProtocol;
use objects::{PyBool, PyDict, PyInt, PyList, PyObjectRef}; use types::{PyBool, PyDict, PyInt, PyList, PyObjectRef};
use Python; use Python;
#[test] #[test]

View File

@ -1,9 +1,9 @@
// Copyright (c) 2017-present PyO3 Project and Contributors // Copyright (c) 2017-present PyO3 Project and Contributors
use ffi; use ffi;
use objects::PyObjectRef;
use python::Python; use python::Python;
use spin; use spin;
use std::{any, marker, rc, sync}; use std::{any, marker, rc, sync};
use types::PyObjectRef;
static START: sync::Once = sync::ONCE_INIT; static START: sync::Once = sync::ONCE_INIT;
static START_PYO3: sync::Once = sync::ONCE_INIT; static START_PYO3: sync::Once = sync::ONCE_INIT;

View File

@ -5,8 +5,6 @@
use class::methods::PyMethodDefType; use class::methods::PyMethodDefType;
use err::{PyErr, PyResult}; use err::{PyErr, PyResult};
use instance::{Py, PyObjectWithToken, PyToken}; use instance::{Py, PyObjectWithToken, PyToken};
use objects::PyObjectRef;
use objects::PyType;
use python::ToPyPointer; use python::ToPyPointer;
use python::{IntoPyPointer, Python}; use python::{IntoPyPointer, Python};
use std; use std;
@ -14,6 +12,8 @@ use std::collections::HashMap;
use std::ffi::CString; use std::ffi::CString;
use std::mem; use std::mem;
use std::os::raw::c_void; use std::os::raw::c_void;
use types::PyObjectRef;
use types::PyType;
use {class, ffi, pythonrun}; use {class, ffi, pythonrun};
/// Python type information. /// Python type information.

View File

@ -2,8 +2,8 @@
use conversion::{IntoPyObject, PyTryFrom, ToBorrowedObject, ToPyObject}; use conversion::{IntoPyObject, PyTryFrom, ToBorrowedObject, ToPyObject};
use ffi; use ffi;
use object::PyObject; use object::PyObject;
use objects::PyObjectRef;
use python::{Python, ToPyPointer}; use python::{Python, ToPyPointer};
use types::PyObjectRef;
use FromPyObject; use FromPyObject;
use PyResult; use PyResult;
@ -81,8 +81,8 @@ impl<'source> FromPyObject<'source> for bool {
mod test { mod test {
use conversion::ToPyObject; use conversion::ToPyObject;
use objectprotocol::ObjectProtocol; use objectprotocol::ObjectProtocol;
use objects::{PyBool, PyObjectRef};
use python::Python; use python::Python;
use types::{PyBool, PyObjectRef};
#[test] #[test]
fn test_true() { fn test_true() {

View File

@ -70,10 +70,10 @@ impl PyByteArray {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use exc; use exceptions;
use object::PyObject; use object::PyObject;
use objects::PyByteArray;
use python::Python; use python::Python;
use types::PyByteArray;
#[test] #[test]
fn test_bytearray() { fn test_bytearray() {
@ -96,7 +96,7 @@ mod test {
let none = py.None(); let none = py.None();
if let Err(err) = PyByteArray::from(py, &none) { if let Err(err) = PyByteArray::from(py, &none) {
assert!(err.is_instance::<exc::TypeError>(py)); assert!(err.is_instance::<exceptions::TypeError>(py));
} else { } else {
panic!("error"); panic!("error");
} }

View File

@ -5,10 +5,10 @@ use err::{self, PyErr, PyResult};
use ffi; use ffi;
use instance::PyObjectWithToken; use instance::PyObjectWithToken;
use object::PyObject; use object::PyObject;
use objects::{PyList, PyObjectRef};
use python::{Python, ToPyPointer}; use python::{Python, ToPyPointer};
use std; use std;
use std::{cmp, collections, hash, mem}; use std::{cmp, collections, hash, mem};
use types::{PyList, PyObjectRef};
/// Represents a Python `dict`. /// Represents a Python `dict`.
#[repr(transparent)] #[repr(transparent)]
@ -256,10 +256,10 @@ where
mod test { mod test {
use conversion::{IntoPyObject, PyTryFrom, ToPyObject}; use conversion::{IntoPyObject, PyTryFrom, ToPyObject};
use instance::AsPyRef; use instance::AsPyRef;
use objects::dict::IntoPyDict;
use objects::{PyDict, PyTuple};
use python::Python; use python::Python;
use std::collections::{BTreeMap, HashMap}; use std::collections::{BTreeMap, HashMap};
use types::dict::IntoPyDict;
use types::{PyDict, PyTuple};
use ObjectProtocol; use ObjectProtocol;
#[test] #[test]

View File

@ -6,12 +6,115 @@ use conversion::ToPyObject;
use err::{PyErr, PyResult}; use err::{PyErr, PyResult};
use ffi; use ffi;
use instance::Py; use instance::Py;
use objects::{PyObjectRef, PyTuple, PyType};
use python::{Python, ToPyPointer}; use python::{Python, ToPyPointer};
use std::ffi::CStr; use std::ffi::CStr;
use std::os::raw::c_char; use std::os::raw::c_char;
use std::{self, ops}; use std::{self, ops};
use typeob::PyTypeObject; use typeob::PyTypeObject;
use types::{PyObjectRef, PyTuple, PyType};
// Copyright (c) 2017-present PyO3 Project and Contributors
/// Stringify a dotted path.
#[doc(hidden)]
#[macro_export]
macro_rules! dot_stringify {
($e:ident) => (
stringify!($e)
);
($e:ident. $($es:ident).+) => (
concat!(stringify!($e), ".", dot_stringify!($($es).*))
);
}
/// Defines rust type for exception defined in Python code.
///
/// # Syntax
/// `import_exception!(module, MyError)`
///
/// * `module` is the name of the containing module.
/// * `MyError` is the name of the new exception type.
///
/// # Example
/// ```
/// #[macro_use] extern crate pyo3;
///
/// use pyo3::Python;
/// use pyo3::types::PyDict;
///
/// import_exception!(socket, gaierror);
///
/// fn main() {
/// let gil = Python::acquire_gil();
/// let py = gil.python();
/// let ctx = PyDict::new(py);
///
/// ctx.set_item("gaierror", py.get_type::<gaierror>()).unwrap();
/// py.run("import socket; assert gaierror is socket.gaierror", None, Some(ctx)).unwrap();
/// }
/// ```
#[macro_export]
macro_rules! import_exception {
($($module:ident).+ , $name: ident) => {
#[allow(non_camel_case_types)]
pub struct $name;
impl ::std::convert::From<$name> for $crate::PyErr {
fn from(_err: $name) -> $crate::PyErr {
$crate::PyErr::new::<$name, _>(())
}
}
impl<T> ::std::convert::Into<$crate::PyResult<T>> for $name {
fn into(self) -> $crate::PyResult<T> {
$crate::PyErr::new::<$name, _>(()).into()
}
}
impl $name {
pub fn py_err<T: $crate::ToPyObject + 'static>(args: T) -> $crate::PyErr
where Self: $crate::typeob::PyTypeObject + Sized
{
$crate::PyErr::new::<Self, T>(args)
}
pub fn into<R, T: $crate::ToPyObject + 'static>(args: T) -> $crate::PyResult<R>
where Self: $crate::typeob::PyTypeObject + Sized
{
$crate::PyErr::new::<Self, T>(args).into()
}
}
impl $crate::typeob::PyTypeObject for $name {
#[inline]
fn init_type() {}
#[inline]
fn type_object() -> $crate::Py<$crate::types::PyType> {
use $crate::IntoPyPointer;
static mut TYPE_OBJECT: *mut $crate::ffi::PyTypeObject = ::std::ptr::null_mut();
unsafe {
if TYPE_OBJECT.is_null() {
let gil = $crate::Python::acquire_gil();
let py = gil.python();
let imp = py.import(dot_stringify!($($module).*))
.expect(concat!(
"Can not import module: ", dot_stringify!($($module).*)));
let cls = imp.get(stringify!($name))
.expect(concat!(
"Can not load exception class: {}.{}", dot_stringify!($($module).*),
".", stringify!($name)));
TYPE_OBJECT = cls.into_ptr() as *mut $crate::ffi::PyTypeObject;
}
$crate::Py::from_borrowed_ptr(
TYPE_OBJECT as *const _ as *mut $crate::ffi::PyObject)
}
}
}
};
}
macro_rules! exc_type ( macro_rules! exc_type (
($name:ident, $exc_name:ident) => ( ($name:ident, $exc_name:ident) => (
@ -193,3 +296,63 @@ pub mod socket {
import_exception!(socket, gaierror); import_exception!(socket, gaierror);
import_exception!(socket, timeout); import_exception!(socket, timeout);
} }
#[cfg(test)]
mod test {
use types::PyDict;
use {PyErr, Python};
import_exception!(socket, gaierror);
import_exception!(email.errors, MessageError);
#[test]
fn test_check_exception() {
let gil = Python::acquire_gil();
let py = gil.python();
let err: PyErr = gaierror.into();
let socket = py
.import("socket")
.map_err(|e| e.print(py))
.expect("could not import socket");
let d = PyDict::new(py);
d.set_item("socket", socket)
.map_err(|e| e.print(py))
.expect("could not setitem");
d.set_item("exc", err)
.map_err(|e| e.print(py))
.expect("could not setitem");
py.run("assert isinstance(exc, socket.gaierror)", None, Some(d))
.map_err(|e| e.print(py))
.expect("assertion failed");
}
#[test]
fn test_check_exception_nested() {
let gil = Python::acquire_gil();
let py = gil.python();
let err: PyErr = MessageError.into();
let email = py
.import("email")
.map_err(|e| e.print(py))
.expect("could not import email");
let d = PyDict::new(py);
d.set_item("email", email)
.map_err(|e| e.print(py))
.expect("could not setitem");
d.set_item("exc", err)
.map_err(|e| e.print(py))
.expect("could not setitem");
py.run(
"assert isinstance(exc, email.errors.MessageError)",
None,
Some(d),
).map_err(|e| e.print(py))
.expect("assertion failed");
}
}

View File

@ -8,9 +8,9 @@ use ffi;
use instance::{Py, PyObjectWithToken}; use instance::{Py, PyObjectWithToken};
use object::PyObject; use object::PyObject;
use objectprotocol::ObjectProtocol; use objectprotocol::ObjectProtocol;
use objects::PyObjectRef;
use python::{Python, ToPyPointer}; use python::{Python, ToPyPointer};
use std::os::raw::c_double; use std::os::raw::c_double;
use types::PyObjectRef;
use FromPyObject; use FromPyObject;
use PyResult; use PyResult;

View File

@ -5,8 +5,8 @@
use err::{PyDowncastError, PyErr, PyResult}; use err::{PyDowncastError, PyErr, PyResult};
use ffi; use ffi;
use instance::PyObjectWithToken; use instance::PyObjectWithToken;
use objects::PyObjectRef;
use python::{Python, ToPyPointer}; use python::{Python, ToPyPointer};
use types::PyObjectRef;
/// A python iterator object. /// A python iterator object.
/// ///
@ -69,9 +69,9 @@ mod tests {
use conversion::{PyTryFrom, ToPyObject}; use conversion::{PyTryFrom, ToPyObject};
use instance::AsPyRef; use instance::AsPyRef;
use objectprotocol::ObjectProtocol; use objectprotocol::ObjectProtocol;
use objects::{PyList, PyObjectRef};
use python::Python; use python::Python;
use pythonrun::GILPool; use pythonrun::GILPool;
use types::{PyList, PyObjectRef};
#[test] #[test]
fn vec_iter() { fn vec_iter() {

View File

@ -9,8 +9,8 @@ use err::{self, PyResult};
use ffi::{self, Py_ssize_t}; use ffi::{self, Py_ssize_t};
use instance::PyObjectWithToken; use instance::PyObjectWithToken;
use object::PyObject; use object::PyObject;
use objects::PyObjectRef;
use python::{IntoPyPointer, Python, ToPyPointer}; use python::{IntoPyPointer, Python, ToPyPointer};
use types::PyObjectRef;
/// Represents a Python `list`. /// Represents a Python `list`.
#[repr(transparent)] #[repr(transparent)]
@ -191,8 +191,8 @@ mod test {
use conversion::{PyTryFrom, ToPyObject}; use conversion::{PyTryFrom, ToPyObject};
use instance::AsPyRef; use instance::AsPyRef;
use objectprotocol::ObjectProtocol; use objectprotocol::ObjectProtocol;
use objects::PyList;
use python::Python; use python::Python;
use types::PyList;
#[test] #[test]
fn test_new() { fn test_new() {

View File

@ -1,5 +1,7 @@
// Copyright (c) 2017-present PyO3 Project and Contributors // Copyright (c) 2017-present PyO3 Project and Contributors
//! Various types defined by the python interpreter such as `int`, `str` and `tuple`
pub use self::boolobject::PyBool; pub use self::boolobject::PyBool;
pub use self::bytearray::PyByteArray; pub use self::bytearray::PyByteArray;
pub use self::complex::PyComplex; pub use self::complex::PyComplex;
@ -11,7 +13,7 @@ pub use self::dict::PyDict;
pub use self::floatob::PyFloat; pub use self::floatob::PyFloat;
pub use self::iterator::PyIterator; pub use self::iterator::PyIterator;
pub use self::list::PyList; pub use self::list::PyList;
pub use self::module::{make_module, PyModule}; pub use self::module::PyModule;
#[cfg(not(Py_3))] #[cfg(not(Py_3))]
pub use self::num2::{PyInt, PyLong}; pub use self::num2::{PyInt, PyLong};
#[cfg(Py_3)] #[cfg(Py_3)]
@ -31,9 +33,6 @@ pub use self::typeobject::PyType;
use ffi; use ffi;
use python::ToPyPointer; use python::ToPyPointer;
#[macro_use]
mod exc_impl;
/// Implements a typesafe conversions throught [FromPyObject], given a typecheck function as second /// Implements a typesafe conversions throught [FromPyObject], given a typecheck function as second
/// parameter /// parameter
#[macro_export] #[macro_export]
@ -42,11 +41,11 @@ macro_rules! pyobject_downcast (
impl<'a, $($type_param,)*> $crate::FromPyObject<'a> for &'a $name impl<'a, $($type_param,)*> $crate::FromPyObject<'a> for &'a $name
{ {
/// Extracts `Self` from the source `PyObject`. /// Extracts `Self` from the source `PyObject`.
fn extract(ob: &'a $crate::PyObjectRef) -> $crate::PyResult<Self> fn extract(ob: &'a $crate::types::PyObjectRef) -> $crate::PyResult<Self>
{ {
unsafe { unsafe {
if $checkfunction(ob.as_ptr()) != 0 { if $checkfunction(ob.as_ptr()) != 0 {
Ok(&*(ob as *const $crate::PyObjectRef as *const $name)) Ok(&*(ob as *const $crate::types::PyObjectRef as *const $name))
} else { } else {
Err($crate::PyDowncastError.into()) Err($crate::PyDowncastError.into())
} }
@ -61,9 +60,9 @@ macro_rules! pyobject_native_type_named (
($name: ty $(,$type_param: ident)*) => { ($name: ty $(,$type_param: ident)*) => {
impl<$($type_param,)*> $crate::PyNativeType for $name {} impl<$($type_param,)*> $crate::PyNativeType for $name {}
impl<$($type_param,)*> ::std::convert::AsRef<$crate::PyObjectRef> for $name { impl<$($type_param,)*> ::std::convert::AsRef<$crate::types::PyObjectRef> for $name {
fn as_ref(&self) -> &$crate::PyObjectRef { fn as_ref(&self) -> &$crate::types::PyObjectRef {
unsafe{&*(self as *const $name as *const $crate::PyObjectRef)} unsafe{&*(self as *const $name as *const $crate::types::PyObjectRef)}
} }
} }
@ -97,9 +96,9 @@ macro_rules! pyobject_native_type (
pyobject_native_type_named!($name $(,$type_param)*); pyobject_native_type_named!($name $(,$type_param)*);
pyobject_native_type_convert!($name, $typeobject, $checkfunction $(,$type_param)*); pyobject_native_type_convert!($name, $typeobject, $checkfunction $(,$type_param)*);
impl<'a, $($type_param,)*> ::std::convert::From<&'a $name> for &'a $crate::PyObjectRef { impl<'a, $($type_param,)*> ::std::convert::From<&'a $name> for &'a $crate::types::PyObjectRef {
fn from(ob: &'a $name) -> Self { fn from(ob: &'a $name) -> Self {
unsafe{&*(ob as *const $name as *const $crate::PyObjectRef)} unsafe{&*(ob as *const $name as *const $crate::types::PyObjectRef)}
} }
} }
}; };
@ -110,7 +109,7 @@ macro_rules! pyobject_native_type_convert(
($name: ty, $typeobject: expr, $checkfunction: path $(,$type_param: ident)*) => { ($name: ty, $typeobject: expr, $checkfunction: path $(,$type_param: ident)*) => {
impl<$($type_param,)*> $crate::typeob::PyTypeInfo for $name { impl<$($type_param,)*> $crate::typeob::PyTypeInfo for $name {
type Type = (); type Type = ();
type BaseType = $crate::PyObjectRef; type BaseType = $crate::types::PyObjectRef;
const NAME: &'static str = stringify!($name); const NAME: &'static str = stringify!($name);
const SIZE: usize = ::std::mem::size_of::<$crate::ffi::PyObject>(); const SIZE: usize = ::std::mem::size_of::<$crate::ffi::PyObject>();
@ -121,7 +120,7 @@ macro_rules! pyobject_native_type_convert(
&mut $typeobject &mut $typeobject
} }
fn is_instance(ptr: &$crate::objects::PyObjectRef) -> bool { fn is_instance(ptr: &$crate::types::PyObjectRef) -> bool {
#[allow(unused_unsafe)] #[allow(unused_unsafe)]
unsafe { $checkfunction(ptr.as_ptr()) > 0 } unsafe { $checkfunction(ptr.as_ptr()) > 0 }
} }
@ -132,8 +131,8 @@ macro_rules! pyobject_native_type_convert(
fn init_type() {} fn init_type() {}
#[inline] #[inline]
fn type_object() -> $crate::Py<$crate::PyType> { fn type_object() -> $crate::Py<$crate::types::PyType> {
$crate::PyType::new::<$name>() $crate::types::PyType::new::<$name>()
} }
} }
@ -188,7 +187,7 @@ mod bytearray;
mod complex; mod complex;
mod datetime; mod datetime;
mod dict; mod dict;
pub mod exc; pub mod exceptions;
mod floatob; mod floatob;
mod iterator; mod iterator;
mod list; mod list;

View File

@ -5,18 +5,15 @@
use conversion::{IntoPyTuple, ToPyObject}; use conversion::{IntoPyTuple, ToPyObject};
use err::{PyErr, PyResult}; use err::{PyErr, PyResult};
use ffi; use ffi;
use init_once;
use instance::PyObjectWithToken; use instance::PyObjectWithToken;
use object::PyObject; use object::PyObject;
use objectprotocol::ObjectProtocol; use objectprotocol::ObjectProtocol;
use objects::{exc, PyDict, PyObjectRef, PyType};
use python::{Python, ToPyPointer}; use python::{Python, ToPyPointer};
use std::ffi::{CStr, CString}; use std::ffi::{CStr, CString};
use std::os::raw::c_char; use std::os::raw::c_char;
use std::ptr;
use std::str; use std::str;
use typeob::{initialize_type, PyTypeInfo}; use typeob::{initialize_type, PyTypeInfo};
use GILPool; use types::{exceptions, PyDict, PyObjectRef, PyType};
/// Represents a Python `module` object. /// Represents a Python `module` object.
#[repr(transparent)] #[repr(transparent)]
@ -84,11 +81,9 @@ impl PyModule {
let slice = CStr::from_ptr(ptr).to_bytes(); let slice = CStr::from_ptr(ptr).to_bytes();
match str::from_utf8(slice) { match str::from_utf8(slice) {
Ok(s) => Ok(s), Ok(s) => Ok(s),
Err(e) => Err(PyErr::from_instance(exc::UnicodeDecodeError::new_utf8( Err(e) => Err(PyErr::from_instance(
self.py(), exceptions::UnicodeDecodeError::new_utf8(self.py(), slice, e)?,
slice, )),
e,
)?)),
} }
} }
} }
@ -194,90 +189,3 @@ impl PyModule {
self.add(name.extract(self.py()).unwrap(), function) self.add(name.extract(self.py()).unwrap(), function)
} }
} }
#[cfg(Py_3)]
#[doc(hidden)]
/// Builds a module (or null) from a user given initializer. Used for `#[pymodinit]`.
pub unsafe fn make_module(
name: &str,
doc: &str,
initializer: impl Fn(Python, &PyModule) -> PyResult<()>,
) -> *mut ffi::PyObject {
use python::IntoPyPointer;
init_once();
#[cfg(py_sys_config = "WITH_THREAD")]
// > Changed in version 3.7: This function is now called by Py_Initialize(), so you dont have
// > to call it yourself anymore.
#[cfg(not(Py_3_7))]
ffi::PyEval_InitThreads();
static mut MODULE_DEF: ffi::PyModuleDef = ffi::PyModuleDef_INIT;
// We can't convert &'static str to *const c_char within a static initializer,
// so we'll do it here in the module initialization:
MODULE_DEF.m_name = name.as_ptr() as *const _;
let module = ffi::PyModule_Create(&mut MODULE_DEF);
if module.is_null() {
return module;
}
let _pool = GILPool::new();
let py = Python::assume_gil_acquired();
let module = match py.from_owned_ptr_or_err::<PyModule>(module) {
Ok(m) => m,
Err(e) => {
e.restore(py);
return ptr::null_mut();
}
};
module
.add("__doc__", doc)
.expect("Failed to add doc for module");
match initializer(py, module) {
Ok(_) => module.into_ptr(),
Err(e) => {
e.restore(py);
ptr::null_mut()
}
}
}
#[cfg(not(Py_3))]
#[doc(hidden)]
/// Builds a module (or null) from a user given initializer. Used for `#[pymodinit]`.
pub unsafe fn make_module(
name: &str,
doc: &str,
initializer: impl Fn(Python, &PyModule) -> PyResult<()>,
) {
init_once();
#[cfg(py_sys_config = "WITH_THREAD")]
ffi::PyEval_InitThreads();
let _name = name.as_ptr() as *const _;
let _pool = GILPool::new();
let py = Python::assume_gil_acquired();
let _module = ffi::Py_InitModule(_name, ptr::null_mut());
if _module.is_null() {
return;
}
let _module = match py.from_borrowed_ptr_or_err::<PyModule>(_module) {
Ok(m) => m,
Err(e) => {
e.restore(py);
return;
}
};
_module
.add("__doc__", doc)
.expect("Failed to add doc for module");
if let Err(e) = initializer(py, _module) {
e.restore(py)
}
}

View File

@ -13,8 +13,8 @@ use err::{PyErr, PyResult};
use ffi; use ffi;
use instance::{Py, PyObjectWithToken}; use instance::{Py, PyObjectWithToken};
use object::PyObject; use object::PyObject;
use objects::{exc, PyObjectRef};
use python::{IntoPyPointer, Python, ToPyPointer}; use python::{IntoPyPointer, Python, ToPyPointer};
use types::{exceptions, PyObjectRef};
/// Represents a Python `int` object. /// Represents a Python `int` object.
/// ///
@ -86,7 +86,7 @@ macro_rules! int_fits_c_long(
} }
match cast::<c_long, $rust_type>(val) { match cast::<c_long, $rust_type>(val) {
Some(v) => Ok(v), Some(v) => Ok(v),
None => Err(exc::OverflowError.into()) None => Err(exceptions::OverflowError.into())
} }
} }
} }
@ -128,7 +128,7 @@ macro_rules! int_convert_u64_or_i64 (
} else if ffi::PyInt_Check(ptr) != 0 { } else if ffi::PyInt_Check(ptr) != 0 {
match cast::<c_long, $rust_type>(ffi::PyInt_AS_LONG(ptr)) { match cast::<c_long, $rust_type>(ffi::PyInt_AS_LONG(ptr)) {
Some(v) => Ok(v), Some(v) => Ok(v),
None => Err(exc::OverflowError.into()) None => Err(exceptions::OverflowError.into())
} }
} else { } else {
let num = PyObject::from_owned_ptr_or_err( let num = PyObject::from_owned_ptr_or_err(

View File

@ -11,10 +11,10 @@ use err::{PyErr, PyResult};
use ffi; use ffi;
use instance::PyObjectWithToken; use instance::PyObjectWithToken;
use object::PyObject; use object::PyObject;
use objects::{exc, PyObjectRef};
use python::{Python, ToPyPointer}; use python::{Python, ToPyPointer};
use std::i64; use std::i64;
use std::os::raw::{c_long, c_uchar}; use std::os::raw::{c_long, c_uchar};
use types::{exceptions, PyObjectRef};
/// Represents a Python `int` object. /// Represents a Python `int` object.
/// ///
@ -61,7 +61,7 @@ macro_rules! int_fits_c_long (
}?; }?;
match cast::<c_long, $rust_type>(val) { match cast::<c_long, $rust_type>(val) {
Some(v) => Ok(v), Some(v) => Ok(v),
None => Err(exc::OverflowError.into()) None => Err(exceptions::OverflowError.into())
} }
} }
} }
@ -148,7 +148,7 @@ mod test {
macro_rules! test_common ( macro_rules! test_common (
($test_mod_name:ident, $t:ty) => ( ($test_mod_name:ident, $t:ty) => (
mod $test_mod_name { mod $test_mod_name {
use objects::exc; use types::exceptions;
use conversion::ToPyObject; use conversion::ToPyObject;
use python::Python; use python::Python;
@ -159,7 +159,7 @@ mod test {
let obj = ("123").to_object(py); let obj = ("123").to_object(py);
let err = obj.extract::<$t>(py).unwrap_err(); let err = obj.extract::<$t>(py).unwrap_err();
assert!(err.is_instance::<exc::TypeError>(py)); assert!(err.is_instance::<exceptions::TypeError>(py));
} }
#[test] #[test]
@ -169,7 +169,7 @@ mod test {
let obj = (12.3).to_object(py); let obj = (12.3).to_object(py);
let err = obj.extract::<$t>(py).unwrap_err(); let err = obj.extract::<$t>(py).unwrap_err();
assert!(err.is_instance::<exc::TypeError>(py)); assert!(err.is_instance::<exceptions::TypeError>(py));
} }
#[test] #[test]

View File

@ -36,7 +36,7 @@ macro_rules! int_fits_larger_int(
let val = try!($crate::objectprotocol::ObjectProtocol::extract::<$larger_type>(obj)); let val = try!($crate::objectprotocol::ObjectProtocol::extract::<$larger_type>(obj));
match cast::<$larger_type, $rust_type>(val) { match cast::<$larger_type, $rust_type>(val) {
Some(v) => Ok(v), Some(v) => Ok(v),
None => Err(exc::OverflowError.into()) None => Err(exceptions::OverflowError.into())
} }
} }
} }
@ -188,8 +188,8 @@ mod test {
fn test_u128_overflow() { fn test_u128_overflow() {
use ffi; use ffi;
use object::PyObject; use object::PyObject;
use objects::exc;
use std::os::raw::c_uchar; use std::os::raw::c_uchar;
use types::exceptions;
let gil = Python::acquire_gil(); let gil = Python::acquire_gil();
let py = gil.python(); let py = gil.python();
let overflow_bytes: [c_uchar; 20] = [255; 20]; let overflow_bytes: [c_uchar; 20] = [255; 20];
@ -202,7 +202,7 @@ mod test {
); );
let obj = PyObject::from_owned_ptr_or_panic(py, obj); let obj = PyObject::from_owned_ptr_or_panic(py, obj);
let err = obj.extract::<u128>(py).unwrap_err(); let err = obj.extract::<u128>(py).unwrap_err();
assert!(err.is_instance::<exc::OverflowError>(py)); assert!(err.is_instance::<exceptions::OverflowError>(py));
} }
} }
} }

View File

@ -7,8 +7,8 @@ use ffi::{self, Py_ssize_t};
use instance::PyObjectWithToken; use instance::PyObjectWithToken;
use object::PyObject; use object::PyObject;
use objectprotocol::ObjectProtocol; use objectprotocol::ObjectProtocol;
use objects::{PyList, PyObjectRef, PyTuple};
use python::ToPyPointer; use python::ToPyPointer;
use types::{PyList, PyObjectRef, PyTuple};
/// Represents a reference to a python object supporting the sequence protocol. /// Represents a reference to a python object supporting the sequence protocol.
#[repr(transparent)] #[repr(transparent)]
@ -313,8 +313,8 @@ mod test {
use instance::AsPyRef; use instance::AsPyRef;
use object::PyObject; use object::PyObject;
use objectprotocol::ObjectProtocol; use objectprotocol::ObjectProtocol;
use objects::PySequence;
use python::{Python, ToPyPointer}; use python::{Python, ToPyPointer};
use types::PySequence;
fn get_object() -> PyObject { fn get_object() -> PyObject {
// Convenience function for getting a single unique object // Convenience function for getting a single unique object

View File

@ -10,8 +10,8 @@ use err::{PyErr, PyResult};
use ffi; use ffi;
use instance::{Py, PyObjectWithToken}; use instance::{Py, PyObjectWithToken};
use object::PyObject; use object::PyObject;
use objects::PyObjectRef;
use python::{Python, ToPyPointer}; use python::{Python, ToPyPointer};
use types::PyObjectRef;
/// Represents a Python `string`. /// Represents a Python `string`.
#[repr(transparent)] #[repr(transparent)]
@ -21,7 +21,9 @@ pyobject_native_type!(PyString, ffi::PyUnicode_Type, ffi::PyUnicode_Check);
/// Represents a Python `unicode string`. /// Represents a Python `unicode string`.
/// Corresponds to `unicode` in Python 2, and `str` in Python 3. /// Corresponds to `unicode` in Python 2, and `str` in Python 3.
pub use PyString as PyUnicode; //pub use PyString as PyUnicode;
pub struct PyUnicode();
/// Represents a Python `byte` string. /// Represents a Python `byte` string.
#[repr(transparent)] #[repr(transparent)]

View File

@ -6,8 +6,8 @@ use std::borrow::Cow;
use std::{char, str}; use std::{char, str};
use err::{PyErr, PyResult}; use err::{PyErr, PyResult};
use objects::exc;
use python::Python; use python::Python;
use types::exceptions;
/// Enum of possible Python string representations. /// Enum of possible Python string representations.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
@ -50,9 +50,9 @@ impl<'a> PyStringData<'a> {
match self { match self {
PyStringData::Utf8(data) => match str::from_utf8(data) { PyStringData::Utf8(data) => match str::from_utf8(data) {
Ok(s) => Ok(Cow::Borrowed(s)), Ok(s) => Ok(Cow::Borrowed(s)),
Err(e) => Err(PyErr::from_instance(exc::UnicodeDecodeError::new_utf8( Err(e) => Err(PyErr::from_instance(
py, data, e, exceptions::UnicodeDecodeError::new_utf8(py, data, e)?,
)?)), )),
}, },
PyStringData::Latin1(data) => { PyStringData::Latin1(data) => {
if data.iter().all(|&b| b.is_ascii()) { if data.iter().all(|&b| b.is_ascii()) {
@ -67,13 +67,15 @@ impl<'a> PyStringData<'a> {
} }
match String::from_utf16(data) { match String::from_utf16(data) {
Ok(s) => Ok(Cow::Owned(s)), Ok(s) => Ok(Cow::Owned(s)),
Err(_) => Err(PyErr::from_instance(exc::UnicodeDecodeError::new_err( Err(_) => Err(PyErr::from_instance(
exceptions::UnicodeDecodeError::new_err(
py, py,
cstr!("utf-16"), cstr!("utf-16"),
utf16_bytes(data), utf16_bytes(data),
0..2 * data.len(), 0..2 * data.len(),
cstr!("invalid utf-16"), cstr!("invalid utf-16"),
)?)), )?,
)),
} }
} }
PyStringData::Utf32(data) => { PyStringData::Utf32(data) => {
@ -82,13 +84,15 @@ impl<'a> PyStringData<'a> {
} }
match data.iter().map(|&u| char::from_u32(u)).collect() { match data.iter().map(|&u| char::from_u32(u)).collect() {
Some(s) => Ok(Cow::Owned(s)), Some(s) => Ok(Cow::Owned(s)),
None => Err(PyErr::from_instance(exc::UnicodeDecodeError::new_err( None => Err(PyErr::from_instance(
exceptions::UnicodeDecodeError::new_err(
py, py,
cstr!("utf-32"), cstr!("utf-32"),
utf32_bytes(data), utf32_bytes(data),
0..4 * data.len(), 0..4 * data.len(),
cstr!("invalid utf-32"), cstr!("invalid utf-32"),
)?)), )?,
)),
} }
} }
} }

View File

@ -2,9 +2,9 @@ use conversion::{IntoPyObject, PyTryFrom, ToPyObject};
use err::PyResult; use err::PyResult;
use instance::PyObjectWithToken; use instance::PyObjectWithToken;
use object::PyObject; use object::PyObject;
use objects::{PyObjectRef, PyString};
use python::Python; use python::Python;
use std::borrow::Cow; use std::borrow::Cow;
use types::{PyObjectRef, PyString};
use FromPyObject; use FromPyObject;
/// Converts Rust `str` to Python object. /// Converts Rust `str` to Python object.

View File

@ -1,14 +1,14 @@
// Copyright (c) 2017-present PyO3 Project and Contributors // Copyright (c) 2017-present PyO3 Project and Contributors
use super::exc; use super::exceptions;
use conversion::{FromPyObject, IntoPyObject, IntoPyTuple, PyTryFrom, ToPyObject}; use conversion::{FromPyObject, IntoPyObject, IntoPyTuple, PyTryFrom, ToPyObject};
use err::{PyErr, PyResult}; use err::{PyErr, PyResult};
use ffi::{self, Py_ssize_t}; use ffi::{self, Py_ssize_t};
use instance::{AsPyRef, Py, PyObjectWithToken}; use instance::{AsPyRef, Py, PyObjectWithToken};
use object::PyObject; use object::PyObject;
use objects::PyObjectRef;
use python::{IntoPyPointer, Python, ToPyPointer}; use python::{IntoPyPointer, Python, ToPyPointer};
use std::slice; use std::slice;
use types::PyObjectRef;
/// Represents a Python `tuple` object. /// Represents a Python `tuple` object.
#[repr(transparent)] #[repr(transparent)]
@ -159,7 +159,7 @@ fn wrong_tuple_length(t: &PyTuple, expected_length: usize) -> PyErr {
expected_length, expected_length,
t.len() t.len()
); );
exc::ValueError::py_err(msg) exceptions::ValueError::py_err(msg)
} }
macro_rules! tuple_conversion ({$length:expr,$(($refN:ident, $n:tt, $T:ident)),+} => { macro_rules! tuple_conversion ({$length:expr,$(($refN:ident, $n:tt, $T:ident)),+} => {
@ -268,10 +268,10 @@ mod test {
use conversion::{PyTryFrom, ToPyObject}; use conversion::{PyTryFrom, ToPyObject};
use instance::AsPyRef; use instance::AsPyRef;
use objectprotocol::ObjectProtocol; use objectprotocol::ObjectProtocol;
use objects::PyObjectRef;
use python::Python; use python::Python;
use std::collections::HashSet; use std::collections::HashSet;
use PyTuple; use types::PyObjectRef;
use types::PyTuple;
#[test] #[test]
fn test_new() { fn test_new() {

View File

@ -24,7 +24,7 @@ pub fn indoc(commands: &str) -> String {
#[macro_export] #[macro_export]
macro_rules! py_run { macro_rules! py_run {
($py:expr, $val:expr, $code:expr) => {{ ($py:expr, $val:expr, $code:expr) => {{
let d = PyDict::new($py); let d = pyo3::types::PyDict::new($py);
d.set_item(stringify!($val), &$val).unwrap(); d.set_item(stringify!($val), &$val).unwrap();
$py.run(&common::indoc($code), None, Some(d)) $py.run(&common::indoc($code), None, Some(d))
.map_err(|e| { .map_err(|e| {
@ -48,11 +48,11 @@ macro_rules! py_assert {
#[macro_export] #[macro_export]
macro_rules! py_expect_exception { macro_rules! py_expect_exception {
($py:expr, $val:ident, $code:expr, $err:ident) => {{ ($py:expr, $val:ident, $code:expr, $err:ident) => {{
let d = PyDict::new($py); let d = pyo3::types::PyDict::new($py);
d.set_item(stringify!($val), &$val).unwrap(); d.set_item(stringify!($val), &$val).unwrap();
let res = $py.run($code, None, Some(d)); let res = $py.run($code, None, Some(d));
let err = res.unwrap_err(); let err = res.unwrap_err();
if !err.matches($py, $py.get_type::<exc::$err>()) { if !err.matches($py, $py.get_type::<pyo3::exceptions::$err>()) {
panic!(format!("Expected {} but got {:?}", stringify!($err), err)) panic!(format!("Expected {} but got {:?}", stringify!($err), err))
} }
}}; }};

View File

@ -2,7 +2,10 @@
extern crate pyo3; extern crate pyo3;
use pyo3::class::*;
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::types::PyObjectRef;
use pyo3::PyObjectWithToken;
#[macro_use] #[macro_use]
mod common; mod common;

View File

@ -5,9 +5,11 @@ extern crate pyo3;
use std::os::raw::{c_int, c_void}; use std::os::raw::{c_int, c_void};
use std::ptr; use std::ptr;
use pyo3::exc::BufferError; use pyo3::class::PyBufferProtocol;
use pyo3::exceptions::BufferError;
use pyo3::ffi; use pyo3::ffi;
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::types::PyDict;
#[pyclass] #[pyclass]
struct TestClass { struct TestClass {

View File

@ -3,6 +3,7 @@
extern crate pyo3; extern crate pyo3;
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::PyRawObject;
#[pyclass] #[pyclass]
struct EmptyClassWithNew {} struct EmptyClassWithNew {}

View File

@ -2,10 +2,10 @@
extern crate pyo3; extern crate pyo3;
use std::iter;
use pyo3::ffi::*; use pyo3::ffi::*;
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::types::{PyDate, PyDateTime, PyDict, PyObjectRef, PyTime};
use std::iter;
fn _get_subclasses<'p>( fn _get_subclasses<'p>(
py: &'p Python, py: &'p Python,
@ -40,6 +40,7 @@ fn _get_subclasses<'p>(
macro_rules! assert_check_exact { macro_rules! assert_check_exact {
($check_func:ident, $obj: expr) => { ($check_func:ident, $obj: expr) => {
unsafe { unsafe {
use pyo3::ToPyPointer;
assert!($check_func(($obj).as_ptr()) != 0); assert!($check_func(($obj).as_ptr()) != 0);
assert!(concat_idents!($check_func, Exact)(($obj).as_ptr()) != 0); assert!(concat_idents!($check_func, Exact)(($obj).as_ptr()) != 0);
} }
@ -49,6 +50,7 @@ macro_rules! assert_check_exact {
macro_rules! assert_check_only { macro_rules! assert_check_only {
($check_func:ident, $obj: expr) => { ($check_func:ident, $obj: expr) => {
unsafe { unsafe {
use pyo3::ToPyPointer;
assert!($check_func(($obj).as_ptr()) != 0); assert!($check_func(($obj).as_ptr()) != 0);
assert!(concat_idents!($check_func, Exact)(($obj).as_ptr()) == 0); assert!(concat_idents!($check_func, Exact)(($obj).as_ptr()) == 0);
} }

View File

@ -2,8 +2,15 @@
extern crate pyo3; extern crate pyo3;
use pyo3::class::{
PyContextProtocol, PyIterProtocol, PyMappingProtocol, PyObjectProtocol, PySequenceProtocol,
};
use pyo3::exceptions::{IndexError, ValueError};
use pyo3::ffi; use pyo3::ffi;
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::python::ToPyPointer;
use pyo3::types::{PyBytes, PyDict, PyObjectRef, PySlice, PyString, PyType};
use pyo3::PyObjectWithToken;
use std::{isize, iter}; use std::{isize, iter};
#[macro_use] #[macro_use]
@ -171,7 +178,7 @@ impl PySequenceProtocol for Sequence {
fn __getitem__(&self, key: isize) -> PyResult<isize> { fn __getitem__(&self, key: isize) -> PyResult<isize> {
if key == 5 { if key == 5 {
return Err(PyErr::new::<exc::IndexError, NoArgs>(NoArgs)); return Err(PyErr::new::<IndexError, NoArgs>(NoArgs));
} }
Ok(key) Ok(key)
} }
@ -369,7 +376,7 @@ impl<'p> PyContextProtocol<'p> for ContextManager {
_traceback: Option<&'p PyObjectRef>, _traceback: Option<&'p PyObjectRef>,
) -> PyResult<bool> { ) -> PyResult<bool> {
self.exit_called = true; self.exit_called = true;
if ty == Some(self.py().get_type::<exc::ValueError>()) { if ty == Some(self.py().get_type::<ValueError>()) {
Ok(true) Ok(true)
} else { } else {
Ok(false) Ok(false)
@ -435,7 +442,7 @@ impl<'p> PyMappingProtocol<'p> for Test {
return Ok("int".into_object(self.py())); return Ok("int".into_object(self.py()));
} }
} }
Err(PyErr::new::<exc::ValueError, _>("error")) Err(PyErr::new::<ValueError, _>("error"))
} }
} }

View File

@ -2,8 +2,16 @@
extern crate pyo3; extern crate pyo3;
use pyo3::class::PyGCProtocol;
use pyo3::class::PyTraverseError;
use pyo3::class::PyVisit;
use pyo3::ffi; use pyo3::ffi;
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::python::ToPyPointer;
use pyo3::types::PyObjectRef;
use pyo3::types::PyTuple;
use pyo3::PyObjectWithToken;
use pyo3::PyRawObject;
use std::cell::RefCell; use std::cell::RefCell;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc; use std::sync::Arc;

View File

@ -3,6 +3,7 @@
extern crate pyo3; extern crate pyo3;
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::types::PyDict;
use std::isize; use std::isize;
#[macro_use] #[macro_use]

View File

@ -3,6 +3,9 @@
extern crate pyo3; extern crate pyo3;
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::types::{PyDict, PyString, PyTuple, PyType};
use pyo3::PyObjectWithToken;
use pyo3::PyRawObject;
#[macro_use] #[macro_use]
mod common; mod common;

View File

@ -4,6 +4,7 @@
extern crate pyo3; extern crate pyo3;
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::types::PyDict;
#[macro_use] #[macro_use]
mod common; mod common;

View File

@ -4,6 +4,7 @@
extern crate pyo3; extern crate pyo3;
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::types::PyDict;
use std::isize; use std::isize;
#[macro_use] #[macro_use]