mirror of
https://github.com/boostorg/python.git
synced 2026-01-22 05:22:45 +00:00
added more test
changed some function names [SVN r7972]
This commit is contained in:
26
extclass.cpp
26
extclass.cpp
@@ -220,35 +220,35 @@ ExtensionClassBase::ExtensionClassBase(const char* name)
|
||||
|
||||
void * ExtensionClassBase::try_class_conversions(InstanceHolderBase * object) const
|
||||
{
|
||||
void * result = try_sub_class_conversions(object);
|
||||
void * result = try_subclass_conversions(object);
|
||||
if(result) return result;
|
||||
result = try_super_class_conversions(object);
|
||||
result = try_superclass_conversions(object);
|
||||
return result;
|
||||
}
|
||||
|
||||
void * ExtensionClassBase::try_super_class_conversions(InstanceHolderBase * object) const
|
||||
void * ExtensionClassBase::try_superclass_conversions(InstanceHolderBase * object) const
|
||||
{
|
||||
void * result = 0;
|
||||
for(int i=0; i<base_classes().size(); ++i)
|
||||
{
|
||||
if(base_classes()[i].second == 0) continue;
|
||||
result = base_classes()[i].first->convert_from_holder(object);
|
||||
if(result) return (*base_classes()[i].second)(result);
|
||||
result = base_classes()[i].first->try_super_class_conversions(object);
|
||||
if(result) return (*base_classes()[i].second)(result);
|
||||
if(base_classes()[i].convert == 0) continue;
|
||||
result = base_classes()[i].class_object->convert_from_holder(object);
|
||||
if(result) return (*base_classes()[i].convert)(result);
|
||||
result = base_classes()[i].class_object->try_superclass_conversions(object);
|
||||
if(result) return (*base_classes()[i].convert)(result);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void * ExtensionClassBase::try_sub_class_conversions(InstanceHolderBase * object) const
|
||||
void * ExtensionClassBase::try_subclass_conversions(InstanceHolderBase * object) const
|
||||
{
|
||||
void * result = 0;
|
||||
for(int i=0; i<sub_classes().size(); ++i)
|
||||
{
|
||||
result = sub_classes()[i].first->convert_from_holder(object);
|
||||
if(result) return (*sub_classes()[i].second)(result);
|
||||
result = sub_classes()[i].first->try_sub_class_conversions(object);
|
||||
if(result) return (*sub_classes()[i].second)(result);
|
||||
result = sub_classes()[i].class_object->convert_from_holder(object);
|
||||
if(result) return (*sub_classes()[i].convert)(result);
|
||||
result = sub_classes()[i].class_object->try_subclass_conversions(object);
|
||||
if(result) return (*sub_classes()[i].convert)(result);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
17
extclass.h
17
extclass.h
@@ -53,8 +53,17 @@ T* check_non_null(T* p)
|
||||
|
||||
template <class T> class HeldInstance;
|
||||
typedef void * (*ConversionFct)(void *);
|
||||
typedef std::pair<TypeObjectBase *, ConversionFct> BaseClassInfo;
|
||||
typedef std::pair<TypeObjectBase *, ConversionFct> SubClassInfo;
|
||||
|
||||
struct BaseClassInfo
|
||||
{
|
||||
BaseClassInfo(TypeObjectBase * t, ConversionFct f)
|
||||
:class_object(t), convert(f)
|
||||
{}
|
||||
|
||||
TypeObjectBase *class_object;
|
||||
ConversionFct convert;
|
||||
};
|
||||
typedef BaseClassInfo SubClassInfo;
|
||||
|
||||
class ExtensionClassBase : public Class<ExtensionInstance>
|
||||
{
|
||||
@@ -71,8 +80,8 @@ class ExtensionClassBase : public Class<ExtensionInstance>
|
||||
void add_getter_method(Function*, const char* name);
|
||||
|
||||
virtual void * try_class_conversions(InstanceHolderBase*) const;
|
||||
virtual void * try_super_class_conversions(InstanceHolderBase*) const;
|
||||
virtual void * try_sub_class_conversions(InstanceHolderBase*) const;
|
||||
virtual void * try_superclass_conversions(InstanceHolderBase*) const;
|
||||
virtual void * try_subclass_conversions(InstanceHolderBase*) const;
|
||||
virtual std::vector<BaseClassInfo> const & base_classes() const = 0;
|
||||
virtual std::vector<SubClassInfo> const & sub_classes() const = 0;
|
||||
};
|
||||
|
||||
@@ -363,10 +363,9 @@ static int getX(OverloadTest * u)
|
||||
return u->x();
|
||||
}
|
||||
|
||||
|
||||
/************************************************************/
|
||||
/* */
|
||||
/* classes to test base declarations snd conversions */
|
||||
/* classes to test base declarations and conversions */
|
||||
/* */
|
||||
/************************************************************/
|
||||
|
||||
@@ -425,6 +424,57 @@ static int testDowncast2(Derived2 * d)
|
||||
return d->x();
|
||||
}
|
||||
|
||||
/************************************************************/
|
||||
/* */
|
||||
/* test classes for interaction of overloading, */
|
||||
/* base declarations, and callbacks */
|
||||
/* */
|
||||
/************************************************************/
|
||||
|
||||
struct CallbackTestBase
|
||||
{
|
||||
virtual int testCallback(int i) { return callback(i); }
|
||||
virtual int callback(int i) = 0;
|
||||
};
|
||||
|
||||
struct CallbackTest : public CallbackTestBase
|
||||
{
|
||||
virtual int callback(int i) { return i + 1; }
|
||||
virtual std::string callbackString(std::string const & i) { return i + " 1"; }
|
||||
};
|
||||
|
||||
struct CallbackTestCallback : public CallbackTest
|
||||
{
|
||||
CallbackTestCallback(PyObject* self)
|
||||
: m_self(self)
|
||||
{}
|
||||
|
||||
int callback(int x)
|
||||
{
|
||||
return py::Callback<int>::call_method(m_self, "callback", x);
|
||||
}
|
||||
std::string callbackString(std::string const & x)
|
||||
{
|
||||
return py::Callback<std::string>::call_method(m_self, "callback", x);
|
||||
}
|
||||
|
||||
static int default_callback(CallbackTest * self, int x)
|
||||
{
|
||||
return self->CallbackTest::callback(x);
|
||||
}
|
||||
static std::string default_callbackString(CallbackTest * self, std::string x)
|
||||
{
|
||||
return self->CallbackTest::callbackString(x);
|
||||
}
|
||||
|
||||
PyObject * m_self;
|
||||
};
|
||||
|
||||
int testCallback(CallbackTestBase * b, int i)
|
||||
{
|
||||
return b->testCallback(i);
|
||||
}
|
||||
|
||||
/************************************************************/
|
||||
/* */
|
||||
/* init the module */
|
||||
@@ -472,7 +522,7 @@ void init_module(py::Module& m)
|
||||
m.def(&test5, "overloaded");
|
||||
|
||||
py::ClassWrapper<OverloadTest> over(m, "OverloadTest");
|
||||
over.def(py::Constructor<>());
|
||||
over.def(py::Constructor<py::Void>());
|
||||
over.def(py::Constructor<OverloadTest const &>());
|
||||
over.def(py::Constructor<int>());
|
||||
over.def(py::Constructor<int, int>());
|
||||
@@ -507,6 +557,19 @@ void init_module(py::Module& m)
|
||||
m.def(&derived2Factory, "derived2Factory");
|
||||
m.def(&testDowncast1, "testDowncast1");
|
||||
m.def(&testDowncast2, "testDowncast2");
|
||||
|
||||
py::ClassWrapper<CallbackTestBase> callbackTestBase(m, "CallbackTestBase");
|
||||
callbackTestBase.def(&CallbackTestBase::testCallback, "testCallback");
|
||||
m.def(&testCallback, "testCallback");
|
||||
|
||||
py::ClassWrapper<CallbackTest, CallbackTestCallback> callbackTest(m, "CallbackTest");
|
||||
callbackTest.def(py::Constructor<py::Void>());
|
||||
callbackTest.def(&CallbackTest::callback, "callback",
|
||||
&CallbackTestCallback::default_callback);
|
||||
callbackTest.def(&CallbackTest::callbackString, "callback",
|
||||
&CallbackTestCallback::default_callbackString);
|
||||
|
||||
callbackTest.declare_base(callbackTestBase);
|
||||
}
|
||||
|
||||
void init_module()
|
||||
|
||||
@@ -62,8 +62,8 @@ class TypeObjectBase : public PythonType
|
||||
virtual int instance_setattr(PyObject* instance, const char* name, PyObject* value) const;
|
||||
|
||||
virtual void * try_class_conversions(InstanceHolderBase*) const { return 0; }
|
||||
virtual void * try_super_class_conversions(InstanceHolderBase*) const { return 0; }
|
||||
virtual void * try_sub_class_conversions(InstanceHolderBase*) const { return 0; }
|
||||
virtual void * try_superclass_conversions(InstanceHolderBase*) const { return 0; }
|
||||
virtual void * try_subclass_conversions(InstanceHolderBase*) const { return 0; }
|
||||
virtual void * convert_from_holder(InstanceHolderBase*) const { return 0; }
|
||||
|
||||
// Dealloc is a special case, since every type needs a nonzero tp_dealloc slot.
|
||||
|
||||
@@ -512,6 +512,46 @@ Testing base class conversions
|
||||
>>> testDowncast2(der1)
|
||||
Traceback (innermost last):
|
||||
TypeError: extension class 'Base' is not convertible into 'Derived2'.
|
||||
|
||||
Testing interaction between callbacks, base declarations, and overloading
|
||||
- testCallback() calls callback() (within C++)
|
||||
- callback() is overloaded (in the wrapped class CallbackTest)
|
||||
- callback() is redefined in RedefineCallback (overloading is simulated by type casing)
|
||||
- testCallback() should use the redefined callback()
|
||||
|
||||
>>> c = CallbackTest()
|
||||
>>> c.testCallback(1)
|
||||
2
|
||||
>>> c.testCallback('foo')
|
||||
Traceback (innermost last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: illegal argument type for built-in operation
|
||||
>>> c.callback(1)
|
||||
2
|
||||
>>> c.callback('foo')
|
||||
'foo 1'
|
||||
|
||||
>>> import types
|
||||
>>> class RedefineCallback(CallbackTest):
|
||||
... def callback(self, x):
|
||||
... if type(x) is types.IntType:
|
||||
... return x - 2
|
||||
... else:
|
||||
... return CallbackTest.callback(self,x)
|
||||
...
|
||||
>>> r = RedefineCallback()
|
||||
>>> r.callback(1)
|
||||
-1
|
||||
>>> r.callback('foo')
|
||||
'foo 1'
|
||||
>>> r.testCallback('foo')
|
||||
Traceback (innermost last):
|
||||
File "<stdin>", line 1, in ?
|
||||
TypeError: illegal argument type for built-in operation
|
||||
>>> r.testCallback(1)
|
||||
-1
|
||||
>>> testCallback(r, 1)
|
||||
-1
|
||||
'''
|
||||
|
||||
from demo import *
|
||||
|
||||
Reference in New Issue
Block a user