From: Roman <rom...@us...> - 2006-04-20 04:07:20
|
Update of /cvsroot/pygccxml/source/pyplusplus/docs/examples/date_time In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6005/pyplusplus/docs/examples/date_time Modified Files: date_time.rest Log Message: I was ill and did not have my TortoiseCVS :-). This commit contains documentation changes only. Those changes had been done for latest release version. Index: date_time.rest =================================================================== RCS file: /cvsroot/pygccxml/source/pyplusplus/docs/examples/date_time/date_time.rest,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** date_time.rest 16 Jan 2006 07:33:07 -0000 1.1 --- date_time.rest 20 Apr 2006 04:06:41 -0000 1.2 *************** *** 16,20 **** `date_time`_ is a cross-platform and open source C++ library designed to provide a basis for performing efficient time calculations. The `date_time`_ library has ! been created by Jeff Garland. In this example I am referring to version 1.33.1. What is the `pyplusplus`_? --- 16,20 ---- `date_time`_ is a cross-platform and open source C++ library designed to provide a basis for performing efficient time calculations. The `date_time`_ library has ! been created by Jeff Garland. What is the `pyplusplus`_? *************** *** 72,76 **** 2. customization_data.py - contains a table of aliases and other data ! 3. create_date_time.py - main file 4. sconstruct - build configuration file --- 72,76 ---- 2. customization_data.py - contains a table of aliases and other data ! 3. generate_code.py - main file 4. sconstruct - build configuration file *************** *** 84,102 **** Where x.y.z is the version of `pyplusplus`_ you are using. ! --------------------------------------------- ! Step 1: preparing declarations to be exported ! --------------------------------------------- ! ! At this step I had to create a set of declarations, that should be exported to ! `Python`_. For this purpose I have used `pygccxml`_ as C++ declarations reader. There were few problems I should have solved at this stage. ! 1. Compilation of the `date_time`_ library takes time, a lot of time. This is a ! real problem. Fortunately `pygccxml`_ provides solution to the problem. ! It allows to create, save and read `GCC-XML`_ generated file. Instead ! of parsing source files each time, `pygccxml`_ parses xml files only. Now, it takes only few seconds to read declarations. - - See create_date_time.py - *exporter_t.read_declarations* function. 2. The `date_time`_ library makes an extensive use of an other C++ libraries. --- 84,97 ---- Where x.y.z is the version of `pyplusplus`_ you are using. ! ------------------------ ! What should be exportes? ! ------------------------ ! The result of this step should be set of declarations I want to export to Python. There were few problems I should have solved at this stage. ! 1. Compilation of the `date_time`_ library takes some time. Fortunately ! `pygccxml`_ allows to create, save and read `GCC-XML`_ generated file. ! Instead of parsing source files each time, `pygccxml`_ parses xml files only. Now, it takes only few seconds to read declarations. 2. The `date_time`_ library makes an extensive use of an other C++ libraries. *************** *** 107,252 **** way I filtered out most of the declarations I do not need. ! See create_date_time.py - *exporter_t.filter_declarations* function. ! ! --------------------------------- ! Step 2: creating extension module ! --------------------------------- ! ! At this step `pyplusplus`_ associates C++ declaration with one or more code ! creators. There is a lot of work done here, but who cares? Small, simple and ! well defined interface of *module_creator.creator_t* class makes this step ! easy. There is something that *module_creator.creator_t* can not do: to guess ! call policies. Well, not a big deal. I defined custom call policies resolver. ! ! See create_date_time.py - *identify_call_policies* function for definition of ! custom call policies resolver. ! ! Also take a look at create_date_time.py - *exporter_t.filter_declarations* ! function. ! ! ------------------------------------ ! Step 3: customizing extension module ! ------------------------------------ ! ! There is a lot of customization that can be applied on extension module. ! Lets start: ! ! * Almost every source file in C++ starts from including an other file. ! `pyplusplus`_ can generate *#include* directives with relative paths. User ! just have to set root directories. That's all. There is some nice side ! effect: for cross-platform libraries generated code is cross-platform too. ! ! * Human should be able to read generated code. More over, one of the goals ! of `pyplusplus`_ is to generate code as close as possible to hand written ! one. One of the aspects of generating such code is namespace aliasing. ! I don't like to read/write code that looks like this: ! *boost::posix_time::ptime pt( boost::posix_time::not_a_date_time ); * ! I prefer: ! *namespace bpt=boost::posix_time;* ! *bpt::ptime pt( bpt::not_a_date_time );* ! This is my personal taste, but I am sure that a lot of people will agree ! with me. So I configured extension module to use predefined namespace ! aliases. ! ! * There is a small rule in C++: template function that was not used is not ! instantiated. Nice rule, but in my case it made a problem: some ! operators and member functions were not exported. The solution is simple. ! I had to add missing functionality by hand. Luckily `pyplusplus`_ allows ! to add user code almost in any place. Using unit test I have found all ! classes, that missed some functionality and added it. ! ! * Operators. The `date_time`_ library is using `boost.operators`_ framework to ! implement operators overloading. This causes a small problem in `Python`_ ! code. Operators, defined in based class, were not visible while using ! derived class. After small conversation with people, from boost.python ! list, the solution was found - to redefine all operators in derived class. ! This functionality was missing in `pyplusplus`_. It took me one hour to ! implement it. *code_creator.class_t* class from now has new property ! called *redefine_operators*. All I needed to do, in order to export ! operators in derived class, is to turn the flag on. ! ! * The `date_time`_ make an extensive use of templates. This means that exported ! class name is not valid `Python`_ identifier. For example: ! *typedef weeks_duration<boost::date_time::duration_traits_adapted> weeks;* ! *weeks_duration<boost::date_time::duration_traits_adapted>* is not valid ! `Python`_ identifier. Also `pyplusplus`_ is able to create valid `Python`_ ! identifier for such case. Those names are not idial. Solution: I created a ! table that maps between original class name to aliases. During the ! extension module customization process I reset the aliases of the exported ! classes. The result: `Python`_ bindings have exactly the same names as in ! C++. This also solves an other very important issue: original library ! documentation and examples - they could be reused, without any changes. ! See create_date_time.py - *exporter_t.customize_extmodule* function. ! ----------------------------- ! Step 4: writing code to files ! ----------------------------- Functionality provided by `pyplusplus`_ was good enough for this use case. More over, `pyplusplus`_ writes code into file only in case the code is different. This functionality was specially useful - small compilation time. ! See create_date_time.py - *exporter_t.write_files* function. ---------- Conclusion ---------- ! I think I proved, at least for my self, that `pyplusplus`_ is not only useful but ! also ready for hard work! Here is summury list of raised problems and implemented ! solutions: ! ! + Problem: ! ! What is the easiest way to define a set of declarations to be exported? ! ! Solution: ! ! The easiest way to define a set of declaration to be exported is to use ! project native layout - namespaces. ! ! + Problem: ! ! How to reduce compilation time? ! ! Solution: ! ! 1. `pygccxml`_ has been configured to work with XML files and not sources. ! ! 2. `pyplusplus`_ has multiple files mode, in which code is written into ! the file only when it had been changed. ! ! + Problem: ! ! I'd like to set function "X" call policies, based on the fact "Y". ! ! Solution: ! ! `pyplusplus`_ allows to create user defined call policies plug in. ! `pygccxml`_ allows user to analize function return and arguments types. ! ! + Problem: ! ! I'd like to insert code "X" at location "Y". ! ! Solution: ! ! `pyplusplus`_ allows to insert user code almost any where. ! ! I think those are common problems, for programmers who try to create `Python`_ ! bindings to some library. More over I think that `pygccxml`_ + `pyplusplus`_ ! provide good solution. ! ! There is one important result - ready to use, good date\\time library for ! `Python`_. You can download `Python`_ packages for Linux ( `Python`_ 2.3 ) or ! Windows (`Python`_ 2.4 ) from http://sourceforge.net/project/showfiles.php?group_id=118209. ! ! I am going to continue development of the `Python`_ bindings for `boost.date_time`_ ! library. ! An other important result is that `pyplusplus`_ gained one more excelent test ! case. .. _`environment.py`: http://cvs.sourceforge.net/viewcvs.py/pygccxml/source/pyplusplus/examples/py_easybmp/environment.py?view=markup --- 102,162 ---- way I filtered out most of the declarations I do not need. ! ---------------------- ! Configure declarations ! ---------------------- ! There is a lot of configuration have been applied on declarations: ! 1. Every template instantiation class has been renamed. The result: `Python`_ ! bindings have exactly the same names as in C++. This also solves an other very ! important issue: original library documentation and examples - they could be ! reused, without any changes. You can take a look on py_date_time/unittests ! directory content. ! 2. Namespace aliases have been introduced. ``bpt`` is shorter then ! ``boost::posix_time``. As a result, generated code is more readable. + 3. Operators. The `date_time`_ library is using `boost.operators`_ framework to + implement operators overloading. This causes a small problem in `Python`_ + code. Operators, defined in based class, were not visible while using + derived class. After small conversation with people, from boost.python + list, the solution was found - to redefine all operators in derived class. + This functionality was missing in `pyplusplus`_. It took me one hour to + implement it. *code_creator.class_t* class from now has new property + called *redefine_operators*. All I needed to do, in order to export + operators in derived class, is to turn the flag on. + + --------------------- + Writing code to files + --------------------- Functionality provided by `pyplusplus`_ was good enough for this use case. More over, `pyplusplus`_ writes code into file only in case the code is different. This functionality was specially useful - small compilation time. ! ----------- ! Small bonus ! ----------- ! `boost.date_time`_ library is under development. There were a lot of changes ! from version 1.33 to 1.34. Nevertheless I almost did not spend time to change ! or update my script. The main reason is of course the script I wrote. Instead ! of working on every single class/function/file, `pyplusplus`_ allowed me to ! create a set of rules, that work on whole set of declarations. ---------- Conclusion ---------- + As for me, `pyplusplus`_ is ready for hard work! + * Big and complex C++ library has been exposed to `Python`_ in few days only. + * You can see from script, that there is no need in deep knowledge of `boost.python`_ library. + * Python gain an excelent functionality for dealing with date/time. + * Real world, 3rd party project is used in testing of `pyplusplus`_. ! -------- ! Download ! -------- ! http://sourceforge.net/project/showfiles.php?group_id=118209. + I am going to continue development of the `Python`_ bindings for + `boost.date_time`_ library. .. _`environment.py`: http://cvs.sourceforge.net/viewcvs.py/pygccxml/source/pyplusplus/examples/py_easybmp/environment.py?view=markup |