Skip to content
This repository was archived by the owner on Sep 18, 2024. It is now read-only.

Commit 888abbc

Browse files
rragundezFrédéric Branchaud-Charron
authored and
Frédéric Branchaud-Charron
committed
Update CI (#159)
### Summary Update CI, basically separate every test component. - PEP8 (no dependencies installed at all) - PyTests (install test dependencies), runs for Python 2.6, 3.6 and Keras PyPI and Keras HEAD - Imports (install package dependencies), runs for Python 2.6, 3.6. Basically imports the package and modules as a check that nothing breaks. I also change where some of the logic happens. Before there was some logic in `travis.yml` that in my opinion `shuoldn't` be there but in `setup.py`, in this way the user can actually execute the same that travis is doing by `pip install -e .[tests] && pytest tests` or `pip install -e .[pep8] && flake8`. So much easier to debug without the need to push and create a pull request to reproduce travis execution (up to some complexity). This should lead to a more robust check and specially avoid the error given during the release of 1.0.6. That error for example will be catch in two places now: - PEP8: as an unused import - Imports: since pandas is not installed on that check. NOTE: The phase caching the bug in the 1.0.6 should not be the Pytest phase, that actually should work. Since pandas is needed for unit testing. By running these tests on the current state of the repo I already found several bugs in the code, several overhead variables being assigned but unused (specially in tests) and like 30 plus PEP8 violations. ### Related Issues #154 ### PR Overview - [ n] This PR requires new unit tests [y/n] (make sure tests are included) - [ n] This PR requires to update the documentation [y/n] (make sure the docs are up-to-date) - [ y] This PR is backwards compatible [y/n] - [ n] This PR changes the current API [y/n] (all API changes need to be approved by fchollet)
1 parent dd35790 commit 888abbc

16 files changed

+75
-94
lines changed

Diff for: .travis.yml

+35-24
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,37 @@ dist: trusty
33
language: python
44
matrix:
55
include:
6+
# check code style and Python 2.7
67
- python: 2.7
78
env: TEST_MODE=PEP8
9+
# run tests with keras from source and Python 2.7
810
- python: 2.7
911
env: KERAS_HEAD=true
12+
env: TEST_MODE=TESTS
13+
# run tests with keras from source and Python 3.6
1014
- python: 3.6
1115
env: KERAS_HEAD=true
16+
env: TEST_MODE=TESTS
17+
# run tests with keras from PyPI and Python 2.7
1218
- python: 2.7
19+
env: TEST_MODE=TESTS
20+
# run tests with keras from PyPI and Python 3.6
1321
- python: 3.6
14-
install:
15-
# code below is taken from http://conda.pydata.org/docs/travis.html
22+
env: TEST_MODE=TESTS
23+
# run import test and Python 2.7
24+
- python: 2.7
25+
env: TEST_MODE=IMPORTS
26+
# run import test and Python 3.6
27+
- python: 3.6
28+
env: TEST_MODE=IMPORTS
29+
30+
31+
before_install:
32+
- sudo apt-get update
1633
# We do this conditionally because it saves us some downloading if the
1734
# version is the same.
1835
- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then
19-
wget https://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh;
36+
wget https://repo.continuum.io/miniconda/Miniconda2-latest-Linux-x86_64.sh -O miniconda.sh;
2037
else
2138
wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh;
2239
fi
@@ -27,32 +44,26 @@ install:
2744
- conda update -q conda
2845
# Useful for debugging any issues with conda
2946
- conda info -a
30-
31-
- conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION pytest pandas
47+
- conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION
3248
- source activate test-environment
33-
- pip install --only-binary=numpy,scipy numpy nose scipy keras
34-
35-
# set library path
36-
- export LD_LIBRARY_PATH=$HOME/miniconda/envs/test-environment/lib/:$LD_LIBRARY_PATH
3749

38-
# install PIL for image tests
39-
- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then
40-
conda install pil;
41-
elif [[ "$TRAVIS_PYTHON_VERSION" == "3.6" ]]; then
42-
conda install Pillow;
43-
fi
50+
install:
4451
- if [[ $KERAS_HEAD == "true" ]]; then
45-
pip install --no-deps git+https://github.com/keras-team/keras.git ;
52+
pip install --no-deps git+https://github.com/keras-team/keras.git --upgrade;
53+
fi
54+
- if [[ "$TEST_MODE" == "PEP8" ]]; then
55+
pip install -e .[pep8];
56+
elif [[ "$TEST_MODE" == "TESTS" ]]; then
57+
pip install -e .[tests];
58+
elif [[ "$TEST_MODE" == "IMPORTS" ]]; then
59+
pip install .;
4660
fi
47-
- pip install -e .[tests]
48-
49-
# install TensorFlow (CPU version).
50-
- pip install tensorflow==1.7
5161

52-
# command to run tests
5362
script:
5463
- if [[ "$TEST_MODE" == "PEP8" ]]; then
55-
PYTHONPATH=$PWD:$PYTHONPATH py.test --pep8 -m pep8 -n0;
56-
else
57-
PYTHONPATH=$PWD:$PYTHONPATH py.test tests/ --cov-config .coveragerc --cov=keras_preprocessing tests/;
64+
flake8 -v --count;
65+
elif [[ "$TEST_MODE" == "TESTS" ]]; then
66+
py.test tests --cov-config .coveragerc --cov=keras_preprocessing tests;
67+
elif [[ "$TEST_MODE" == "IMPORTS" ]]; then
68+
python -c "import keras_preprocessing; from keras_preprocessing import image; from keras_preprocessing import sequence; from keras_preprocessing import text";
5869
fi

Diff for: keras_preprocessing/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,5 @@ def get_keras_submodule(name):
3939
elif name == 'utils':
4040
return _KERAS_UTILS
4141

42+
4243
__version__ = '1.0.8'

Diff for: keras_preprocessing/image/__init__.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
"""Enables dynamic setting of underlying Keras module.
22
"""
33
from __future__ import absolute_import
4-
from __future__ import division
5-
from __future__ import print_function
6-
4+
# flake8: noqa:F401
75
from .affine_transformations import *
86
from .dataframe_iterator import DataFrameIterator
97
from .directory_iterator import DirectoryIterator

Diff for: keras_preprocessing/image/affine_transformations.py

+1-7
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,13 @@
44
from __future__ import division
55
from __future__ import print_function
66

7-
import os
8-
import re
9-
import warnings
10-
117
import numpy as np
128

139
from .utils import (array_to_img,
1410
img_to_array)
1511

1612
try:
1713
import scipy
18-
# scipy.linalg cannot be accessed until explicitly imported
19-
from scipy import linalg
2014
# scipy.ndimage cannot be accessed until explicitly imported
2115
from scipy import ndimage
2216
except ImportError:
@@ -327,7 +321,7 @@ def apply_affine_transform(x, theta=0, tx=0, ty=0, shear=0, zx=1, zy=1,
327321
final_affine_matrix = transform_matrix[:2, :2]
328322
final_offset = transform_matrix[:2, 2]
329323

330-
channel_images = [scipy.ndimage.interpolation.affine_transform(
324+
channel_images = [ndimage.interpolation.affine_transform(
331325
x_channel,
332326
final_affine_matrix,
333327
final_offset,

Diff for: keras_preprocessing/image/dataframe_iterator.py

+2-7
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,8 @@
77
import os
88
import warnings
99

10-
import numpy as np
11-
1210
from .iterator import BatchFromFilesMixin, Iterator
13-
from .utils import (array_to_img,
14-
get_extension,
15-
img_to_array,
16-
load_img)
11+
from .utils import get_extension
1712

1813

1914
class DataFrameIterator(BatchFromFilesMixin, Iterator):
@@ -220,7 +215,7 @@ def remove_classes(labels, classes):
220215
else:
221216
raise TypeError(
222217
"Expect string, list or tuple but found {} in {} column "
223-
.format(type(x), y_col)
218+
.format(type(labels), y_col)
224219
)
225220

226221
if classes:

Diff for: keras_preprocessing/image/directory_iterator.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@
1111
import numpy as np
1212

1313
from .iterator import BatchFromFilesMixin, Iterator
14-
from .utils import (array_to_img,
15-
img_to_array,
16-
_list_valid_filenames_in_directory,
17-
load_img)
14+
from .utils import _list_valid_filenames_in_directory
1815

1916

2017
class DirectoryIterator(BatchFromFilesMixin, Iterator):

Diff for: keras_preprocessing/image/image_data_generator.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
# scipy.linalg cannot be accessed until explicitly imported
1515
from scipy import linalg
1616
# scipy.ndimage cannot be accessed until explicitly imported
17-
from scipy import ndimage
1817
except ImportError:
1918
scipy = None
2019

@@ -957,6 +956,6 @@ def fit(self, x,
957956
flat_x = np.reshape(
958957
x, (x.shape[0], x.shape[1] * x.shape[2] * x.shape[3]))
959958
sigma = np.dot(flat_x.T, flat_x) / flat_x.shape[0]
960-
u, s, _ = scipy.linalg.svd(sigma)
959+
u, s, _ = linalg.svd(sigma)
961960
s_inv = 1. / np.sqrt(s[np.newaxis] + self.zca_epsilon)
962961
self.principal_components = (u * s_inv).dot(u.T)

Diff for: keras_preprocessing/image/iterator.py

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from __future__ import division
55
from __future__ import print_function
66

7+
import os
78
import threading
89
import numpy as np
910
from keras_preprocessing import get_keras_submodule

Diff for: keras_preprocessing/image/utils.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ def _recursive_list(subpath):
156156
warnings.warn('Using ".tiff" files with multiple bands '
157157
'will cause distortion. Please verify your output.')
158158
if get_extension(fname) in white_list_formats:
159-
yield root, fname
159+
yield root, fname
160160

161161

162162
def _list_valid_filenames_in_directory(directory, white_list_formats, split,

Diff for: keras_preprocessing/sequence.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -384,15 +384,15 @@ def get_config(self):
384384
data = self.data.tolist()
385385
try:
386386
json_data = json.dumps(data)
387-
except:
387+
except TypeError:
388388
raise TypeError('Data not JSON Serializable:', data)
389389

390390
targets = self.targets
391391
if type(self.targets).__module__ == np.__name__:
392392
targets = self.targets.tolist()
393393
try:
394394
json_targets = json.dumps(targets)
395-
except:
395+
except TypeError:
396396
raise TypeError('Targets not JSON Serializable:', targets)
397397

398398
return {

Diff for: keras_preprocessing/text.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ def hashing_trick(text, n,
126126
if hash_function is None:
127127
hash_function = hash
128128
elif hash_function == 'md5':
129-
hash_function = lambda w: int(md5(w.encode()).hexdigest(), 16)
129+
def hash_function(w):
130+
return int(md5(w.encode()).hexdigest(), 16)
130131

131132
seq = text_to_word_sequence(text,
132133
filters=filters,

Diff for: pytest.ini renamed to setup.cfg

+8-10
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
# Configuration of py.test
2-
[pytest]
3-
addopts=-v
4-
-n 2
5-
--durations=20
6-
2+
[tool:pytest]]
3+
addopts=-v -n 2 --durations=20
74
# Do not run tests in the build folder
8-
norecursedirs= build
5+
norecursedirs=build
96

7+
[flake8]
108
# Use 85 as max line length in PEP8 test.
11-
pep8maxlinelength=85
12-
9+
max-line-length=85
10+
# do not run pep8 test in the build folder
11+
exclude=build
1312
# PEP-8 The following are ignored:
1413
# E731 do not assign a lambda expression, use a def
1514
# E402 module level import not at top of file
16-
1715
pep8ignore=* E731 \
18-
* E402 \
16+
* E402 \

Diff for: setup.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import sys
2+
13
from setuptools import setup
24
from setuptools import find_packages
35

@@ -33,10 +35,14 @@
3335
install_requires=['numpy>=1.9.1',
3436
'six>=1.9.0'],
3537
extras_require={
36-
'tests': ['pytest',
37-
'pytest-pep8',
38+
'tests': ['pandas',
39+
'Pillow' if sys.version_info >= (3, 0) else 'pillow',
40+
'tensorflow==1.7', # CPU version
41+
'keras',
42+
'pytest',
3843
'pytest-xdist',
3944
'pytest-cov'],
45+
'pep8': ['flake8'],
4046
'image': ['scipy>=0.14',
4147
'Pillow>=5.2.0'],
4248
},

Diff for: tests/image_test.py

+10-15
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,9 @@
44
import os
55
import tempfile
66
import shutil
7-
import keras
87
import pandas as pd
98
import random
109

11-
# TODO: remove the 3 lines below once the Keras release
12-
# is configured to use keras_preprocessing
13-
import keras_preprocessing
14-
keras_preprocessing.set_keras_submodules(
15-
backend=keras.backend, utils=keras.utils)
16-
17-
# This enables this import
1810
from keras_preprocessing import image
1911

2012

@@ -262,7 +254,7 @@ def test_image_data_generator_with_validation_split(self):
262254

263255
def test_image_data_generator_with_split_value_error(self):
264256
with pytest.raises(ValueError):
265-
generator = image.ImageDataGenerator(validation_split=5)
257+
image.ImageDataGenerator(validation_split=5)
266258

267259
def test_image_data_generator_invalid_data(self):
268260
generator = image.ImageDataGenerator(
@@ -535,12 +527,14 @@ def test_dataframe_iterator(self, tmpdir):
535527
dtype=str)
536528
batch_x, batch_y = next(df_multiple_y_iterator)
537529
with pytest.raises(TypeError):
538-
df_multiple_y_iterator = generator.flow_from_dataframe(
530+
generator.flow_from_dataframe(
539531
df_regression, str(tmpdir), y_col=["col1", "col2"],
540-
class_mode="other")
532+
class_mode="other"
533+
)
541534
with pytest.raises(TypeError):
542-
df_single_y_iterator = generator.flow_from_dataframe(
543-
df_regression, str(tmpdir), y_col="col1", class_mode="other")
535+
generator.flow_from_dataframe(
536+
df_regression, str(tmpdir), y_col="col1", class_mode="other"
537+
)
544538
# check number of classes and images
545539
assert len(df_iterator.class_indices) == num_classes
546540
assert len(df_iterator.classes) == count
@@ -913,12 +907,12 @@ def test_dataframe_iterator_with_drop_duplicates(self, tmpdir):
913907
# create iterators
914908
generator = image.ImageDataGenerator()
915909
df_drop_iterator = generator.flow_from_dataframe(
916-
df2, str(tmpdir), class_mode=None, drop_duplicates=True)
910+
df, str(tmpdir), class_mode=None, drop_duplicates=True)
917911
df_no_drop_iterator = generator.flow_from_dataframe(
918912
df2, str(tmpdir), class_mode=None, drop_duplicates=False)
919913

920914
# Test drop_duplicates
921-
assert df_drop_iterator.n == len(set(input_filenames2))
915+
assert df_drop_iterator.n == len(set(input_filenames))
922916
assert df_no_drop_iterator.n == len(input_filenames2)
923917

924918
def test_dataframe_iterator_with_subdirs(self, tmpdir):
@@ -1230,5 +1224,6 @@ def test_load_img(self, tmpdir):
12301224
loaded_im = image.load_img(filename_rgb, target_size=(25, 25),
12311225
interpolation="unsupported")
12321226

1227+
12331228
if __name__ == '__main__':
12341229
pytest.main([__file__])

Diff for: tests/sequence_test.py

-8
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,6 @@
55
from numpy.testing import assert_equal
66
from numpy.testing import assert_raises
77

8-
import keras
9-
10-
# TODO: remove the 3 lines below once the Keras release
11-
# is configured to use keras_preprocessing
12-
import keras_preprocessing
13-
keras_preprocessing.set_keras_submodules(
14-
backend=keras.backend, utils=keras.utils)
15-
168
from keras_preprocessing import sequence
179

1810

Diff for: tests/text_test.py

+1-8
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,6 @@
33
import pytest
44

55
import keras
6-
7-
# TODO: remove the 3 lines below once the Keras release
8-
# is configured to use keras_preprocessing
9-
import keras_preprocessing
10-
keras_preprocessing.set_keras_submodules(
11-
backend=keras.backend, utils=keras.utils)
12-
136
from keras_preprocessing import text
147
from collections import OrderedDict
158

@@ -54,7 +47,7 @@ def test_tokenizer():
5447
tokenizer.fit_on_sequences(sequences)
5548

5649
for mode in ['binary', 'count', 'tfidf', 'freq']:
57-
matrix = tokenizer.texts_to_matrix(sample_texts, mode)
50+
tokenizer.texts_to_matrix(sample_texts, mode)
5851

5952

6053
def test_tokenizer_serde_no_fitting():

0 commit comments

Comments
 (0)