diff --git a/.travis.yml b/.travis.yml index 46b82d49aa55b8e5e966cc7bb1439882ac19feec..28b061bc72497a2688bf1ca97cc7211698fbe786 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 86435a434c234fdf295768d6e538e0dbe2cc84f5..9f837bbc619716b86ecd00e3f6f9d44bc477fc17 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 b0647885b1ac23e0a0d85a3698ae1e55e3219573..bfd80a63822cd619e43911581ec0ca3706eb761b 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 6eb994bfe2f861f9f47631eddcd9954c96371d37..05dd62aba69bb2f07f1933b06d0222bb5c307654 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 8d7522fa1269ae792a83aa4126d845a8b329e3f4..46beda662ae146b5a10db4c7178fa8c329529b06 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 037f7b8258a38894527a5128dfc8a61446a69dad..59f092b5dc2a208b9a9aeebe0bf3e1b5d2bddea0 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 324fdf8c54f40f677ea73d3aae421e8de42b9f7d..e7106f73da111cae7e161b43660ceb6e2b6578d2 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 46726beb405827778da3d9ea09737fe012386087..d494394e2a96de82119c9a0386ae662a972e46ae 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 b830d1d2cf8a6ce65693709364354ce98e13df10..df691458943010c4ff7d3530619a3becc033a0b6 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 801570fb751a0cf9f8b1a030e8d0f98d21ce0099..a17b155ed28f030e32b64acb16b7d7e15144562c 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 07cc3b4ccdb77aadf8f84590f2375d7c7404286a..5ce5d8336b74105202a9733a89a5591203bf1290 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 c02d382d903b7c2e9e246f74ca536c3202129473..e4e924cb50df1d1305af207d9c0d268ada2418bc 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 553b57575443ad2edba3eed78d697bbc88a2e5fe..5e8350ac5eaf4b302b02296fd5749481c15c55e0 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=[