mirror of
https://github.com/boostorg/python.git
synced 2026-01-27 07:02:15 +00:00
Fix a bug in dangling reference/pointer detection. Thanks to Daniel
Paull <dlp-at-fractaltechnologies.com> for reporting it. [SVN r18498]
This commit is contained in:
@@ -52,13 +52,22 @@ call(PyObject* callable
|
||||
, boost::type<R>* = 0
|
||||
)
|
||||
{
|
||||
converter::return_from_python<R> converter;
|
||||
return converter(
|
||||
PyObject* const result =
|
||||
PyEval_CallFunction(
|
||||
callable
|
||||
, const_cast<char*>("(" BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FIXED, "O") ")")
|
||||
BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET, nil)
|
||||
));
|
||||
);
|
||||
|
||||
// This conversion *must not* be done in the same expression as
|
||||
// the call, because, in the special case where the result is a
|
||||
// reference a Python object which was created by converting a C++
|
||||
// argument for passing to PyEval_CallFunction, its reference
|
||||
// count will be 2 until the end of the full expression containing
|
||||
// the conversion, and that interferes with dangling
|
||||
// pointer/reference detection.
|
||||
converter::return_from_python<R> converter;
|
||||
return converter(result);
|
||||
}
|
||||
|
||||
# undef N
|
||||
|
||||
@@ -51,14 +51,23 @@ call_method(PyObject* self, char const* name
|
||||
, boost::type<R>* = 0
|
||||
)
|
||||
{
|
||||
converter::return_from_python<R> converter;
|
||||
return converter(
|
||||
PyObject* const result =
|
||||
PyEval_CallMethod(
|
||||
self
|
||||
, const_cast<char*>(name)
|
||||
, const_cast<char*>("(" BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FIXED, "O") ")")
|
||||
BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET, nil)
|
||||
));
|
||||
);
|
||||
|
||||
// This conversion *must not* be done in the same expression as
|
||||
// the call, because, in the special case where the result is a
|
||||
// reference a Python object which was created by converting a C++
|
||||
// argument for passing to PyEval_CallFunction, its reference
|
||||
// count will be 2 until the end of the full expression containing
|
||||
// the conversion, and that interferes with dangling
|
||||
// pointer/reference detection.
|
||||
converter::return_from_python<R> converter;
|
||||
return converter(result);
|
||||
}
|
||||
|
||||
# undef N
|
||||
|
||||
@@ -218,7 +218,7 @@ namespace
|
||||
, char const* ref_type)
|
||||
{
|
||||
handle<> holder(source);
|
||||
if (source->ob_refcnt <= 2)
|
||||
if (source->ob_refcnt <= 1)
|
||||
{
|
||||
handle<> msg(
|
||||
::PyString_FromFormat(
|
||||
|
||||
@@ -15,9 +15,18 @@ Once we have array conversion support, this test will fail. Er,
|
||||
succeed<wink>:
|
||||
|
||||
>>> try: apply_to_string_literal(identity)
|
||||
... except: pass # expected
|
||||
... except ReferenceError: pass # expected
|
||||
... else: print 'expected an exception!'
|
||||
|
||||
>>> try: apply_X_ref_handle(lambda ignored:X(42), None)
|
||||
... except ReferenceError: pass # expected
|
||||
... else: print 'expected an exception!'
|
||||
|
||||
>>> x = X(42)
|
||||
>>> x.y = X(7)
|
||||
>>> apply_X_ref_handle(lambda z:z.y, x).value()
|
||||
7
|
||||
|
||||
>>> x = apply_X_X(identity, X(42))
|
||||
>>> x.value()
|
||||
42
|
||||
|
||||
Reference in New Issue
Block a user