2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-20 04:42:28 +00:00

Compare commits

..

14 Commits

Author SHA1 Message Date
Beman Dawes
bf05bdc0c3 Release 1.48.0 beta 1
[SVN r75132]
2011-10-27 15:04:52 +00:00
Ralf W. Grosse-Kunstleve
49e8699b9f merging current boost/python and libs/python from trunk into release branch
[SVN r74931]
2011-10-12 21:38:53 +00:00
Ralf W. Grosse-Kunstleve
cfa2baf8c9 merging current boost/python and libs/python from trunk into release branch
[SVN r72464]
2011-06-07 04:15:33 +00:00
Ralf W. Grosse-Kunstleve
faf3cd0b78 merging current boost/python and libs/python from trunk into release branch
[SVN r72277]
2011-05-30 05:51:49 +00:00
Ralf W. Grosse-Kunstleve
a5e564be83 merging current boost/python and libs/python from trunk into release branch
[SVN r71226]
2011-04-13 17:34:35 +00:00
Dave Abrahams
dcc3590907 verifying commit privs
[SVN r71150]
2011-04-09 16:55:43 +00:00
Ralf W. Grosse-Kunstleve
74daea3d88 boost/libs/python/doc/PyConDC_2003: removing $Date$ and $Revision$ so they do not create noise on each merge to the release branch
[SVN r71004]
2011-04-05 16:49:31 +00:00
Ralf W. Grosse-Kunstleve
e28f0509d8 merging current boost/python and libs/python from trunk into release branch
[SVN r71002]
2011-04-05 16:31:51 +00:00
Ralf W. Grosse-Kunstleve
0a211a746d merging current boost/python and libs/python from trunk into release branch
[SVN r70448]
2011-03-23 00:14:55 +00:00
Ralf W. Grosse-Kunstleve
ba213663b6 merging current boost/python and libs/python from trunk into release branch
[SVN r67483]
2010-12-28 20:38:29 +00:00
Ralf W. Grosse-Kunstleve
736ba48c2b merging current boost/python and libs/python from trunk into release branch
[SVN r67446]
2010-12-24 17:31:05 +00:00
Eric Niebler
6066ffef9a Merged revisions 66606 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r66606 | rwgk | 2010-11-15 18:17:00 -0500 (Mon, 15 Nov 2010) | 1 line
  
  boost/python/object/make_instance.hpp: adding missing includes
........


[SVN r66614]
2010-11-16 18:30:39 +00:00
Ralf W. Grosse-Kunstleve
f759e9eb0e merging current boost/python and libs/python from trunk into release branch
[SVN r66066]
2010-10-18 04:04:52 +00:00
Douglas Gregor
846c5d9914 Add missing includes
[SVN r65142]
2010-08-31 04:50:56 +00:00
31 changed files with 277 additions and 93 deletions

28
class.cpp Normal file
View File

@@ -0,0 +1,28 @@
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/object.hpp>
#include <boost/python/class.hpp>
using namespace boost::python;
struct X
{
int x;
X(int n) : x(n) { }
};
int x_function(X& x)
{ return x.x;
}
BOOST_PYTHON_MODULE(class_ext)
{
class_<X>("X", init<int>());
def("x_function", x_function);
}
#include "module_tail.cpp"

View File

@@ -27,7 +27,6 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Somerville, MA 02143
:Contact: dave@boost-consulting.com
:organization: `Boost Consulting`_
:date: $Date$
:status: This is a "work in progress"
:version: 1
:copyright: Copyright David Abrahams 2002. All rights reserved

View File

@@ -1,8 +1,6 @@
/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date$
:version: $Revision$
:copyright: This stylesheet has been placed in the public domain.
boostinspect:nolicense

View File

@@ -124,7 +124,7 @@
<p>
</p>
<pre class="programlisting"><span class="special">&gt;&gt;&gt;</span> <span class="keyword">import</span> <span class="identifier">hello_ext</span>
<span class="special">&gt;&gt;&gt;</span> <span class="keyword">print</span> <span class="identifier">hello</span><span class="special">.</span><span class="identifier">greet</span><span class="special">()</span>
<span class="special">&gt;&gt;&gt;</span> <span class="keyword">print</span> <span class="identifier">hello_ext</span><span class="special">.</span><span class="identifier">greet</span><span class="special">()</span>
<span class="identifier">hello</span><span class="special">,</span> <span class="identifier">world</span>
</pre>
<p>

View File

@@ -62,7 +62,7 @@ resulting DLL is now visible to Python. Here's a sample Python session:
[python]
>>> import hello_ext
>>> print hello.greet()
>>> print hello_ext.greet()
hello, world
[c++]

View File

@@ -85,7 +85,7 @@ namespace boost { namespace python
object stop();
object step();
// The return type of slice::get_indicies()
// The return type of slice::get_indices()
template &lt;typename RandomAccessIterator&gt;
struct range
{
@@ -96,7 +96,7 @@ namespace boost { namespace python
template &lt;typename RandomAccessIterator&gt;
range&lt;RandomAccessIterator&gt;
get_indicies(
get_indices(
RandomAccessIterator const&amp; begin,
RandomAccessIterator const&amp; end);
};
@@ -164,7 +164,7 @@ slice object, but in practice they are usually integers.</dt>
<pre>
template &lt;typename RandomAccessIterator&gt;
slice::range&lt;RandomAccessIterator&gt;
slice::get_indicies(
slice::get_indices(
RandomAccessIterator const&amp; begin,
RandomAccessIterator const&amp; end) const;
</pre>
@@ -173,8 +173,8 @@ slice::get_indicies(
Iterators that form a half-open range.</dt>
<dt><b>Effects:</b> Create a RandomAccessIterator pair that defines a
fully-closed range within the [begin,end) range of its arguments.&nbsp;
This function translates this slice's indicies while accounting for the
effects of any PyNone or negative indicies, and non-singular step sizes.</dt>
This function translates this slice's indices while accounting for the
effects of any PyNone or negative indices, and non-singular step sizes.</dt>
<dt><b>Returns:</b> a slice::range
that has been initialized with a non-zero value of step and a pair of
RandomAccessIterators that point within the range of this functions
@@ -182,7 +182,7 @@ arguments and define a closed interval.</dt>
<dt><b>Throws:</b> <a href="definitions.html#raise">Raises</a> a Python <code>TypeError</code> exception if any of this slice's arguments
are neither references to <code>PyNone</code> nor convertible to <code>int</code>.&nbsp; Throws
<code>std::invalid_argument</code> if the resulting range would be empty.&nbsp; You
should always wrap calls to <code>slice::get_indicies()</code>
should always wrap calls to <code>slice::get_indices()</code>
within <code>try { ...; } catch (std::invalid_argument) {}</code> to
handle this case and take appropriate action.</dt>
<dt><b>Rationale</b>: closed-interval: If
@@ -221,7 +221,7 @@ double partial_sum(std::vector&lt;double&gt; const&amp; Foo, const slice index)
{
slice::range&lt;std::vector&lt;double&gt;::const_iterator&gt; bounds;
try {
bounds = index.get_indicies&lt;&gt;(Foo.begin(), Foo.end());
bounds = index.get_indices&lt;&gt;(Foo.begin(), Foo.end());
}
catch (std::invalid_argument) {
return 0.0;

View File

@@ -91,7 +91,7 @@
<hr>
<h2>
<a name="introduction">Introduction</a>
</h2>This header provides faciliites for establishing a lifetime
</h2>This header provides facilities for establishing a lifetime
dependency between two of a function's Python argument or result objects.
The <i>ward</i> object will not be destroyed until after the custodian as
long as the <i>custodian</i> object supports <a href=

View File

@@ -26,6 +26,14 @@ project
# source files after the colon separated by spaces.
python-extension hello_ext : hello.cpp ;
# Put the extension and Boost.Python DLL in the current directory, so
# that running script by hand works.
install convenient_copy
: hello_ext
: <install-dependencies>on <install-type>SHARED_LIB <install-type>PYTHON_EXTENSION
<location>.
;
# A little "rule" (function) to clean up the syntax of declaring tests
# of these extension modules.
local rule run-test ( test-name : sources + )

View File

@@ -138,7 +138,8 @@ namespace detail
static void
must_be_derived_class_member(Default const&)
{
typedef typename assertion<mpl::not_<is_same<Default,Fn> > >::failed test0;
// https://svn.boost.org/trac/boost/ticket/5803
//typedef typename assertion<mpl::not_<is_same<Default,Fn> > >::failed test0;
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
typedef typename assertion<is_polymorphic<T> >::failed test1;
# endif

View File

@@ -122,7 +122,7 @@ BOOST_PYTHON_TO_INT(short)
BOOST_PYTHON_TO_INT(int)
BOOST_PYTHON_TO_INT(long)
# if defined(_MSC_VER) && defined(_WIN64)
# if defined(_MSC_VER) && defined(_WIN64) && PY_VERSION_HEX < 0x03000000
/* Under 64-bit Windows std::size_t is "unsigned long long". To avoid
getting a Python long for each std::size_t the value is checked before
the conversion. A std::size_t is converted to a simple Python int

View File

@@ -57,7 +57,7 @@ object make_keyword_range_constructor(
, Holder* = 0
, ArgList* = 0, Arity* = 0)
{
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE)
python_class<BOOST_DEDUCED_TYPENAME Holder::value_type>::register_();
#endif
return detail::make_keyword_range_function(

View File

@@ -53,6 +53,9 @@ enum operator_id
op_nonzero,
#endif
op_repr
#if PY_VERSION_HEX >= 0x03000000
,op_truediv
#endif
};
}}} // namespace boost::python::detail

View File

@@ -13,27 +13,54 @@
namespace boost { namespace python { namespace detail {
# if PY_VERSION_HEX >= 0x03000000
BOOST_PYTHON_DECL PyObject* init_module(PyModuleDef&, void(*)());
#else
BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*)());
#endif
}}}
# if PY_VERSION_HEX >= 0x03000000
# define _BOOST_PYTHON_MODULE_INIT(name) \
PyObject* BOOST_PP_CAT (PyInit_,name)() \
{ \
return boost::python::detail::init_module( \
BOOST_PP_STRINGIZE(name),&BOOST_PP_CAT(init_module_,name)); \
} \
void BOOST_PP_CAT(init_module_,name)()
# define _BOOST_PYTHON_MODULE_INIT(name) \
PyObject* BOOST_PP_CAT(PyInit_, name)() \
{ \
static PyModuleDef_Base initial_m_base = { \
PyObject_HEAD_INIT(NULL) \
0, /* m_init */ \
0, /* m_index */ \
0 /* m_copy */ }; \
static PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } }; \
\
static struct PyModuleDef moduledef = { \
initial_m_base, \
BOOST_PP_STRINGIZE(name), \
0, /* m_doc */ \
-1, /* m_size */ \
initial_methods, \
0, /* m_reload */ \
0, /* m_traverse */ \
0, /* m_clear */ \
0, /* m_free */ \
}; \
\
return boost::python::detail::init_module( \
moduledef, BOOST_PP_CAT(init_module_, name) ); \
} \
void BOOST_PP_CAT(init_module_, name)()
# else
# define _BOOST_PYTHON_MODULE_INIT(name) \
void BOOST_PP_CAT(init,name)() \
void BOOST_PP_CAT(init,name)() \
{ \
boost::python::detail::init_module( \
BOOST_PP_STRINGIZE(name),&BOOST_PP_CAT(init_module_,name)); \
BOOST_PP_STRINGIZE(name),&BOOST_PP_CAT(init_module_,name)); \
} \
void BOOST_PP_CAT(init_module_,name)()
@@ -42,23 +69,23 @@ BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*)());
# if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(BOOST_PYTHON_STATIC_MODULE)
# define BOOST_PYTHON_MODULE_INIT(name) \
void BOOST_PP_CAT(init_module_,name)(); \
void BOOST_PP_CAT(init_module_,name)(); \
extern "C" __declspec(dllexport) _BOOST_PYTHON_MODULE_INIT(name)
# elif BOOST_PYTHON_USE_GCC_SYMBOL_VISIBILITY
# define BOOST_PYTHON_MODULE_INIT(name) \
void BOOST_PP_CAT(init_module_,name)(); \
void BOOST_PP_CAT(init_module_,name)(); \
extern "C" __attribute__ ((visibility("default"))) _BOOST_PYTHON_MODULE_INIT(name)
# else
# define BOOST_PYTHON_MODULE_INIT(name) \
void BOOST_PP_CAT(init_module_,name)(); \
void BOOST_PP_CAT(init_module_,name)(); \
extern "C" _BOOST_PYTHON_MODULE_INIT(name)
# endif
# endif
# endif
#endif // MODULE_INIT_DWA20020722_HPP

View File

@@ -238,7 +238,7 @@ struct class_metadata
//
inline static void maybe_register_pointer_to_python(...) {}
#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
inline static void maybe_register_pointer_to_python(void*,void*,mpl::true_*)
{
objects::copy_class_object(python::type_id<T>(), python::type_id<back_reference<T const &> >());
@@ -255,7 +255,7 @@ struct class_metadata
, make_ptr_instance<T2, pointer_holder<held_type, T2> >
>()
);
#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
// explicit qualification of type_id makes msvc6 happy
objects::copy_class_object(python::type_id<T2>(), python::type_id<held_type>());
#endif
@@ -270,7 +270,7 @@ struct class_metadata
inline static void maybe_register_class_to_python(T2*, mpl::false_)
{
python::detail::force_instantiate(class_cref_wrapper<T2, make_instance<T2, holder> >());
#ifndef BOOST_PYTHON_NO_PY_SYGNATURES
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
// explicit qualification of type_id makes msvc6 happy
objects::copy_class_object(python::type_id<T2>(), python::type_id<held_type>());
#endif

View File

@@ -39,6 +39,8 @@ struct BOOST_PYTHON_DECL function : PyObject
void doc(object const& x);
object const& name() const;
object const& get_namespace() const { return m_namespace; }
private: // helper functions
object signature(bool show_return_type=false) const;

View File

@@ -12,7 +12,7 @@
# include <boost/python/object/instance.hpp>
# include <boost/python/converter/registry.hpp>
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE)
# include <boost/python/detail/python_type.hpp>
#endif
@@ -81,7 +81,7 @@ struct make_holder<N>
# endif
static void execute(
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SYGNATURES_PROPER_INIT_SELF_TYPE)
#if !defined( BOOST_PYTHON_NO_PY_SIGNATURES) && defined( BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE)
boost::python::detail::python_class<BOOST_DEDUCED_TYPENAME Holder::value_type> *p
#else
PyObject *p

View File

@@ -10,6 +10,8 @@
# include <boost/python/converter/registered.hpp>
# include <boost/python/detail/decref_guard.hpp>
# include <boost/python/detail/none.hpp>
# include <boost/mpl/assert.hpp>
# include <boost/mpl/or.hpp>
# include <boost/type_traits/is_union.hpp>
namespace boost { namespace python { namespace objects {

View File

@@ -212,7 +212,11 @@ namespace self_ns \
BOOST_PYTHON_BINARY_OPERATOR(add, radd, +)
BOOST_PYTHON_BINARY_OPERATOR(sub, rsub, -)
BOOST_PYTHON_BINARY_OPERATOR(mul, rmul, *)
BOOST_PYTHON_BINARY_OPERATOR(div, rdiv, /)
#if PY_VERSION_HEX >= 0x03000000
BOOST_PYTHON_BINARY_OPERATOR(truediv, rtruediv, /)
#else
BOOST_PYTHON_BINARY_OPERATOR(div, rdiv, /)
#endif
BOOST_PYTHON_BINARY_OPERATOR(mod, rmod, %)
BOOST_PYTHON_BINARY_OPERATOR(lshift, rlshift, <<)
BOOST_PYTHON_BINARY_OPERATOR(rshift, rrshift, >>)

View File

@@ -77,7 +77,7 @@ namespace detail
template <class T>
T unchecked(type<T>* = 0)
{
return extract<T>(m_obj)();
return extract<T>(m_obj.get())();
}
private:
mutable handle<> m_obj;

View File

@@ -30,7 +30,7 @@ namespace detail
// that created this slice, than that parameter is None here, and compares
// equal to a default-constructed boost::python::object.
// If a user-defined type wishes to support slicing, then support for the
// special meaning associated with negative indicies is up to the user.
// special meaning associated with negative indices is up to the user.
object start() const;
object stop() const;
object step() const;
@@ -63,7 +63,7 @@ class slice : public detail::slice_base
// The following algorithm is intended to automate the process of
// determining a slice range when you want to fully support negative
// indicies and non-singular step sizes. Its functionallity is simmilar to
// indices and non-singular step sizes. Its functionallity is simmilar to
// PySlice_GetIndicesEx() in the Python/C API, but tailored for C++ users.
// This template returns a slice::range struct that, when used in the
// following iterative loop, will traverse a slice of the function's
@@ -110,7 +110,7 @@ class slice : public detail::slice_base
template<typename RandomAccessIterator>
slice::range<RandomAccessIterator>
get_indicies( const RandomAccessIterator& begin,
get_indices( const RandomAccessIterator& begin,
const RandomAccessIterator& end) const
{
// This is based loosely on PySlice_GetIndicesEx(), but it has been
@@ -240,6 +240,16 @@ class slice : public detail::slice_base
return ret;
}
// Incorrect spelling. DO NOT USE. Only here for backward compatibility.
// Corrected 2011-06-14.
template<typename RandomAccessIterator>
slice::range<RandomAccessIterator>
get_indicies( const RandomAccessIterator& begin,
const RandomAccessIterator& end) const
{
get_indices(begin, end);
}
public:
// This declaration, in conjunction with the specialization of

View File

@@ -366,7 +366,9 @@ namespace
static PyTypeObject const* get_pytype() { return &PyFloat_Type;}
};
#if PY_VERSION_HEX >= 0x03000000
unaryfunc py_unicode_as_string_unaryfunc = PyUnicode_AsUTF8String;
#endif
// A SlotPolicy for extracting C++ strings from Python objects.
struct string_rvalue_from_python
@@ -431,7 +433,10 @@ namespace
if (!result.empty())
{
int err = PyUnicode_AsWideChar(
(PyUnicodeObject *)intermediate
#if PY_VERSION_HEX < 0x03020000
(PyUnicodeObject *)
#endif
intermediate
, &result[0]
, result.size());

View File

@@ -44,11 +44,8 @@ BOOST_PYTHON_DECL rvalue_from_python_stage1_data rvalue_from_python_stage1(
// First check to see if it's embedded in an extension class
// instance, as a special case.
data.convertible = objects::find_instance_impl(source, converters.target_type, converters.is_shared_ptr);
if (data.convertible)
{
data.construct = 0;
}
else
if (!data.convertible)
{
for (rvalue_from_python_chain const* chain = converters.rvalue_chain;
chain != 0;

View File

@@ -11,6 +11,23 @@
namespace boost { namespace python { namespace detail {
namespace
{
PyObject* init_module_in_scope(PyObject* m, void(*init_function)())
{
if (m != 0)
{
// Create the current module scope
object m_obj(((borrowed_reference_t*)m));
scope current_module(m_obj);
handle_exception(init_function);
}
return m;
}
}
BOOST_PYTHON_DECL void scope_setattr_doc(char const* name, object const& x, char const* doc)
{
// Use function::add_to_namespace to achieve overloading if
@@ -19,42 +36,31 @@ BOOST_PYTHON_DECL void scope_setattr_doc(char const* name, object const& x, char
objects::add_to_namespace(current, name, x, doc);
}
#if PY_VERSION_HEX >= 0x03000000
BOOST_PYTHON_DECL PyObject* init_module(PyModuleDef& moduledef, void(*init_function)())
{
return init_module_in_scope(
PyModule_Create(&moduledef),
init_function);
}
#else
namespace
{
PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } };
PyMethodDef initial_methods[] = { { 0, 0, 0, 0 } };
}
BOOST_PYTHON_DECL PyObject* init_module(char const* name, void(*init_function)())
{
#if PY_VERSION_HEX >= 0x03000000
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
name,
0, /* m_doc */
-1, /* m_size */
initial_methods,
0, /* m_reload */
0, /* m_traverse */
0, /* m_clear */
0, /* m_free */
};
PyObject* m = PyModule_Create(&moduledef);
#else
PyObject* m
= Py_InitModule(const_cast<char*>(name), initial_methods);
#endif
if (m != 0)
{
// Create the current module scope
object m_obj(((borrowed_reference_t*)m));
scope current_module(m_obj);
handle_exception(init_function);
}
return m;
return init_module_in_scope(
Py_InitModule(const_cast<char*>(name), initial_methods),
init_function);
}
#endif
}}} // namespace boost::python::detail
namespace boost { namespace python {

View File

@@ -76,11 +76,11 @@ extern "C"
static int property_init(PyObject *self, PyObject *args, PyObject *kwds)
{
PyObject *get = NULL, *set = NULL, *del = NULL, *doc = NULL;
static char *kwlist[] = {"fget", "fset", "fdel", "doc", 0};
static const char *kwlist[] = {"fget", "fset", "fdel", "doc", 0};
propertyobject *prop = (propertyobject *)self;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO:property",
kwlist, &get, &set, &del, &doc))
const_cast<char **>(kwlist), &get, &set, &del, &doc))
return -1;
if (get == Py_None)
@@ -303,7 +303,7 @@ static PyTypeObject class_metatype_object = {
// object.
void instance_holder::install(PyObject* self) throw()
{
assert(Py_TYPE(Py_TYPE(self)) == &class_metatype_object);
assert(PyType_IsSubtype(Py_TYPE(Py_TYPE(self)), &class_metatype_object));
m_next = ((objects::instance<>*)self)->objects;
((objects::instance<>*)self)->objects = this;
}
@@ -482,7 +482,8 @@ namespace objects
BOOST_PYTHON_DECL void*
find_instance_impl(PyObject* inst, type_info type, bool null_shared_ptr_only)
{
if (Py_TYPE(Py_TYPE(inst)) != &class_metatype_object)
if (!Py_TYPE(Py_TYPE(inst)) ||
!PyType_IsSubtype(Py_TYPE(Py_TYPE(inst)), &class_metatype_object))
return 0;
instance<>* self = reinterpret_cast<instance<>*>(inst);
@@ -727,7 +728,7 @@ namespace objects
void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std::size_t holder_size)
{
assert(Py_TYPE(Py_TYPE(self_)) == &class_metatype_object);
assert(PyType_IsSubtype(Py_TYPE(Py_TYPE(self_)), &class_metatype_object));
objects::instance<>* self = (objects::instance<>*)self_;
int total_size_needed = holder_offset + holder_size;
@@ -752,7 +753,7 @@ void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std:
void instance_holder::deallocate(PyObject* self_, void* storage) throw()
{
assert(Py_TYPE(Py_TYPE(self_)) == &class_metatype_object);
assert(PyType_IsSubtype(Py_TYPE(Py_TYPE(self_)), &class_metatype_object));
objects::instance<>* self = (objects::instance<>*)self_;
if (storage != (char*)self + Py_SIZE(self))
{

View File

@@ -433,23 +433,23 @@ void function::add_to_namespace(
if (attribute.ptr()->ob_type == &function_type)
{
function* new_func = downcast<function>(attribute.ptr());
PyObject* dict = 0;
handle<> dict;
#if PY_VERSION_HEX < 0x03000000
// Old-style class gone in Python 3
if (PyClass_Check(ns))
dict = ((PyClassObject*)ns)->cl_dict;
dict = handle<>(borrowed(((PyClassObject*)ns)->cl_dict));
else
#endif
if (PyType_Check(ns))
dict = ((PyTypeObject*)ns)->tp_dict;
dict = handle<>(borrowed(((PyTypeObject*)ns)->tp_dict));
else
dict = PyObject_GetAttrString(ns, const_cast<char*>("__dict__"));
dict = handle<>(PyObject_GetAttrString(ns, const_cast<char*>("__dict__")));
if (dict == 0)
throw_error_already_set();
handle<> existing(allow_null(::PyObject_GetItem(dict, name.ptr())));
handle<> existing(allow_null(::PyObject_GetItem(dict.get(), name.ptr())));
if (existing)
{
@@ -670,11 +670,26 @@ extern "C"
{
return python::incref(upcast<PyObject>(&PyCFunction_Type));
}
static PyObject* function_get_module(PyObject* op, void*)
{
function* f = downcast<function>(op);
object const& ns = f->get_namespace();
if (!ns.is_none()) {
return python::incref(ns.ptr());
}
PyErr_SetString(
PyExc_AttributeError, const_cast<char*>(
"Boost.Python function __module__ unknown."));
return 0;
}
}
static PyGetSetDef function_getsetlist[] = {
{const_cast<char*>("__name__"), (getter)function_get_name, 0, 0, 0 },
{const_cast<char*>("func_name"), (getter)function_get_name, 0, 0, 0 },
{const_cast<char*>("__module__"), (getter)function_get_module, 0, 0, 0 },
{const_cast<char*>("func_module"), (getter)function_get_module, 0, 0, 0 },
{const_cast<char*>("__class__"), (getter)function_get_class, 0, 0, 0 }, // see note above
{const_cast<char*>("__doc__"), (getter)function_get_doc, (setter)function_set_doc, 0, 0},
{const_cast<char*>("func_doc"), (getter)function_get_doc, (setter)function_set_doc, 0, 0},

View File

@@ -3,11 +3,15 @@
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import python ;
import os ;
lib socket ;
use-project /boost/python : ../build ;
project /boost/python/test
: requirements
<toolset>gcc:<cxxflags>-Wextra
<target-os>qnxnto:<library>socket
;
local PY = ;
@@ -117,6 +121,7 @@ bpl-test crossmod_exception
[ bpl-test defaults ]
[ bpl-test object ]
[ bpl-test class ]
[ bpl-test list ]
[ bpl-test long ]
[ bpl-test dict ]

28
test/class.cpp Normal file
View File

@@ -0,0 +1,28 @@
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/object.hpp>
#include <boost/python/class.hpp>
using namespace boost::python;
struct X
{
int x;
X(int n) : x(n) { }
};
int x_function(X& x)
{ return x.x;
}
BOOST_PYTHON_MODULE(class_ext)
{
class_<X>("X", init<int>());
def("x_function", x_function);
}
#include "module_tail.cpp"

40
test/class.py Executable file
View File

@@ -0,0 +1,40 @@
# Distributed under the Boost
# Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
'''
>>> from class_ext import *
Ensure sanity:
>>> x = X(42)
>>> x_function(x)
42
Demonstrate extraction in the presence of metaclass changes:
>>> class MetaX(X.__class__):
... def __new__(cls, *args):
... return super(MetaX, cls).__new__(cls, *args)
>>> class XPlusMetatype(X):
... __metaclass__ = MetaX
>>> x = XPlusMetatype(42)
>>> x_function(x)
42
'''
def run(args = None):
import sys
import doctest
if args is not None:
sys.argv = args
return doctest.testmod(sys.modules.get(__name__))
if __name__ == '__main__':
print "running..."
import sys
status = run()[0]
if (status == 0): print "Done."
sys.exit(status)

View File

@@ -7,6 +7,11 @@
>>> print func.__doc__.splitlines()[1]
func( (A)arg1) -> A :
>>> print func.__module__
pytype_function_ext
>>> print func.__name__
func
"""
def run(args = None):
import sys

View File

@@ -98,9 +98,9 @@ bool accept_slice( slice) { return true; }
#if BOOST_WORKAROUND( BOOST_MSVC, BOOST_TESTED_AT(1400)) \
|| BOOST_WORKAROUND( BOOST_INTEL_WIN, == 710)
int check_slice_get_indicies(slice index);
int check_slice_get_indices(slice index);
#endif
int check_slice_get_indicies(
int check_slice_get_indices(
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
const
#endif
@@ -116,7 +116,7 @@ int check_slice_get_indicies(
slice::range<std::vector<int>::iterator> bounds;
try {
bounds = index.get_indicies(coll.begin(), coll.end());
bounds = index.get_indices(coll.begin(), coll.end());
}
catch (std::invalid_argument) {
return 0;
@@ -136,5 +136,5 @@ BOOST_PYTHON_MODULE(slice_ext)
def( "accept_slice", accept_slice);
def( "check_numeric_array_rich_slice", check_numeric_array_rich_slice);
def( "check_string_rich_slice", check_string_rich_slice);
def( "check_slice_get_indicies", check_slice_get_indicies);
def( "check_slice_get_indices", check_slice_get_indices);
}

View File

@@ -37,17 +37,17 @@ test passed
... print 1
...
1
>>> check_slice_get_indicies( slice(None))
>>> check_slice_get_indices( slice(None))
0
>>> check_slice_get_indicies( slice(2,-2))
>>> check_slice_get_indices( slice(2,-2))
0
>>> check_slice_get_indicies( slice(2, None, 2))
>>> check_slice_get_indices( slice(2, None, 2))
5
>>> check_slice_get_indicies( slice(2, None, -1))
>>> check_slice_get_indices( slice(2, None, -1))
-12
>>> check_slice_get_indicies( slice( 20, None))
>>> check_slice_get_indices( slice( 20, None))
0
>>> check_slice_get_indicies( slice( -2, -5, -2))
>>> check_slice_get_indices( slice( -2, -5, -2))
6
"""