Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix doctests and let TravisCI run doctests #811

Merged
merged 75 commits into from
Nov 18, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
f4b211f
Add make instruction for doctest
ahojnnes Nov 3, 2013
313c444
Let travis run doctests
ahojnnes Nov 3, 2013
610f589
Fix corner doc tests
ahojnnes Nov 3, 2013
40fc5d2
Fix corner_subpix function for corners near border
ahojnnes Nov 3, 2013
dc35d3d
Add example for corner_subpix function
ahojnnes Nov 3, 2013
c7fbd32
Fix doctest of remove_small_objects
ahojnnes Nov 3, 2013
facc8f5
Fix watershed doctest
ahojnnes Nov 3, 2013
87dcaa4
Fix hough_line_peaks doctest
ahojnnes Nov 3, 2013
c737861
Fix block_reduce doctest
ahojnnes Nov 3, 2013
41d1246
Fix RANSAC doctest
ahojnnes Nov 3, 2013
45eae57
Use NORMALIZE_WHITESPACE directive for block_reduce doctest
ahojnnes Nov 3, 2013
256a0ba
Fix montage2d doctest
ahojnnes Nov 3, 2013
411de75
Remove plotter from doctest and use comparison to np.histogram instead
ahojnnes Nov 3, 2013
d726a54
Fix precision of output in hough_line_peaks doctest
ahojnnes Nov 3, 2013
80ec4fc
Install nose from PyPI
ahojnnes Nov 3, 2013
326557e
Remove unnecessary coverage directive
ahojnnes Nov 3, 2013
31b52e9
Install PyQt4 for doctests
ahojnnes Nov 3, 2013
757c081
Install Cython from apt
ahojnnes Nov 3, 2013
bf82a0a
Fix PyQt4 for python 3
ahojnnes Nov 3, 2013
7bf858c
Install xserver
ahojnnes Nov 3, 2013
0f303a2
Install Cython via pip
ahojnnes Nov 3, 2013
cc33e53
Use xvfb rather than xorg
ahojnnes Nov 3, 2013
0e32735
Do not change into a separate directory for testing
ahojnnes Nov 3, 2013
66219e8
Build extensions in-place
ahojnnes Nov 3, 2013
1dc346f
Fix duplicate percentile names rank namespace
ahojnnes Nov 3, 2013
e92f415
Fix duplicate find_contours names in namespace
ahojnnes Nov 3, 2013
5038a0e
Remove numpy prefix from pad function examples
ahojnnes Nov 3, 2013
f038a95
Skip ransac doctests
ahojnnes Nov 3, 2013
20e8e72
Only build in-place
ahojnnes Nov 3, 2013
8047d5f
Update bento.info
ahojnnes Nov 3, 2013
8daeb65
Fix novice doctests
ahojnnes Nov 3, 2013
2e7f14d
Fix multi image doctest
ahojnnes Nov 3, 2013
23444a5
Explicitly cast window extent to integer for python 3
ahojnnes Nov 3, 2013
753cc6f
Fix novice doctest
ahojnnes Nov 3, 2013
6e6ca86
Fix corner_foerstner doctest
ahojnnes Nov 3, 2013
8b74ab4
Fix python 3 syntax error
ahojnnes Nov 3, 2013
a1fcc65
Also run doc tests for files with a leading underscore
ahojnnes Nov 3, 2013
b7b391c
Temporarily disable brief test cases and ignore test files with a lea…
ahojnnes Nov 3, 2013
c6f9b53
Fix rank order doc test
ahojnnes Nov 3, 2013
099b428
Fix marching_cubes doctest
ahojnnes Nov 3, 2013
ad0347d
Fix regionprops doctest
ahojnnes Nov 3, 2013
dd572a6
Fix medial_axis and skeletonize doctests
ahojnnes Nov 3, 2013
591aa08
Fix geometric doctests
ahojnnes Nov 3, 2013
0dd36ab
Fix downscale_local_means doctest
ahojnnes Nov 3, 2013
aaf0749
Fix hough_line_peaks doctest
ahojnnes Nov 3, 2013
863e89b
Fix data type issue in python 3
ahojnnes Nov 3, 2013
bb1f7df
Improve usage of doctest directives
ahojnnes Nov 4, 2013
dd06dc8
Use a better way to comment out the brief examples temporarily
ahojnnes Nov 4, 2013
e282b3e
Revert ellipsis to skip directive
ahojnnes Nov 4, 2013
64e21e9
Use travis-ci python config
ahojnnes Nov 7, 2013
f76f06c
Discard pip installation and install matplotlib from PyPI
ahojnnes Nov 7, 2013
49fc67c
Simplify travis config
ahojnnes Nov 8, 2013
4fa7b5b
Touch non-existent matplotlibrc
ahojnnes Nov 9, 2013
729c38c
Fix matplotlibrc configuration
ahojnnes Nov 9, 2013
a242f00
Add python 2.6 and 3.3 environments
ahojnnes Nov 9, 2013
c9a0e53
Remove python 2.6 and 3.3
ahojnnes Nov 9, 2013
615866a
Cast label_field to integer dtype for float intput
ahojnnes Nov 9, 2013
7f27d5b
Fix label2rgb bug
ahojnnes Nov 9, 2013
fb1c1d3
Fix misspelled sections
ahojnnes Nov 9, 2013
ad34647
Fix doc string syntax errors
ahojnnes Nov 9, 2013
f651cba
Reduce runtime of daisy visualization test case
ahojnnes Nov 9, 2013
f8a0fcb
Reduce runtime of radon test cases
ahojnnes Nov 9, 2013
b4c190e
Explicitly set sigma value to 0 to avoid warning
ahojnnes Nov 12, 2013
3b1182c
Skip show commands for doc tests
ahojnnes Nov 12, 2013
825ebdf
Add note about disabled doctests
ahojnnes Nov 15, 2013
ffc28d1
Enable doc tests of ransac function
ahojnnes Nov 15, 2013
4566c36
Add doctest function to skimage
ahojnnes Nov 18, 2013
b1d146d
Use skimage test functions instead of nose commandline
ahojnnes Nov 18, 2013
307725e
Add --exe directive to doc test
ahojnnes Nov 18, 2013
e472528
Return correct exit code for tests
ahojnnes Nov 18, 2013
b9b50dc
Make sure stdlib io is not shadowed by skimage.io
ahojnnes Nov 18, 2013
2bc4cf6
Skip failing ransac doctest
ahojnnes Nov 18, 2013
df4ca92
Reduce runtime of long doctests
ahojnnes Nov 18, 2013
12d2e9a
Fix indentation
ahojnnes Nov 18, 2013
83f7f37
Use explicit interger division
ahojnnes Nov 18, 2013
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
88 changes: 57 additions & 31 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,42 +1,68 @@
# vim ft=yaml
# travis-ci.org definition for skimage build
#
# We pretend to be erlang because we can't use the python support in
# travis-ci; it uses virtualenvs, they do not have numpy, scipy, matplotlib,
# and it is impractical to build them

language: erlang
env:
- PYTHON=python PYSUF='' PYVER=2.7
- PYTHON=python3 PYSUF='3' PYVER=3.2
install:
- sudo apt-get update # needed for python3-numpy
- sudo apt-get install $PYTHON-dev

# After changing this file, check it on:
# http://lint.travis-ci.org/


language: python

python:
- 2.6

matrix:
include:
- python: 2.7
env:
- PYTHON=python
- PYVER=2.x
- python: 3.2
env:
- PYTHON=python3
- PYVER=3.x
exclude:
- python: 2.6

virtualenv:
system_site_packages: true

before_install:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start

- sudo apt-get update
- sudo apt-get install $PYTHON-numpy
- sudo apt-get install $PYTHON-scipy
- sudo apt-get install $PYTHON-setuptools
- sudo apt-get install $PYTHON-nose
- sudo easy_install$PYSUF pip
- sudo pip-$PYVER install cython
- sudo apt-get install libfreeimage3
- if [[ $PYVER == '2.7' ]]; then sudo apt-get install $PYTHON-matplotlib; fi
- if [[ $PYVER == '3.2' ]]; then sudo pip-$PYVER install git+git://github.com/matplotlib/matplotlib.git@v1.2.x; fi
- sudo pip-$PYVER install flake8
- sudo pip-$PYVER install six
- $PYTHON setup.py build
- sudo $PYTHON setup.py install

- if [[ $PYVER == '2.x' ]]; then
- sudo apt-get install $PYTHON-qt4;
- sudo apt-get install $PYTHON-matplotlib;
- fi
- if [[ $PYVER == '3.x' ]]; then
- sudo apt-get install $PYTHON-pyqt4;
- pip install matplotlib;
- fi

- pip install cython
- pip install flake8
- pip install six

- python check_bento_build.py

install:
- python setup.py build_ext --inplace

script:
# Check if setup.py's match bento.info
- $PYTHON check_bento_build.py
# Change into an innocuous directory and find tests from installation
# Setup matplotlib settings
- mkdir $HOME/.matplotlib
- touch $HOME/.matplotlib/matplotlibrc
- "echo 'backend : Agg' > $HOME/.matplotlib/matplotlibrc"
- "echo 'backend.qt4 : PyQt4' >> $HOME/.matplotlib/matplotlibrc"
- mkdir for_test
- cd for_test
- nosetests-$PYVER --exe -v --cover-package=skimage skimage
# Change back to repository root directory and run all doc examples
- cd ..
# Run all tests
- python -c "import skimage, sys, io; sys.exit(skimage.test_verbose())"
- python -c "import skimage, sys, io; sys.exit(skimage.doctest_verbose())"
# Run all doc examples
- export PYTHONPATH=$(pwd):$PYTHONPATH
- for f in doc/examples/*.py; do $PYTHON "$f"; if [ $? -ne 0 ]; then exit 1; fi done
- for f in doc/examples/applications/*.py; do $PYTHON "$f"; if [ $? -ne 0 ]; then exit 1; fi done
# Run pep8 and flake tests
Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ clean:
find . -name "*.so" -o -name "*.pyc" -o -name "*.pyx.md5" | xargs rm -f

test:
nosetests skimage
python -c "import skimage, sys, io; sys.exit(skimage.test_verbose())"

doctest:
python -c "import skimage, sys, io; sys.exit(skimage.doctest_verbose())"

coverage:
nosetests skimage --with-coverage --cover-package=skimage
3 changes: 2 additions & 1 deletion TODO.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Version 0.10
* Remove deprecated parameter `epsilon` of `skimage.viewer.LineProfile`
* Remove backwards-compatability of `skimage.measure.regionprops`
* Remove {`ratio`, `sigma`} deprecation warnings of `skimage.segmentation.slic`
and also remove explicit `sigma` parameter from doc-string example
* Change default mode of random_walker segmentation to 'cg_mg' > 'cg' > 'bf',
depending on which optional dependencies are available.
* Remove deprecated `out` parameter of `skimage.morphology.binary_*`
Expand All @@ -12,4 +13,4 @@ Version 0.10
* Remove deprecated function `filter.median_filter`
* Remove deprecated `skimage.color.is_gray` and `skimage.color.is_rgb`
functions

* Enable doctests of experimental `skimage.feature.brief`
4 changes: 2 additions & 2 deletions bento.info
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ Library:
Extension: skimage.io._plugins._colormixer
Sources:
skimage/io/_plugins/_colormixer.pyx
Extension: skimage.measure._find_contours
Extension: skimage.measure._find_contours_cy
Sources:
skimage/measure/_find_contours.pyx
skimage/measure/_find_contours_cy.pyx
Extension: skimage.measure._moments
Sources:
skimage/measure/_moments.pyx
Expand Down
38 changes: 31 additions & 7 deletions skimage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import os.path as _osp
import imp as _imp
import functools as _functools
import warnings as _warnings
from skimage._shared.utils import deprecated as _deprecated

pkg_dir = _osp.abspath(_osp.dirname(__file__))
Expand All @@ -68,24 +69,48 @@
_imp.find_module('nose')
except ImportError:
def _test(verbose=False):
"""This would invoke the skimage test suite, but nose couldn't be
"""This would run all unit tests, but nose couldn't be
imported so the test suite can not run.
"""
raise ImportError("Could not load nose. Unit tests not available.")

def _doctest(verbose=False):
"""This would run all doc tests, but nose couldn't be
imported so the test suite can not run.
"""
raise ImportError("Could not load nose. Doctests not available.")
else:
def _test(verbose=False):
"""Invoke the skimage test suite."""
def _test(doctest=False, verbose=False):
"""Run all unit tests."""
import nose
args = ['', pkg_dir, '--exe']
args = ['', pkg_dir, '--exe', '--ignore-files=^_test']
if verbose:
args.extend(['-v', '-s'])
nose.run('skimage', argv=args)
if doctest:
args.extend(['--with-doctest', '--ignore-files=^\.',
'--ignore-files=^setup\.py$$', '--ignore-files=test'])
# Make sure warnings do not break the doc tests
with _warnings.catch_warnings():
_warnings.simplefilter("ignore")
success = nose.run('skimage', argv=args)
else:
success = nose.run('skimage', argv=args)
# Return sys.exit code
if success:
return 0
else:
return 1


# do not use `test` as function name as this leads to a recursion problem with
# the nose test suite
test = _test
test_verbose = _functools.partial(test, verbose=True)
test_verbose.__doc__ = test.__doc__
doctest = _functools.partial(test, doctest=True)
doctest.__doc__ = doctest.__doc__
doctest_verbose = _functools.partial(test, doctest=True, verbose=True)
doctest_verbose.__doc__ = doctest.__doc__


class _Log(Warning):
Expand All @@ -105,10 +130,9 @@ def __init__(self, name):
"""
self._name = name

import warnings
warnings.simplefilter("always", _Log)

self._warnings = warnings
self._warnings = _warnings

def _warn(self, msg, wtype):
self._warnings.warn('%s: %s' % (wtype, msg), _Log)
Expand Down
2 changes: 1 addition & 1 deletion skimage/color/colorlabel.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def label2rgb(label, image=None, colors=None, alpha=0.3,
label = label - offset # Make sure you don't modify the input array.
bg_label -= offset

new_type = np.min_scalar_type(label.max())
new_type = np.min_scalar_type(int(label.max()))
if new_type == np.bool:
new_type = np.uint8
label = label.astype(new_type)
Expand Down
15 changes: 8 additions & 7 deletions skimage/exposure/exposure.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
def histogram(image, nbins=256):
"""Return histogram of image.


Unlike `numpy.histogram`, this function returns the centers of bins and
does not rebin integer arrays. For integer arrays, each integer value has
its own bin, which improves speed and intensity-resolution.
Expand All @@ -40,11 +39,12 @@ def histogram(image, nbins=256):

Examples
--------
>>> from skimage import data
>>> hist = histogram(data.camera())
>>> import matplotlib.pyplot as plt
>>> plt.plot(hist[1], hist[0]) # doctest: +ELLIPSIS
[...]
>>> from skimage import data, exposure, util
>>> image = util.img_as_float(data.camera())
>>> np.histogram(image, bins=2)
(array([107432, 154712]), array([ 0. , 0.5, 1. ]))
>>> exposure.histogram(image, nbins=2)
(array([107432, 154712]), array([ 0.25, 0.75]))
"""
sh = image.shape
if len(sh) == 3 and sh[-1] < 4:
Expand Down Expand Up @@ -339,7 +339,8 @@ def adjust_sigmoid(image, cutoff=0.5, gain=10, inv=False):
References
----------
.. [1] Gustav J. Braun, "Image Lightness Rescaling Using Sigmoidal Contrast
Enhancement Functions" http://www.cis.rit.edu/fairchild/PDFs/PAP07.pdf
Enhancement Functions",
http://www.cis.rit.edu/fairchild/PDFs/PAP07.pdf

"""
_assert_non_negative(image)
Expand Down
39 changes: 20 additions & 19 deletions skimage/feature/_brief.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,11 @@ def brief(image, keypoints, descriptor_size=256, mode='normal', patch_size=49,

Examples
--------
>>> import numpy as np
>>> from skimage.feature.corner import corner_peaks, corner_harris
>>> from skimage.feature import pairwise_hamming_distance, brief, match_keypoints_brief
>>> square1 = np.zeros([8, 8], dtype=np.int32)
>>> square1[2:6, 2:6] = 1
>>> square1
>> from skimage.feature import corner_peaks, corner_harris, \\
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why change this to just two greater-thans?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because for the time being (not working right now) those tests must be skipped, and the simplest way is to use >>.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, you've used # doctest: +SKIP elsewhere, why not here? I think that explicit flag is much better for readability.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

brief is currently hidden from the public as an experimental function until we merge Ankit's branch #699. It was just easier for now to disable them this way temporarily. They will be reenabled shortly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a satisfactory solution for you?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Um... That depends... How is it "hidden"? (Sorry, I only skimmed that discussion.) Isn't it possible to make doctest as a whole skip the entire file? This seems hacky. At any rate, I'm semi-happy to allow it but I'd like a +1 from e.g. @stefanv. =)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am happy with this as long as we note it somewhere else.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

e.g. in todo.txt?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, or in a ticket--either is fine.

.. pairwise_hamming_distance, brief, match_keypoints_brief
>> square1 = np.zeros([8, 8], dtype=np.int32)
>> square1[2:6, 2:6] = 1
>> square1
array([[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 0, 0],
Expand All @@ -71,21 +70,21 @@ def brief(image, keypoints, descriptor_size=256, mode='normal', patch_size=49,
[0, 0, 1, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]], dtype=int32)
>>> keypoints1 = corner_peaks(corner_harris(square1), min_distance=1)
>>> keypoints1
>> keypoints1 = corner_peaks(corner_harris(square1), min_distance=1)
>> keypoints1
array([[2, 2],
[2, 5],
[5, 2],
[5, 5]])
>>> descriptors1, keypoints1 = brief(square1, keypoints1, patch_size=5)
>>> keypoints1
>> descriptors1, keypoints1 = brief(square1, keypoints1, patch_size=5)
>> keypoints1
array([[2, 2],
[2, 5],
[5, 2],
[5, 5]])
>>> square2 = np.zeros([9, 9], dtype=np.int32)
>>> square2[2:7, 2:7] = 1
>>> square2
>> square2 = np.zeros([9, 9], dtype=np.int32)
>> square2[2:7, 2:7] = 1
>> square2
array([[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 0, 0],
Expand All @@ -95,24 +94,25 @@ def brief(image, keypoints, descriptor_size=256, mode='normal', patch_size=49,
[0, 0, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=int32)
>>> keypoints2 = corner_peaks(corner_harris(square2), min_distance=1)
>>> keypoints2
>> keypoints2 = corner_peaks(corner_harris(square2), min_distance=1)
>> keypoints2
array([[2, 2],
[2, 6],
[6, 2],
[6, 6]])
>>> descriptors2, keypoints2 = brief(square2, keypoints2, patch_size=5)
>>> keypoints2
>> descriptors2, keypoints2 = brief(square2, keypoints2, patch_size=5)
>> keypoints2
array([[2, 2],
[2, 6],
[6, 2],
[6, 6]])
>>> pairwise_hamming_distance(descriptors1, descriptors2)
>> pairwise_hamming_distance(descriptors1, descriptors2)
array([[ 0.03125 , 0.3203125, 0.3671875, 0.6171875],
[ 0.3203125, 0.03125 , 0.640625 , 0.375 ],
[ 0.375 , 0.6328125, 0.0390625, 0.328125 ],
[ 0.625 , 0.3671875, 0.34375 , 0.0234375]])
>>> match_keypoints_brief(keypoints1, descriptors1, keypoints2, descriptors2)
>> match_keypoints_brief(keypoints1, descriptors1,
.. keypoints2, descriptors2)
array([[[ 2, 2],
[ 2, 2]],

Expand All @@ -126,6 +126,7 @@ def brief(image, keypoints, descriptor_size=256, mode='normal', patch_size=49,
[ 6, 6]]])

"""

np.random.seed(sample_seed)

image = np.squeeze(image)
Expand Down