2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-21 17:12:22 +00:00

Oops, previous check-in was into the wrong branch.

Rolling everything back.


[SVN r8312]
This commit is contained in:
Ullrich Köthe
2000-11-23 22:58:35 +00:00
parent ec4bc0382f
commit e668f3ce56
18 changed files with 1134 additions and 1153 deletions

1002
caller.h

File diff suppressed because it is too large Load Diff

View File

@@ -329,9 +329,9 @@ PyObject* read_only_setattr_function::do_call(PyObject* /*args*/, PyObject* /*ke
return 0;
}
PyObject* read_only_setattr_function::description() const
const char* read_only_setattr_function::description() const
{
return BOOST_PYTHON_CONVERSION::to_python("uncallable");
return "uncallable";
}
extension_class_base::extension_class_base(const char* name)
@@ -469,19 +469,6 @@ operator_dispatcher::create(const ref& object, const ref& self)
return result;
}
namespace {
void set_attribute_error(const char* oper, tuple args)
{
PyErr_Clear();
string message(oper);
message += argument_tuple_as_string(args);
message += " undefined.";
PyErr_SetObject(PyExc_TypeError, message.get());
}
} // anonymous namespace
extern "C"
{
@@ -511,7 +498,7 @@ int operator_dispatcher_coerce(PyObject** l, PyObject** r)
#define PY_DEFINE_OPERATOR(id, symbol) \
PyObject* operator_dispatcher_call_##id(PyObject* left, PyObject* right) \
PyObject* operator_dispatcher_call_##id(PyObject* left, PyObject* right) \
{ \
/* unwrap the arguments from their OperatorDispatcher */ \
PyObject* self; \
@@ -519,20 +506,17 @@ int operator_dispatcher_coerce(PyObject** l, PyObject** r)
int reverse = unwrap_args(left, right, self, other); \
if (reverse == unwrap_exception_code) \
return 0; \
const char * oper = reverse \
? "__r" #id "__" \
: "__" #id "__"; \
\
/* call the function */ \
PyObject* result = \
PyEval_CallMethod(self, \
const_cast<char*>(oper), \
const_cast<char*>(reverse ? "__r" #id "__" : "__" #id "__"), \
const_cast<char*>("(O)"), \
other); \
if (result == 0 && PyErr_GivenExceptionMatches(PyErr_Occurred(), PyExc_AttributeError)) \
{ \
tuple args(ref(self, ref::increment_count), ref(other, ref::increment_count)); \
set_attribute_error(oper , args); \
PyErr_Clear(); \
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for " #symbol); \
} \
return result; \
}
@@ -578,34 +562,24 @@ PyObject* operator_dispatcher_call_pow(PyObject* left, PyObject* right, PyObject
if (reverse == unwrap_exception_code)
return 0;
const char * oper = (reverse == 0)
? "__pow__"
: (reverse == 1)
? "__rpow__"
: "__rrpow__";
// call the function
PyObject* result =
PyEval_CallMethod(self,
const_cast<char*>(oper),
const_cast<char*>((reverse == 0)
? "__pow__"
: (reverse == 1)
? "__rpow__"
: "__rrpow__"),
const_cast<char*>("(OO)"),
first, second);
if (result == 0 && PyErr_GivenExceptionMatches(PyErr_Occurred(), PyExc_AttributeError))
{
if(m == Py_None)
{
tuple args(ref(self, ref::increment_count), ref(first, ref::increment_count));
set_attribute_error(oper , args);
}
else
{
tuple args(ref(self, ref::increment_count),
ref(first, ref::increment_count),
ref(second, ref::increment_count));
set_attribute_error(oper , args);
}
}
if (result == 0 &&
(PyErr_GivenExceptionMatches(PyErr_Occurred(), PyExc_TypeError) ||
PyErr_GivenExceptionMatches(PyErr_Occurred(), PyExc_AttributeError)))
{
PyErr_Clear();
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for pow()");
}
return result;
}
@@ -618,23 +592,16 @@ int operator_dispatcher_call_cmp(PyObject* left, PyObject* right)
if (reverse == unwrap_exception_code)
return -1;
const char * oper = reverse
? "__rcmp__"
: "__cmp__";
// call the function
PyObject* result =
PyEval_CallMethod(self,
const_cast<char*>(oper),
const_cast<char*>(reverse ? "__rcmp__" : "__cmp__"),
const_cast<char*>("(O)"),
other);
if (result == 0 && PyErr_GivenExceptionMatches(PyErr_Occurred(), PyExc_AttributeError))
{
tuple args(ref(self, ref::increment_count), ref(other, ref::increment_count));
set_attribute_error(oper , args);
}
if (result == 0)
{
PyErr_Clear();
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for cmp() or <");
return -1;
}
else

View File

@@ -133,39 +133,6 @@ class class_registry
static std::vector<derived_class_info> static_derived_class_info;
};
template <class T, class H>
no_t* is_plain_aux(type<instance_value_holder<T, H> >);
template <class T, class H>
string forward_python_type_name(python::type<instance_value_holder<T, H> >)
{
static const bool is_plain = BOOST_PYTHON_IS_PLAIN(T);
return python_type_name_selector<is_plain>::get(python::type<T>());
}
template <class T, class H>
no_t* is_plain_aux(type<instance_ptr_holder<T, H> >);
template <class T, class H>
string forward_python_type_name(python::type<instance_ptr_holder<T, H> >)
{
static const bool is_plain = BOOST_PYTHON_IS_PLAIN(T);
return python_type_name_selector<is_plain>::get(python::type<T>());
}
template <class T>
string python_type_name(type<T>)
{
if(class_registry<T>::class_object() == 0)
{
return string("UnknownType");
}
else
{
return class_registry<T>::class_object()->complete_class_name();
}
}
}} // namespace python::detail
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
@@ -347,9 +314,7 @@ class read_only_setattr_function : public function
public:
read_only_setattr_function(const char* name);
PyObject* do_call(PyObject* args, PyObject* keywords) const;
PyObject* description() const;
string function_name() const
{ return m_name; }
const char* description() const;
private:
string m_name;
};
@@ -463,7 +428,7 @@ class extension_class
template <class Fn>
inline void def_raw(Fn fn, const char* name)
{
this->add_method(new_raw_arguments_function(fn, name), name);
this->add_method(new_raw_arguments_function(fn), name);
}
// define member functions. In fact this works for free functions, too -
@@ -473,7 +438,7 @@ class extension_class
template <class Fn>
inline void def(Fn fn, const char* name)
{
this->add_method(new_wrapped_function(fn, name), name);
this->add_method(new_wrapped_function(fn), name);
}
// Define a virtual member function with a default implementation.
@@ -482,7 +447,7 @@ class extension_class
template <class Fn, class DefaultFn>
inline void def(Fn fn, const char* name, DefaultFn default_fn)
{
this->add_method(new_virtual_function(type<T>(), fn, default_fn, name), name);
this->add_method(new_virtual_function(type<T>(), fn, default_fn), name);
}
// Provide a function which implements x.<name>, reading from the given
@@ -490,7 +455,7 @@ class extension_class
template <class MemberType>
inline void def_getter(MemberType T::*pm, const char* name)
{
this->add_getter_method(new getter_function<T, MemberType>(pm, name), name);
this->add_getter_method(new getter_function<T, MemberType>(pm), name);
}
// Provide a function which implements assignment to x.<name>, writing to
@@ -498,7 +463,7 @@ class extension_class
template <class MemberType>
inline void def_setter(MemberType T::*pm, const char* name)
{
this->add_setter_method(new setter_function<T, MemberType>(pm, name), name);
this->add_setter_method(new setter_function<T, MemberType>(pm), name);
}
// Expose the given member (pm) of the T obj as a read-only attribute

View File

@@ -11,35 +11,13 @@
#include "singleton.h"
#include "objects.h"
#include "errors.h"
#include "extclass.h"
namespace python { namespace detail {
string argument_tuple_as_string(tuple arguments)
{
string result("(");
for (std::size_t i = 0; i < arguments.size(); ++i)
{
if (i != 0)
result += ", ";
if(arguments[i]->ob_type->ob_type == extension_meta_class())
{
result += downcast<class_base>(arguments[i]->ob_type).get()->complete_class_name();
}
else
{
result += arguments[i]->ob_type->tp_name;
}
}
result += ")";
return result;
}
struct function::type_object :
singleton<function::type_object, getattrable<callable<python::detail::type_object<function> > > >
singleton<function::type_object, callable<python::detail::type_object<function> > >
{
type_object() : singleton_base(&PyType_Type)
{}
type_object() : singleton_base(&PyType_Type) {}
};
@@ -78,38 +56,6 @@ function::function()
{
}
PyObject* function::getattr(const char * name) const
{
if(strcmp(name, "__signatures__") == 0)
{
list signatures;
for (const function* f = this; f != 0; f = f->m_overloads.get())
{
signatures.push_back(f->description());
}
return signatures.reference().release();
}
else if(strcmp(name, "__name__") == 0)
{
return function_name().reference().release();
}
else if(strcmp(name, "__dict__") == 0)
{
dictionary items;
items.set_item(string("__name__"), detail::none());
items.set_item(string("__signatures__"), detail::none());
return items.reference().release();
}
else
{
PyErr_SetString(PyExc_AttributeError, name);
return 0;
}
}
PyObject* function::call(PyObject* args, PyObject* keywords) const
{
for (const function* f = this; f != 0; f = f->m_overloads.get())
@@ -123,26 +69,6 @@ PyObject* function::call(PyObject* args, PyObject* keywords) const
}
catch(const argument_error&)
{
if(m_overloads.get() == 0 && rephrase_argument_error() &&
PyErr_GivenExceptionMatches(PyErr_Occurred(), PyExc_TypeError))
{
PyErr_Clear();
string message("");
string name(this->function_name());
if(name.size() != 0)
{
message += "'";
message += name;
message += "' ";
}
message += "expected argument(s) ";
message += description_as_string();
message += ",\nbut got ";
tuple arguments(ref(args, ref::increment_count));
message += argument_types_as_string(arguments);
message += " instead.";
PyErr_SetObject(PyExc_TypeError, message.get());
}
}
}
@@ -150,52 +76,27 @@ PyObject* function::call(PyObject* args, PyObject* keywords) const
return 0;
PyErr_Clear();
string message("No variant of overloaded function");
string name(this->function_name());
if(name.size() != 0)
{
message += " '";
message += name;
message += "'";
}
message += " matches argument(s):\n";
string message("No overloaded functions match (");
tuple arguments(ref(args, ref::increment_count));
message += argument_types_as_string(arguments);
for (std::size_t i = 0; i < arguments.size(); ++i)
{
if (i != 0)
message += ", ";
message += arguments[i]->ob_type->tp_name;
}
message += "\nCandidates are:\n";
message += "). Candidates are:\n";
for (const function* f1 = this; f1 != 0; f1 = f1->m_overloads.get())
{
if (f1 != this)
message += "\n";
message += f1->description_as_string();
message += f1->description();
}
PyErr_SetObject(PyExc_TypeError, message.get());
return 0;
}
string function::description_as_string() const
{
string result("(");
tuple arguments(ref(this->description()));
for (std::size_t i = 0; i < arguments.size(); ++i)
{
if (i != 0)
result += ", ";
result += string(arguments[i]);
}
result += ")";
return result;
}
string function::argument_types_as_string(tuple arguments) const
{
return argument_tuple_as_string(arguments);
}
bound_function* bound_function::create(const ref& target, const ref& fn)
{
bound_function* const result = free_list;

View File

@@ -25,8 +25,6 @@ namespace python { namespace detail {
// forward declaration
class extension_instance;
string argument_tuple_as_string(tuple args);
// function --
// the common base class for all overloadable function and method objects
@@ -40,36 +38,17 @@ class function : public python_object
virtual ~function() {}
PyObject* call(PyObject* args, PyObject* keywords) const;
PyObject* getattr(const char * name) const;
static void add_to_namespace(reference<function> f, const char* name, PyObject* dict);
protected:
virtual PyObject* description() const = 0;
private:
virtual PyObject* do_call(PyObject* args, PyObject* keywords) const = 0;
virtual string description_as_string() const;
virtual string argument_types_as_string(tuple args) const;
virtual string function_name() const = 0;
virtual bool rephrase_argument_error() const
{ return true; }
virtual const char* description() const = 0;
private:
struct type_object;
private:
reference<function> m_overloads;
};
struct named_function : function
{
named_function(const char * name)
: m_name(name)
{}
string function_name() const
{ return m_name; }
string m_name;
};
// wrapped_function_pointer<> --
// A single function or member function pointer wrapped and presented to
// Python as a callable object.
@@ -78,19 +57,19 @@ struct named_function : function
// R - the return type of the function pointer
// F - the complete type of the wrapped function pointer
template <class R, class F>
struct wrapped_function_pointer : named_function
struct wrapped_function_pointer : function
{
typedef F ptr_fun; // pointer-to--function or pointer-to-member-function
wrapped_function_pointer(ptr_fun pf, const char * name)
: named_function(name), m_pf(pf) {}
wrapped_function_pointer(ptr_fun pf)
: m_pf(pf) {}
private:
PyObject* do_call(PyObject* args, PyObject* keywords) const
{ return caller<R>::call(m_pf, args, keywords); }
PyObject* description() const
{ return function_signature(m_pf); }
const char* description() const
{ return typeid(F).name(); }
private:
const ptr_fun m_pf;
@@ -101,15 +80,15 @@ struct wrapped_function_pointer : named_function
// verbatim to C++ (useful for customized argument parsing and variable
// argument lists)
template <class Ret, class Args, class Keywords>
struct raw_arguments_function : named_function
struct raw_arguments_function : function
{
typedef Ret (*ptr_fun)(Args, Keywords);
raw_arguments_function(ptr_fun pf, const char * name)
: named_function(name), m_pf(pf) {}
raw_arguments_function(ptr_fun pf)
: m_pf(pf) {}
private:
PyObject* do_call(PyObject* args, PyObject* keywords) const
PyObject* do_call(PyObject* args, PyObject* keywords) const
{
ref dict(keywords ?
ref(keywords, ref::increment_count) :
@@ -120,17 +99,9 @@ struct raw_arguments_function : named_function
from_python(dict.get(), python::type<Keywords>())));
}
PyObject* description() const
{
tuple result(1);
result.set_item(0, string("..."));
return result.reference().release();
}
const char* description() const
{ return typeid(ptr_fun).name(); }
virtual bool rephrase_argument_error() const
{ return false; }
private:
const ptr_fun m_pf;
};
@@ -148,20 +119,19 @@ struct raw_arguments_function : named_function
// parameter and calls T::f on it /non-virtually/, where V
// approximates &T::f.
template <class T, class R, class V, class D>
class virtual_function : public named_function
class virtual_function : public function
{
public:
virtual_function(V virtual_function_ptr, D default_implementation, const char * name)
: named_function(name),
m_virtual_function_ptr(virtual_function_ptr),
virtual_function(V virtual_function_ptr, D default_implementation)
: m_virtual_function_ptr(virtual_function_ptr),
m_default_implementation(default_implementation)
{}
private:
PyObject* do_call(PyObject* args, PyObject* keywords) const;
PyObject* description() const
{ return function_signature(m_virtual_function_ptr); }
const char* description() const
{ return typeid(V).name(); }
private:
const V m_virtual_function_ptr;
@@ -172,26 +142,26 @@ class virtual_function : public named_function
// functionality once the return type has already been deduced. R is expected to
// be type<X>, where X is the actual return type of pmf.
template <class F, class R>
function* new_wrapped_function_aux(R, F pmf, const char * name)
function* new_wrapped_function_aux(R, F pmf)
{
// We can't just use "typename R::Type" below because MSVC (incorrectly) pukes.
typedef typename R::type return_type;
return new wrapped_function_pointer<return_type, F>(pmf, name);
return new wrapped_function_pointer<return_type, F>(pmf);
}
// Create and return a new member function object wrapping the given
// pointer-to-member function
template <class F>
inline function* new_wrapped_function(F pmf, const char * name)
inline function* new_wrapped_function(F pmf)
{
// Deduce the return type and pass it off to the helper function above
return new_wrapped_function_aux(return_value(pmf), pmf, name);
return new_wrapped_function_aux(return_value(pmf), pmf);
}
template <class R, class Args, class keywords>
function* new_raw_arguments_function(R (*pmf)(Args, keywords), const char * name)
function* new_raw_arguments_function(R (*pmf)(Args, keywords))
{
return new raw_arguments_function<R, Args, keywords>(pmf, name);
return new raw_arguments_function<R, Args, keywords>(pmf);
}
@@ -200,26 +170,26 @@ function* new_raw_arguments_function(R (*pmf)(Args, keywords), const char * name
// be type<X>, where X is the actual return type of V.
template <class T, class R, class V, class D>
inline function* new_virtual_function_aux(
type<T>, R, V virtual_function_ptr, D default_implementation,
const char * name)
type<T>, R, V virtual_function_ptr, D default_implementation
)
{
// We can't just use "typename R::Type" below because MSVC (incorrectly) pukes.
typedef typename R::type return_type;
return new virtual_function<T, return_type, V, D>(
virtual_function_ptr, default_implementation, name);
virtual_function_ptr, default_implementation);
}
// Create and return a new virtual_function object wrapping the given
// virtual_function_ptr and default_implementation
template <class T, class V, class D>
inline function* new_virtual_function(
type<T>, V virtual_function_ptr, D default_implementation,
const char * name)
type<T>, V virtual_function_ptr, D default_implementation
)
{
// Deduce the return type and pass it off to the helper function above
return new_virtual_function_aux(
type<T>(), return_value(virtual_function_ptr),
virtual_function_ptr, default_implementation, name);
virtual_function_ptr, default_implementation);
}
// A function with a bundled "bound target" object. This is what is produced by
@@ -250,37 +220,37 @@ class bound_function : public python_object
// Special functions designed to access data members of a wrapped C++ object.
template <class ClassType, class MemberType>
class getter_function : public named_function
class getter_function : public function
{
public:
typedef MemberType ClassType::* pointer_to_member;
getter_function(pointer_to_member pm, const char * name)
: named_function(name), m_pm(pm) {}
getter_function(pointer_to_member pm)
: m_pm(pm) {}
private:
PyObject* do_call(PyObject* args, PyObject* keywords) const;
PyObject* description() const
{ return function_signature((MemberType (*)(const ClassType&))0); }
const char* description() const
{ return typeid(MemberType (*)(const ClassType&)).name(); }
private:
pointer_to_member m_pm;
};
template <class ClassType, class MemberType>
class setter_function : public named_function
class setter_function : public function
{
public:
typedef MemberType ClassType::* pointer_to_member;
setter_function(pointer_to_member pm, const char * name)
: named_function(name), m_pm(pm) {}
setter_function(pointer_to_member pm)
: m_pm(pm) {}
private:
PyObject* do_call(PyObject* args, PyObject* keywords) const;
PyObject* description() const
{ return function_signature((void (*)(const ClassType&, const MemberType&))0); }
const char* description() const
{ return typeid(void (*)(const ClassType&, const MemberType&)).name(); }
private:
pointer_to_member m_pm;
};

View File

@@ -31,7 +31,6 @@ body_sections = (
# include <boost/config.hpp>
# include "signatures.h"
# include "none.h"
# include "objects.h"
namespace python {
@@ -57,25 +56,9 @@ struct caller<void>
''',
'''};
namespace detail
{
// create signature tuples
inline''',
'''
// member functions
''',
'''
// const member functions
''',
'''
// free functions
''',
'''} // namespace detail
}
} // namespace python
#endif // CALLER_DWA05090_H_
#endif
''')
#'
@@ -104,34 +87,6 @@ free_function = '''%{ template <%(class A%n%:, %)>
'''
function_signature = '''%{template <%}%(class A%n%:, %)%{>%}
PyObject* function_signature(%(type<A%n>%:, %)) {
%( static const bool is_plain_A%n = BOOST_PYTHON_IS_PLAIN(A%n);
%) tuple result(%x);
%( result.set_item(%N, python_type_name_selector<is_plain_A%n>::get(type<A%n>()));
%)
return result.reference().release();
}
'''
member_function_signature = '''template <class R, class T%(, class A%n%)>
inline PyObject* function_signature(R (T::*pmf)(%(A%n%:, %))%1) {
return function_signature(
python::type<T>()%(,
python::type<A%n>()%));
}
'''
free_function_signature = '''template <class R%(, class A%n%)>
inline PyObject* function_signature(R (*f)(%(A%n%:, %))) {
return function_signature(%(
python::type<A%n>()%:,%));
}
'''
def gen_caller(member_function_args, free_function_args = None):
if free_function_args is None:
free_function_args = member_function_args + 1
@@ -163,16 +118,6 @@ def gen_caller(member_function_args, free_function_args = None):
+ gen_functions(free_function, free_function_args,
'void', '', return_none)
+ body_sections[6]
# create lists describing the function signatures
+ gen_functions(function_signature, free_function_args)
+ body_sections[7]
+ gen_functions(member_function_signature, member_function_args, '')
+ body_sections[8]
+ gen_functions(member_function_signature, member_function_args, ' const')
+ body_sections[9]
+ gen_functions(free_function_signature, free_function_args)
+ body_sections[10]
)
if __name__ == '__main__':

View File

@@ -138,39 +138,6 @@ class class_registry
static std::vector<derived_class_info> static_derived_class_info;
};
template <class T, class H>
no_t* is_plain_aux(type<instance_value_holder<T, H> >);
template <class T, class H>
string forward_python_type_name(python::type<instance_value_holder<T, H> >)
{
static const bool is_plain = BOOST_PYTHON_IS_PLAIN(T);
return python_type_name_selector<is_plain>::get(python::type<T>());
}
template <class T, class H>
no_t* is_plain_aux(type<instance_ptr_holder<T, H> >);
template <class T, class H>
string forward_python_type_name(python::type<instance_ptr_holder<T, H> >)
{
static const bool is_plain = BOOST_PYTHON_IS_PLAIN(T);
return python_type_name_selector<is_plain>::get(python::type<T>());
}
template <class T>
string python_type_name(type<T>)
{
if(class_registry<T>::class_object() == 0)
{
return string("UnknownType");
}
else
{
return class_registry<T>::class_object()->complete_class_name();
}
}
}} // namespace python::detail
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
@@ -352,9 +319,7 @@ class read_only_setattr_function : public function
public:
read_only_setattr_function(const char* name);
PyObject* do_call(PyObject* args, PyObject* keywords) const;
PyObject* description() const;
string function_name() const
{ return m_name; }
const char* description() const;
private:
string m_name;
};
@@ -468,7 +433,7 @@ class extension_class
template <class Fn>
inline void def_raw(Fn fn, const char* name)
{
this->add_method(new_raw_arguments_function(fn, name), name);
this->add_method(new_raw_arguments_function(fn), name);
}
// define member functions. In fact this works for free functions, too -
@@ -478,7 +443,7 @@ class extension_class
template <class Fn>
inline void def(Fn fn, const char* name)
{
this->add_method(new_wrapped_function(fn, name), name);
this->add_method(new_wrapped_function(fn), name);
}
// Define a virtual member function with a default implementation.
@@ -487,7 +452,7 @@ class extension_class
template <class Fn, class DefaultFn>
inline void def(Fn fn, const char* name, DefaultFn default_fn)
{
this->add_method(new_virtual_function(type<T>(), fn, default_fn, name), name);
this->add_method(new_virtual_function(type<T>(), fn, default_fn), name);
}
// Provide a function which implements x.<name>, reading from the given
@@ -495,7 +460,7 @@ class extension_class
template <class MemberType>
inline void def_getter(MemberType T::*pm, const char* name)
{
this->add_getter_method(new getter_function<T, MemberType>(pm, name), name);
this->add_getter_method(new getter_function<T, MemberType>(pm), name);
}
// Provide a function which implements assignment to x.<name>, writing to
@@ -503,7 +468,7 @@ class extension_class
template <class MemberType>
inline void def_setter(MemberType T::*pm, const char* name)
{
this->add_setter_method(new setter_function<T, MemberType>(pm, name), name);
this->add_setter_method(new setter_function<T, MemberType>(pm), name);
}
// Expose the given member (pm) of the T obj as a read-only attribute

View File

@@ -35,8 +35,6 @@ def _gen_arg(template, n, args, delimiter = '%'):
if key == 'n':
result = result + `n`
elif key == 'N':
result = result + `n-1`
else:
result = result + _gen_common_key(key, n, args)
@@ -57,13 +55,8 @@ def gen_function(template, n, *args, **keywords):
%n is transformed into the string representation of 1..n for each repetition
of n.
%N is transformed into the string representation of 0..(n-1) for each repetition
of n.
%i, where i is a digit, is transformed into the corresponding additional
%x, where x is a digit, is transformed into the corresponding additional
argument.
%x is transformed into the number of the current repetition
for example,

View File

@@ -130,8 +130,6 @@ private: // override function hook
PyObject* do_call(PyObject* args, PyObject* keywords) const;
private:
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* tail_args, PyObject* keywords) const = 0;
string description_as_string() const;
string argument_types_as_string(tuple args) const;
};
""" + gen_functions("""
@@ -147,20 +145,8 @@ struct init%x : init
python::detail::reference_parameter<A%n>(from_python(a%n, type<A%n>()))%)
);
}
PyObject* description() const
{
return function_signature(python::type<T>()%(,
python::type<A%n>()%));
}
string function_name() const
{
static const bool is_plain = BOOST_PYTHON_IS_PLAIN(T);
string result(python_type_name_selector<is_plain>::get(python::type<T>()));
result += ".__init__";
return result;
}
const char* description() const
{ return typeid(void (*)(T&%(, A%n%%))).name(); }
};""", args) + """
}} // namespace python::detail

View File

@@ -33,24 +33,4 @@ namespace python { namespace detail {
return none();
}
string init::description_as_string() const
{
tuple arguments(ref(this->description()));
string result("(");
for (std::size_t i = 1; i < arguments.size(); ++i)
{
if (i != 1)
result += ", ";
result += string(arguments[i]);
}
result += ")";
return result;
}
string init::argument_types_as_string(tuple arguments) const
{
return argument_tuple_as_string(arguments.slice(1,arguments.size()));
}
}} // namespace python::detail

View File

@@ -110,6 +110,11 @@ template <class T, class A1, class A2> struct init2;
template <class T, class A1, class A2, class A3> struct init3;
template <class T, class A1, class A2, class A3, class A4> struct init4;
template <class T, class A1, class A2, class A3, class A4, class A5> struct init5;
template <class T, class A1, class A2, class A3, class A4, class A5, class A6> struct Init6;
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7> struct Init7;
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> struct Init8;
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> struct Init9;
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10> struct Init10;
template <class T>
struct init_function
@@ -157,6 +162,71 @@ struct init_function
detail::parameter_traits<A4>::const_reference,
detail::parameter_traits<A5>::const_reference>;
}
template <class A1, class A2, class A3, class A4, class A5, class A6>
static init* create(signature6<A1, A2, A3, A4, A5, A6>) {
return new Init6<T,
detail::parameter_traits<A1>::const_reference,
detail::parameter_traits<A2>::const_reference,
detail::parameter_traits<A3>::const_reference,
detail::parameter_traits<A4>::const_reference,
detail::parameter_traits<A5>::const_reference,
detail::parameter_traits<A6>::const_reference>;
}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7>
static init* create(signature7<A1, A2, A3, A4, A5, A6, A7>) {
return new Init7<T,
detail::parameter_traits<A1>::const_reference,
detail::parameter_traits<A2>::const_reference,
detail::parameter_traits<A3>::const_reference,
detail::parameter_traits<A4>::const_reference,
detail::parameter_traits<A5>::const_reference,
detail::parameter_traits<A6>::const_reference,
detail::parameter_traits<A7>::const_reference>;
}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
static init* create(signature8<A1, A2, A3, A4, A5, A6, A7, A8>) {
return new Init8<T,
detail::parameter_traits<A1>::const_reference,
detail::parameter_traits<A2>::const_reference,
detail::parameter_traits<A3>::const_reference,
detail::parameter_traits<A4>::const_reference,
detail::parameter_traits<A5>::const_reference,
detail::parameter_traits<A6>::const_reference,
detail::parameter_traits<A7>::const_reference,
detail::parameter_traits<A8>::const_reference>;
}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
static init* create(signature9<A1, A2, A3, A4, A5, A6, A7, A8, A9>) {
return new Init9<T,
detail::parameter_traits<A1>::const_reference,
detail::parameter_traits<A2>::const_reference,
detail::parameter_traits<A3>::const_reference,
detail::parameter_traits<A4>::const_reference,
detail::parameter_traits<A5>::const_reference,
detail::parameter_traits<A6>::const_reference,
detail::parameter_traits<A7>::const_reference,
detail::parameter_traits<A8>::const_reference,
detail::parameter_traits<A9>::const_reference>;
}
template <class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
static init* create(signature10<A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>) {
return new Init10<T,
detail::parameter_traits<A1>::const_reference,
detail::parameter_traits<A2>::const_reference,
detail::parameter_traits<A3>::const_reference,
detail::parameter_traits<A4>::const_reference,
detail::parameter_traits<A5>::const_reference,
detail::parameter_traits<A6>::const_reference,
detail::parameter_traits<A7>::const_reference,
detail::parameter_traits<A8>::const_reference,
detail::parameter_traits<A9>::const_reference,
detail::parameter_traits<A10>::const_reference>;
}
};
class init : public function
@@ -165,8 +235,6 @@ private: // override function hook
PyObject* do_call(PyObject* args, PyObject* keywords) const;
private:
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* tail_args, PyObject* keywords) const = 0;
string description_as_string() const;
string argument_types_as_string(tuple args) const;
};
@@ -180,19 +248,8 @@ struct init0 : init
return new T(self
);
}
PyObject* description() const
{
return function_signature(python::type<T>());
}
string function_name() const
{
static const bool is_plain = BOOST_PYTHON_IS_PLAIN(T);
string result(python_type_name_selector<is_plain>::get(python::type<T>()));
result += ".__init__";
return result;
}
const char* description() const
{ return typeid(void (*)(T&)).name(); }
};
template <class T, class A1>
@@ -207,20 +264,8 @@ struct init1 : init
python::detail::reference_parameter<A1>(from_python(a1, type<A1>()))
);
}
PyObject* description() const
{
return function_signature(python::type<T>(),
python::type<A1>());
}
string function_name() const
{
static const bool is_plain = BOOST_PYTHON_IS_PLAIN(T);
string result(python_type_name_selector<is_plain>::get(python::type<T>()));
result += ".__init__";
return result;
}
const char* description() const
{ return typeid(void (*)(T&, A1)).name(); }
};
template <class T, class A1, class A2>
@@ -237,21 +282,8 @@ struct init2 : init
python::detail::reference_parameter<A2>(from_python(a2, type<A2>()))
);
}
PyObject* description() const
{
return function_signature(python::type<T>(),
python::type<A1>(),
python::type<A2>());
}
string function_name() const
{
static const bool is_plain = BOOST_PYTHON_IS_PLAIN(T);
string result(python_type_name_selector<is_plain>::get(python::type<T>()));
result += ".__init__";
return result;
}
const char* description() const
{ return typeid(void (*)(T&, A1, A2)).name(); }
};
template <class T, class A1, class A2, class A3>
@@ -270,22 +302,8 @@ struct init3 : init
python::detail::reference_parameter<A3>(from_python(a3, type<A3>()))
);
}
PyObject* description() const
{
return function_signature(python::type<T>(),
python::type<A1>(),
python::type<A2>(),
python::type<A3>());
}
string function_name() const
{
static const bool is_plain = BOOST_PYTHON_IS_PLAIN(T);
string result(python_type_name_selector<is_plain>::get(python::type<T>()));
result += ".__init__";
return result;
}
const char* description() const
{ return typeid(void (*)(T&, A1, A2, A3)).name(); }
};
template <class T, class A1, class A2, class A3, class A4>
@@ -306,23 +324,8 @@ struct init4 : init
python::detail::reference_parameter<A4>(from_python(a4, type<A4>()))
);
}
PyObject* description() const
{
return function_signature(python::type<T>(),
python::type<A1>(),
python::type<A2>(),
python::type<A3>(),
python::type<A4>());
}
string function_name() const
{
static const bool is_plain = BOOST_PYTHON_IS_PLAIN(T);
string result(python_type_name_selector<is_plain>::get(python::type<T>()));
result += ".__init__";
return result;
}
const char* description() const
{ return typeid(void (*)(T&, A1, A2, A3, A4)).name(); }
};
template <class T, class A1, class A2, class A3, class A4, class A5>
@@ -345,27 +348,160 @@ struct init5 : init
python::detail::reference_parameter<A5>(from_python(a5, type<A5>()))
);
}
PyObject* description() const
{
return function_signature(python::type<T>(),
python::type<A1>(),
python::type<A2>(),
python::type<A3>(),
python::type<A4>(),
python::type<A5>());
const char* description() const
{ return typeid(void (*)(T&, A1, A2, A3, A4, A5)).name(); }
};
template <class T, class A1, class A2, class A3, class A4, class A5, class A6>
struct Init6 : init
{
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
PyObject* a1;
PyObject* a2;
PyObject* a3;
PyObject* a4;
PyObject* a5;
PyObject* a6;
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6))
throw argument_error();
return new T(self,
python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
python::detail::reference_parameter<A3>(from_python(a3, type<A3>())),
python::detail::reference_parameter<A4>(from_python(a4, type<A4>())),
python::detail::reference_parameter<A5>(from_python(a5, type<A5>())),
python::detail::reference_parameter<A6>(from_python(a6, type<A6>()))
);
}
string function_name() const
{
static const bool is_plain = BOOST_PYTHON_IS_PLAIN(T);
string result(python_type_name_selector<is_plain>::get(python::type<T>()));
result += ".__init__";
return result;
const char* description() const
{ return typeid(void (*)(T&, A1, A2, A3, A4, A5, A6)).name(); }
};
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
struct Init7 : init
{
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
PyObject* a1;
PyObject* a2;
PyObject* a3;
PyObject* a4;
PyObject* a5;
PyObject* a6;
PyObject* a7;
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7))
throw argument_error();
return new T(self,
python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
python::detail::reference_parameter<A3>(from_python(a3, type<A3>())),
python::detail::reference_parameter<A4>(from_python(a4, type<A4>())),
python::detail::reference_parameter<A5>(from_python(a5, type<A5>())),
python::detail::reference_parameter<A6>(from_python(a6, type<A6>())),
python::detail::reference_parameter<A7>(from_python(a7, type<A7>()))
);
}
const char* description() const
{ return typeid(void (*)(T&, A1, A2, A3, A4, A5, A6, A7)).name(); }
};
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
struct Init8 : init
{
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
PyObject* a1;
PyObject* a2;
PyObject* a3;
PyObject* a4;
PyObject* a5;
PyObject* a6;
PyObject* a7;
PyObject* a8;
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8))
throw argument_error();
return new T(self,
python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
python::detail::reference_parameter<A3>(from_python(a3, type<A3>())),
python::detail::reference_parameter<A4>(from_python(a4, type<A4>())),
python::detail::reference_parameter<A5>(from_python(a5, type<A5>())),
python::detail::reference_parameter<A6>(from_python(a6, type<A6>())),
python::detail::reference_parameter<A7>(from_python(a7, type<A7>())),
python::detail::reference_parameter<A8>(from_python(a8, type<A8>()))
);
}
const char* description() const
{ return typeid(void (*)(T&, A1, A2, A3, A4, A5, A6, A7, A8)).name(); }
};
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
struct Init9 : init
{
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
PyObject* a1;
PyObject* a2;
PyObject* a3;
PyObject* a4;
PyObject* a5;
PyObject* a6;
PyObject* a7;
PyObject* a8;
PyObject* a9;
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9))
throw argument_error();
return new T(self,
python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
python::detail::reference_parameter<A3>(from_python(a3, type<A3>())),
python::detail::reference_parameter<A4>(from_python(a4, type<A4>())),
python::detail::reference_parameter<A5>(from_python(a5, type<A5>())),
python::detail::reference_parameter<A6>(from_python(a6, type<A6>())),
python::detail::reference_parameter<A7>(from_python(a7, type<A7>())),
python::detail::reference_parameter<A8>(from_python(a8, type<A8>())),
python::detail::reference_parameter<A9>(from_python(a9, type<A9>()))
);
}
const char* description() const
{ return typeid(void (*)(T&, A1, A2, A3, A4, A5, A6, A7, A8, A9)).name(); }
};
template <class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
struct Init10 : init
{
virtual instance_holder_base* create_holder(extension_instance* self, PyObject* args, PyObject* /*keywords*/) const
{
PyObject* a1;
PyObject* a2;
PyObject* a3;
PyObject* a4;
PyObject* a5;
PyObject* a6;
PyObject* a7;
PyObject* a8;
PyObject* a9;
PyObject* a10;
if (!PyArg_ParseTuple(args, const_cast<char*>("OOOOOOOOOO"), &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10))
throw argument_error();
return new T(self,
python::detail::reference_parameter<A1>(from_python(a1, type<A1>())),
python::detail::reference_parameter<A2>(from_python(a2, type<A2>())),
python::detail::reference_parameter<A3>(from_python(a3, type<A3>())),
python::detail::reference_parameter<A4>(from_python(a4, type<A4>())),
python::detail::reference_parameter<A5>(from_python(a5, type<A5>())),
python::detail::reference_parameter<A6>(from_python(a6, type<A6>())),
python::detail::reference_parameter<A7>(from_python(a7, type<A7>())),
python::detail::reference_parameter<A8>(from_python(a8, type<A8>())),
python::detail::reference_parameter<A9>(from_python(a9, type<A9>())),
python::detail::reference_parameter<A10>(from_python(a10, type<A10>()))
);
}
const char* description() const
{ return typeid(void (*)(T&, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)).name(); }
};
}} // namespace python::detail
#endif // INIT_FUNCTION_DWA052000_H_

View File

@@ -18,6 +18,8 @@ namespace python {
class module_builder
{
typedef PyObject * (*raw_function_ptr)(python::tuple const &, python::dictionary const &);
public:
// Create a module. REQUIRES: only one module_builder is created per module.
module_builder(const char* name);
@@ -30,13 +32,13 @@ class module_builder
template <class Fn>
void def_raw(Fn fn, const char* name)
{
add(detail::new_raw_arguments_function(fn, name), name);
add(detail::new_raw_arguments_function(fn), name);
}
template <class Fn>
void def(Fn fn, const char* name)
{
add(detail::new_wrapped_function(fn, name), name);
add(detail::new_wrapped_function(fn), name);
}
static string name();

146
objects.h
View File

@@ -293,152 +293,6 @@ struct list::slice_proxy
int m_low, m_high;
};
namespace detail
{
#define BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(T, name) \
inline string python_type_name(python::type<T >) \
{ return string(#name); }
#if 0
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(long, types.IntType);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(unsigned long, types.IntType);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(int, types.IntType);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(unsigned int, types.IntType);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(short, types.IntType);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(unsigned short, types.IntType);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(signed char, types.IntType);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(unsigned char, types.IntType);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(bool, types.IntType);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(float, types.FloatType);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(double, types.FloatType);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(void, types.NoneType);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(const char *, types.StringType);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(std::string, types.StringType);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(PyObject, AnyType);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(reference<PyObject>, AnyType);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(list, types.ListType);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(tuple, types.TupleType);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(dictionary, types.DictionaryType);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(string, types.StringType);
#endif /* #if 0 */
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(long, int);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(unsigned long, int);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(int, int);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(unsigned int, int);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(short, int);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(unsigned short, int);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(signed char, int);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(unsigned char, int);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(bool, int);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(float, float);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(double, float);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(void, None);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(const char *, string);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(std::string, string);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(PyObject, any);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(reference<PyObject>, any);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(list, list);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(tuple, tuple);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(dictionary, dictionary);
BOOST_PYTHON_OVERLOAD_TYPENAME_FUNCTION(string, string);
typedef char no_t[1];
typedef char yes_t[2];
yes_t* is_plain_aux(...);
template <class T>
no_t* is_plain_aux(type<T *>);
template <class T>
no_t* is_plain_aux(type<T const *>);
template <class T>
no_t* is_plain_aux(type<T &>);
template <class T>
no_t* is_plain_aux(type<T const &>);
template <class T>
no_t* is_plain_aux(type<std::auto_ptr<T> >);
template <class T>
no_t* is_plain_aux(type<boost::shared_ptr<T> >);
template <class T>
no_t* is_plain_aux(type<reference<T> >);
#define BOOST_PYTHON_IS_PLAIN(T) \
(sizeof(*python::detail::is_plain_aux(python::type<T>())) == \
sizeof(python::detail::yes_t))
template <bool is_plain>
struct python_type_name_selector
{
template <class T>
static string get(python::type<T> t)
{ return python_type_name(t); }
};
template <class T>
string forward_python_type_name(python::type<T&>)
{
static const bool is_plain = BOOST_PYTHON_IS_PLAIN(T);
return python_type_name_selector<is_plain>::get(python::type<T>());
}
template <class T>
string forward_python_type_name(python::type<const T&>)
{
static const bool is_plain = BOOST_PYTHON_IS_PLAIN(T);
return python_type_name_selector<is_plain>::get(python::type<T>());
}
template <class T>
string forward_python_type_name(python::type<T*>)
{
static const bool is_plain = BOOST_PYTHON_IS_PLAIN(T);
return python_type_name_selector<is_plain>::get(python::type<T>());
}
template <class T>
string forward_python_type_name(python::type<const T*>)
{
static const bool is_plain = BOOST_PYTHON_IS_PLAIN(T);
return python_type_name_selector<is_plain>::get(python::type<T>());
}
template <class T>
string forward_python_type_name(python::type<std::auto_ptr<T> >)
{
static const bool is_plain = BOOST_PYTHON_IS_PLAIN(T);
return python_type_name_selector<is_plain>::get(python::type<T>());
}
template <class T>
string forward_python_type_name(python::type<boost::shared_ptr<T> >)
{
static const bool is_plain = BOOST_PYTHON_IS_PLAIN(T);
return python_type_name_selector<is_plain>::get(python::type<T>());
}
template <class T>
string forward_python_type_name(python::type<reference<T> >)
{
static const bool is_plain = BOOST_PYTHON_IS_PLAIN(T);
return python_type_name_selector<is_plain>::get(python::type<T>());
}
template <>
struct python_type_name_selector<false>
{
template <class T>
static string get(python::type<T> t)
{ return forward_python_type_name(t); }
};
} // namespace detail
} // namespace python
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE

View File

@@ -197,7 +197,8 @@ namespace detail
};
};
// Fully specialize define_operator for all operators defined in operator_id above.
// Every specialization defines one function object for normal operator calls and one
// for operator calls with operands reversed ("__r*__" function variants).
@@ -213,20 +214,15 @@ namespace detail
{ \
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
{ \
tuple args(ref(arguments, ref::increment_count)); \
tuple args(ref(arguments, ref::increment_count)); \
\
return BOOST_PYTHON_CONVERSION::to_python( \
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), python::type<Left>()) oper \
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), python::type<Right>())); \
} \
\
string function_name() const \
{ return string(name()); } \
\
PyObject* description() const \
{ \
return function_signature(python::type<Left>(), python::type<Right>()); \
} \
const char* description() const \
{ return "__" #id "__"; } \
}; \
\
template <class Right, class Left> \
@@ -234,20 +230,15 @@ namespace detail
{ \
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
{ \
tuple args(ref(arguments, ref::increment_count)); \
tuple args(ref(arguments, ref::increment_count)); \
\
return BOOST_PYTHON_CONVERSION::to_python( \
return BOOST_PYTHON_CONVERSION::to_python( \
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), python::type<Left>()) oper \
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), python::type<Right>())); \
} \
\
string function_name() const \
{ return string(rname()); } \
\
PyObject* description() const \
{ \
return function_signature(python::type<Left>(), python::type<Right>()); \
} \
const char* description() const \
{ return "__r" #id "__"; } \
\
}; \
\
@@ -264,19 +255,14 @@ namespace detail
{ \
PyObject* do_call(PyObject* arguments, PyObject* /* keywords */) const \
{ \
tuple args(ref(arguments, ref::increment_count)); \
tuple args(ref(arguments, ref::increment_count)); \
\
return BOOST_PYTHON_CONVERSION::to_python( \
return BOOST_PYTHON_CONVERSION::to_python( \
oper(BOOST_PYTHON_CONVERSION::from_python(args[0].get(), python::type<operand>()))); \
} \
\
string function_name() const \
{ return string(name()); } \
\
PyObject* description() const \
{ \
return function_signature(python::type<operand>()); \
} \
const char* description() const \
{ return "__" #id "__"; } \
}; \
\
static const char * name() { return "__" #id "__"; } \
@@ -331,13 +317,8 @@ namespace detail
BOOST_PYTHON_CONVERSION::from_python(args[1].get(), python::type<Right>())));
}
string function_name() const
{ return string(name()); }
PyObject* description() const
{
return function_signature(python::type<Left>(), python::type<Right>());
}
const char* description() const
{ return "__pow__"; }
};
@@ -350,7 +331,7 @@ namespace detail
if (args.size() == 3 && args[2]->ob_type != Py_None->ob_type)
{
PyErr_SetString(PyExc_TypeError, "'__pow__' expected 2 arguments, got 3.");
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for pow()");
throw argument_error();
}
@@ -359,13 +340,8 @@ namespace detail
BOOST_PYTHON_CONVERSION::from_python(args[0].get(), python::type<Right>())));
}
string function_name() const
{ return string(rname()); }
PyObject* description() const
{
return function_signature(python::type<Left>(), python::type<Right>());
}
const char* description() const
{ return "__rpow__"; }
};
@@ -398,13 +374,8 @@ namespace detail
return res;
}
string function_name() const
{ return string(name()); }
PyObject* description() const
{
return function_signature(python::type<Left>(), python::type<Right>());
}
const char* description() const
{ return "__divmod__"; }
};
@@ -428,13 +399,9 @@ namespace detail
return res;
}
string function_name() const
{ return string(rname()); }
const char* description() const
{ return "__rdivmod__"; }
PyObject* description() const
{
return function_signature(python::type<Left>(), python::type<Right>());
}
};
static const char * name() { return "__divmod__"; }
@@ -463,13 +430,8 @@ namespace detail
0) ;
}
string function_name() const
{ return string(name()); }
PyObject* description() const
{
return function_signature(python::type<Left>(), python::type<Right>());
}
const char* description() const
{ return "__cmp__"; }
};
@@ -490,13 +452,8 @@ namespace detail
0) ;
}
string function_name() const
{ return string(rname()); }
PyObject* description() const
{
return function_signature(python::type<Left>(), python::type<Right>());
}
const char* description() const
{ return "__rcmp__"; }
};
@@ -531,13 +488,8 @@ namespace detail
#endif
}
string function_name() const
{ return string(name()); }
PyObject* description() const
{
return function_signature(python::type<operand>());
}
const char* description() const
{ return "__str__"; }
};

View File

@@ -18,7 +18,7 @@ namespace detail {
// A stand-in for the built-in void. This one can be passed to functions and
// (under MSVC, which has a bug, be used as a default template type parameter).
struct void_t {};
} // namespace detail
}
// An envelope in which type information can be delivered for the purposes
// of selecting an overloaded from_python() function. This is needed to work

View File

@@ -67,7 +67,7 @@ namespace {
ref global_class_reduce()
{
static ref result(detail::new_wrapped_function(class_reduce, "__reduce__"));
static ref result(detail::new_wrapped_function(class_reduce));
return result;
}
@@ -111,7 +111,7 @@ namespace {
ref global_instance_reduce()
{
static ref result(detail::new_wrapped_function(instance_reduce, "__reduce__"));
static ref result(detail::new_wrapped_function(instance_reduce));
return result;
}
}
@@ -225,21 +225,14 @@ namespace detail {
// Mostly copied wholesale from Python's classobject.c
PyObject* class_base::repr() const
{
unsigned long address = reinterpret_cast<unsigned long>(this);
string result = string("<extension class %s at %lx>") % tuple(complete_class_name(), address);
return result.reference().release();
}
// Mostly copied wholesale from Python's classobject.c
string class_base::complete_class_name() const
{
PyObject *mod = PyDict_GetItemString(
m_name_space.get(), const_cast<char*>("__module__"));
return (mod == NULL || !PyString_Check(mod))
? m_name
: string("%s.%s") % tuple(ref(mod, ref::increment_count), m_name);
unsigned long address = reinterpret_cast<unsigned long>(this);
string result = (mod == NULL || !PyString_Check(mod))
? string("<extension class %s at %lx>") % tuple(m_name, address)
: string("<extension class %s.%s at %lx>") % tuple(ref(mod, ref::increment_count), m_name, address);
return result.reference().release();
}

View File

@@ -97,9 +97,6 @@ namespace detail {
int setattr(const char* name, PyObject* value);
PyObject* repr() const;
void add_base(ref base);
// get the complete class name (i.e. "module.class")
virtual string complete_class_name() const;
protected:
bool initialize_instance(instance* obj, PyObject* args, PyObject* keywords);

View File

@@ -10,18 +10,15 @@ r'''
Automatic checking of the number and type of arguments. Foo's constructor takes
a single long parameter.
>>> try: ext = Foo()
... except TypeError, err:
... assert re.match(
... "'demo.Foo.__init__' expected argument\(s\) \(int\),\n"
... "but got \(\) instead.", str(err))
... else: print 'no exception'
>>> ext = Foo()
Traceback (innermost last):
File "<stdin>", line 1, in ?
TypeError: function requires exactly 1 argument; 0 given
>>> try: ext = Foo('foo')
... except TypeError, err:
... assert re.match(
... "'demo.Foo.__init__' expected argument\(s\) \(int\),\n"
... "but got \(string\) instead.", str(err))
... '(illegal argument type for built-in operation)|(an integer is required)', str(err))
... else: print 'no exception'
>>> ext = Foo(1)
@@ -163,16 +160,10 @@ a Bar parameter:
But objects not derived from Bar cannot:
>>> try: baz.pass_bar(baz)
... except TypeError, err:
... assert re.match(
... "'pass_bar' expected argument\(s\) \(demo.Baz, demo.Bar\),\n"
... "but got \(demo.Baz, demo.Baz\) instead.", str(err))
... else: print 'no exception'
(this error was:
TypeError: extension class 'Baz' is not convertible into 'Bar'.
)
>>> baz.pass_bar(baz)
Traceback (innermost last):
...
TypeError: extension class 'Baz' is not convertible into 'Bar'.
The clone function on Baz returns a smart pointer; we wrap it into an
extension_instance and make it look just like any other Baz obj.
@@ -363,11 +354,7 @@ Some simple overloading tests:
>>> try: r = Range('yikes')
... except TypeError, e:
... assert re.match(
... "No variant of overloaded function 'demo.Range.__init__' matches argument\(s\):\n"
... "\(string\)\n"
... "Candidates are:\n"
... "\(int\)\n"
... "\(int, int\)",
... 'No overloaded functions match [(]Range, string[)]\. Candidates are:\n.*\n.*',
... str(e))
... else: print 'no exception'
@@ -577,17 +564,7 @@ Testing overloaded free functions
15
>>> try: overloaded(1, 'foo')
... except TypeError, err:
... assert re.match(
... "No variant of overloaded function 'overloaded' matches argument\(s\):\n"
... "\(int, string\)\n"
... "Candidates are:\n"
... "\(\)\n"
... "\(int\)\n"
... "\(string\)\n"
... "\(int, int\)\n"
... "\(int, int, int\)\n"
... "\(int, int, int, int\)\n"
... "\(int, int, int, int, int\)",
... assert re.match("No overloaded functions match \(int, string\)\. Candidates are:",
... str(err))
... else:
... print 'no exception'
@@ -617,17 +594,7 @@ Testing overloaded constructors
5
>>> try: over = OverloadTest(1, 'foo')
... except TypeError, err:
... assert re.match(
... "No variant of overloaded function 'demo.OverloadTest.__init__' matches argument\(s\):\n"
... "\(int, string\)\n"
... "Candidates are:\n"
... "\(\)\n"
... "\(demo.OverloadTest\)\n"
... "\(int\)\n"
... "\(int, int\)\n"
... "\(int, int, int\)\n"
... "\(int, int, int, int\)\n"
... "\(int, int, int, int, int\)",
... assert re.match("No overloaded functions match \(OverloadTest, int, string\)\. Candidates are:",
... str(err))
... else:
... print 'no exception'
@@ -649,35 +616,16 @@ Testing overloaded methods
5
>>> try: over.overloaded(1,'foo')
... except TypeError, err:
... assert re.match(
... "No variant of overloaded function 'overloaded' matches argument\(s\):\n"
... "\(demo.OverloadTest, int, string\)\n"
... "Candidates are:\n"
... "\(demo.OverloadTest\)\n"
... "\(demo.OverloadTest, int\)\n"
... "\(demo.OverloadTest, int, int\)\n"
... "\(demo.OverloadTest, int, int, int\)\n"
... "\(demo.OverloadTest, int, int, int, int\)\n"
... "\(demo.OverloadTest, int, int, int, int, int\)",
... assert re.match("No overloaded functions match \(OverloadTest, int, string\)\. Candidates are:",
... str(err))
... else:
... print 'no exception'
Testing base class conversions
>>> try: testUpcast(over)
... except TypeError, err:
... assert re.match(
... "'testUpcast' expected argument\(s\) \(demo.Base\),\n"
... "but got \(demo.OverloadTest\) instead.",
... str(err))
... else:
... print 'no exception'
(this error was:
TypeError: extension class 'OverloadTest' is not convertible into 'Base'.
)
>>> testUpcast(over)
Traceback (innermost last):
TypeError: extension class 'OverloadTest' is not convertible into 'Base'.
>>> der1 = Derived1(333)
>>> der1.x()
333
@@ -686,37 +634,18 @@ TypeError: extension class 'OverloadTest' is not convertible into 'Base'.
>>> der1 = derived1Factory(1000)
>>> testDowncast1(der1)
1000
>>> try: testDowncast2(der1)
... except TypeError, err:
... assert re.match(
... "'testDowncast2' expected argument\(s\) \(demo.Derived2\),\n"
... "but got \(demo.Base\) instead.",
... str(err))
... else:
... print 'no exception'
(this error was:
>>> testDowncast2(der1)
Traceback (innermost last):
TypeError: extension class 'Base' is not convertible into 'Derived2'.
)
>>> der2 = Derived2(444)
>>> der2.x()
444
>>> testUpcast(der2)
444
>>> der2 = derived2Factory(1111)
>>> try: testDowncast2(der2)
... except TypeError, err:
... assert re.match(
... "'testDowncast2' expected argument\(s\) \(demo.Derived2\),\n"
... "but got \(demo.Base\) instead.",
... str(err))
... else:
... print 'no exception'
(this error was:
>>> testDowncast2(der2)
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++)
@@ -727,14 +656,10 @@ Testing interaction between callbacks, base declarations, and overloading
>>> c = CallbackTest()
>>> c.testCallback(1)
2
>>> try: c.testCallback('foo')
... except TypeError, err:
... assert re.match(
... "'testCallback' expected argument\(s\) \(demo.CallbackTestBase, int\),\n"
... "but got \(demo.CallbackTest, string\) instead.",
... str(err))
... else:
... print 'no exception'
>>> 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')
@@ -753,14 +678,10 @@ Testing interaction between callbacks, base declarations, and overloading
-1
>>> r.callback('foo')
'foo 1'
>>> try: r.testCallback('foo')
... except TypeError, err:
... assert re.match(
... "'testCallback' expected argument\(s\) \(demo.CallbackTestBase, int\),\n"
... "but got \(demo.RedefineCallback, string\) instead.",
... str(err))
... else:
... print 'no exception'
>>> 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)
@@ -1048,33 +969,15 @@ test inheritB2
>>> j = pow(i, 5)
>>> j.i()
32
>>> try: j = pow(i, 5, k)
... except TypeError, err:
... assert re.match(
... "No variant of overloaded function '__pow__' matches argument\(s\):\n"
... "\(demo.Int, int, demo.Int\)\n"
... "Candidates are:\n"
... "\(demo.Int, demo.Int\)\n"
... "\(demo.Int, demo.Int, demo.Int\)\n"
... "\(demo.Int, int\)",
... str(err))
... else:
... print 'no exception'
>>> try: j = pow(i, 5, 5)
... except TypeError, err:
... assert re.match(
... "No variant of overloaded function '__pow__' matches argument\(s\):\n"
... "\(demo.Int, int, int\)\n"
... "Candidates are:\n"
... "\(demo.Int, demo.Int\)\n"
... "\(demo.Int, demo.Int, demo.Int\)\n"
... "\(demo.Int, int\)",
... str(err))
... else:
... print 'no exception'
>>> j = pow(i, 5, k)
Traceback (innermost last):
TypeError: bad operand type(s) for pow()
>>> j = pow(i, 5, 5)
Traceback (innermost last):
TypeError: bad operand type(s) for pow()
>>> j = i/1
Traceback (innermost last):
TypeError: __div__(demo.Int, int) undefined.
TypeError: bad operand type(s) for /
>>> j = 1+i
>>> j.i()
3
@@ -1090,10 +993,10 @@ test inheritB2
-1
>>> j = 1/i
Traceback (innermost last):
TypeError: __rdiv__(demo.Int, int) undefined.
TypeError: bad operand type(s) for /
>>> pow(1,i)
Traceback (innermost last):
TypeError: __rpow__(demo.Int, int) undefined.
TypeError: bad operand type(s) for pow()
Test operator export to a subclass