Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r64634 - in trunk/tools/build/v2: engine/src tools
From: ghost_at_[hidden]
Date: 2010-08-06 07:24:00


Author: vladimir_prus
Date: 2010-08-06 07:22:42 EDT (Fri, 06 Aug 2010)
New Revision: 64634
URL: http://svn.boost.org/trac/boost/changeset/64634

Log:
Handle list of instances with __jam_repr__ method returned from Python.

This re-fixes test/inline.py broken by 'lib' changes.

Text files modified:
   trunk/tools/build/v2/engine/src/compile.c | 92 +++++++++++++++++++++++----------------
   trunk/tools/build/v2/tools/builtin.py | 6 --
   2 files changed, 56 insertions(+), 42 deletions(-)

Modified: trunk/tools/build/v2/engine/src/compile.c
==============================================================================
--- trunk/tools/build/v2/engine/src/compile.c (original)
+++ trunk/tools/build/v2/engine/src/compile.c 2010-08-06 07:22:42 EDT (Fri, 06 Aug 2010)
@@ -770,6 +770,45 @@
 
 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 @@
             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 );

Modified: trunk/tools/build/v2/tools/builtin.py
==============================================================================
--- trunk/tools/build/v2/tools/builtin.py (original)
+++ trunk/tools/build/v2/tools/builtin.py 2010-08-06 07:22:42 EDT (Fri, 06 Aug 2010)
@@ -462,11 +462,7 @@
                                                       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)
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk