2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-20 16:52:15 +00:00

Compare commits

...

3 Commits

Author SHA1 Message Date
Ullrich Köthe
9374bca9a0 improved error reporting
[SVN r8400]
2000-12-08 00:56:11 +00:00
Ullrich Köthe
922525faa0 added support for sharing of extension_classes across modules
[SVN r8399]
2000-12-08 00:06:18 +00:00
nobody
c1e69eecff This commit was manufactured by cvs2svn to create branch
'shared_modules'.

[SVN r8376]
2000-12-01 02:27:07 +00:00
12 changed files with 1357 additions and 15 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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
View 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

File diff suppressed because it is too large Load Diff

41
shared_modules/m1.cpp Normal file
View 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
View 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
View 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
View 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 */

View 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()

View File

@@ -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;

View File

@@ -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__")));
}