Re: [C++-sig] New Major-Release Boost.Python Development

2011-08-29 Thread Hans Meine

Am 26.08.2011 um 20:25 schrieb Jim Bosch:
> - … the rvalue converters in particular don't seem to have been intended as 
part of the public API originally, and I think they're an important part of 
the library.

Correct, great!

> - Automatic conversions for newer boost libraries (Fusion, Pointer 
Container, and Filesystem are at the top of my list), and more for the STL and 
iostreams standard libraries.  I'd like to integrate the indexing suite (v2) 
into Boost.Python proper.

Probably makes sense, in particular the STL part is an often (understandibly) 
expected feature.

> - Allow Boost.Python wrapped classes to inherit from Python classes.

Yes yes yes!  (list/dict inheritence in particular is /so/ useful.)

> - Some limited degree of priority-based overload matching.  Not sure how 
best to approach this one yet, though.

A related goal (also template-related) is better support for error messages in 
the face of overloaded functions.  In our VIGRA library [1], we have a lot of 
overloaded functions performing image analysis tasks on NumPy arrays.  
Currently, we face the following problems:

- The automatically generated signatures in the docstrings are hard to read.  
Don’t know if there is a better way of presenting signatures of heavily 
templated code (improvements from the error messages of modern compilers or 
STLfilt come to my mind), or if there should simply be a hook for custom 
postprocessing.  (Maybe just __doc__ being writeable from Python?)

- The same goes for error messages when calling with the wrong arguments.

- Furthermore, we have custom converters that check certain properties of the 
passed arrays, e.g. dimensionality, memory layout, or dtype.  With 
overloading, all variants are tried in turn, but there’s no good way to 
"collect" error messages, and tell the user why no registered overload would 
match.  (The C++ signatures don’t necessarily give the user enough 
information.)

My feeling is that all this is strongly related to the features you already 
have in mind, but hopefully my notes help in steering this into an even 
better, more general direction.

Oh, and there’s another missing feature:

- Better support for introspection, e.g. by the ’inspect’ module or 
documentation tools.

Looking forward to a "more accessible" BPL,
  Hans^

[1] http://hci.iwr.uni-heidelberg.de/vigra/doc/vigranumpy/index.html
___
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig



Re: [C++-sig] [Boost.Python v3] Features and Scope

2011-08-29 Thread Stefan Seefeld
On 08/28/2011 02:14 PM, Jim Bosch wrote:
>
> To solve it, I think you'd want anything registered by a specific
> module to appear both in that module's registry and the global
> registry, with the module's registry taking precedence.  Are there any
> cases where you'd want something only to appear in the module-specific
> registry?

Anything that gets injected into the global registry is prone to violate
the ODR. Of course, also adding it into a local registry and letting
that have precedence may mask the ODR violation issue. But in that case,
it isn't clear why we'd add it to the global registry at all.

It may make sense to define a policy that types exported explicitly by
an extension module may be added to the global repository. In contrast,
prerequisite types that are only by way of dependency added (e.g.,
common libstdc++ types) should be stored in a local / private registry.

Stefan

-- 

  ...ich hab' noch einen Koffer in Berlin...

___
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig


Re: [C++-sig] sending a c++ class to a python function

2011-08-29 Thread Jim Bosch
Normally a to-python converter is needed when you have a function that 
returns a C++ object, and you want to wrap that function so the returned 
thing can be used in Python.  I don't see any functions that return a 
Scene object.  They will also enable expressions of the form 
"object(scene)", but you can't use that sort of expression to define the 
converter itself.


When you're writing the conversion function, remember that Boost.Python 
really doesn't know anything about your class unless you tell it about 
it using a boost::python::class_ definition, and doing that will already 
define a to-python converter for it.  The instructions you're following 
are for things like strings that already have a Python type they can be 
converted to; you probably want to use class_ for something like Scene. 
 Now, if you just wanted to convert Scene to a dict instead of having a 
Scene type in Python, a custom conversion would indeed be the way to go, 
but you'd need to create a dict and fill it in the convert function.


Anyhow, my best guess for the segfault is that you have an infinite 
recursion - when you call object(scene), it needs to look for a 
to-python converter in the registry.  So it finds yours, which calls 
object(scene).  Repeat.


Jim




On 08/28/2011 08:22 PM, Josh Stratton wrote:

I'm getting an error when I try to pass down my object that results in
a seg fault.  I've registered my class I'm sending down, but when I
actually send it, my program exits at this line in the library right
after I call the importFile() function...

 return call(get_managed_object(self, tag),
BOOST_PP_ENUM_PARAMS_Z(1, N, a));

// here's the class I'm trying to send down
class Scene
{
public:
 MeshP   mesh(int key);
 voidclearScene();
 CameraP createCamera(QString name);
 MeshP   createMesh(QString name);
 voidsetMesh(int meshKey, MeshP mesh) {
_meshes[meshKey] = mesh; }
 QHashIteratormeshes() { return
QHashIterator(_meshes); }
 QHashIterator  cameras() { return
QHashIterator(_cameras); }
 CameraP fetchCamera(QString name);
 QList   importExtensions();
 voidimportFile(QString fileName);
 voidevalPythonFile(QString fileName);
 Scene();
protected:
 intuniqueCameraKey();
 intuniqueMeshKey();
 QStringuniqueName(QString prefix);

private:
 QHash_meshes;
 QHash  _cameras;
 //QHash   _lights;
 QSet   _names;
//PythonQtObjectPtr  _context;
 object _pyMainModule;
 object _pyMainNamespace;
public slots:
 void   pythonStdOut(const QString&s)
{ std::cout<<  s.toStdString()<<  std::flush; }
 void   pythonStdErr(const QString&s)
{ std::cout<<  s.toStdString()<<  std::flush; }
};

// first I create the mapping, which I'm not sure is correct, trying
to follow: 
http://misspent.wordpress.com/2009/09/27/how-to-write-boost-python-converters/
struct SceneToPython
{
 static PyObject* convert(Scene const&  scene)
 {
 return boost::python::incref(boost::python::object(scene).ptr());
 }
};

// then I register it
 boost::python::to_python_converter();

// then I send it down from inside my Scene object
 try {
 object processFileFunc =
_pyMainModule.attr("MeshImporter").attr("processFile");
 processFileFunc(this, fileName); // seems to error here
 } catch (boost::python::error_already_set const&) {
 QString perror = parse_python_exception();
 std::cerr<<  "Error in Python: "<<  perror.toStdString()<<  std::endl;
 }

I'm not really sure what actually is wrong besides something being
setup incorrectly.  Do I need to make a python-to-C++ converter as
well even if I'm not sending it back to C++?  Or is my convert()
function just improperly implemented?  I wasn't sure how much I need
to actually get it to map correctly.  Thanks.
___
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig


___
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig


Re: [C++-sig] [Boost.Python v3] Features and Scope

2011-08-29 Thread Jim Bosch

On 08/29/2011 09:41 AM, Stefan Seefeld wrote:

On 08/28/2011 02:14 PM, Jim Bosch wrote:


To solve it, I think you'd want anything registered by a specific
module to appear both in that module's registry and the global
registry, with the module's registry taking precedence.  Are there any
cases where you'd want something only to appear in the module-specific
registry?


Anything that gets injected into the global registry is prone to violate
the ODR. Of course, also adding it into a local registry and letting
that have precedence may mask the ODR violation issue. But in that case,
it isn't clear why we'd add it to the global registry at all.



The reason to add it to the global registry is so if you know one of the 
modules you depend on registered a converter, you don't have to do it 
yourself.



It may make sense to define a policy that types exported explicitly by
an extension module may be added to the global repository. In contrast,
prerequisite types that are only by way of dependency added (e.g.,
common libstdc++ types) should be stored in a local / private registry.



I don't see how having a global registry makes things any worse from an 
ODR perspective.  It seems like it's mostly just the same "where do 
templates get instantiated" problem that compilers and linkers always 
have to deal with.  In other words, instantiating something like:


class_< std::vector >

in two shared libraries doesn't seem any different from instantiating 
something like:


std::vector

in two shared libraries, and we basically always have to leave it up to 
the compiler/linker to solve the latter.


Is the problem the fact that the global registry stores function 
pointers to template instantiations?  I can see how that would appear to 
make the multiple (template) definitions more problematic, but it also 
seems like that's a problem compilers and linkers would have to have 
already solved.  Of course, this may just be wishful thinking on my 
part; I admit I'm not very familiar with how these problems are handled 
in practice.


Jim
___
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig