From 988f70d66d79d02c78e6516fc789a105c8bc7954 Mon Sep 17 00:00:00 2001 From: Andre Anjos <andre.anjos@idiap.ch> Date: Mon, 26 May 2014 13:00:14 +0200 Subject: [PATCH] xbob -> bob --- .travis.yml | 4 +- MANIFEST.in | 2 +- README.rst | 189 ++----------- {xbob => bob}/__init__.py | 0 {xbob => bob}/extension/__init__.py | 10 +- {xbob => bob}/extension/boost.py | 8 +- .../include/bob.extension}/documentation.h | 96 +++---- {xbob => bob}/extension/pkgconfig.py | 4 +- {xbob => bob}/extension/test_boost.py | 0 {xbob => bob}/extension/test_pkgconfig.py | 0 {xbob => bob}/extension/test_utils.py | 0 {xbob => bob}/extension/utils.py | 10 +- buildout.cfg | 4 +- doc/conf.py | 12 +- doc/guide.rst | 248 ++++++++++++++++-- doc/py_api.rst | 6 +- setup.py | 6 +- 17 files changed, 328 insertions(+), 271 deletions(-) rename {xbob => bob}/__init__.py (100%) rename {xbob => bob}/extension/__init__.py (97%) rename {xbob => bob}/extension/boost.py (96%) rename {xbob/extension/include/xbob.extension => bob/extension/include/bob.extension}/documentation.h (91%) rename {xbob => bob}/extension/pkgconfig.py (99%) rename {xbob => bob}/extension/test_boost.py (100%) rename {xbob => bob}/extension/test_pkgconfig.py (100%) rename {xbob => bob}/extension/test_utils.py (100%) rename {xbob => bob}/extension/utils.py (95%) diff --git a/.travis.yml b/.travis.yml index 46b82d4..28b061b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,8 +13,8 @@ install: - "python bootstrap.py" - "./bin/buildout" script: - - "./bin/python -c 'from xbob.extension import get_config; print(get_config())'" - - "./bin/coverage run --source=xbob.extension ./bin/nosetests -sv" + - "./bin/python -c 'from bob.extension import get_config; print(get_config())'" + - "./bin/coverage run --source=bob.extension ./bin/nosetests -sv" - "./bin/sphinx-build -b doctest doc sphinx" - "./bin/sphinx-build -b html doc sphinx" after_success: diff --git a/MANIFEST.in b/MANIFEST.in index 86435a4..9f837bb 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,2 @@ include LICENSE README.rst bootstrap.py buildout.cfg -recursive-include xbob/extension *.h \ No newline at end of file +recursive-include bob/extension *.h \ No newline at end of file diff --git a/README.rst b/README.rst index b064788..bfd80a6 100644 --- a/README.rst +++ b/README.rst @@ -2,16 +2,16 @@ .. Andre Anjos <andre.anjos@idiap.ch> .. Thu 30 Jan 08:46:53 2014 CET -.. image:: https://travis-ci.org/bioidiap/xbob.extension.svg?branch=prototype - :target: https://travis-ci.org/bioidiap/xbob.extension -.. image:: https://coveralls.io/repos/bioidiap/xbob.extension/badge.png?branch=prototype - :target: https://coveralls.io/r/bioidiap/xbob.extension?branch=prototype -.. image:: http://img.shields.io/github/tag/bioidiap/xbob.extension.png - :target: https://github.com/bioidiap/xbob.extension -.. image:: http://img.shields.io/pypi/v/xbob.extension.png - :target: https://pypi.python.org/pypi/xbob.extension -.. image:: http://img.shields.io/pypi/dm/xbob.extension.png - :target: https://pypi.python.org/pypi/xbob.extension +.. image:: https://travis-ci.org/bioidiap/bob.extension.svg?branch=prototype + :target: https://travis-ci.org/bioidiap/bob.extension +.. image:: https://coveralls.io/repos/bioidiap/bob.extension/badge.png?branch=prototype + :target: https://coveralls.io/r/bioidiap/bob.extension?branch=prototype +.. image:: http://img.shields.io/github/tag/bioidiap/bob.extension.png + :target: https://github.com/bioidiap/bob.extension +.. image:: http://img.shields.io/pypi/v/bob.extension.png + :target: https://pypi.python.org/pypi/bob.extension +.. image:: http://img.shields.io/pypi/dm/bob.extension.png + :target: https://pypi.python.org/pypi/bob.extension =========================================== Python/C++ Bob Extension Building Support @@ -22,7 +22,7 @@ This package provides a simple mechanims for building Python/C++ extensions for it in your ``setup.py`` file. Building with ``zc.buildout`` is possible using the ``develop`` recipe in -`xbob.buildout <http://pypi.python.org/pypi/xbob.buildout>`_. Follow the +`bob.buildout <http://pypi.python.org/pypi/bob.buildout>`_. Follow the instructions described on that package for this recipe. Preparing for C++ Compilation @@ -32,35 +32,35 @@ Creating C++/Python bindings should be trivial. Firstly, edit your ``setup.py`` so that you include the following:: from setuptools import dist - dist.Distribution(dict(setup_requires=['xbob.extension'])) - from xbob.extension import Extension + dist.Distribution(dict(setup_requires=['bob.extension'])) + from bob.extension import Extension ... setup( - name="xbob.myext", + name="bob.myext", version="1.0.0", ... setup_requires=[ - 'xbob.extension', + 'bob.extension', ], ... ext_modules=[ - Extension("xbob.myext._myext", + Extension("bob.myext._myext", [ - "xbob/myext/ext/file1.cpp", - "xbob/myext/ext/file2.cpp", - "xbob/myext/ext/main.cpp", + "bob/myext/ext/file1.cpp", + "bob/myext/ext/file2.cpp", + "bob/myext/ext/main.cpp", ], packages = [ #pkg-config modules to append 'blitz>=0.10', 'bob-core', ], include_dirs = [ #optionally, include directories - "xbob/myext/ext/headers/", + "bob/myext/ext/headers/", ], ), ... #add more extensions if you wish @@ -76,8 +76,8 @@ manually using `the standard options for python extensions on the package through ``zc.buildout``, add the following section to your ``buildout.cfg``:: - [xbob.myext] - recipe = xbob.buildout:develop + [bob.myext] + recipe = bob.buildout:develop verbose = true ;enables command-line verbosity debug = true ;compiles the module in debug mode @@ -103,8 +103,8 @@ know it needs it before importing it. You can achieve this with the following trick:: from setuptools import dist - dist.Distribution(dict(setup_requires='xbob.extension')) - from xbob.extension.pkgconfig import pkgconfig + dist.Distribution(dict(setup_requires='bob.extension')) + from bob.extension.pkgconfig import pkgconfig .. note:: @@ -133,8 +133,8 @@ To use this package at your ``setup.py`` file, you will also need the same trick as with ``pkgconfig``:: from setuptools import dist - dist.Distribution(dict(setup_requires='xbob.extension')) - from xbob.extension.boost import boost + dist.Distribution(dict(setup_requires='bob.extension')) + from bob.extension.boost import boost After inclusion, you can just instantiate an object of type ``boost``:: @@ -150,140 +150,3 @@ After inclusion, you can just instantiate an object of type ``boost``:: ['boost_system-mt', 'boost_python-mt-py27'] -Documenting your Python extension ---------------------------------- -One part of this package are some functions that makes it easy to generate a proper python documentation for your bound C++ functions. -This documentation can be used after:: - - #include <xbob.extension/documentation.h> - - -Function documentation -====================== -To generate a properly aligned function documentation, you can use:: - - static xbob::extension::FunctionDoc description( - "function_name", - "Short function description", - "Optional long function description" - ); - -.. note:: - Please assure that you define this variable as ``static``. - -.. note:: - If you want to document a member function of a class, you should use set fourth boolean option to true. - This is required since the default python class member documentation is indented four more spaces, which we need to balance:: - - static xbob::extension::FunctionDoc member_function_description( - "function_name", - "Short function description", - "Optional long function description", - true - ); - -Using this object, you can add several parts of the function that need documentation: - -1. ``description.add_prototype("variable1, variable2", "return1, return2");`` can be used to add function definitions (i.e., ways how to use your function). - This function needs to be called at least once. - If the function does not define a return value, it can be left out (in which case the default ``"None"`` is used). - -2. ``description.add_parameter("variable1, variable2", "datatype", "Variable description");`` should be defined for each variable that you have used in the prototypes. - -3. ``description.add_return("return1", "datatype", "Return value description");`` should be defined for each return value that you have used in the prototypes. - -.. note:: - All these functions return a reference to the object, so that you can use them in line, e.g.:: - - static auto description = xbob::extension::FunctionDoc(...) - .add_prototype(...) - .add_parameter(...) - .add_return(...) - ; - -Finally, when binding you function, you can use: - -a) ``description.name()`` to get the name of the function - -b) ``description.doc()`` to get the aligned documentation of the function, properly indented and broken at 80 characters (by default). - This call will check that all parameters and return values are documented, and add a ``.. todo`` directive if not. - -Sphinx directives like ``.. note::``, ``.. warning::`` or ``.. math::`` will be automatically detected and aligned, when they are used as one-line directive, e.g.:: - - "(more text)\n\n.. note:: This is a note\n\n(more text)" - -Also, enumerations and listings (using the ``*`` character to define a list element) are handled automatically:: - - "(more text)\n\n* Point 1\n* Point 2\n\n(more text)" - -.. note:: - Please assure that directives are surrounded by double ``\n`` characters (see example above) so that they are put as paragraphs. - Otherwise, they will not be displayed correctly. - -.. note:: - The ``.. todo::`` directive seems not to like being broken at 80 characters. - If you want to use ``.. todo::``, please call, e.g., ``description.doc(10000)`` to avoid line breaking. - -.. note:: - To increase readability, you might want to split your documentation lines, e.g.:: - - "(more text)\n" - "\n" - "* Point 1\n" - "* Point 2\n" - "\n" - "(more text)" - -Leading white-spaces in the documentation string are handled correctly, so you can use several layers of indentation. - - -Class documentation -=================== -To document a bound C++ class, you can use the ``xbob::extension::ClassDoc("class_name", "Short class description", "Optional long class description")`` function to align and wrap your documentation. -Again, during binding you can use the functions ``description.name()`` and ``description.doc()`` as above. - -Additionally, the class documentation has a function to add constructor definitions, which takes an ``xbob::extension::FunctionDoc`` object. -The shortest way to get a proper class documentation is:: - - static auto my_class_doc = - xbob::extension::ClassDoc("class_name", "Short description", "Long Description") - .add_constructor( - xbob::extension::FunctionDoc("class_name", "Constructor Description") - .add_prototype("param1", "") - .add_parameter("param1", "type1", "Description of param1") - ) - ; - -.. note:: - The second parameter ``""`` in ``add_prototype`` prevents the output type (which otherwise defaults to ``"None"``) to be written. - -.. note:: - For constructor documentations, there is no need to declare them as member functions. - This is done automatically for you. - -Currently, the ClassDoc allows to highlight member functions or variables at the beginning of the class documentation. -This highlighting is still under development and might not work as expected. - -Possible speed issues -===================== - -In order to speed up the loading time of the modules, you might want to reduce the amount of documentation that is generated (though I haven't experienced any speed differences). -For this purpose, just compile your bindings using the "-DXBOB_SHORT_DOCSTRINGS" compiler option, e.g. by adding it to the setup.py as follows (see also above):: - - ... - ext_modules=[ - Extension("xbob.myext._myext", - [ - ... - ], - ... - define_macros = [('XBOB_SHORT_DOCSTRINGS',1)], - ), - ], - ... - -or simply define an environment variable ``XBOB_SHORT_DOCSTRINGS=1`` before invoking buildout. - -In any of these cases, only the short descriptions will be returned as the doc string. - - diff --git a/xbob/__init__.py b/bob/__init__.py similarity index 100% rename from xbob/__init__.py rename to bob/__init__.py diff --git a/xbob/extension/__init__.py b/bob/extension/__init__.py similarity index 97% rename from xbob/extension/__init__.py rename to bob/extension/__init__.py index 6eb994b..05dd62a 100644 --- a/xbob/extension/__init__.py +++ b/bob/extension/__init__.py @@ -81,16 +81,16 @@ def generate_self_macros(extname, version): s = extname.rsplit('.', 1) retval = [ - ('XBOB_EXT_MODULE_PREFIX', '"%s"' % s[0]), - ('XBOB_EXT_MODULE_NAME', '"%s"' % s[1]), + ('BOB_EXT_MODULE_PREFIX', '"%s"' % s[0]), + ('BOB_EXT_MODULE_NAME', '"%s"' % s[1]), ] if sys.version_info[0] >= 3: - retval.append(('XBOB_EXT_ENTRY_NAME', 'PyInit_%s' % s[1])) + retval.append(('BOB_EXT_ENTRY_NAME', 'PyInit_%s' % s[1])) else: - retval.append(('XBOB_EXT_ENTRY_NAME', 'init%s' % s[1])) + retval.append(('BOB_EXT_ENTRY_NAME', 'init%s' % s[1])) - if version: retval.append(('XBOB_EXT_MODULE_VERSION', '"%s"' % version)) + if version: retval.append(('BOB_EXT_MODULE_VERSION', '"%s"' % version)) return retval diff --git a/xbob/extension/boost.py b/bob/extension/boost.py similarity index 96% rename from xbob/extension/boost.py rename to bob/extension/boost.py index 8d7522f..46beda6 100644 --- a/xbob/extension/boost.py +++ b/bob/extension/boost.py @@ -35,7 +35,7 @@ class boost: .. doctest:: :options: +NORMALIZE_WHITESPACE +ELLIPSIS - >>> from xbob.extension import boost + >>> from bob.extension import boost >>> pkg = boost('>= 1.35') >>> pkg.include_directory '...' @@ -48,7 +48,7 @@ class boost: .. doctest:: :options: +NORMALIZE_WHITESPACE +ELLIPSIS - >>> from xbob.extension import boost + >>> from bob.extension import boost >>> pkg = boost('>= 1.35') >>> pkg.libconfig(['python', 'system']) (...) @@ -59,7 +59,7 @@ class boost: """ Searches for the Boost library in stock locations. Allows user to override. - If the user sets the environment variable XBOB_PREFIX_PATH, that prefixes + If the user sets the environment variable BOB_PREFIX_PATH, that prefixes the standard path locations. """ @@ -199,7 +199,7 @@ class boost: .. doctest:: :options: +NORMALIZE_WHITESPACE +ELLIPSIS - >>> from xbob.extension import boost + >>> from bob.extension import boost >>> pkg = boost('>= 1.34') >>> pkg.macros() [('HAVE_BOOST', '1'), ('BOOST_VERSION', '"..."')] diff --git a/xbob/extension/include/xbob.extension/documentation.h b/bob/extension/include/bob.extension/documentation.h similarity index 91% rename from xbob/extension/include/xbob.extension/documentation.h rename to bob/extension/include/bob.extension/documentation.h index 037f7b8..59f092b 100644 --- a/xbob/extension/include/xbob.extension/documentation.h +++ b/bob/extension/include/bob.extension/documentation.h @@ -1,5 +1,5 @@ /** - * @file xbob/extension/include/xbob.extension/documentation.h + * @file bob/extension/include/bob.extension/documentation.h * @date Fri Feb 21 18:29:37 CET 2014 * @author Manuel Guenther <manuel.guenther@idiap.ch> * @@ -8,8 +8,8 @@ * Copyright (C) 2011-2014 Idiap Research Institute, Martigny, Switzerland */ -#ifndef XBOB_EXTENSION_DOCUMENTATION_H_INCLUDED -#define XBOB_EXTENSION_DOCUMENTATION_H_INCLUDED +#ifndef BOB_EXTENSION_DOCUMENTATION_H_INCLUDED +#define BOB_EXTENSION_DOCUMENTATION_H_INCLUDED #include <string> #include <vector> @@ -17,7 +17,7 @@ #include <stdexcept> #include <iostream> -namespace xbob{ +namespace bob{ namespace extension{ /** @@ -266,7 +266,7 @@ namespace xbob{ // TODO: remove #include <iostream> -#ifndef XBOB_SHORT_DOCSTRINGS +#ifndef BOB_SHORT_DOCSTRINGS // removes leading and trailing spaces static std::string _strip(const std::string& str, const std::string& sep = " []()|"){ unsigned first = 0, last = str.size(); @@ -410,20 +410,20 @@ static void _check(std::string& doc, const std::vector<std::string>& vars, const } } -#endif // ! XBOB_SHORT_DOCSTRINGS +#endif // ! BOB_SHORT_DOCSTRINGS ///////////////////////////////////////////////////////////// /// FunctionDoc -inline xbob::extension::FunctionDoc::FunctionDoc( +inline bob::extension::FunctionDoc::FunctionDoc( const char* const function_name, const char* const short_description, const char* const long_description, bool is_member_function ) : function_name(function_name), function_description(short_description), is_member(is_member_function) { -#ifndef XBOB_SHORT_DOCSTRINGS +#ifndef BOB_SHORT_DOCSTRINGS if (long_description){ function_description += "\n\n"; function_description += long_description; @@ -431,54 +431,54 @@ inline xbob::extension::FunctionDoc::FunctionDoc( #endif } -inline xbob::extension::FunctionDoc& xbob::extension::FunctionDoc::add_prototype( +inline bob::extension::FunctionDoc& bob::extension::FunctionDoc::add_prototype( const char* const variables, const char* const return_values ){ -#ifndef XBOB_SHORT_DOCSTRINGS +#ifndef BOB_SHORT_DOCSTRINGS prototype_variables.push_back(variables); if (!return_values) prototype_returns.push_back(""); else prototype_returns.push_back(return_values); -#endif // XBOB_SHORT_DOCSTRINGS +#endif // BOB_SHORT_DOCSTRINGS return *this; } -inline xbob::extension::FunctionDoc& xbob::extension::FunctionDoc::add_parameter( +inline bob::extension::FunctionDoc& bob::extension::FunctionDoc::add_parameter( const char* const parameter_name, const char* const parameter_type, const char* const parameter_description ) { -#ifndef XBOB_SHORT_DOCSTRINGS +#ifndef BOB_SHORT_DOCSTRINGS parameter_names.push_back(parameter_name); parameter_types.push_back(parameter_type); parameter_descriptions.push_back(parameter_description); -#endif // XBOB_SHORT_DOCSTRINGS +#endif // BOB_SHORT_DOCSTRINGS return *this; } -inline xbob::extension::FunctionDoc& xbob::extension::FunctionDoc::add_return( +inline bob::extension::FunctionDoc& bob::extension::FunctionDoc::add_return( const char* const parameter_name, const char* const parameter_type, const char* const parameter_description ) { -#ifndef XBOB_SHORT_DOCSTRINGS +#ifndef BOB_SHORT_DOCSTRINGS return_names.push_back(parameter_name); return_types.push_back(parameter_type); return_descriptions.push_back(parameter_description); -#endif // XBOB_SHORT_DOCSTRINGS +#endif // BOB_SHORT_DOCSTRINGS return *this; } -inline const char* const xbob::extension::FunctionDoc::doc( +inline const char* const bob::extension::FunctionDoc::doc( const unsigned alignment, const unsigned indent ) const { -#ifdef XBOB_SHORT_DOCSTRINGS +#ifdef BOB_SHORT_DOCSTRINGS return function_description.c_str(); #else if (description.empty()){ @@ -529,12 +529,12 @@ inline const char* const xbob::extension::FunctionDoc::doc( // return the description return description.c_str(); -#endif // XBOB_SHORT_DOCSTRINGS +#endif // BOB_SHORT_DOCSTRINGS } -inline void xbob::extension::FunctionDoc::print_usage() const +inline void bob::extension::FunctionDoc::print_usage() const { -#ifdef XBOB_SHORT_DOCSTRINGS +#ifdef BOB_SHORT_DOCSTRINGS return function_description.c_str(); #else // in case of member functions, the alignment has to be decreased further since class member function are automatically indented by 4 further spaces. @@ -553,7 +553,7 @@ inline void xbob::extension::FunctionDoc::print_usage() const std::cerr << _align(_usage(function_name, prototype_variables[n], prototype_returns[n]), 0, unsigned(-1)) << "\n"; } std::cerr << std::endl; -#endif // XBOB_SHORT_DOCSTRINGS +#endif // BOB_SHORT_DOCSTRINGS } @@ -561,25 +561,25 @@ inline void xbob::extension::FunctionDoc::print_usage() const ///////////////////////////////////////////////////////////// /// ClassDoc -inline xbob::extension::ClassDoc::ClassDoc( +inline bob::extension::ClassDoc::ClassDoc( const char* const class_name, const char* const short_description, const char* const long_description ) : class_name(class_name), class_description(short_description) { -#ifndef XBOB_SHORT_DOCSTRINGS +#ifndef BOB_SHORT_DOCSTRINGS if (long_description){ class_description += "\n\n"; class_description += long_description; } -#endif // ! XBOB_SHORT_DOCSTRINGS +#endif // ! BOB_SHORT_DOCSTRINGS } -inline xbob::extension::ClassDoc& xbob::extension::ClassDoc::add_constructor( - const xbob::extension::FunctionDoc& constructor_documentation +inline bob::extension::ClassDoc& bob::extension::ClassDoc::add_constructor( + const bob::extension::FunctionDoc& constructor_documentation ) { -#ifndef XBOB_SHORT_DOCSTRINGS +#ifndef BOB_SHORT_DOCSTRINGS if (!constructor.empty()){ throw std::runtime_error("The class documentation can have only a single constructor documentation"); } @@ -587,36 +587,36 @@ inline xbob::extension::ClassDoc& xbob::extension::ClassDoc::add_constructor( // since we indent the constructor documentation ourselves, we don't need to consider it to be a member function. constructor.back().is_member = false; constructor.back().function_name = class_name; -#endif // XBOB_SHORT_DOCSTRINGS +#endif // BOB_SHORT_DOCSTRINGS return *this; } -inline xbob::extension::ClassDoc& xbob::extension::ClassDoc::highlight( - const xbob::extension::FunctionDoc& function_documentation +inline bob::extension::ClassDoc& bob::extension::ClassDoc::highlight( + const bob::extension::FunctionDoc& function_documentation ) { -#ifndef XBOB_SHORT_DOCSTRINGS +#ifndef BOB_SHORT_DOCSTRINGS highlighted_functions.push_back(function_documentation); -#endif // XBOB_SHORT_DOCSTRINGS +#endif // BOB_SHORT_DOCSTRINGS return *this; } -inline xbob::extension::ClassDoc& xbob::extension::ClassDoc::highlight( - const xbob::extension::VariableDoc& variable_documentation +inline bob::extension::ClassDoc& bob::extension::ClassDoc::highlight( + const bob::extension::VariableDoc& variable_documentation ) { -#ifndef XBOB_SHORT_DOCSTRINGS +#ifndef BOB_SHORT_DOCSTRINGS highlighted_variables.push_back(variable_documentation); -#endif // XBOB_SHORT_DOCSTRINGS +#endif // BOB_SHORT_DOCSTRINGS return *this; } -inline char* xbob::extension::ClassDoc::doc( +inline char* bob::extension::ClassDoc::doc( const unsigned alignment ) const { -#ifdef XBOB_SHORT_DOCSTRINGS +#ifdef BOB_SHORT_DOCSTRINGS return const_cast<char*>(class_description.c_str()); #else if (description.empty()){ @@ -642,32 +642,32 @@ inline char* xbob::extension::ClassDoc::doc( } } return const_cast<char*>(description.c_str()); -#endif // XBOB_SHORT_DOCSTRINGS +#endif // BOB_SHORT_DOCSTRINGS } ///////////////////////////////////////////////////////////// /// VariableDoc -inline xbob::extension::VariableDoc::VariableDoc( +inline bob::extension::VariableDoc::VariableDoc( const char* const variable_name, const char* const variable_type, const char* const short_description, const char* const long_description ) : variable_name(variable_name), variable_type(variable_type), variable_description(short_description) { -#ifndef XBOB_SHORT_DOCSTRINGS +#ifndef BOB_SHORT_DOCSTRINGS if (long_description){ variable_description += "\n\n"; variable_description += long_description; } -#endif // ! XBOB_SHORT_DOCSTRINGS +#endif // ! BOB_SHORT_DOCSTRINGS } -inline char* xbob::extension::VariableDoc::doc( +inline char* bob::extension::VariableDoc::doc( const unsigned alignment ) const { -#ifdef XBOB_SHORT_DOCSTRINGS +#ifdef BOB_SHORT_DOCSTRINGS return const_cast<char*>(variable_description.c_str()); #else if (description.empty()){ @@ -678,8 +678,8 @@ inline char* xbob::extension::VariableDoc::doc( description = _align("*" + variable_type + "* <-- " + variable_description, 0, alignment); } return const_cast<char*>(description.c_str()); -#endif // XBOB_SHORT_DOCSTRINGS +#endif // BOB_SHORT_DOCSTRINGS } -#endif // XBOB_EXTENSION_DOCUMENTATION_H_INCLUDED +#endif // BOB_EXTENSION_DOCUMENTATION_H_INCLUDED diff --git a/xbob/extension/pkgconfig.py b/bob/extension/pkgconfig.py similarity index 99% rename from xbob/extension/pkgconfig.py rename to bob/extension/pkgconfig.py index 324fdf8..e7106f7 100644 --- a/xbob/extension/pkgconfig.py +++ b/bob/extension/pkgconfig.py @@ -83,7 +83,7 @@ class pkgconfig: .. doctest:: :options: +NORMALIZE_WHITESPACE +ELLIPSIS - >>> from xbob.extension import pkgconfig + >>> from bob.extension import pkgconfig >>> blitz = pkgconfig('blitz') >>> blitz.include_directories() [...] @@ -349,7 +349,7 @@ class pkgconfig: .. doctest:: :options: +NORMALIZE_WHITESPACE +ELLIPSIS - >>> from xbob.extension import pkgconfig + >>> from bob.extension import pkgconfig >>> blitz = pkgconfig('blitz') >>> blitz.package_macros() [('HAVE_BLITZ', '1'), ('BLITZ_VERSION', '"..."')] diff --git a/xbob/extension/test_boost.py b/bob/extension/test_boost.py similarity index 100% rename from xbob/extension/test_boost.py rename to bob/extension/test_boost.py diff --git a/xbob/extension/test_pkgconfig.py b/bob/extension/test_pkgconfig.py similarity index 100% rename from xbob/extension/test_pkgconfig.py rename to bob/extension/test_pkgconfig.py diff --git a/xbob/extension/test_utils.py b/bob/extension/test_utils.py similarity index 100% rename from xbob/extension/test_utils.py rename to bob/extension/test_utils.py diff --git a/xbob/extension/utils.py b/bob/extension/utils.py similarity index 95% rename from xbob/extension/utils.py rename to bob/extension/utils.py index 46726be..d494394 100644 --- a/xbob/extension/utils.py +++ b/bob/extension/utils.py @@ -23,7 +23,7 @@ def find_file(name, subpaths=None, prefixes=None): This method will find all occurrences of a given name on the file system and will return them to the user. - If the environment variable ``XBOB_PREFIX_PATH`` is set, then it is + If the environment variable ``BOB_PREFIX_PATH`` is set, then it is considered a unix path list that is prepended to the list of prefixes to search for. The environment variable has the highest priority on the search order. The order on the variable for each path is respected. @@ -51,8 +51,8 @@ def find_file(name, subpaths=None, prefixes=None): search = [] # Priority 1 - if 'XBOB_PREFIX_PATH' in os.environ: - search += os.environ['XBOB_PREFIX_PATH'].split(os.pathsep) + if 'BOB_PREFIX_PATH' in os.environ: + search += os.environ['BOB_PREFIX_PATH'].split(os.pathsep) # Priority 2 if prefixes: @@ -93,7 +93,7 @@ def find_header(name, subpaths=None, prefixes=None): This method will find all occurrences of a given name on the file system and will return them to the user. - If the environment variable ``XBOB_PREFIX_PATH`` is set, then it is + If the environment variable ``BOB_PREFIX_PATH`` is set, then it is considered a unix path list that is prepended to the list of prefixes to search for. The environment variable has the highest priority on the search order. The order on the variable for each path is respected. @@ -132,7 +132,7 @@ def find_library(name, version=None, subpaths=None, prefixes=None, This method will find all occurrences of a given name on the file system and will return them to the user. - If the environment variable ``XBOB_PREFIX_PATH`` is set, then it is + If the environment variable ``BOB_PREFIX_PATH`` is set, then it is considered a unix path list that is prepended to the list of prefixes to search for. The environment variable has the highest priority on the search order. The order on the variable for each path is respected. diff --git a/buildout.cfg b/buildout.cfg index b830d1d..df69145 100644 --- a/buildout.cfg +++ b/buildout.cfg @@ -5,7 +5,7 @@ [buildout] parts = scripts develop = . -eggs = xbob.extension +eggs = bob.extension [scripts] -recipe = xbob.buildout:scripts +recipe = bob.buildout:scripts diff --git a/doc/conf.py b/doc/conf.py index 801570f..a17b155 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -58,12 +58,12 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = u'xbob.extension' +project = u'bob.extension' import time copyright = u'%s, Idiap Research Institute' % time.strftime('%Y') # Grab the setup entry -distribution = pkg_resources.require('xbob.extension')[0] +distribution = pkg_resources.require('bob.extension')[0] # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -129,7 +129,7 @@ if sphinx.__version__ >= "1.0": #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = 'xbob_extension' +#html_short_title = 'bob_extension' # The name of an image file (relative to this directory) to place at the top # of the sidebar. @@ -187,7 +187,7 @@ html_favicon = 'img/favicon.ico' #html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'xbob_extension_doc' +htmlhelp_basename = 'bob_extension_doc' # -- Options for LaTeX output -------------------------------------------------- @@ -201,7 +201,7 @@ latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'xbob_extension.tex', u'Bob Extension Building', + ('index', 'bob_extension.tex', u'Bob Extension Building', u'Biometrics Group, Idiap Research Institute', 'manual'), ] @@ -241,7 +241,7 @@ rst_epilog = """ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'xbob_extension', u'Bob Extension Building Documentation', [u'Idiap Research Institute'], 1) + ('index', 'bob_extension', u'Bob Extension Building Documentation', [u'Idiap Research Institute'], 1) ] # Default processing flags for sphinx diff --git a/doc/guide.rst b/doc/guide.rst index 07cc3b4..5ce5d83 100644 --- a/doc/guide.rst +++ b/doc/guide.rst @@ -69,7 +69,7 @@ The anatomy of a minimal package should look like the following: +-- docs # documentation directory | +-- conf.py # Sphinx configuration | +-- index.rst # Documentation starting point for Sphinx - +-- xbob # python package (a.k.a. "the code") + +-- bob # python package (a.k.a. "the code") | +-- example | | +-- script | | | +-- __init__.py @@ -102,7 +102,7 @@ Python and C/C++. The package you cloned above is a pure-Python example package and contains all elements to get you started. It defines a single library inside called -``xbob.example``, which declares a simple script, called ``version.py`` that +``bob.example``, which declares a simple script, called ``version.py`` that prints out the version of |project|. When you clone the package, you will not find any executable as ``buildout`` needs to check all dependencies and install missing ones before you can execute anything. Here is how to go from nothing to @@ -118,8 +118,8 @@ everything: Generated script '/home/user/work/tmp/bob.project.example/bin/buildout'. $ ./bin/buildout Develop: '/remote/filer.gx/user.active/aanjos/work/tmp/bob.project.example/.' - Getting distribution for 'xbob.buildout'. - Got xbob.buildout 0.2.13. + Getting distribution for 'bob.buildout'. + Got bob.buildout 0.2.13. Getting distribution for 'zc.recipe.egg>=2.0.0a3'. Got zc.recipe.egg 2.0.0. Installing scripts. @@ -139,10 +139,10 @@ You should now be able to execute ``./bin/version.py``: .. code-block:: sh $ ./bin/version.py - The installed version of xbob.blitz is `2.0.0a0' - xbob.blitz is installed at `...' - xbob.blitz depends on the following Python packages: - * xbob.extension: 0.3.0a0 (...) + The installed version of bob.blitz is `2.0.0a0' + bob.blitz is installed at `...' + bob.blitz depends on the following Python packages: + * bob.extension: 0.3.0a0 (...) * numpy: 1.6.2 (/usr/lib/python2.7/dist-packages) * distribute: 0.6.28dev-r0 (/usr/lib/python2.7/dist-packages) * coverage: 3.7.1 (...) @@ -151,7 +151,7 @@ You should now be able to execute ``./bin/version.py``: * docutils: 0.8.1 (/usr/lib/python2.7/dist-packages) * jinja2: 2.6 (/usr/lib/python2.7/dist-packages) * pygments: 1.5 (/usr/lib/python2.7/dist-packages) - xbob.blitz depends on the following C/C++ APIs: + bob.blitz depends on the following C/C++ APIs: * Python: 2.7.3 * Boost: 1.50.0 * Blitz++: 0.10 @@ -175,30 +175,30 @@ so that you include the following: .. code-block:: python from setuptools import setup, find_packages, dist - dist.Distribution(dict(setup_requires=['xbob.blitz'])) - from xbob.blitz.extension import Extension + dist.Distribution(dict(setup_requires=['bob.blitz'])) + from bob.blitz.extension import Extension ... setup( - name="xbob.myext", + name="bob.myext", version="1.0.0", ... install_requires=[ 'setuptools', - 'xbob.blitz', + 'bob.blitz', ], ... namespace_packages=[ - 'xbob', + 'bob', ], ... ext_modules=[ - Extension("xbob.myext._myext", + Extension("bob.myext._myext", [ - "xbob/myext/ext/file1.cpp", - "xbob/myext/ext/file2.cpp", - "xbob/myext/ext/main.cpp", + "bob/myext/ext/file1.cpp", + "bob/myext/ext/file2.cpp", + "bob/myext/ext/main.cpp", ], packages = [ #other c/c++ api dependences 'bob-math', @@ -212,12 +212,205 @@ so that you include the following: ) These modifications will allow you to compile extensions that are linked -against our core Python-C++ bridge ``xbob.blitz``. You can specify any +against our core Python-C++ bridge ``bob.blitz``. You can specify any ``pkg-config`` module and that will be linked in (for example, ``bob-ip`` or ``opencv``) using the ``packages`` setting as shown above. Other modules and options can be set manually using `the standard options for python extensions <http://docs.python.org/2/extending/building.html>`_. +Documenting your C/C++ Python Extension +======================================= + +One part of this package are some functions that makes it easy to generate a +proper python documentation for your bound C/C++ functions. This documentation +can be used after: + +.. code-block:: c++ + + #include <bob.extension/documentation.h> + +**Function documentation** + +To generate a properly aligned function documentation, you can use: + +.. code-block:: c++ + + static bob::extension::FunctionDoc description( + "function_name", + "Short function description", + "Optional long function description" + ); + +.. note:: + + Please assure that you define this variable as ``static``. + +.. note:: + + If you want to document a member function of a class, you should use set + fourth boolean option to true. This is required since the default python + class member documentation is indented four more spaces, which we need to + balance: + + .. code-block:: c++ + + static bob::extension::FunctionDoc member_function_description( + "function_name", + "Short function description", + "Optional long function description", + true + ); + +Using this object, you can add several parts of the function that need +documentation: + +1. ``description.add_prototype("variable1, variable2", "return1, return2");`` + can be used to add function definitions (i.e., ways how to use your + function). This function needs to be called at least once. If the function + does not define a return value, it can be left out (in which case the + default ``"None"`` is used). + +2. ``description.add_parameter("variable1, variable2", "datatype", "Variable + description");`` should be defined for each variable that you have used in + the prototypes. + +3. ``description.add_return("return1", "datatype", "Return value + description");`` should be defined for each return value that you have used + in the prototypes. + +.. note:: + + All these functions return a reference to the object, so that you can use + them in line, e.g.: + + .. code-block:: c++ + + static auto description = bob::extension::FunctionDoc(...) + .add_prototype(...) + .add_parameter(...) + .add_return(...) + ; + +Finally, when binding you function, you can use: + +a. ``description.name()`` to get the name of the function + +b. ``description.doc()`` to get the aligned documentation of the function, + properly indented and broken at 80 characters (by default). This call will + check that all parameters and return values are documented, and add a ``.. + todo`` directive if not. + +Sphinx directives like ``.. note::``, ``.. warning::`` or ``.. math::`` will be +automatically detected and aligned, when they are used as one-line directive, +e.g.: + +.. code-block:: c++ + + "(more text)\n\n.. note:: This is a note\n\n(more text)" + +Also, enumerations and listings (using the ``*`` character to define a list +element) are handled automatically: + + +.. code-block:: c++ + + "(more text)\n\n* Point 1\n* Point 2\n\n(more text)" + +.. note:: + + Please assure that directives are surrounded by double ``\n`` characters + (see example above) so that they are put as paragraphs. Otherwise, they + will not be displayed correctly. + +.. note:: + + The ``.. todo::`` directive seems not to like being broken at 80 characters. + If you want to use ``.. todo::``, please call, e.g., + ``description.doc(10000)`` to avoid line breaking. + +.. note:: + + To increase readability, you might want to split your documentation lines, + e.g.: + + .. code-block:: c++ + + "(more text)\n" + "\n" + "* Point 1\n" + "* Point 2\n" + "\n" + "(more text)" + +Leading white-spaces in the documentation string are handled correctly, so you +can use several layers of indentation. + +**Class documentation** + +To document a bound class, you can use the +``bob::extension::ClassDoc("class_name", "Short class description", "Optional +long class description")`` function to align and wrap your documentation. +Again, during binding you can use the functions ``description.name()`` and +``description.doc()`` as above. + +Additionally, the class documentation has a function to add constructor +definitions, which takes an ``bob::extension::FunctionDoc`` object. The +shortest way to get a proper class documentation is: + +.. code-block:: c++ + + static auto my_class_doc = + bob::extension::ClassDoc("class_name", "Short description", "Long Description") + .add_constructor( + bob::extension::FunctionDoc("class_name", "Constructor Description") + .add_prototype("param1", "") + .add_parameter("param1", "type1", "Description of param1") + ) + ; + +.. note:: + + The second parameter ``""`` in ``add_prototype`` prevents the output type + (which otherwise defaults to ``"None"``) to be written. + +.. note:: + + For constructor documentations, there is no need to declare them as member + functions. This is done automatically for you. + +Currently, the ClassDoc allows to highlight member functions or variables at +the beginning of the class documentation. This highlighting is still under +development and might not work as expected. + +Possible speed issues +===================== + +In order to speed up the loading time of the modules, you might want to reduce +the amount of documentation that is generated (though I haven't experienced any +speed differences). For this purpose, just compile your bindings using the +"-DBOB_SHORT_DOCSTRINGS" compiler option, e.g. by adding it to the setup.py as +follows (see also above): + +.. code-block:: python + + ... + ext_modules=[ + Extension("bob.myext._myext", + [ + ... + ], + ... + define_macros = [('BOB_SHORT_DOCSTRINGS',1)], + ), + ], + ... + +or simply define an environment variable ``BOB_SHORT_DOCSTRINGS=1`` before +invoking buildout. + +In any of these cases, only the short descriptions will be returned as the doc +string. + Document Generation and Unit Testing ------------------------------------ @@ -266,21 +459,22 @@ platforms and a great way to make sure all is OK. Test units are run with .. code-block:: sh $ ./bin/nosetests -v - test_version (xbob.example.test.MyTests) ... ok + test_version (bob.example.test.MyTests) ... ok ---------------------------------------------------------------------- Ran 1 test in 0.001s OK + Creating Database Satellite Packages ------------------------------------ Database satellite packages are special satellite packages that can hook-in -|project|'s database manager ``xbob_dbmanage.py``. Except for this detail, they +|project|'s database manager ``bob_dbmanage.py``. Except for this detail, they should look exactly like a normal package. -To allow the database to be hooked to the ``xbob_dbmanage.py`` you must +To allow the database to be hooked to the ``bob_dbmanage.py`` you must implement a non-virtual python class that inherits from :py:class:`bob.db.driver.Interface`. Your concrete implementation should then be described at the ``setup.py`` file with a special ``bob.db`` entry point: @@ -289,7 +483,7 @@ be described at the ``setup.py`` file with a special ``bob.db`` entry point: # bob database declaration 'bob.db': [ - 'replay = xbob.db.replay.driver:Interface', + 'replay = bob.db.replay.driver:Interface', ], At present, there is no formal design guide for databases. Nevertheless, it is @@ -305,18 +499,18 @@ go well together. Python package namespaces are `explained in details here together with implementation details. Two basic namespaces are available when you are operating with |project| or add-ons, such as database access APIs (shipped separately): the ``bob`` namespace is reserved for utilities built and -shiped with |project|. The namespace ``xbob`` (as for *external* |project| +shiped with |project|. The namespace ``bob`` (as for *external* |project| packages) should be used for all other applications that are meant to be distributed and augment |project|'s features. -The example package you downloaded creates package inside the ``xbob`` +The example package you downloaded creates package inside the ``bob`` namespace called ``example``. Examine this example in details and understand how to distributed namespace'd packages in the URL above. In particular, if you are creating a database access API, please consider putting all of your package contents *inside* the namespace -``xbob.db.<package>``, therefore declaring two namespaces: ``xbob`` and -``xbob.db``. All standard database access APIs follow this strategy. Just look +``bob.db.<package>``, therefore declaring two namespaces: ``bob`` and +``bob.db``. All standard database access APIs follow this strategy. Just look at our currently existing database `satellite packages`_ for examples. Distributing Your Work diff --git a/doc/py_api.rst b/doc/py_api.rst index c02d382..e4e924c 100644 --- a/doc/py_api.rst +++ b/doc/py_api.rst @@ -3,10 +3,10 @@ .. Sat 16 Nov 20:52:58 2013 ================================ - Python API to `xbob.extension` + Python API to `bob.extension` ================================ This section includes information for using the Python API of -``xbob.extension``. +``bob.extension``. -.. automodule:: xbob.extension +.. automodule:: bob.extension diff --git a/setup.py b/setup.py index 553b575..5e8350a 100644 --- a/setup.py +++ b/setup.py @@ -10,10 +10,10 @@ from setuptools import setup, find_packages setup( - name="xbob.extension", + name="bob.extension", version="0.3.0a0", description="Helps projects building Python/C++ extensions for Bob", - url='http://github.com/bioidiap/xbob.extension', + url='http://github.com/bioidiap/bob.extension', license="BSD", author='Andre Anjos', author_email='andre.anjos@idiap.ch', @@ -23,7 +23,7 @@ setup( zip_safe=True, namespace_packages=[ - "xbob", + "bob", ], install_requires=[ -- GitLab