Commit e8a542f6 authored by Pavel KORSHUNOV's avatar Pavel KORSHUNOV

fixing issue #35

parent ee4ace56
Pipeline #33888 passed with stage
in 10 minutes and 41 seconds
include LICENSE README.rst buildout.cfg version.txt
recursive-include doc conf.py *.rst
recursive-include bob *.cpp *.h
recursive-include bob/extension/examples *
recursive-include bob/extension/data *
============================================
Instructions for Updating Example Projects
============================================
If you modify examples in this directory, please remember to tar ball them and
copy the resulting files into ``bob/extension/data/``::
$ ./update_examples.sh
Missing to do so will not affect the tests in the way you expect.
*~
*.swp
*.pyc
bin
eggs
parts
.installed.cfg
.mr.developer.cfg
*.egg-info
src
develop-eggs
sphinx
dist
This diff is collapsed.
include README.rst bootstrap-buildout.py buildout.cfg COPYING version.txt requirements.txt
recursive-include doc *.py *.rst *.ico *.png
.. vim: set fileencoding=utf-8 :
.. Mon 03 Jul 2017 11:48:20 CEST
.. image:: http://img.shields.io/badge/docs-stable-yellow.svg
:target: https://www.idiap.ch/software/bob/docs/bob/bob.example.extension/stable/index.html
.. image:: http://img.shields.io/badge/docs-latest-orange.svg
:target: https://www.idiap.ch/software/bob/docs/bob/bob.example.extension/master/index.html
.. image:: https://gitlab.idiap.ch/bob/bob.example.extension/badges/master/build.svg
:target: https://gitlab.idiap.ch/bob/bob.example.extension/commits/master
.. image:: https://gitlab.idiap.ch/bob/bob.example.extension/badges/master/coverage.svg
:target: https://gitlab.idiap.ch/bob/bob.example.extension/commits/master
.. image:: https://img.shields.io/badge/gitlab-project-0000c0.svg
:target: https://gitlab.idiap.ch/bob/bob.example.extension
.. image:: http://img.shields.io/pypi/v/bob.example.extension.svg
:target: https://pypi.python.org/pypi/bob.example.extension
============================
Example buildout environment
============================
This package is part of the signal-processing and machine learning toolbox
Bob_. This simple example demonstrates how to wrap Bob-based scripts on buildout
environments. This may be useful for homework assignments, tests or as a way to
distribute code to reproduce your publication. In summary, if you need to give
out code to others, we recommend you do it following this template so your code
can be tested, documented and run in an orderly fashion.
Installation
------------
Follow our `installation`_ instructions. Then, using the Python interpreter
provided by the distribution, build this package with::
$ buildout
Documentation and Further Information
-------------------------------------
Refer to the latest Bob_ documentation for details. In particular, the
guide `Bob Package Development`_ contains details on how to setup, build and
roll out your own code.
Contact
-------
For questions or reporting issues to this software package, contact our
development `mailing list`_.
.. Place your references here:
.. _bob: https://www.idiap.ch/software/bob
.. _installation: https://www.idiap.ch/software/bob/install
.. _mailing list: https://www.idiap.ch/software/bob/discuss
.. _bob package development: https://www.idiap.ch/software/bob/docs/bob/bob.extension/master/
# see https://docs.python.org/3/library/pkgutil.html
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
# see https://docs.python.org/3/library/pkgutil.html
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
#include <blitz/array.h>
/**
Simple example of a function dealing with a blitz array
*/
blitz::Array<double,1> reverse (const blitz::Array<double,1>& array){
// create new array in the desired shape
blitz::Array<double,1> retval(array.shape());
// copy data
for (int i = 0, j = array.extent(0)-1; i < array.extent(0); ++i, --j){
retval(j) = array(i);
}
// return the copied data
return retval;
}
# import all packages with direct dependencies
# (This will load their pure C++ libraries, if needed)
import bob.blitz
# ... in fact, bob.blitz does not have a C++ library and it would not be needed to import it here
# ... nevertheless, it stays here not to forget it!
# import the C++ function ``reverse`` from the library
from ._library import reverse
# import the ``version`` library as well
from . import version as _version
version = _version.module
def get_config():
"""Returns a string containing the configuration information.
"""
import bob.extension
return bob.extension.get_config(__name__, _version.externals)
# gets sphinx autodoc done right - don't remove it
__all__ = [_ for _ in dir() if not _.startswith('_')]
// include directly and indirectly dependent libraries
#ifdef NO_IMPORT_ARRAY
#undef NO_IMPORT_ARRAY
#endif
#include <bob.blitz/cppapi.h>
#include <bob.blitz/cleanup.h>
#include <bob.extension/documentation.h>
// declare C++ function
extern blitz::Array<double,1> reverse (const blitz::Array<double,1>&);
// use the documentation classes to document the function
static bob::extension::FunctionDoc reverse_doc = bob::extension::FunctionDoc(
"reverse",
"This is a simple example of bridging between blitz arrays (C++) and numpy.ndarrays (Python)",
"Detailed documentation of the function goes here."
)
.add_prototype("array", "reversed")
.add_parameter("array", "array_like (1D, float)", "The array to reverse")
.add_return("reversed", "array_like (1D, float)", "A copy of the ``array`` with reversed order of entries")
;
// declare the function
// we use the default Python C-API here.
static PyObject* PyReverse(PyObject*, PyObject* args, PyObject* kwargs) {
BOB_TRY
// declare the expected parameter names
char** kwlist = reverse_doc.kwlist(0);
// declare an object of the bridging type
PyBlitzArrayObject* array;
// ... and get the command line argument
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&", kwlist, &PyBlitzArray_Converter, &array)) return 0;
// since PyBlitzArray_Converter increased the reference count of array,
// assure that the reference is decreased when the function exits (either way)
auto array_ = make_safe(array);
// check that the array has the expected properties
if (array->type_num != NPY_FLOAT64 || array->ndim != 1){
PyErr_Format(PyExc_TypeError, "%s : Only 1D arrays of type float are allowed", reverse_doc.name());
return 0;
}
// extract the actual blitz array from the Python type
blitz::Array<double, 1> bz = *PyBlitzArrayCxx_AsBlitz<double, 1>(array);
// call the C++ function
blitz::Array<double, 1> reversed = reverse(bz);
// convert the blitz array back to numpy and return it
return PyBlitzArrayCxx_AsNumpy(reversed);
// handle exceptions that occurred in this function
BOB_CATCH_FUNCTION("reverse", 0)
}
//////////////////////////////////////////////////////////////////////////
/////// Python module declaration ////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// module-wide methods
static PyMethodDef module_methods[] = {
{
reverse_doc.name(),
(PyCFunction)PyReverse,
METH_VARARGS|METH_KEYWORDS,
reverse_doc.doc()
},
{NULL} // Sentinel
};
// module documentation
PyDoc_STRVAR(module_docstr, "Exemplary Python Bindings");
// module definition
#if PY_VERSION_HEX >= 0x03000000
static PyModuleDef module_definition = {
PyModuleDef_HEAD_INIT,
BOB_EXT_MODULE_NAME,
module_docstr,
-1,
module_methods,
0, 0, 0, 0
};
#endif
// create the module
static PyObject* create_module (void) {
# if PY_VERSION_HEX >= 0x03000000
PyObject* module = PyModule_Create(&module_definition);
auto module_ = make_xsafe(module);
const char* ret = "O";
# else
PyObject* module = Py_InitModule3(BOB_EXT_MODULE_NAME, module_methods, module_docstr);
const char* ret = "N";
# endif
if (!module) return 0;
if (PyModule_AddStringConstant(module, "__version__", BOB_EXT_MODULE_VERSION) < 0) return 0;
/* imports bob.blitz C-API + dependencies */
if (import_bob_blitz() < 0) return 0;
return Py_BuildValue(ret, module);
}
PyMODINIT_FUNC BOB_EXT_ENTRY_NAME (void) {
# if PY_VERSION_HEX >= 0x03000000
return
# endif
create_module();
}
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
"""Inverts the list of floating point numbers given on command line
"""
from .._library import reverse
def main():
"""Main routine, called by the script that gets the configuration of bob.blitz"""
import sys
if len(sys.argv) == 1:
print ("Usage: %s <numbers>\n" % sys.argv[0])
return
numbers = [float(n) for n in sys.argv[1:]]
print (numbers)
rev = reverse(numbers)
print ("%s reversed is %s" % (numbers, rev))
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
"""Prints the version of bob and exits
"""
def main():
"""Main routine, called by the script that gets the configuration of bob.blitz"""
import bob.blitz
print (bob.blitz.get_config())
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
"""Test Units
"""
def test_reverse():
from . import reverse
count = 10000
source = [float(f) for f in range(count)]
target = reverse(source)
for i in range(count):
assert target[i] == source[count-i-1]
/**
* @author Andre Anjos <andre.anjos@idiap.ch>
* @date Thu 7 Nov 13:50:16 2013
*
* @brief Binds configuration information available from bob
*/
#define BOB_IMPORT_VERSION
#include <bob.blitz/config.h>
#include <bob.blitz/cleanup.h>
// builds the dictionary of versions
static PyObject* build_version_dictionary() {
PyObject* retval = PyDict_New();
if (!retval) return 0;
auto retval_ = make_safe(retval);
if (!dict_steal(retval, "Blitz++", blitz_version())) return 0;
if (!dict_steal(retval, "Boost", boost_version())) return 0;
if (!dict_steal(retval, "Compiler", compiler_version())) return 0;
if (!dict_steal(retval, "Python", python_version())) return 0;
if (!dict_steal(retval, "NumPy", numpy_version())) return 0;
if (!dict_steal(retval, "bob.blitz", bob_blitz_version())) return 0;
return Py_BuildValue("O", retval);
}
static PyMethodDef module_methods[] = {
{0} /* Sentinel */
};
PyDoc_STRVAR(module_docstr,
"Information about software used to compile the C++ Bob API"
);
#if PY_VERSION_HEX >= 0x03000000
static PyModuleDef module_definition = {
PyModuleDef_HEAD_INIT,
BOB_EXT_MODULE_NAME,
module_docstr,
-1,
module_methods,
0, 0, 0, 0
};
#endif
static PyObject* create_module (void) {
# if PY_VERSION_HEX >= 0x03000000
PyObject* module = PyModule_Create(&module_definition);
auto module_ = make_xsafe(module);
const char* ret = "O";
# else
PyObject* module = Py_InitModule3(BOB_EXT_MODULE_NAME, module_methods, module_docstr);
const char* ret = "N";
# endif
if (!module) return 0;
/* register version numbers and constants */
if (PyModule_AddStringConstant(module, "module", BOB_EXT_MODULE_VERSION) < 0) return 0;
if (PyModule_AddObject(module, "externals", build_version_dictionary()) < 0) return 0;
return Py_BuildValue(ret, module);
}
PyMODINIT_FUNC BOB_EXT_ENTRY_NAME (void) {
# if PY_VERSION_HEX >= 0x03000000
return
# endif
create_module();
}
; vim: set fileencoding=utf-8 :
; Fri Dec 23 13:40:37 CET 2016
[buildout]
parts = scripts
develop = .
eggs = bob.example.extension
extensions = bob.buildout
newest = false
verbose = true
[scripts]
recipe = bob.buildout:scripts
dependent-scripts = true
\ No newline at end of file
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
import os
import sys
import glob
import pkg_resources
# -- General configuration -----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
needs_sphinx = '1.3'
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = [
'sphinx.ext.todo',
'sphinx.ext.coverage',
'sphinx.ext.ifconfig',
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
'sphinx.ext.doctest',
'sphinx.ext.graphviz',
'sphinx.ext.intersphinx',
'sphinx.ext.napoleon',
'sphinx.ext.viewcode',
#'matplotlib.sphinxext.plot_directive'
]
import sphinx
if sphinx.__version__ >= "1.4.1":
extensions.append('sphinx.ext.imgmath')
imgmath_image_format = 'svg'
else:
extensions.append('sphinx.ext.pngmath')
# Be picky about warnings
nitpicky = True
# Ignores stuff we can't easily resolve on other project's sphinx manuals
nitpick_ignore = []
# Allows the user to override warnings from a separate file
if os.path.exists('nitpick-exceptions.txt'):
for line in open('nitpick-exceptions.txt'):
if line.strip() == "" or line.startswith("#"):
continue
dtype, target = line.split(None, 1)
target = target.strip()
try: # python 2.x
target = unicode(target)
except NameError:
pass
nitpick_ignore.append((dtype, target))
# Always includes todos
todo_include_todos = True
# Generates auto-summary automatically
autosummary_generate = True
# Create numbers on figures with captions
numfig = True
# If we are on OSX, the 'dvipng' path maybe different
dvipng_osx = '/opt/local/libexec/texlive/binaries/dvipng'
if os.path.exists(dvipng_osx): pngmath_dvipng = dvipng_osx
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'bob.example.extension'
import time
copyright = u'%s, Idiap Research Institute' % time.strftime('%Y')
# Grab the setup entry
distribution = pkg_resources.require(project)[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
# built documents.
#
# The short X.Y version.
version = distribution.version
# The full version, including alpha/beta/rc tags.
release = distribution.version
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['links.rst']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# Some variables which are useful for generated material
project_variable = project.replace('.', '_')
short_description = u'Example for using Bob inside a C++ extension of a buildout project'
owner = [u'Idiap Research Institute']
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = project_variable
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
html_logo = 'img/logo.png'
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
html_favicon = 'img/favicon.ico'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
#html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = project_variable + u'_doc'
# -- Post configuration --------------------------------------------------------
# Included after all input documents
rst_epilog = """
.. |project| replace:: Bob
.. |version| replace:: %s
.. |current-year| date:: %%Y
""" % (version,)
# Default processing flags for sphinx
autoclass_content = 'class'
autodoc_member_order = 'bysource'
autodoc_default_flags = [
'members',
'undoc-members',
'inherited-members',
'show-inheritance',
]
# For inter-documentation mapping:
from bob.extension.utils import link_documentation, load_requirements
sphinx_requirements = "extra-intersphinx.txt"
if os.path.exists(sphinx_requirements):
intersphinx_mapping = link_documentation(
additional_packages=['python','numpy'] + \
load_requirements(sphinx_requirements)
)
else:
intersphinx_mapping = link_documentation()
# We want to remove all private (i.e. _. or __.__) members
# that are not in the list of accepted functions
accepted_private_functions = ['__array__']
def member_function_test(app, what, name, obj, skip, options):
# test if we have a private function
if len(name) > 1 and name[0] == '_':
# test if this private function should be allowed
if name not in accepted_private_functions: