mirror of
https://github.com/boostorg/build.git
synced 2026-02-16 01:12:13 +00:00
Handle list of instances with __jam_repr__ method returned from Python.
This re-fixes test/inline.py broken by 'lib' changes. [SVN r64634]
This commit is contained in:
@@ -770,6 +770,45 @@ enter_rule( char *rulename, module_t *target_module );
|
||||
|
||||
static int python_instance_number = 0;
|
||||
|
||||
|
||||
/* Given a Python object, return a string to use in Jam
|
||||
code instead of said object.
|
||||
If the object is string, use the string value
|
||||
If the object implemenets __jam_repr__ method, use that.
|
||||
Otherwise return 0.
|
||||
|
||||
The result value is newstr-ed. */
|
||||
char *python_to_string(PyObject* value)
|
||||
{
|
||||
if (PyString_Check(value))
|
||||
{
|
||||
return newstr(PyString_AsString(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* See if this is an instance that defines special __jam_repr__
|
||||
method. */
|
||||
if (PyInstance_Check(value)
|
||||
&& PyObject_HasAttrString(value, "__jam_repr__"))
|
||||
{
|
||||
PyObject* repr = PyObject_GetAttrString(value, "__jam_repr__");
|
||||
if (repr)
|
||||
{
|
||||
PyObject* arguments2 = PyTuple_New(0);
|
||||
PyObject* value2 = PyObject_Call(repr, arguments2, 0);
|
||||
Py_DECREF(repr);
|
||||
Py_DECREF(arguments2);
|
||||
if (PyString_Check(value2))
|
||||
{
|
||||
return newstr(PyString_AsString(value2));
|
||||
}
|
||||
Py_DECREF(value2);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static LIST*
|
||||
call_python_function(RULE* r, FRAME* frame)
|
||||
{
|
||||
@@ -835,52 +874,31 @@ call_python_function(RULE* r, FRAME* frame)
|
||||
for ( i = 0; i < size; ++i )
|
||||
{
|
||||
PyObject * item = PyList_GetItem( py_result, i );
|
||||
if ( PyString_Check( item ) )
|
||||
{
|
||||
result = list_new( result,
|
||||
newstr( PyString_AsString( item ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
char *s = python_to_string (item);
|
||||
if (!s) {
|
||||
fprintf( stderr, "Non-string object returned by Python call.\n" );
|
||||
} else {
|
||||
result = list_new (result, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (PyString_Check(py_result))
|
||||
{
|
||||
result = list_new (0, newstr (PyString_AsString(py_result)));
|
||||
}
|
||||
else if ( py_result == Py_None )
|
||||
{
|
||||
result = L0;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
/* See if this is an instance that defines special __jam_repr__
|
||||
method. */
|
||||
if (PyInstance_Check(py_result)
|
||||
&& PyObject_HasAttrString(py_result, "__jam_repr__"))
|
||||
{
|
||||
PyObject* repr = PyObject_GetAttrString(py_result, "__jam_repr__");
|
||||
if (repr)
|
||||
{
|
||||
PyObject* arguments2 = PyTuple_New(0);
|
||||
PyObject* py_result2 = PyObject_Call(repr, arguments2, 0);
|
||||
Py_DECREF(repr);
|
||||
Py_DECREF(arguments2);
|
||||
if (PyString_Check(py_result2))
|
||||
{
|
||||
result = list_new(0, newstr(PyString_AsString(py_result2)));
|
||||
}
|
||||
Py_DECREF(py_result2);
|
||||
}
|
||||
}
|
||||
|
||||
/* If 'result' is still empty, do nothing. There are cases, e.g.
|
||||
feature.feature function that should return value for the benefit
|
||||
of Python code and which also can be called by Jam code, where
|
||||
no sensible value can be returned. We cannot even emit a warning,
|
||||
since there will be a pile of them. */
|
||||
char *s = python_to_string(py_result);
|
||||
if (s)
|
||||
result = list_new(0, s);
|
||||
else
|
||||
/* We have tried all we could. Return empty list. There are
|
||||
cases, e.g. feature.feature function that should return
|
||||
value for the benefit of Python code and which also can be
|
||||
called by Jam code, where no sensible value can be
|
||||
returned. We cannot even emit a warning, since there will
|
||||
be a pile of them. */
|
||||
result = L0;
|
||||
}
|
||||
|
||||
Py_DECREF( py_result );
|
||||
|
||||
@@ -462,11 +462,7 @@ def lib(names, sources=[], requirements=[], default_build=[], usage_requirements
|
||||
r,
|
||||
default_build,
|
||||
usage_requirements))
|
||||
# Ideally, we're return the list of targets, but at present,
|
||||
# bjam, when give a list of non-strings, emits a warning. It
|
||||
# should be modified to try calling __jam_repr__ on each
|
||||
# element of the string, but that's for future.
|
||||
#return [result]
|
||||
return result
|
||||
|
||||
get_manager().projects().add_rule("lib", lib)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user