Skip to content

Commit cfbc1a6

Browse files
committed
Fully removed convertible() test from to_python converter protocol
Added tests for detecting unregistered classes when converting indirectly to python. [SVN r16396]
1 parent 31b8b58 commit cfbc1a6

16 files changed

Lines changed: 77 additions & 83 deletions

include/boost/python/converter/arg_to_python.hpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ template <class T> struct is_object_manager;
2929

3030
namespace detail
3131
{
32-
BOOST_PYTHON_DECL void throw_no_class_registered();
33-
3432
template <class T>
3533
struct function_arg_to_python : handle<>
3634
{
@@ -209,8 +207,6 @@ namespace detail
209207
inline PyObject* reference_arg_to_python<T>::get_object(T& x)
210208
{
211209
to_python_indirect<T&,python::detail::make_reference_holder> convert;
212-
if (!convert.convertible())
213-
throw_no_class_registered();
214210
return convert(x);
215211
}
216212

@@ -231,9 +227,7 @@ namespace detail
231227
inline PyObject* pointer_shallow_arg_to_python<Ptr>::get_object(Ptr x)
232228
{
233229
to_python_indirect<Ptr,python::detail::make_reference_holder> convert;
234-
if (!convert.convertible())
235-
throw_no_class_registered();
236-
return x ? convert(x) : python::detail::none();
230+
return convert(x);
237231
}
238232
}
239233

include/boost/python/converter/builtin_converters.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ namespace detail
3737
// a converter.
3838
struct builtin_to_python
3939
{
40-
static bool convertible() { return true; }
41-
4240
// This information helps make_getter() decide whether to try to
4341
// return an internal reference or not. I don't like it much,
4442
// but it will have to serve for now.

include/boost/python/converter/registrations.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ struct BOOST_PYTHON_DECL registration
3535
// Convert the appropriately-typed data to Python
3636
PyObject* to_python(void const volatile*) const;
3737

38+
// Return the class object, or raise an appropriate Python
39+
// exception if no class has been registered.
40+
PyTypeObject* get_class_object() const;
41+
3842
public: // data members. So sue me.
3943
const python::type_info target_type;
4044

@@ -45,7 +49,7 @@ struct BOOST_PYTHON_DECL registration
4549
rvalue_from_python_chain* rvalue_chain;
4650

4751
// The class object associated with this type
48-
PyTypeObject* class_object;
52+
PyTypeObject* m_class_object;
4953

5054
// The unique to_python converter for the associated C++ type.
5155
to_python_function_t m_to_python;
@@ -64,7 +68,7 @@ inline registration::registration(type_info target_type)
6468
, lvalue_chain(0)
6569
, rvalue_chain(0)
6670
, m_to_python(0)
67-
, class_object(0)
71+
, m_class_object(0)
6872
{}
6973

7074
inline bool operator<(registration const& lhs, registration const& rhs)

include/boost/python/data_members.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ namespace detail
3636
typedef typename Policies::result_converter result_converter;
3737
typedef typename boost::add_reference<Data>::type source;
3838
typename mpl::apply1<result_converter,source>::type cr;
39-
if (!cr.convertible()) return 0;
4039

4140
if (!policies.precall(args_)) return 0;
4241

include/boost/python/enum.hpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@ struct enum_ : public objects::enum_base
1717
{
1818
typedef objects::enum_base base;
1919

20+
// Declare a new enumeration type in the current scope()
2021
enum_(char const* name);
22+
23+
// Add a new enumeration value with the given name and value.
2124
inline enum_<T>& value(char const* name, T);
2225

2326
private:
2427
static PyObject* to_python(void const* x);
25-
static void* convertible(PyObject* obj);
28+
static void* convertible_from_python(PyObject* obj);
2629
static void construct(PyObject* obj, converter::rvalue_from_python_stage1_data* data);
2730
};
2831

@@ -31,32 +34,42 @@ inline enum_<T>::enum_(char const* name)
3134
: base(
3235
name
3336
, &enum_<T>::to_python
34-
, &enum_<T>::convertible
37+
, &enum_<T>::convertible_from_python
3538
, &enum_<T>::construct
3639
, type_id<T>())
3740
{
3841
}
3942

40-
// This is the conversion function that gets registered for converting
43+
// This is the conversion function that gets registered for converting
44+
// these enums to Python.
4145
template <class T>
4246
PyObject* enum_<T>::to_python(void const* x)
4347
{
4448
return base::to_python(
45-
converter::registered<T>::converters.class_object
49+
converter::registered<T>::converters.m_class_object
4650
, static_cast<long>(*(T const*)x));
4751
}
4852

53+
//
54+
// The following two static functions serve as the elements of an
55+
// rvalue from_python converter for the enumeration type.
56+
//
57+
58+
// This checks that a given Python object can be converted to the
59+
// enumeration type.
4960
template <class T>
50-
void* enum_<T>::convertible(PyObject* obj)
61+
void* enum_<T>::convertible_from_python(PyObject* obj)
5162
{
5263
return PyObject_IsInstance(
5364
obj
5465
, upcast<PyObject>(
55-
converter::registered<T>::converters.class_object))
66+
converter::registered<T>::converters.m_class_object))
5667

5768
? obj : 0;
5869
}
59-
70+
71+
// Constructs an instance of the enumeration type in the from_python
72+
// data.
6073
template <class T>
6174
void enum_<T>::construct(PyObject* obj, converter::rvalue_from_python_stage1_data* data)
6275
{

include/boost/python/object/iterator.hpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ namespace detail
8787
{
8888
typedef typename Policies::result_converter result_converter;
8989
typename mpl::apply1<result_converter,ValueType&>::type cr;
90-
if (!cr.convertible()) return 0;
9190

9291
return cr(x);
9392
}
@@ -96,7 +95,6 @@ namespace detail
9695
{
9796
typedef typename Policies::result_converter result_converter;
9897
typename mpl::apply1<result_converter,ValueType const&>::type cr;
99-
if (!cr.convertible()) return 0;
10098

10199
return cr(x);
102100
}
@@ -150,11 +148,6 @@ namespace detail
150148

151149
to_python_value<iterator_range<NextPolicies,Iterator> > cr;
152150

153-
// This check is probably redundant, since we ensure the
154-
// type is registered above.
155-
if (!cr.convertible())
156-
return 0;
157-
158151
// Extract x from the first argument
159152
PyObject* arg0 = PyTuple_GET_ITEM(args_, 0);
160153
arg_from_python<Target> c0(arg0);

include/boost/python/object/make_instance.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ struct make_instance
2020
static PyObject* execute(Arg& x)
2121
{
2222
BOOST_STATIC_ASSERT(is_class<T>::value);
23-
PyTypeObject* type = converter::registered<T>::converters.class_object;
23+
24+
PyTypeObject* type = converter::registered<T>::converters.get_class_object();
2425

2526
PyObject* raw_result = type->tp_alloc(
2627
type, objects::additional_instance_size<Holder>::value);

include/boost/python/to_python_indirect.hpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ namespace boost { namespace python {
2121
template <class T, class MakeHolder>
2222
struct to_python_indirect
2323
{
24-
static bool convertible();
2524
PyObject* operator()(T ptr) const;
2625
private:
2726
static PyTypeObject* type();
@@ -90,16 +89,11 @@ namespace detail
9089
}
9190
}
9291

93-
template <class T, class MakeHolder>
94-
inline bool to_python_indirect<T,MakeHolder>::convertible()
95-
{
96-
BOOST_STATIC_ASSERT(is_pointer<T>::value || is_reference<T>::value);
97-
return type() != 0;
98-
}
99-
10092
template <class T, class MakeHolder>
10193
inline PyObject* to_python_indirect<T,MakeHolder>::operator()(T x) const
10294
{
95+
BOOST_STATIC_ASSERT(is_pointer<T>::value || is_reference<T>::value);
96+
10397
PyObject* const null_result = detail::null_pointer_to_none(x, 1L);
10498
if (null_result != 0)
10599
return null_result;

include/boost/python/to_python_value.hpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ namespace detail
2727
typename add_const<T>::type
2828
>::type argument_type;
2929

30-
static bool convertible();
3130
PyObject* operator()(argument_type) const;
3231

3332
// This information helps make_getter() decide whether to try to
@@ -44,7 +43,6 @@ namespace detail
4443
typename add_const<T>::type
4544
>::type argument_type;
4645

47-
static bool convertible();
4846
PyObject* operator()(argument_type) const;
4947

5048
// This information helps make_getter() decide whether to try to
@@ -73,24 +71,12 @@ struct to_python_value
7371
//
7472
namespace detail
7573
{
76-
template <class T>
77-
inline bool registry_to_python_value<T>::convertible()
78-
{
79-
return converter::registered<argument_type>::converters.to_python != 0;
80-
}
81-
8274
template <class T>
8375
inline PyObject* registry_to_python_value<T>::operator()(argument_type x) const
8476
{
8577
return converter::registered<argument_type>::converters.to_python(&x);
8678
}
8779

88-
template <class T>
89-
inline bool object_manager_to_python_value<T>::convertible()
90-
{
91-
return true;
92-
}
93-
9480
template <class T>
9581
inline PyObject* object_manager_to_python_value<T>::operator()(argument_type x) const
9682
{

src/converter/arg_to_python_base.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,6 @@ namespace detail
4343
(converters.to_python(source))
4444
{
4545
}
46-
47-
BOOST_PYTHON_DECL void throw_no_class_registered()
48-
{
49-
PyErr_SetString(
50-
PyExc_TypeError
51-
, const_cast<char*>("class not registered for to_python type"));
52-
throw_error_already_set();
53-
}
5446
}
5547

5648
}}} // namespace boost::python::converter

0 commit comments

Comments
 (0)