Skip to content

Commit 44d39e0

Browse files
committed
Merge pull request #1791 from kernc/travis-trusty
[MAINT] Travis Trusty (cherry picked from commit 4071837)
1 parent bda7df4 commit 44d39e0

File tree

10 files changed

+54
-36
lines changed

10 files changed

+54
-36
lines changed

.coveragerc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
[run]
2+
parallel = 1
3+
concurrency =
4+
multiprocessing
5+
thread
6+
source =
7+
Orange
28
omit =
39
Orange/canvas/*
410
Orange/widgets/*

.travis.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ matrix:
1515
env: BUILD_DOCS=true
1616
python: '3.4'
1717
script: source $TRAVIS_BUILD_DIR/.travis/build_doc.sh
18+
- python: '3.5'
19+
env: PYQT5=true
20+
dist: trusty
21+
addons: { apt: { packages: [] } }
1822
allow_failures:
1923
- *pylint
2024
fast_finish: true
@@ -34,10 +38,8 @@ addons:
3438
packages:
3539
- libblas-dev
3640
- liblapack-dev
37-
- postgresql-server-dev-9.1
3841
- libqt4-dev
3942
- gfortran
40-
- xvfb
4143

4244
before_install:
4345
- set -e # fail on any error

.travis/install_pyqt.sh

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
if [ "$PYQT5" ]; then
2+
foldable pip install sip pyqt5
3+
return $?;
4+
fi
5+
16
PYQT=$TRAVIS_BUILD_DIR/pyqt
27

38
SIP_VERSION=4.16.9
@@ -31,5 +36,3 @@ make install
3136

3237
cd $PYQT/PyQt
3338
make install
34-
35-
pip install pyqtgraph

.travis/stage_script.sh

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,13 @@ cd "$ORANGE_DIR"
1111
python -c "from Orange.tests import *"
1212
cp "$TRAVIS_BUILD_DIR"/.coveragerc ./ # for covereage and codecov
1313
export PYTHONPATH="$ORANGE_DIR" PYTHONUNBUFFERED=x
14-
catchsegv xvfb-run coverage run --source=Orange \
15-
-m unittest -v Orange.tests \
16-
Orange.widgets.tests \
17-
Orange.canvas.report.tests
14+
15+
# Screen must be 24bpp lest pyqt5 crashes, see pytest-dev/pytest-qt/35
16+
XVFBARGS="-screen 0 1280x1024x24"
17+
18+
catchsegv xvfb-run -a -s "$XVFBARGS" \
19+
coverage run -m unittest -v \
20+
Orange.tests \
21+
Orange.widgets.tests \
22+
Orange.canvas.report.tests
23+
coverage combine

Orange/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,13 @@
2525
datasets = _DatasetInfo()
2626

2727
del mod_name
28+
29+
# If Qt is available (GUI) and Qt5, install backport for PyQt4 imports
30+
try:
31+
import AnyQt.importhooks
32+
except ImportError:
33+
pass
34+
else:
35+
if AnyQt.USED_API == "pyqt5":
36+
AnyQt.importhooks.install_backport_hook('pyqt4')
37+
del AnyQt

Orange/canvas/__main__.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,6 @@
2121
from AnyQt.QtWidgets import QMessageBox
2222
from AnyQt.QtCore import Qt, QDir, QUrl, QSettings
2323

24-
import AnyQt.importhooks
25-
26-
if AnyQt.USED_API == "pyqt5":
27-
# Use a backport shim to fake leftover PyQt4 imports
28-
AnyQt.importhooks.install_backport_hook('pyqt4')
29-
3024
from Orange import canvas
3125
from Orange.canvas.application.application import CanvasApplication
3226
from Orange.canvas.application.canvasmain import CanvasMainWindow

Orange/canvas/report/owreport.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,16 +248,16 @@ def _build_html(self):
248248
self.report_view.setHtml(html)
249249

250250
def _scroll_to_item(self, item):
251-
self.report_view.runJavaScript(
251+
self.report_view.evalJS(
252252
"document.getElementById('{}').scrollIntoView();".format(item.id)
253253
)
254254

255255
def _change_selected_item(self, item):
256-
self.report_view.runJavaScript(
256+
self.report_view.evalJS(
257257
"var sel_el = document.getElementsByClassName('selected')[0]; "
258258
"if (sel_el.id != {}) "
259259
" sel_el.className = 'normal';".format(item.id))
260-
self.report_view.runJavaScript(
260+
self.report_view.evalJS(
261261
"document.getElementById('{}').className = 'selected';"
262262
.format(item.id))
263263
self.report_changed = True

Orange/evaluation/testing.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,8 @@ def get_augmented_data(self, model_names, include_attrs=True, include_prediction
303303
predictions.name = data.name
304304
return predictions
305305

306+
_MIN_NJOBS_X_SIZE = 20e3
307+
306308
def fit(self, train_data, test_data=None):
307309
"""Fits `self.learners` using folds sampled from the provided data.
308310
@@ -343,7 +345,8 @@ def _is_picklable(obj):
343345
mp_ctx = mp.get_context(
344346
'forkserver' if sys.platform.startswith(('darwin', 'linux')) and n_jobs > 1 else None)
345347

346-
if n_jobs > 1 and mp_ctx.get_start_method() != 'fork' and train_data.X.size < 20e3:
348+
if (n_jobs > 1 and mp_ctx.get_start_method() != 'fork' and
349+
train_data.X.size < self._MIN_NJOBS_X_SIZE):
347350
n_jobs = 1
348351
warnings.warn("Working with small-enough data; single-threaded "
349352
"sequential excecution will (probably) be faster. "

Orange/tests/test_evaluation_testing.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
import unittest
55
import multiprocessing as mp
6+
from unittest.mock import patch
7+
68
import numpy as np
79

810
from Orange.classification import NaiveBayesLearner, MajorityLearner
@@ -270,6 +272,12 @@ def test_internal_cv(self):
270272
CrossValidation, self.iris, [_ParameterTuningLearner()], k=2, n_jobs=3)
271273
proc.daemon = was_daemon
272274

275+
def test_njobs(self):
276+
with patch('Orange.evaluation.testing.CrossValidation._MIN_NJOBS_X_SIZE', 1):
277+
res = CrossValidation(self.random_table, [NaiveBayesLearner()], k=5, n_jobs=3)
278+
self.check_folds(res, 5, self.nrows)
279+
280+
273281
class TestLeaveOneOut(TestSampling):
274282
def test_results(self):
275283
nrows = self.nrows

Orange/widgets/tests/base.py

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
from Orange.widgets.utils.annotated_data import (ANNOTATED_DATA_FEATURE_NAME,
2020
ANNOTATED_DATA_SIGNAL_NAME)
2121

22+
# For tests, let memory freeing entirely to Python / OS
23+
import sip
24+
sip.setdestroyonexit(False)
25+
2226
app = None
2327

2428

@@ -77,24 +81,6 @@ def setUpClass(cls):
7781
cls.widgets.append(report)
7882
OWReport.get_instance = lambda: report
7983

80-
@classmethod
81-
def tearDownClass(cls):
82-
"""Cleanup after tests
83-
84-
Process any pending events and properly destroy created widgets by
85-
calling their onDeleteWidget method which does the widget-specific
86-
cleanup.
87-
88-
NOTE: sip.delete is mandatory. In some cases, widgets are deleted by
89-
python while some references in QApplication remain
90-
(QApplication::topLevelWidgets()), causing a segmentation fault when
91-
QApplication is destroyed.
92-
"""
93-
app.processEvents()
94-
for w in cls.widgets:
95-
w.onDeleteWidget()
96-
sip.delete(w)
97-
9884
def create_widget(self, cls, stored_settings=None, reset_default_settings=True):
9985
"""Create a widget instance.
10086

0 commit comments

Comments
 (0)