2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-24 18:12:43 +00:00

reference<> => handle<>

[SVN r14136]
This commit is contained in:
Dave Abrahams
2002-06-12 21:59:17 +00:00
parent 0d58869d6e
commit 366ee6d24b
36 changed files with 1264 additions and 293 deletions

View File

@@ -9,7 +9,7 @@
#include <boost/python/converter/builtin_converters.hpp>
#include <boost/python/converter/from_python_data.hpp>
#include <boost/python/converter/registry.hpp>
#include <boost/python/reference.hpp>
#include <boost/python/handle.hpp>
#include <boost/python/type_id.hpp>
#include <boost/python/errors.hpp>
#include <boost/cast.hpp>
@@ -54,7 +54,7 @@ namespace
{
// Get the (intermediate) source object
unaryfunc creator = *static_cast<unaryfunc*>(data->convertible);
ref intermediate(creator(obj));
handle<> intermediate(creator(obj));
// Get the location in which to construct
void* storage = ((rvalue_base_data<T>*)data)->storage.bytes;

View File

@@ -7,7 +7,7 @@
#include <boost/python/converter/arg_to_python_base.hpp>
#include <boost/python/errors.hpp>
#include <boost/python/converter/find_from_python.hpp>
#include <boost/python/reference.hpp>
#include <boost/python/handle.hpp>
#include <boost/python/detail/none.hpp>
namespace boost { namespace python { namespace converter {
@@ -35,7 +35,7 @@ namespace detail
arg_to_python_base::arg_to_python_base(
void const volatile* source, to_python_function_t converter)
: arg_to_python_holder(convert(source, converter))
: handle<>(convert(source, converter))
{
}
@@ -65,7 +65,7 @@ namespace detail
PyObject* source
, lvalue_from_python_registration*const& converters)
{
ref holder(source);
handle<> holder(source);
if (source->ob_refcnt <= 2)
{
PyErr_SetString(
@@ -106,7 +106,7 @@ namespace detail
BOOST_PYTHON_DECL void* convert_rvalue(PyObject* src, rvalue_stage1_data& data, void* storage)
{
ref holder(src);
handle<> holder(src);
data = find(src, static_cast<rvalue_from_python_registration*>(data.convertible));

View File

@@ -54,13 +54,6 @@ void BOOST_PYTHON_DECL throw_error_already_set()
throw error_already_set();
}
BOOST_PYTHON_DECL PyObject* expect_non_null_impl(PyObject* x)
{
if (x == 0)
throw_error_already_set();
return x;
}
namespace detail {
BOOST_PYTHON_DECL void expect_complex(PyObject* p)

View File

@@ -8,13 +8,14 @@
#include <boost/python/detail/module_base.hpp>
#include <boost/python/object/function.hpp>
#include <boost/python/cast.hpp>
namespace boost { namespace python { namespace detail {
module_base::module_base(const char* name)
: m_module(
Py_InitModule(const_cast<char*>(name), initial_methods)
, ref::increment_count)
borrow(Py_InitModule(const_cast<char*>(name), initial_methods))
)
{
}
@@ -24,38 +25,33 @@ module_base::~module_base()
void module_base::setattr(const char* name, PyObject* x)
{
setattr(name, ref(x));
setattr(name, handle<>(x));
}
void module_base::setattr(char const* name, ref const& x)
void module_base::setattr(char const* name, handle<> const& x)
{
// Use function::add_to_namespace to achieve overloading if
// appropriate.
objects::function::add_to_namespace(m_module, name, x);
}
void module_base::add(PyTypeObject* x)
void module_base::add(type_handle const& x)
{
this->setattr(x->tp_name, (PyObject*)x);
this->setattr(x->tp_name, x);
}
void module_base::add_type(ref x)
void module_base::add_class(type_handle const& class_obj)
{
assert(PyObject_TypeCheck(x.get(), &PyType_Type));
add((PyTypeObject*)x.release());
}
void module_base::add_class(ref const& class_obj)
{
this->add_type(class_obj);
this->add(class_obj);
ref module_name(
handle<> module_name(
PyObject_GetAttrString(
m_module.get(), const_cast<char*>("__name__"))
);
int status = PyObject_SetAttrString(
class_obj.get(), const_cast<char*>("__module__"), module_name.get());
python::upcast<PyObject>(class_obj.get())
, const_cast<char*>("__module__"), module_name.get());
if (status == -1)
throw_error_already_set();

View File

@@ -101,16 +101,16 @@ void instance_holder::install(PyObject* self) throw()
namespace objects
{
// Get the metatype object for all extension classes.
BOOST_PYTHON_DECL ref class_metatype()
BOOST_PYTHON_DECL type_handle class_metatype()
{
if (class_metatype_object.tp_dict == 0)
{
class_metatype_object.ob_type = &PyType_Type;
class_metatype_object.tp_base = &PyType_Type;
if (PyType_Ready(&class_metatype_object))
return ref();
return type_handle();
}
return ref((PyObject*)&class_metatype_object, ref::increment_count);
return type_handle(borrow(&class_metatype_object));
}
extern "C"
{
@@ -172,16 +172,16 @@ namespace objects
PyType_GenericNew
};
BOOST_PYTHON_DECL ref class_type()
BOOST_PYTHON_DECL type_handle class_type()
{
if (class_type_object.tp_dict == 0)
{
class_type_object.ob_type = (PyTypeObject*)class_metatype().release();
class_type_object.ob_type = incref(class_metatype().get());
class_type_object.tp_base = &PyBaseObject_Type;
if (PyType_Ready(&class_type_object))
return ref();
return type_handle();
}
return ref((PyObject*)&class_type_object, ref::increment_count);
return type_handle(borrow(&class_type_object));
}
BOOST_PYTHON_DECL void*
@@ -206,11 +206,11 @@ namespace objects
struct class_registry
{
public:
ref get(class_id id) const;
ref query(class_id id) const;
void set(class_id, ref class_object);
type_handle get(class_id id) const;
type_handle query(class_id id) const;
void set(class_id, type_handle class_object);
private:
typedef detail::map_entry<class_id,ref> entry;
typedef detail::map_entry<class_id,type_handle> entry;
std::vector<entry> m_impl;
};
@@ -220,7 +220,7 @@ namespace objects
return x;
}
inline ref class_registry::query(class_id id) const
inline type_handle class_registry::query(class_id id) const
{
std::vector<entry>::const_iterator start = m_impl.begin();
std::vector<entry>::const_iterator finish = m_impl.end();
@@ -228,12 +228,12 @@ namespace objects
std::vector<entry>::const_iterator p
= boost::detail::lower_bound(start, finish, id);
return (p == finish || p->key != id) ? ref() : p->value;
return (p == finish || p->key != id) ? type_handle() : p->value;
}
inline ref class_registry::get(class_id id) const
inline type_handle class_registry::get(class_id id) const
{
ref result(this->query(id));
type_handle result(this->query(id));
if (result.get() == 0)
{
@@ -245,7 +245,7 @@ namespace objects
return result;
}
inline void class_registry::set(class_id id, ref object)
inline void class_registry::set(class_id id, type_handle object)
{
std::vector<entry>::iterator start = m_impl.begin();
std::vector<entry>::iterator finish = m_impl.end();
@@ -276,8 +276,10 @@ namespace objects
args.set_item(0, string(name).reference());
args.set_item(1, bases.reference());
args.set_item(2, dictionary().reference());
m_object = ref(PyObject_CallObject(class_metatype().get(), args.get()));
PyObject* c = PyObject_CallObject(upcast<PyObject>(class_metatype().get()), args.get());
assert(PyType_IsSubtype(c->ob_type, &PyType_Type));
m_object = type_handle((PyTypeObject*)c);
r.set(types[0], m_object);
}
@@ -287,25 +289,25 @@ namespace objects
extern DL_IMPORT(PyTypeObject) PyProperty_Type;
}
void class_base::add_property(char const* name, ref const& fget)
void class_base::add_property(char const* name, handle<> const& fget)
{
ref property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "O", fget.get()));
handle<> property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "O", fget.get()));
setattr(name, property);
}
void class_base::add_property(char const* name, ref const& fget, ref const& fset)
void class_base::add_property(char const* name, handle<> const& fget, handle<> const& fset)
{
ref property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "OO", fget.get(), fset.get()));
handle<> property(PyObject_CallFunction((PyObject*)&PyProperty_Type, "OO", fget.get(), fset.get()));
setattr(name, property);
}
void class_base::setattr(char const* name, ref const& x)
void class_base::setattr(char const* name, handle<> const& x)
{
if (PyObject_SetAttrString(object().get(), const_cast<char*>(name), x.get()) < 0)
if (PyObject_SetAttrString(upcast<PyObject>(object().get()), const_cast<char*>(name), x.get()) < 0)
throw_error_already_set();
}
BOOST_PYTHON_DECL ref registered_class_object(class_id id)
BOOST_PYTHON_DECL type_handle registered_class_object(class_id id)
{
return registry().query(id);
}

View File

@@ -149,14 +149,14 @@ namespace
function* not_implemented_function()
{
static function* result = new function(py_function(&not_implemented_impl), 2, 3);
static ref keeper(result);
static handle<> keeper(result);
return result;
}
}
void function::add_to_namespace(
ref const& name_space, char const* name_, ref const& attribute)
handle<> const& name_space, char const* name_, handle<> const& attribute)
{
string const name(name_);
PyObject* const ns = name_space.get();
@@ -175,7 +175,7 @@ void function::add_to_namespace(
if (dict == 0)
throw_error_already_set();
ref existing(PyObject_GetItem(dict, name.get()), ref::null_ok);
handle<> existing( allow_null(PyObject_GetItem(dict, name.get())) );
if (existing.get())
{

View File

@@ -6,7 +6,7 @@
#include <boost/python/object/iterator_core.hpp>
#include <boost/python/object/function.hpp>
#include <boost/python/reference.hpp>
#include <boost/python/handle.hpp>
#include <boost/bind.hpp>
namespace boost { namespace python { namespace objects {
@@ -18,9 +18,9 @@ static PyObject* identity(PyObject* args_, PyObject*)
return x;
}
BOOST_PYTHON_DECL ref identity_function()
BOOST_PYTHON_DECL handle<> identity_function()
{
static ref result(new objects::function(py_function(&identity), 1));
static handle<> result(new objects::function(py_function(&identity), 1));
return result;
}

426
src/objects2.cpp Executable file
View File

@@ -0,0 +1,426 @@
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
// The author gratefully acknowleges the support of Dragon Systems, Inc., in
// producing this work.
// TODO: Move inline implementations from objects.cpp here
#ifndef BOOST_PYTHON_SOURCE
# define BOOST_PYTHON_SOURCE
#endif
#include <boost/python/objects.hpp>
#include <boost/python/detail/none.hpp>
namespace boost { namespace python {
objects_base::objects_base(handle<> const& p)
: m_p(borrow(p.get())) // Do the null check here
{}
// Return a reference to the held object
handle<> objects_base::reference() const
{
return m_p;
}
// Return a raw pointer to the held object
PyObject* objects_base::get() const
{
return m_p.get();
}
}} // namespace boost::python
namespace boost { namespace python {
tuple_base::tuple_base(std::size_t n)
: objects_base(handle<>(PyTuple_New(n)))
{
for (std::size_t i = 0; i < n; ++i)
PyTuple_SET_ITEM(get(), i, detail::none());
}
tuple_base::tuple_base(handle<> p)
: objects_base(p)
{
assert(accepts(p));
if (!accepts(p))
{
PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
throw_error_already_set();
}
}
PyTypeObject* tuple_base::type_obj()
{
return &PyTuple_Type;
}
bool tuple_base::accepts(handle<> p)
{
return PyTuple_Check(p.get());
}
std::size_t tuple_base::size() const
{
return PyTuple_Size(get());
}
handle<> tuple_base::operator[](std::size_t pos) const
{
return handle<>(borrow(PyTuple_GetItem(get(), static_cast<int>(pos))));
}
void tuple_base::set_item(std::size_t pos, const handle<>& rhs)
{
int failed = PyTuple_SetItem(
get()
, static_cast<int>(pos)
, incref(expect_non_null(rhs.get()))
);
(void)failed;
assert(failed == 0);
}
tuple tuple_base::slice(int low, int high) const
{
return tuple(handle<>(PyTuple_GetSlice(get(), low, high)));
}
BOOST_PYTHON_DECL tuple& operator+=(tuple& self, const tuple& rhs)
{
return self = self + rhs;
}
// Construct from an owned PyObject*.
// Precondition: p must point to a python string.
string::string(handle<> p)
: objects_base(p)
{
assert(accepts(p));
if (!accepts(p))
{
PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
throw_error_already_set();
}
}
string::string(const char* s)
: objects_base(handle<>(PyString_FromString(s))) {}
string::string(const char* s, std::size_t length)
: objects_base(handle<>(PyString_FromStringAndSize(s, length))) {}
string::string(const char* s, interned_t)
: objects_base(handle<>(PyString_InternFromString(s))) {}
string::string(const string& rhs)
: objects_base(rhs.reference()) {}
// Get the type object for Strings
PyTypeObject* string::type_obj()
{ return &PyString_Type; }
// Return true if the given object is a python string
bool string::accepts(handle<> o)
{ return PyString_Check(o.get()); }
// Return the length of the string.
std::size_t string::size() const
{
int size = PyString_GET_SIZE(get());
assert(size >= 0);
return static_cast<std::size_t>(size);
}
// Returns a null-terminated representation of the contents of string.
// The pointer refers to the internal buffer of string, not a copy.
// The data must not be modified in any way. It must not be de-allocated.
const char* string::c_str() const
{ return PyString_AS_STRING(get()); }
void string::intern()
{ // UNTESTED!!
*this = string(handle<>(borrow(PyString_InternFromString(c_str()))));
}
string& string::operator*=(unsigned int repeat_count)
{
*this = string(handle<>(PySequence_Repeat(get(), repeat_count)));
return *this;
}
dictionary_base::dictionary_base(handle<> p)
: objects_base(p)
{
assert(accepts(p));
if (!accepts(p))
{
PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
throw_error_already_set();
}
}
dictionary_base::dictionary_base()
: objects_base(handle<>(PyDict_New())) {}
PyTypeObject* dictionary_base::type_obj()
{ return &PyDict_Type; }
bool dictionary_base::accepts(handle<> p)
{ return PyDict_Check(p.get()); }
void dictionary_base::clear()
{ PyDict_Clear(get()); }
const handle<>& dictionary_proxy::operator=(const handle<>& rhs)
{
if (PyDict_SetItem(m_dict.get(), m_key.get(), rhs.get()) == -1)
throw_error_already_set();
return rhs;
}
dictionary_proxy::operator handle<>() const
{
return handle<>(
m_dict->ob_type->tp_as_mapping->mp_subscript(m_dict.get(), m_key.get()));
}
dictionary_proxy::dictionary_proxy(const handle<>& dict, const handle<>& key)
: m_dict(dict), m_key(key) {}
dictionary_proxy dictionary_base::operator[](handle<> key)
{ return proxy(reference(), key); }
handle<> dictionary_base::operator[](handle<> key) const {
// An odd MSVC bug causes the ".operator Ptr()" to be needed
return proxy(reference(), key).operator handle<>();
}
handle<> dictionary_base::get_item(const handle<>& key) const
{
return get_item(key, handle<>());
}
handle<> dictionary_base::get_item(const handle<>& key, const handle<>& default_) const
{
PyObject* value_or_null = PyDict_GetItem(get(), key.get());
if (value_or_null == 0 && !PyErr_Occurred())
return default_;
else
return handle<>(borrow(value_or_null)); // Will throw if there was another error
}
void dictionary_base::set_item(const handle<>& key, const handle<>& value)
{
if (PyDict_SetItem(get(), key.get(), value.get()) == -1)
throw_error_already_set();
}
void dictionary_base::erase(handle<> key) {
if (PyDict_DelItem(get(), key.get()) == -1)
throw_error_already_set();
}
list dictionary_base::items() const { return list(handle<>(PyDict_Items(get()))); }
list dictionary_base::keys() const { return list(handle<>(PyDict_Keys(get()))); }
list dictionary_base::values() const { return list(handle<>(PyDict_Values(get()))); }
std::size_t dictionary_base::size() const { return static_cast<std::size_t>(PyDict_Size(get())); }
string operator+(string x, string y)
{
PyObject* io_string = incref(x.get());
PyString_Concat(&io_string, y.get());
return string(handle<>(io_string));
}
string& string::operator+=(const string& rhs)
{
return *this = *this + rhs;
}
string& string::operator+=(const char* y)
{
return *this += string(y);
}
string operator%(const string& format, const tuple& args)
{
return string(handle<>(PyString_Format(format.get(), args.reference().get())));
}
string operator+(string x, const char* y)
{
return x + string(y);
}
string operator+(const char* x, string y)
{
return string(x) + y;
}
tuple operator+(const tuple& x, const tuple& y)
{
tuple result(x.size() + y.size());
for (std::size_t xi = 0; xi < x.size(); ++xi)
result.set_item(xi, x[xi]);
for (std::size_t yi = 0; yi < y.size(); ++yi)
result.set_item(yi + x.size(), y[yi]);
return result;
}
list_base::list_base(handle<> p)
: objects_base(p)
{
assert(accepts(p));
if (!accepts(p))
{
PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
throw_error_already_set();
}
}
list_base::list_base(std::size_t sz)
: objects_base(handle<>(PyList_New(sz)))
{
}
PyTypeObject* list_base::type_obj()
{
return &PyList_Type;
}
bool list_base::accepts(handle<> p)
{
return PyList_Check(p.get());
}
std::size_t list_base::size() const
{
return PyList_Size(get());
}
handle<> list_base::operator[](std::size_t pos) const
{
return handle<>(borrow(PyList_GetItem(get(), pos)));
}
list_proxy list_base::operator[](std::size_t pos)
{
return proxy(reference(), pos);
}
void list_base::insert(std::size_t index, const handle<>& item)
{
if (PyList_Insert(get(), index, item.get()) == -1)
throw_error_already_set();
}
void list_base::push_back(const handle<>& item)
{
if (PyList_Append(get(), item.get()) == -1)
throw_error_already_set();
}
void list_base::append(const handle<>& item)
{
this->push_back(item);
}
list list_base::slice(int low, int high) const
{
return list(handle<>(PyList_GetSlice(get(), low, high)));
}
list_slice_proxy list_base::slice(int low, int high)
{
return list_slice_proxy(reference(), low, high);
}
void list_base::sort()
{
if (PyList_Sort(get()) == -1)
throw_error_already_set();
}
void list_base::reverse()
{
if (PyList_Reverse(get()) == -1)
throw_error_already_set();
}
tuple list_base::as_tuple() const
{
return tuple(handle<>(PyList_AsTuple(get())));
}
const handle<>& list_proxy::operator=(const handle<>& rhs)
{
m_list.set_item(m_index, rhs);
return rhs;
}
list_proxy::operator handle<>() const
{
return handle<>(borrow(PyList_GetItem(m_list.get(), m_index)));
}
handle<> list_base::get_item(std::size_t pos) const
{
return handle<>(borrow(PyList_GetItem(this->get(), pos)));
}
void list_base::set_item(std::size_t pos, const handle<>& rhs)
{
int result = PyList_SetItem(this->get(), pos, rhs.get());
if (result == -1)
throw_error_already_set();
Py_INCREF(rhs.get());
}
list_proxy::list_proxy(const handle<>& list, std::size_t index)
: m_list(list), m_index(index)
{
}
const list& list_slice_proxy::operator=(const list& rhs)
{
if (PyList_SetSlice(m_list.get(), m_low, m_high, rhs.get()) == -1)
throw_error_already_set();
return rhs;
}
list_slice_proxy::operator handle<>() const
{
return handle<>(PyList_GetSlice(m_list.get(), m_low, m_high));
}
list_slice_proxy::operator list() const
{
return list(this->operator handle<>());
}
std::size_t list_slice_proxy::size() const
{
return this->operator list().size();
}
handle<> list_slice_proxy::operator[](std::size_t pos) const
{
return this->operator list()[pos].operator handle<>();
}
list_slice_proxy::list_slice_proxy(const handle<>& list, int low, int high)
: m_list(list), m_low(low), m_high(high)
{
}
}} // namespace boost::python