[C++-sig] [pybindgen] Problems on class constructor

Olaf Peter ope-devel at gmx.de
Thu Aug 21 19:31:04 CEST 2008


Hi,

given the following header:

---8<---
class PyConsole;

class StdoutPy
{
public:
    StdoutPy(PyConsole* console);
    void write(PyObject* args);
    void flush();
private:
    PyConsole*			m_console;
};

class PyConsole
{
    void writeOut(PyObject* args);
    void writeErr(PyObject* args);
    void flush();
};
--->8---


and the python script:

---8<---
import pybindgen
import sys

# convenience
param=pybindgen.param
retval=pybindgen.retval

pybindgen.settings.min_python_version = (2,5)

mod = pybindgen.Module('redirector')
mod.add_include('"redirector.hpp"')

stdout_py = mod.add_class('StdoutPy')
stdout_py.add_constructor([param('PyConsole*', 'cpp_parent',
transfer_ownership=False)])
stdout_py.add_method('write', None, [param('PyObject*', 'value',
transfer_ownership=False)])
stdout_py.add_method('flush', None, [])

mod.generate(sys.stdout)
--->8---

I get the error:

$ python redirector.py
Traceback (most recent call last):
  File "redirector.py", line 14, in <module>
    stdout_py.add_constructor([param('PyConsole*', 'cpp_parent',
transfer_ownership=False)])
  File "/usr/lib/python2.5/site-packages/pybindgen/cppclass.py", line
1228, in add_constructor
    constructor = CppConstructor(*args, **kwargs)
  File "/usr/lib/python2.5/site-packages/pybindgen/cppmethod.py", line
415, in __init__
    parameters = [utils.eval_param(param, self) for param in parameters]
  File "/usr/lib/python2.5/site-packages/pybindgen/utils.py", line 205,
in eval_param
    TypeLookupError))
  File "/usr/lib/python2.5/site-packages/pybindgen/utils.py", line 115,
in call_with_error_handling
    return callable(*args, **kwargs)
  File
"/usr/lib/python2.5/site-packages/pybindgen/typehandlers/base.py", line
1167, in new
    param_type_matcher.lookup(ctype)
  File
"/usr/lib/python2.5/site-packages/pybindgen/typehandlers/base.py", line
1300, in lookup
    raise TypeLookupError(name)
pybindgen.typehandlers.base.TypeLookupError: PyConsole *


It seems, that I have to register my own types but I have no idea how to
do this. For Testing I've used the xmlgcc approach:

---8<---
import sys

from pybindgen import FileCodeSink
from pybindgen.gccxmlparser import ModuleParser

def my_module_gen():
    module_parser = ModuleParser('redirector', '::')
    module_parser.parse([sys.argv[1]],
include_paths=['/usr/include/python2.5'],includes=['"redirector.hpp"'],
pygen_sink=FileCodeSink(sys.stdout))

if __name__ == '__main__':
    my_module_gen()
--->8---

which results in errors too:

/usr/lib/python2.5/site-packages/pybindgen/gccxmlparser.py:580:
DeprecationWarning: Parameter include_paths is deprecated, use
gccxml_options instead
  self.parse_init(header_files, include_paths, whitelist_paths,
includes, pygen_sink, pygen_classifier)

INFO Parsing source file "redirector.hpp" ...

INFO gccxml cmd: /usr/bin/gccxml  -I"." -I"/usr/include/python2.5"
"redirector.hpp" -fxml="/tmp/tmp5ORqw3.xml"

INFO GCCXML version - 0.7
/usr/lib/python2.5/site-packages/pygccxml/parser/scanner.py:335:
UserWarning: unable to find out array size from expression ""
  warnings.warn( msg )
from pybindgen import Module, FileCodeSink, param, retval, cppclass


import pybindgen.settings
import warnings

class ErrorHandler(pybindgen.settings.ErrorHandler):
    def handle_error(self, wrapper, exception, traceback_):
        warnings.warn("exception %r in wrapper %s" % (exception, wrapper))
        return True
pybindgen.settings.error_handler = ErrorHandler()


import sys

def module_init():
    root_module = Module('redirector', cpp_namespace='::')
    root_module.add_include('"redirector.hpp"')
    return root_module

def register_types(module):
    root_module = module.get_root()

    module.add_class('StdoutPy')
    module.add_class('PyConsole')

    ## Register a nested module for the namespace std

    nested_module = module.add_cpp_namespace('std')
    register_types_std(nested_module)


def register_types_std(module):
    root_module = module.get_root()


def register_methods(root_module):
    register_StdoutPy_methods(root_module, root_module['StdoutPy'])
    register_PyConsole_methods(root_module, root_module['PyConsole'])
    return

def register_StdoutPy_methods(root_module, cls):
/usr/lib/python2.5/site-packages/pybindgen/gccxmlparser.py:215:
UserWarning: multiple &'s not handled
  warnings.warn("multiple &'s not handled")
/usr/lib/python2.5/site-packages/pybindgen/gccxmlparser.py:211:
UserWarning: multiple consts not handled
  warnings.warn("multiple consts not handled")
    cls.add_constructor([param('StdoutPy&', '_ctor_arg', is_const=True)])
    cls.add_constructor([param('PyConsole *', 'console')])
/var/tmp/redirector.hpp:12: WrapperWarning: Parameter '::PyConsole *
console' error (used in StdoutPy::StdoutPy(PyConsole * console)
[constructor]): TypeConfigurationError('transfer_ownership parameter
missing',)
  StdoutPy(PyConsole* console);
    cls.add_method('write',
                   'void',
                   [param('PyObject *', 'args')])
/usr/lib/python2.5/site-packages/pybindgen/typehandlers/base.py:1173:
UserWarning: Exception '__init__() takes at least 4 arguments (3 given)'
in type handler <class
'pybindgen.typehandlers.pyobjecttype.PyObjectParam'> constructor
  warnings.warn("Exception %r in type handler %s constructor" %
(str(ex), type_handler_class))
Traceback (most recent call last):
  File "redirector_py.py", line 13, in <module>
    my_module_gen()
  File "redirector_py.py", line 10, in my_module_gen
    module_parser.parse([sys.argv[1]],
include_paths=['/usr/include/python2.5'],includes=['"redirector.hpp"'],
pygen_sink=FileCodeSink(sys.stdout))
  File "/usr/lib/python2.5/site-packages/pybindgen/gccxmlparser.py",
line 582, in parse
    self.scan_methods()
  File "/usr/lib/python2.5/site-packages/pybindgen/gccxmlparser.py",
line 809, in scan_methods
    self._scan_class_methods(class_wrapper.gccxml_definition,
class_wrapper, pygen_sink)
  File "/usr/lib/python2.5/site-packages/pybindgen/gccxmlparser.py",
line 1420, in _scan_class_methods
    arguments.append(Parameter.new(*arg[0], **arg[1]))
  File
"/usr/lib/python2.5/site-packages/pybindgen/typehandlers/base.py", line
1171, in new
    return type_handler_class(*args, **kwargs)
TypeError: __init__() takes at least 4 arguments (3 given)

BTW, how can I prevent the construction of the StdoutPy class from
python? It has to be created from c++ side.

Thanks,
Olaf



More information about the Cplusplus-sig mailing list