[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