pygccxml-development Mailing List for C++ Python language bindings (Page 2)
Brought to you by:
mbaas,
roman_yakovenko
You can subscribe to this list here.
2006 |
Jan
|
Feb
(6) |
Mar
(160) |
Apr
(96) |
May
(152) |
Jun
(72) |
Jul
(99) |
Aug
(189) |
Sep
(161) |
Oct
(110) |
Nov
(9) |
Dec
(3) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
(13) |
Feb
(48) |
Mar
(35) |
Apr
(7) |
May
(37) |
Jun
(8) |
Jul
(15) |
Aug
(8) |
Sep
(2) |
Oct
(1) |
Nov
(2) |
Dec
(38) |
2008 |
Jan
(11) |
Feb
(29) |
Mar
(17) |
Apr
(3) |
May
|
Jun
(64) |
Jul
(49) |
Aug
(51) |
Sep
(18) |
Oct
(22) |
Nov
(9) |
Dec
(9) |
2009 |
Jan
(28) |
Feb
(15) |
Mar
(2) |
Apr
(11) |
May
(6) |
Jun
(2) |
Jul
(3) |
Aug
(34) |
Sep
(5) |
Oct
(7) |
Nov
(13) |
Dec
(14) |
2010 |
Jan
(39) |
Feb
(3) |
Mar
(3) |
Apr
(14) |
May
(11) |
Jun
(8) |
Jul
(9) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
|
Feb
|
Mar
(7) |
Apr
|
May
|
Jun
(3) |
Jul
(3) |
Aug
(3) |
Sep
|
Oct
|
Nov
|
Dec
|
2015 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
(2) |
2016 |
Jan
(1) |
Feb
(1) |
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
(1) |
Aug
(1) |
Sep
|
Oct
|
Nov
(1) |
Dec
|
2019 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
(1) |
2020 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
(1) |
2021 |
Jan
(1) |
Feb
(1) |
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(1) |
Nov
|
Dec
|
From: Roman Y. <rom...@gm...> - 2011-03-07 19:07:05
|
On Mon, Mar 7, 2011 at 8:32 PM, Scott Sturdivant <sc...@bi...> wrote: > Hi, > I'm experiencing strange behavior with the techniques described by the > multi-module development documentation. > > With the attached example, I have a common extension that's able to perform > exception translation. I'm able to use it like this: > > scott@blargh-desktop:~/workspace/excepTest$ python > Python 2.6.6 (r266:84292, Sep 15 2010, 16:22:56) > [GCC 4.4.5] on linux2 > Type "help", "copyright", "credits" or "license" for more information. >>>> from usage import usage >>>> usage.UseThem().foo() > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > RuntimeError: unidentifiable C++ exception >>>> from myexception import libmyexception >>>> usage.UseThem().foo() > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > RuntimeError: This is my exception. > > However, if I compile and run this code on a different machine, I get the > following behavior: > > ssturdiv other-desktop:~/excepTest [753]% python > Python 2.6.5 (r265:79063, Oct 13 2010, 08:09:12) > [GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2 > Type "help", "copyright", "credits" or "license" for more information. >>>> from myexception import > KeyboardInterrupt >>>> from usage import usage >>>> usage.UseThem().foo() > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > RuntimeError: unidentifiable C++ exception >>>> from myexception import libmyexception >>>> usage.UseThem().foo() > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > RuntimeError: unidentifiable C++ exception >>>> > > For the machine that works, my version of libboost_python is 1.42 whereas on > the machine that doesn't work, I'm using version 1.43. Similarly, > pyplusplus.__version__ shows '1.5.0' on the working machine, '1.0.0' on the > non-working one. There are other difference like the default gcc. May I ask you to try to add the following line: import sys sys.setdlopenflags(RTLD_NOW | RTLD_GLOBAL) If this helps, I suggest you to use technique described here: http://www.boost.org/doc/libs/1_46_0/libs/python/doc/tutorial/doc/html/python/techniques.html#python.creating_packages It will save you some time later. > Does this behavior ring any bells for someone? Would an upgrade on the > non-working machine solve the problem? I'm somewhat hesitant to upgrade, as > the non-working machine has its Py++ installed from the 1.0.0 release zip > file. Correct me if I'm wrong, but upgrading at this point would involve > just grabbing HEAD from SVN? Yes, but I don't believe your issue will gone. HTH |
From: Roman Y. <rom...@gm...> - 2010-07-19 06:42:40
|
On Fri, Jul 16, 2010 at 5:50 PM, Gustavo Carneiro <gjc...@gm...> wrote: > Here's the patch as promised. > Best regards. Thank you. Your patch was integrated: http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1844&view=rev . -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Roman Y. <rom...@gm...> - 2010-07-19 05:15:14
|
On Mon, Jul 19, 2010 at 7:50 AM, Alexey Stepanov <Ale...@ro...> wrote: > Thanks a lot the reply. If I understood your advice correctly, such an approach is not good for me, for it had got some important drawbacks. > (i.e. I have to make header files, and cpp for them is to be generated with the code injection) > > Firstly, in any case this code is being located in the same cpp files with the wrappers, though I have not corrected them (time of compilation!). > Secondly, before correction the code must be written first in the separate files, and then the generating script is be executed (time on gccxml!). > Thirdly, the manually made headers have to be corrected separately from realizations. > > Looking at the generated file structure I surmised, that there is an ordinary possibility to move the wrapeprs into the header file > (I have not found such a one) and simply include them into the generated file (I've found such a possibility). > > Do you have any ideas how to move in this direction? May be it is my English, but I am not able to understand you. What Benoit described, is just a way to integrate generated code with the hand-written one. If you don't like it, you can choose your own one. py++ is pretty flexible. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Alexey S. <Ale...@ro...> - 2010-07-19 04:50:50
|
Thanks a lot the reply. If I understood your advice correctly, such an approach is not good for me, for it had got some important drawbacks. (i.e. I have to make header files, and cpp for them is to be generated with the code injection) Firstly, in any case this code is being located in the same cpp files with the wrappers, though I have not corrected them (time of compilation!). Secondly, before correction the code must be written first in the separate files, and then the generating script is be executed (time on gccxml!). Thirdly, the manually made headers have to be corrected separately from realizations. Looking at the generated file structure I surmised, that there is an ordinary possibility to move the wrapeprs into the header file (I have not found such a one) and simply include them into the generated file (I've found such a possibility). Do you have any ideas how to move in this direction? |
From: Gustavo C. <gjc...@gm...> - 2010-07-16 14:50:36
|
Here's the patch as promised. Best regards. On Tue, Jul 6, 2010 at 19:49, Roman Yakovenko <rom...@gm...>wrote: > On Tue, Jul 6, 2010 at 5:04 PM, Gustavo Carneiro <gjc...@gm...> > wrote: > > It seems pygccxml (1.0) tracbacks when the type __int128_t is found in a > > header file. I don't really care about the type, it is used internally > by > > an implementation class which I do not wish to wrap, but the mere > presence > > of this type is enough to crash pygccxml and stop me from scanning the > rest > > of the API. > > I understand. > > We have few ways to continue: > * you create an xml file that contains that type and send it to me and > I fix pygccxml > * you can add that type to pygccxml by yourself and send me the patches :-) > > > Basically the are only few place, where pygccxml should be changed: > * declarations/cpptypes.py > * Python class, that represents the type should be created and added > to the FUNDAMENTAL_TYPES dictionary > * declarations/type_traits.py > * is_integral function should be changed to return "true" for this type > too > * declarations/__init__.py > * the file should provide access to the class > > That's all. You are free to select any method you want :-) > > > > -- > Roman Yakovenko > C++ Python language binding > http://www.language-binding.net/ > -- Gustavo J. A. M. Carneiro INESC Porto, UTM, WiN, http://win.inescporto.pt/gjc "The universe is always one step beyond logic." -- Frank Herbert |
From: Benoit L. <ben...@mo...> - 2010-07-16 11:33:25
|
Alexey Stepanov wrote: > I’d like to use Python in the following way: > 1) create a library (pyd) with some interfaces of the main program taken > outside; generate then its code with py++ > 2) create a set of scripts, that use this library > 3) execute these scripts with boost::python from the main program > Unwillingness to carry out any manual corrections of the generated code > is an important part of the solution. The code is being generated > authomatically, and only the script and the imported header are to be > corrected in case of any problem. It is motivated by the fact, that > the program is developing dynamically and it is better to see and solve > immedeately the emerging discrepancies. > Thus, the main task of implementation phase been solved already, but > there arose the following problem: there appeared a desire to transfer > into python our objects (from those being exposed). But all wrappers are > being generated into the library from the point 1, and are in the > cpp files. > I’m ready to make the dependance of the main module on the library. But > how to get the wrappers, if it is undesirable to correct the generated > code manually? Was my answer on cplusplus-sig irrelevant? As you moved the discussion here, here it is for reference: --- Manually fixing the generated code is indeed a bad idea. You should take a look at the code injection feature of py++. What you can do is having your "binding generator" detecting some custom files and then injecting the code in the wrappers. - you define a "custom code" folder, - whenever your generator detects a "MyClass_injection.cpp" file, then it will inject the code of this file into the wrapper of 'MyClass', cls.add_wrapper_code( custom_code ) This is the basic approach, you may need to inject declaration code, registration code, some code at the module level and not the class level, handle templates, etc. but once you get the basic system in place, you can add more features as the need arise. This way, you don't have to change your original headers nor the generated code directly. Hope that helps, --- Best, Benoit |
From: Alexey S. <Ale...@ro...> - 2010-07-16 11:20:26
|
Hi, I'd like to use Python in the following way: 1) create a library (pyd) with some interfaces of the main program taken outside; generate then its code with py++ 2) create a set of scripts, that use this library 3) execute these scripts with boost::python from the main program Unwillingness to carry out any manual corrections of the generated code is an important part of the solution. The code is being generated authomatically, and only the script and the imported header are to be corrected in case of any problem. It is motivated by the fact, that the program is developing dynamically and it is better to see and solve immedeately the emerging discrepancies. Thus, the main task of implementation phase been solved already, but there arose the following problem: there appeared a desire to transfer into python our objects (from those being exposed). But all wrappers are being generated into the library from the point 1, and are in the cpp files. I'm ready to make the dependance of the main module on the library. But how to get the wrappers, if it is undesirable to correct the generated code manually? Thanks, Alex |
From: Roman Y. <rom...@gm...> - 2010-07-06 18:50:06
|
On Tue, Jul 6, 2010 at 5:04 PM, Gustavo Carneiro <gjc...@gm...> wrote: > It seems pygccxml (1.0) tracbacks when the type __int128_t is found in a > header file. I don't really care about the type, it is used internally by > an implementation class which I do not wish to wrap, but the mere presence > of this type is enough to crash pygccxml and stop me from scanning the rest > of the API. I understand. We have few ways to continue: * you create an xml file that contains that type and send it to me and I fix pygccxml * you can add that type to pygccxml by yourself and send me the patches :-) Basically the are only few place, where pygccxml should be changed: * declarations/cpptypes.py * Python class, that represents the type should be created and added to the FUNDAMENTAL_TYPES dictionary * declarations/type_traits.py * is_integral function should be changed to return "true" for this type too * declarations/__init__.py * the file should provide access to the class That's all. You are free to select any method you want :-) -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Benoit L. <ben...@mo...> - 2010-07-06 14:22:35
|
Hello, If anyone is trying to work with boost 1.43, you'll need to apply a patch to the boost config file for gcc-xml before being able to run pygccxml (or just gccxml) on it. (the patch is taken from the trunk (soon to become 1.44 branch) of boost) File to patch: boost/config/compiler/gcc_xml.hpp Patch: 27a28,52 > // C++0x features: > // > # define BOOST_NO_CONSTEXPR > # define BOOST_NO_NULLPTR > # define BOOST_NO_TEMPLATE_ALIASES > # define BOOST_NO_DECLTYPE > # define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS > # define BOOST_NO_RVALUE_REFERENCES > # define BOOST_NO_STATIC_ASSERT > # define BOOST_NO_VARIADIC_TEMPLATES > # define BOOST_NO_AUTO_DECLARATIONS > # define BOOST_NO_AUTO_MULTIDECLARATIONS > # define BOOST_NO_CHAR16_T > # define BOOST_NO_CHAR32_T > # define BOOST_NO_DEFAULTED_FUNCTIONS > # define BOOST_NO_DELETED_FUNCTIONS > # define BOOST_NO_INITIALIZER_LISTS > # define BOOST_NO_SCOPED_ENUMS > # define BOOST_NO_SFINAE_EXPR > # define BOOST_NO_SCOPED_ENUMS > # define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS > # define BOOST_NO_LAMBDAS > # define BOOST_NO_RAW_LITERALS > # define BOOST_NO_UNICODE_LITERALS > |
From: Gustavo C. <gjc...@gm...> - 2010-07-06 14:05:12
|
It seems pygccxml (1.0) tracbacks when the type __int128_t is found in a header file. I don't really care about the type, it is used internally by an implementation class which I do not wish to wrap, but the mere presence of this type is enough to crash pygccxml and stop me from scanning the rest of the API. File "/home/tomh/hg/jul10/ns-3-allinone/pybindgen/pybindgen/gccxmlparser.py", line 683, in parse_init self.declarations = parser.parse(header_files, self.gccxml_config) File "/usr/lib/python2.5/site-packages/pygccxml/parser/__init__.py", line 50, in parse self.declarations = parser.parse(header_files, self.gccxml_config) File "/usr/lib/python2.5/site-packages/pygccxml/parser/__init__.py", line 50, in parse answer = parser.read_files(files, compilation_mode) File "/usr/lib/python2.5/site-packages/pygccxml/parser/project_reader.py", line 225, in read_files answer = parser.read_files(files, compilation_mode) File "/usr/lib/python2.5/site-packages/pygccxml/parser/project_reader.py", line 225, in read_files return self.__parse_file_by_file(files) File "/usr/lib/python2.5/site-packages/pygccxml/parser/project_reader.py", line 250, in __parse_file_by_file decls = reader.read_file( header ) File "/usr/lib/python2.5/site-packages/pygccxml/parser/source_reader.py", line 197, in read_file return self.__parse_file_by_file(files) File "/usr/lib/python2.5/site-packages/pygccxml/parser/project_reader.py", line 250, in __parse_file_by_file decls = reader.read_file( header ) File "/usr/lib/python2.5/site-packages/pygccxml/parser/source_reader.py", line 197, in read_file return self.read_gccxml_file( source_file ) File "/usr/lib/python2.5/site-packages/pygccxml/parser/source_reader.py", line 224, in read_gccxml_file raise error RuntimeError: pygccxml error: unable to find fundamental type with name '__int128_t'. return self.read_gccxml_file( source_file ) File "/usr/lib/python2.5/site-packages/pygccxml/parser/source_reader.py", line 224, in read_gccxml_file raise error RuntimeError: pygccxml error: unable to find fundamental type with name '__int128_t'. -- Gustavo J. A. M. Carneiro INESC Porto, UTM, WiN, http://win.inescporto.pt/gjc "The universe is always one step beyond logic." -- Frank Herbert |
From: Benoit L. <ben...@mo...> - 2010-06-28 13:20:46
|
Roman Yakovenko wrote: > On Mon, Jun 28, 2010 at 1:22 PM, Benoit Leveau > <ben...@mo...> wrote: >> Hello, >> >> In a class, I have the following method: >> void addLayer( boost::shared_ptr<Color> color = Color::create(1,1,1) ); >> >> This method is exposed by py++ with the following incorrect code: >> ClassWrapper_exposer.def( >> "addLayer", >> addLayer_function_type( &::MyClass::addLayer ), >> bp::arg("color")=Color::create(float, float, float)(1.0e+0f, 1.0e+0f) ); >> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> note the (float..) part which is incorrect, and only 2 parameters are >> supplied then >> >> Rright now i have to edit the code generated by py++...or maybe I can try to >> use the following code: >> >> boost::shared_ptr<Color> defaultColor() { return Color::create(1,1,1); } >> void addLayer( boost::shared_ptr<Color> color = defaultColor() ); >> >> Is it a known bug in py++? > > Yes. basically this is a limitation of the technology, py++ is built > on - gccxml : http://language-binding.net/pygccxml/upgrade_issues.html?highlight=default#free-and-member-function-default-arguments > GCCXML is not able to dump any/arbitrary C++ expression. You can find > a lot of post on this subject in GCCXML mailing list. pygccxml/py++ > tries pretty hard to fix this behavior, but there are cases where it > fails. Thanks! I don't know why I didn't find this page :( and I didn't think about searching specifically in the gccxml mailing list... > The work-around is pretty simple: > > #f is "calldef_t" instance > for arg in f.arguments: > arg.default_value = "<<<new default value or None>>>" > > thus you will not have to touch generated code. > Works great thanks. Benoit |
From: Roman Y. <rom...@gm...> - 2010-06-28 10:33:57
|
On Mon, Jun 28, 2010 at 1:22 PM, Benoit Leveau <ben...@mo...> wrote: > Hello, > > In a class, I have the following method: > void addLayer( boost::shared_ptr<Color> color = Color::create(1,1,1) ); > > This method is exposed by py++ with the following incorrect code: > ClassWrapper_exposer.def( > "addLayer", > addLayer_function_type( &::MyClass::addLayer ), > bp::arg("color")=Color::create(float, float, float)(1.0e+0f, 1.0e+0f) ); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > note the (float..) part which is incorrect, and only 2 parameters are > supplied then > > Rright now i have to edit the code generated by py++...or maybe I can try to > use the following code: > > boost::shared_ptr<Color> defaultColor() { return Color::create(1,1,1); } > void addLayer( boost::shared_ptr<Color> color = defaultColor() ); > > Is it a known bug in py++? Yes. basically this is a limitation of the technology, py++ is built on - gccxml : http://language-binding.net/pygccxml/upgrade_issues.html?highlight=default#free-and-member-function-default-arguments GCCXML is not able to dump any/arbitrary C++ expression. You can find a lot of post on this subject in GCCXML mailing list. pygccxml/py++ tries pretty hard to fix this behavior, but there are cases where it fails. The work-around is pretty simple: #f is "calldef_t" instance for arg in f.arguments: arg.default_value = "<<<new default value or None>>>" thus you will not have to touch generated code. HTH -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Benoit L. <ben...@mo...> - 2010-06-28 10:22:45
|
Hello, In a class, I have the following method: void addLayer( boost::shared_ptr<Color> color = Color::create(1,1,1) ); This method is exposed by py++ with the following incorrect code: ClassWrapper_exposer.def( "addLayer", addLayer_function_type( &::MyClass::addLayer ), bp::arg("color")=Color::create(float, float, float)(1.0e+0f, 1.0e+0f) ); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ note the (float..) part which is incorrect, and only 2 parameters are supplied then Rright now i have to edit the code generated by py++...or maybe I can try to use the following code: boost::shared_ptr<Color> defaultColor() { return Color::create(1,1,1); } void addLayer( boost::shared_ptr<Color> color = defaultColor() ); Is it a known bug in py++? Thanks! |
From: Roman Y. <rom...@gm...> - 2010-06-25 18:53:27
|
On Thu, Jun 24, 2010 at 3:13 PM, Benoit Leveau <ben...@mo...> wrote: > ok thanks for the explanation! > As i said in my additional note, I don't really have to fix this problem as > I'm supposed to exclude these methods in the first place, but > thanks for the explanation! Good to know. > Also, I'm curious. If I call rename(new_name) at some point on some class > declarations, do I need to call the run_query_optimizer too? Can it affect > the generated code if I don't do it? Yes. Internally py++ does a lot of searches. For example, it tries to understand from the class name ( std::vector< int > ) the "item" type. It parses the name and then executes a lot of searches to find the declaration. I follow the principle "the error should not pass silently", so it is possible that some internal detail of py++ will change and your code will stop working. You'd better run the code optimizer one more time. > I've just implemented an easy workaround which creates one > module_builder.module_builder_t, extracts all the readme strings into a > dict, then deletes this module_builder_t > and creates a new one to do all the binding. When I want to access a readme > string, I just use the dict instead. :-), nice work around. I will try to find some time next week and resolve the bug. > >> May I suggest you something? Can you create a single file, which >> includes all other files and pass it to py++? >> The proposed mode has few advantages, over the current one: >> * much faster >> * doesn't contain known bugs :-) >> >> Can you try to switch to it? > > I'm already using this approach (don't exactly remember why but I had to at > some point), ie. I dynamically creates a temporary file which #include all > the header files I want to bind. And the problem with "readme" still exists? Strange. The tests you gave, uses the opposite approach: "parse each file and then merge the declarations tree into a single one". Can you confirm this? I would like to deprecate "parse each file and then merge the declarations tree into a single one" method, since it introduces more problems, then solves. So there is no motivation to fix bugs in that code, but if you say that you don't use it and still has the "buggy" behavior, than the bug will be found and fixed. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Benoit L. <ben...@mo...> - 2010-06-24 16:30:23
|
Roman Yakovenko wrote: > On Thu, Jun 24, 2010 at 1:49 PM, Benoit Leveau > <ben...@mo...> wrote: >> Benoit Leveau wrote: > > I am really sorry for late response - few issues in production :-( no problem, and I don't consider a response within 24h as late ;) >>> Here is an extract of my class (complete test case attached) >>> -- >>> class Foo >>> { >>> ... >>> protected: >>> template< typename T > void method_( std::vector< T > &vec ); >>> }; > > > py++ contains work around for the issue you have. > > You will have to change the function name: > > mb = module_builder_t( ... ) > f = mb.mem_fun( ... ) > f.name = f.demangled_name > > mb.run_query_optimizer() > > > Description. GCCXML, when reports found function declarations, reports > name only. py++ (via pygccxml) uses "mangled" function name and tries > to extract the relevant information. The approach is an error prone > and I don't have enough use case, to make it to be the "default" > behavior. > > After you change the function name, you will have to re-initialize the > "query optimizer". Query optimizer allows py++ to find declaration > very quickly. A declaration name is one of the important keys in its > data structure. ok thanks for the explanation! As i said in my additional note, I don't really have to fix this problem as I'm supposed to exclude these methods in the first place, but thanks for the explanation! Also, I'm curious. If I call rename(new_name) at some point on some class declarations, do I need to call the run_query_optimizer too? Can it affect the generated code if I don't do it? >> Additional note: >> I'm excluding the protected/private functions from the binding so this bug shouldn't bother me, >> but because of the other bug I reported (caused by the readme() call), these protected functions are not excluded as they should, >> so the compilation error appears. > > :-((( I've just implemented an easy workaround which creates one module_builder.module_builder_t, extracts all the readme strings into a dict, then deletes this module_builder_t and creates a new one to do all the binding. When I want to access a readme string, I just use the dict instead. > May I suggest you something? Can you create a single file, which > includes all other files and pass it to py++? > The proposed mode has few advantages, over the current one: > * much faster > * doesn't contain known bugs :-) > > Can you try to switch to it? I'm already using this approach (don't exactly remember why but I had to at some point), ie. I dynamically creates a temporary file which #include all the header files I want to bind. |
From: Roman Y. <rom...@gm...> - 2010-06-24 11:47:00
|
On Thu, Jun 24, 2010 at 1:49 PM, Benoit Leveau <ben...@mo...> wrote: > Benoit Leveau wrote: I am really sorry for late response - few issues in production :-( >> Here is an extract of my class (complete test case attached) >> -- >> class Foo >> { >> ... >> protected: >> template< typename T > void method_( std::vector< T > &vec ); >> }; py++ contains work around for the issue you have. You will have to change the function name: mb = module_builder_t( ... ) f = mb.mem_fun( ... ) f.name = f.demangled_name mb.run_query_optimizer() Description. GCCXML, when reports found function declarations, reports name only. py++ (via pygccxml) uses "mangled" function name and tries to extract the relevant information. The approach is an error prone and I don't have enough use case, to make it to be the "default" behavior. After you change the function name, you will have to re-initialize the "query optimizer". Query optimizer allows py++ to find declaration very quickly. A declaration name is one of the important keys in its data structure. > Additional note: > I'm excluding the protected/private functions from the binding so this bug shouldn't bother me, > but because of the other bug I reported (caused by the readme() call), these protected functions are not excluded as they should, > so the compilation error appears. :-((( May I suggest you something? Can you create a single file, which includes all other files and pass it to py++? The proposed mode has few advantages, over the current one: * much faster * doesn't contain known bugs :-) Can you try to switch to it? -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Benoit L. <ben...@mo...> - 2010-06-24 10:50:05
|
Benoit Leveau wrote: > Hello, > > I just found a case where the code generated by py++ doesn't compile. A > method of the class wrapper tries to call the original class's method, > but without giving the correct template parameter in the call, resulting > in a compilation error. > > Here is an extract of my class (complete test case attached) > -- > class Foo > { > ... > protected: > template< typename T > void method_( std::vector< T > &vec ); > }; > -- > > Py++ generates this: > -- > struct Foo_wrapper : Foo, bp::wrapper< Foo > > { > ... > void method_( ::std::vector< int > &vec ) > { > Foo::method_( boost::ref(vec) ); > ^======== misses the '<int>' > } > }; > -- > > Note that if I use 'T' instead of 'std::vector<T>', then it compiles > fine. Here, the compiler apparently can't decide based on > 'boost::ref(vec)' type which T to use. > > To reproduce: > >> python py_bug_reproduce.py > warning W1031: `Py++` will generate class wrapper - user asked to expose > non - public member function "method_" >> g++ -c -o generated/Foo.pypp.o -I/software/tools/include/boost/1.36.0 >> -I/software/python/2.5.1/linux.centos4.x86_64/include/python2.5 >> generated/Foo.pypp.cpp > generated/Foo.pypp.cpp: In member function ‘void > Foo_wrapper::method_(std::vector<int, std::allocator<int> >&)’: > generated/Foo.pypp.cpp:38: error: no matching function for call to > ‘Foo_wrapper::method_(const boost::reference_wrapper<std::vector<int, > std::allocator<int> > >)’ > > Is the error caused by what py++ warns about? (W1031) > If I remove the 'protected:' line from Foo class, py++ doesn't generate > any code for method_ in Foo_wrapper, and binds the Foo method directly, > which successfully compiles. Additional note: I'm excluding the protected/private functions from the binding so this bug shouldn't bother me, but because of the other bug I reported (caused by the readme() call), these protected functions are not excluded as they should, so the compilation error appears. |
From: Benoit L. <ben...@mo...> - 2010-06-23 17:59:09
|
Hello, I just found a case where the code generated by py++ doesn't compile. A method of the class wrapper tries to call the original class's method, but without giving the correct template parameter in the call, resulting in a compilation error. Here is an extract of my class (complete test case attached) -- class Foo { ... protected: template< typename T > void method_( std::vector< T > &vec ); }; -- Py++ generates this: -- struct Foo_wrapper : Foo, bp::wrapper< Foo > { ... void method_( ::std::vector< int > &vec ) { Foo::method_( boost::ref(vec) ); ^======== misses the '<int>' } }; -- Note that if I use 'T' instead of 'std::vector<T>', then it compiles fine. Here, the compiler apparently can't decide based on 'boost::ref(vec)' type which T to use. To reproduce: > python py_bug_reproduce.py warning W1031: `Py++` will generate class wrapper - user asked to expose non - public member function "method_" > g++ -c -o generated/Foo.pypp.o -I/software/tools/include/boost/1.36.0 -I/software/python/2.5.1/linux.centos4.x86_64/include/python2.5 generated/Foo.pypp.cpp generated/Foo.pypp.cpp: In member function ‘void Foo_wrapper::method_(std::vector<int, std::allocator<int> >&)’: generated/Foo.pypp.cpp:38: error: no matching function for call to ‘Foo_wrapper::method_(const boost::reference_wrapper<std::vector<int, std::allocator<int> > >)’ Is the error caused by what py++ warns about? (W1031) If I remove the 'protected:' line from Foo class, py++ doesn't generate any code for method_ in Foo_wrapper, and binds the Foo method directly, which successfully compiles. Thanks! Benoit |
From: Benoît L. <ben...@gm...> - 2010-05-17 19:16:17
|
2010/5/17 Roman Yakovenko <rom...@gm...>: > On Mon, May 17, 2010 at 9:09 PM, Benoit Leveau > <ben...@mo...> wrote: >> Ok, that's what I thought! >> And I guess there is no way to "register" some Python code to be executed >> when the module is loaded, it must be done in the __init__.py file, right? > > No: > http://www.boost.org/doc/libs/1_43_0/libs/python/doc/tutorial/doc/html/python/embedding.html > > In any case, I suggest you to wrap your module in a Python package. > This will save you a lot of time later. Even now, you will not have to > learn how to "embed" Python code via Boost.Python. I am sure, this is > a nice topic to learn, but after all we have to deliver a product and > get some money :-) ? This is already a Python package actually ;) Thanks for the link. >>> The only help, you get from Py++, is warning "W1010". You can use >>> "x.readme()" functionality to check whether set of functions have such >>> problem or not. You can use that functionality as assert for the >>> "solution 4". >> >> Good, I didn't know a warning was issued in that case. >> >>>> From my experience patching boost, creates a huge headache. This is >>> >>> exactly the reason, why I migrated indexing suite v2 to be header only >>> library. >> >> Thanks! > > You are welcome. > > > > -- > Roman Yakovenko > C++ Python language binding > http://www.language-binding.net/ Thanks again! Benoit |
From: Roman Y. <rom...@gm...> - 2010-05-17 18:19:23
|
On Mon, May 17, 2010 at 9:09 PM, Benoit Leveau <ben...@mo...> wrote: > Ok, that's what I thought! > And I guess there is no way to "register" some Python code to be executed > when the module is loaded, it must be done in the __init__.py file, right? No: http://www.boost.org/doc/libs/1_43_0/libs/python/doc/tutorial/doc/html/python/embedding.html In any case, I suggest you to wrap your module in a Python package. This will save you a lot of time later. Even now, you will not have to learn how to "embed" Python code via Boost.Python. I am sure, this is a nice topic to learn, but after all we have to deliver a product and get some money :-) ? >> The only help, you get from Py++, is warning "W1010". You can use >> "x.readme()" functionality to check whether set of functions have such >> problem or not. You can use that functionality as assert for the >> "solution 4". > > Good, I didn't know a warning was issued in that case. > >>> From my experience patching boost, creates a huge headache. This is >> >> exactly the reason, why I migrated indexing suite v2 to be header only >> library. > > Thanks! You are welcome. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Roman Y. <rom...@gm...> - 2010-05-17 18:12:14
|
On Mon, May 17, 2010 at 8:31 PM, Benoit Leveau <ben...@mo...> wrote: > I already took a look at that page and: > - solution 1 doesn't work if you want to bind all the functions to one > unique alias: __setitem__ Ok. > - solution 2 & 3 don't change the fact that only one of the two functions > will be called (as bool and int can be converted to each other, it's always > the last one exposed that will be called) You are right. > - solution 4 is what I was mentionning in my message, but it doesn't seem > py++ can generate that code yet. Or does it? No, it doesn't. I guess you have no choice, but to implement that last method by yourself :-( The only help, you get from Py++, is warning "W1010". You can use "x.readme()" functionality to check whether set of functions have such problem or not. You can use that functionality as assert for the "solution 4". >From my experience patching boost, creates a huge headache. This is exactly the reason, why I migrated indexing suite v2 to be header only library. HTH -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Benoit L. <ben...@mo...> - 2010-05-17 18:09:30
|
Roman Yakovenko wrote: > On Mon, May 17, 2010 at 8:31 PM, Benoit Leveau > <ben...@mo...> wrote: >> I already took a look at that page and: >> - solution 1 doesn't work if you want to bind all the functions to one >> unique alias: __setitem__ > > Ok. > >> - solution 2 & 3 don't change the fact that only one of the two functions >> will be called (as bool and int can be converted to each other, it's always >> the last one exposed that will be called) > > You are right. > >> - solution 4 is what I was mentionning in my message, but it doesn't seem >> py++ can generate that code yet. Or does it? > > No, it doesn't. I guess you have no choice, but to implement that > last method by yourself :-( Ok, that's what I thought! And I guess there is no way to "register" some Python code to be executed when the module is loaded, it must be done in the __init__.py file, right? > The only help, you get from Py++, is warning "W1010". You can use > "x.readme()" functionality to check whether set of functions have such > problem or not. You can use that functionality as assert for the > "solution 4". Good, I didn't know a warning was issued in that case. >>From my experience patching boost, creates a huge headache. This is > exactly the reason, why I migrated indexing suite v2 to be header only > library. Thanks! |
From: Benoit L. <ben...@mo...> - 2010-05-17 17:31:22
|
Roman Yakovenko wrote: > On Mon, May 17, 2010 at 6:23 PM, Benoit Leveau > <ben...@mo...> wrote: >> Hello, >> >> Consider the following class: >> >> struct MyClass >> { >> void setBool(bool a); >> void setInt(int a); >> }; >> >> Because of the way the overloading resolution works currently in boost >> python, if you're trying to bind these two functions to __setitem__, >> only one of these functions (the last one bound actually) will always be >> called, no matter if you call __setitem__ with a bool or an int (for >> more information of the why, please take a look at the cplusplus-sig >> thread mentioned below). >> >> The only way I could find to bind these two methods to __setitem__ and >> have them called "correctly" is to bind them as two separate functions, >> and then define a __setitem__ function in python at runtime, by adding >> something like that in the __init__.py file: >> >> def custom_set_item(a): >> if isinstanceof(a, bool): >> ... >> ... >> >> MyClass.__setitem__ = custom_set_item >> >> Maybe there's a way to do that by binding a setitem which would take a >> bp::object and test the type in C++, I haven't tried. > > You can do this in C++ too, but why bother? You can generate that code > from Py++ :-) > >> It looks like Troy D. Straszheim came with a better implementation of >> the overloading mechanism (which is much closer to what we expect): >> http://mail.python.org/pipermail/cplusplus-sig/2009-December/015047.html >> >> It is apparently considered for addition in boost, but looks like >> they're waiting for the new langbinding integration: >> http://www.boost.org/doc/libs/1_43_0/libs/python/todo.html >> >> Any chance one of you have tried Troy's modification, or have any >> suggestion for this problem? > > Yes, I do. Please take a look on the following document( > http://language-binding.net/pyplusplus/documentation/functions/registration_order.html > ) and let me know whether it solved your problem or not. > I already took a look at that page and: - solution 1 doesn't work if you want to bind all the functions to one unique alias: __setitem__ - solution 2 & 3 don't change the fact that only one of the two functions will be called (as bool and int can be converted to each other, it's always the last one exposed that will be called) - solution 4 is what I was mentionning in my message, but it doesn't seem py++ can generate that code yet. Or does it? |
From: Roman Y. <rom...@gm...> - 2010-05-17 17:23:55
|
On Mon, May 17, 2010 at 6:23 PM, Benoit Leveau <ben...@mo...> wrote: > Hello, > > Consider the following class: > > struct MyClass > { > void setBool(bool a); > void setInt(int a); > }; > > Because of the way the overloading resolution works currently in boost > python, if you're trying to bind these two functions to __setitem__, > only one of these functions (the last one bound actually) will always be > called, no matter if you call __setitem__ with a bool or an int (for > more information of the why, please take a look at the cplusplus-sig > thread mentioned below). > > The only way I could find to bind these two methods to __setitem__ and > have them called "correctly" is to bind them as two separate functions, > and then define a __setitem__ function in python at runtime, by adding > something like that in the __init__.py file: > > def custom_set_item(a): > if isinstanceof(a, bool): > ... > ... > > MyClass.__setitem__ = custom_set_item > > Maybe there's a way to do that by binding a setitem which would take a > bp::object and test the type in C++, I haven't tried. You can do this in C++ too, but why bother? You can generate that code from Py++ :-) > It looks like Troy D. Straszheim came with a better implementation of > the overloading mechanism (which is much closer to what we expect): > http://mail.python.org/pipermail/cplusplus-sig/2009-December/015047.html > > It is apparently considered for addition in boost, but looks like > they're waiting for the new langbinding integration: > http://www.boost.org/doc/libs/1_43_0/libs/python/todo.html > > Any chance one of you have tried Troy's modification, or have any > suggestion for this problem? Yes, I do. Please take a look on the following document( http://language-binding.net/pyplusplus/documentation/functions/registration_order.html ) and let me know whether it solved your problem or not. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Benoit L. <ben...@mo...> - 2010-05-17 15:23:50
|
Hello, Consider the following class: struct MyClass { void setBool(bool a); void setInt(int a); }; Because of the way the overloading resolution works currently in boost python, if you're trying to bind these two functions to __setitem__, only one of these functions (the last one bound actually) will always be called, no matter if you call __setitem__ with a bool or an int (for more information of the why, please take a look at the cplusplus-sig thread mentioned below). The only way I could find to bind these two methods to __setitem__ and have them called "correctly" is to bind them as two separate functions, and then define a __setitem__ function in python at runtime, by adding something like that in the __init__.py file: def custom_set_item(a): if isinstanceof(a, bool): ... ... MyClass.__setitem__ = custom_set_item Maybe there's a way to do that by binding a setitem which would take a bp::object and test the type in C++, I haven't tried. It looks like Troy D. Straszheim came with a better implementation of the overloading mechanism (which is much closer to what we expect): http://mail.python.org/pipermail/cplusplus-sig/2009-December/015047.html It is apparently considered for addition in boost, but looks like they're waiting for the new langbinding integration: http://www.boost.org/doc/libs/1_43_0/libs/python/todo.html Any chance one of you have tried Troy's modification, or have any suggestion for this problem? Thanks! Benoit |