mirror of
https://github.com/boostorg/python.git
synced 2026-01-20 16:52:15 +00:00
Compare commits
3 Commits
svn-branch
...
svn-branch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9374bca9a0 | ||
|
|
922525faa0 | ||
|
|
c1e69eecff |
@@ -96,12 +96,28 @@ class class_builder
|
||||
void def_standard_coerce()
|
||||
{ m_class->def_standard_coerce(); }
|
||||
|
||||
// declare the given class a base class of this one and register
|
||||
// conversion functions
|
||||
template <class S>
|
||||
void declare_base(type<S> const & t)
|
||||
{
|
||||
m_class->declare_base(t);
|
||||
}
|
||||
|
||||
// declare the given class a base class of this one and register
|
||||
// upcast conversion function
|
||||
template <class S>
|
||||
void declare_base(type<S> const & t, without_downcast_t)
|
||||
{
|
||||
m_class->declare_base(t, without_downcast);
|
||||
}
|
||||
|
||||
// declare the given class a base class of this one and register
|
||||
// conversion functions
|
||||
template <class S, class V>
|
||||
void declare_base(class_builder<S, V> const & base)
|
||||
{
|
||||
m_class->declare_base(base.get_extension_class());
|
||||
declare_base(type<S>());
|
||||
}
|
||||
|
||||
// declare the given class a base class of this one and register
|
||||
@@ -109,7 +125,7 @@ class class_builder
|
||||
template <class S, class V>
|
||||
void declare_base(class_builder<S, V> const & base, without_downcast_t)
|
||||
{
|
||||
m_class->declare_base(base.get_extension_class(), without_downcast);
|
||||
declare_base(type<S>(), without_downcast);
|
||||
}
|
||||
|
||||
// get the embedded ExtensioClass object
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
# include <memory>
|
||||
# include <boost/python/detail/init_function.hpp>
|
||||
# include <typeinfo>
|
||||
# include <stdexcept>
|
||||
# include <boost/smart_ptr.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
@@ -487,9 +488,15 @@ class extension_class
|
||||
|
||||
// declare the given class a base class of this one and register
|
||||
// up and down conversion functions
|
||||
template <class S, class V>
|
||||
void declare_base(extension_class<S, V>* base)
|
||||
template <class S>
|
||||
void declare_base(type<S>)
|
||||
{
|
||||
extension_class_base * base = class_registry<S>::class_object();
|
||||
|
||||
if(base == 0)
|
||||
throw std::runtime_error(
|
||||
"extension_class::declare_base(type<S>): base undefined.");
|
||||
|
||||
// see extclass.cpp for an explanation of why we need to register
|
||||
// conversion functions
|
||||
base_class_info baseInfo(base,
|
||||
@@ -501,12 +508,19 @@ class extension_class
|
||||
&define_conversion<T, S>::upcast_ptr);
|
||||
class_registry<S>::register_derived_class(derivedInfo);
|
||||
}
|
||||
|
||||
|
||||
// declare the given class a base class of this one and register
|
||||
// only up conversion function
|
||||
template <class S, class V>
|
||||
void declare_base(extension_class<S, V>* base, without_downcast_t)
|
||||
template <class S>
|
||||
void declare_base(type<S>, without_downcast_t)
|
||||
{
|
||||
extension_class_base * base = class_registry<S>::class_object();
|
||||
|
||||
if(base == 0)
|
||||
throw std::runtime_error(
|
||||
"extension_class::declare_base(type<S>, without_downcast_t): base undefined.");
|
||||
|
||||
// see extclass.cpp for an explanation of why we need to register
|
||||
// conversion functions
|
||||
base_class_info baseInfo(base, 0);
|
||||
@@ -517,7 +531,6 @@ class extension_class
|
||||
&define_conversion<T, S>::upcast_ptr);
|
||||
class_registry<S>::register_derived_class(derivedInfo);
|
||||
}
|
||||
|
||||
private: // types
|
||||
typedef instance_value_holder<T,U> holder;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
// When STLport is used with native streams, _STL::ostringstream().str() is not
|
||||
// _STL::string, but std::string. This confuses to_python(), so we'll use
|
||||
// strstream instead. Also, GCC 2.95.2 doesn't have sstream.
|
||||
# if defined(__SGI_STL_PORT) ? __SGI_STL_OWN_IOSTREAMS : !defined(__GNUC__) || __GNUC__ > 2
|
||||
# if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2)
|
||||
# include <sstream>
|
||||
# else
|
||||
# include <strstream>
|
||||
@@ -482,7 +482,7 @@ namespace detail
|
||||
|
||||
// When STLport is used with native streams, _STL::ostringstream().str() is not
|
||||
// _STL::string, but std::string.
|
||||
#if defined(__SGI_STL_PORT) ? __SGI_STL_OWN_IOSTREAMS : !defined(__GNUC__)
|
||||
#if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2)
|
||||
std::ostringstream s;
|
||||
s << BOOST_PYTHON_CONVERSION::from_python(args[0].get(), boost::python::type<operand>());
|
||||
return BOOST_PYTHON_CONVERSION::to_python(s.str());
|
||||
|
||||
32
shared_modules/Makefile
Normal file
32
shared_modules/Makefile
Normal file
@@ -0,0 +1,32 @@
|
||||
include ../build/Makefile
|
||||
|
||||
SRC = \
|
||||
m1.cpp \
|
||||
m2.cpp \
|
||||
shared.cpp
|
||||
|
||||
TARGETS = $(SRC:.cpp:module$(MODULE_EXTENSION))
|
||||
|
||||
LIBBPL = -L$(TARGET_LIBDIR) -l$(TARGET_LIBNAME)
|
||||
|
||||
all: m1module$(MODULE_EXTENSION) m2module$(MODULE_EXTENSION)
|
||||
python shared_modules.py
|
||||
|
||||
m1module.so: m1.o sharedmodule$(MODULE_EXTENSION)
|
||||
$(CXX_SHARED_LINKER) -o m1module.so m1.o sharedmodule$(MODULE_EXTENSION) $(LIBBPL)
|
||||
|
||||
m2module.so: m2.o sharedmodule$(MODULE_EXTENSION)
|
||||
$(CXX_SHARED_LINKER) -o m2module.so m2.o sharedmodule$(MODULE_EXTENSION) $(LIBBPL)
|
||||
|
||||
sharedmodule$(MODULE_EXTENSION): shared.o
|
||||
$(CXX_SHARED_LINKER) -o sharedmodule$(MODULE_EXTENSION) shared.o $(LIBBPL)
|
||||
|
||||
.PRECIOUS: so
|
||||
|
||||
clean:
|
||||
rm -rf *.o *$(MODULE_EXTENSION) *.a *.d *.pyc *.bak a.out
|
||||
|
||||
ifneq "$(MAKECMDGOALS)" "clean"
|
||||
include $(SRC:.cpp=.d)
|
||||
endif
|
||||
|
||||
1112
shared_modules/doctest.py
Normal file
1112
shared_modules/doctest.py
Normal file
File diff suppressed because it is too large
Load Diff
41
shared_modules/m1.cpp
Normal file
41
shared_modules/m1.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#include "boost/python/module_builder.hpp"
|
||||
#include "boost/python/class_builder.hpp"
|
||||
#include "shared.hpp"
|
||||
#include "Python.h"
|
||||
|
||||
struct M1 : Shared
|
||||
{
|
||||
char const * name() const { return "M1"; }
|
||||
};
|
||||
|
||||
namespace py = boost::python;
|
||||
|
||||
char const * test(Shared const & m)
|
||||
{
|
||||
return m.name();
|
||||
}
|
||||
|
||||
extern "C" void initm1()
|
||||
{
|
||||
try {
|
||||
py::module_builder m1("m1");
|
||||
|
||||
|
||||
py::class_builder<M1> m1_class(m1, "M1");
|
||||
m1_class.def(py::constructor<>());
|
||||
|
||||
try {
|
||||
m1_class.declare_base(py::type<Shared>());
|
||||
}
|
||||
catch(std::runtime_error & )
|
||||
{
|
||||
throw std::runtime_error("You must load module `shared' before module `m1'");
|
||||
}
|
||||
|
||||
m1.def(&test, "test");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
py::handle_exception();
|
||||
}
|
||||
}
|
||||
31
shared_modules/m2.cpp
Normal file
31
shared_modules/m2.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "boost/python/module_builder.hpp"
|
||||
#include "boost/python/class_builder.hpp"
|
||||
#include "shared.hpp"
|
||||
|
||||
struct M2 : Shared
|
||||
{
|
||||
char const * name() const { return "M2"; }
|
||||
};
|
||||
|
||||
namespace py = boost::python;
|
||||
|
||||
extern "C" void initm2()
|
||||
{
|
||||
try {
|
||||
py::module_builder m2("m2");
|
||||
|
||||
py::class_builder<M2> m2_class(m2, "M2");
|
||||
m2_class.def(py::constructor<>());
|
||||
try {
|
||||
m2_class.declare_base(py::type<Shared>());
|
||||
}
|
||||
catch(std::runtime_error & )
|
||||
{
|
||||
throw std::runtime_error("You must load module `shared' before module `m2'");
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
py::handle_exception();
|
||||
}
|
||||
}
|
||||
25
shared_modules/shared.cpp
Normal file
25
shared_modules/shared.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "boost/python/module_builder.hpp"
|
||||
#include "boost/python/class_builder.hpp"
|
||||
#include "shared.hpp"
|
||||
|
||||
namespace py = boost::python;
|
||||
|
||||
char const * test(Shared const & m)
|
||||
{
|
||||
return m.name();
|
||||
}
|
||||
|
||||
extern "C" void initshared()
|
||||
{
|
||||
try {
|
||||
py::module_builder shared("shared");
|
||||
py::class_builder<Shared> shared_class(shared, "Shared");
|
||||
shared_class.def(py::constructor<>());
|
||||
shared_class.def(&Shared::name, "name");
|
||||
shared.def(&test, "test");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
py::handle_exception();
|
||||
}
|
||||
}
|
||||
19
shared_modules/shared.hpp
Normal file
19
shared_modules/shared.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef SHARED_HPP
|
||||
#define SHARED_HPP
|
||||
|
||||
#include "boost/python/module_builder.hpp"
|
||||
#include "boost/python/class_builder.hpp"
|
||||
|
||||
struct Shared
|
||||
{
|
||||
virtual char const * name() const { return "Shared"; }
|
||||
};
|
||||
|
||||
|
||||
char const * test(Shared const & m);
|
||||
|
||||
struct DefineFromPythonForShared
|
||||
: python_extension_class_converters<Shared>
|
||||
{};
|
||||
|
||||
#endif /* SHARED_HPP */
|
||||
40
shared_modules/shared_modules.py
Normal file
40
shared_modules/shared_modules.py
Normal file
@@ -0,0 +1,40 @@
|
||||
r'''
|
||||
>>> import shared
|
||||
>>> import m1
|
||||
>>> import m2
|
||||
>>> ls = shared.Shared()
|
||||
>>> ls.name()
|
||||
'Shared'
|
||||
>>> l1 = m1.M1()
|
||||
>>> l1.name()
|
||||
'M1'
|
||||
>>> l2 = m2.M2()
|
||||
>>> l2.name()
|
||||
'M2'
|
||||
>>> shared.test(ls)
|
||||
'Shared'
|
||||
>>> shared.test(l1)
|
||||
'M1'
|
||||
>>> shared.test(l2)
|
||||
'M2'
|
||||
>>>
|
||||
>>> m1.test(ls)
|
||||
'Shared'
|
||||
>>> m1.test(l1)
|
||||
'M1'
|
||||
>>> m1.test(l2)
|
||||
'M2'
|
||||
'''
|
||||
|
||||
import string
|
||||
import re
|
||||
import sys
|
||||
|
||||
def run(args = None):
|
||||
if args is not None:
|
||||
sys.argv = args
|
||||
import doctest, shared_modules
|
||||
doctest.testmod(shared_modules)
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
@@ -26,6 +26,7 @@ def gen_extclass(args):
|
||||
# include <memory>
|
||||
# include <boost/python/detail/init_function.hpp>
|
||||
# include <typeinfo>
|
||||
# include <stdexcept>
|
||||
# include <boost/smart_ptr.hpp>
|
||||
|
||||
namespace boost { namespace python {
|
||||
@@ -492,9 +493,15 @@ class extension_class
|
||||
|
||||
// declare the given class a base class of this one and register
|
||||
// up and down conversion functions
|
||||
template <class S, class V>
|
||||
void declare_base(extension_class<S, V>* base)
|
||||
template <class S>
|
||||
void declare_base(type<S>)
|
||||
{
|
||||
extension_class_base * base = class_registry<S>::class_object();
|
||||
|
||||
if(base == 0)
|
||||
throw std::runtime_error(
|
||||
"extension_class::declare_base(type<S>): base undefined.");
|
||||
|
||||
// see extclass.cpp for an explanation of why we need to register
|
||||
// conversion functions
|
||||
base_class_info baseInfo(base,
|
||||
@@ -506,12 +513,19 @@ class extension_class
|
||||
&define_conversion<T, S>::upcast_ptr);
|
||||
class_registry<S>::register_derived_class(derivedInfo);
|
||||
}
|
||||
|
||||
|
||||
// declare the given class a base class of this one and register
|
||||
// only up conversion function
|
||||
template <class S, class V>
|
||||
void declare_base(extension_class<S, V>* base, without_downcast_t)
|
||||
template <class S>
|
||||
void declare_base(type<S>, without_downcast_t)
|
||||
{
|
||||
extension_class_base * base = class_registry<S>::class_object();
|
||||
|
||||
if(base == 0)
|
||||
throw std::runtime_error(
|
||||
"extension_class::declare_base(type<S>, without_downcast_t): base undefined.");
|
||||
|
||||
// see extclass.cpp for an explanation of why we need to register
|
||||
// conversion functions
|
||||
base_class_info baseInfo(base, 0);
|
||||
@@ -522,7 +536,6 @@ class extension_class
|
||||
&define_conversion<T, S>::upcast_ptr);
|
||||
class_registry<S>::register_derived_class(derivedInfo);
|
||||
}
|
||||
|
||||
private: // types
|
||||
typedef instance_value_holder<T,U> holder;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ module_builder::module_builder(const char* name)
|
||||
: m_module(Py_InitModule(const_cast<char*>(name), initial_methods))
|
||||
{
|
||||
// If this fails, you've created more than 1 module_builder object in your module
|
||||
assert(name_holder.get() == 0);
|
||||
// assert(name_holder.get() == 0);
|
||||
name_holder = ref(PyObject_GetAttrString(m_module, const_cast<char*>("__name__")));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user