Browse Source

version bump

Médéric Hurier 2 months ago
parent
commit
c0e9ac09f7

+ 1
- 0
.coveragerc View File

@@ -0,0 +1 @@
1
+covers/coverage.ini

+ 1
- 1
.python-version View File

@@ -1 +1 @@
1
-3.7.0
1
+3.7.1

+ 12
- 10
Makefile View File

@@ -1,18 +1,20 @@
1
-export PYTHONPATH=${PWD}
1
+include */Makefile
2 2
 
3
-MKFILES = $(wildcard */Makefile)
3
+MAKEFLAGS += --silent
4
+MAKECONFS += $(wildcard */Makefile)
5
+MAKEREPOS += $(subst /,, $(dir ${MAKECONFS}))
4 6
 
5 7
 .venv:
6
-	python -m venv .venv --clear
8
+	python -m venv .venv --clear --symlinks
7 9
 
8
-init: .venv
9
-	@for MK in ${MKFILES}; do make --no-print-directory -f $$MK init-$$(dirname $$MK); done
10
+init:
11
+	@for dir in ${MAKEREPOS} ; do make init-$$dir ; done
10 12
 
11 13
 clean:
12
-	@for MK in ${MKFILES}; do make --no-print-directory -f $$MK clean-$$(dirname $$MK); done
14
+	@for dir in ${MAKEREPOS} ; do make clean-$$dir ; done
13 15
 
14
-commit: .venv
15
-	@set -e; \
16
-	for MK in ${MKFILES}; do make --no-print-directory -f $$MK commit-$$(dirname $$MK); done
16
+check:
17
+	@for dir in ${MAKEREPOS} ; do make check-$$dir ; done
17 18
 
18
-include */Makefile
19
+commit:
20
+	@for dir in ${MAKEREPOS} ; do make commit-$$dir ; done

+ 1
- 0
black.ini View File

@@ -0,0 +1 @@
1
+formats/black.ini

+ 11
- 6
covers/Makefile View File

@@ -1,17 +1,22 @@
1
-.PHONY: cover
2
-
3 1
 NAME = $(shell .venv/bin/python setup.py --name)
4 2
 
5 3
 init-covers: .venv
6 4
 	.venv/bin/pip install '.[covers]'
5
+	ln -fs 'covers/coverage.ini' '.coveragerc'
7 6
 
8 7
 clean-covers:
9
-	find . -name '.mypy_cache' -exec rm -fr {} +
8
+	rm -rf "covers/htmlcov"
9
+	find . -name '.coverage' -exec rm -fr {} +
10
+
11
+check-covers: ;
10 12
 
11
-commit-covers: report;
13
+commit-covers: htmlcov;
12 14
 
13 15
 cover: .venv
14
-	.venv/bin/coverage run --rcfile="covers/coverage.ini" --source ${NAME} -m pytest --doctest-modules -q
16
+	.venv/bin/coverage run --source ${NAME} -m pytest -q
15 17
 
16 18
 report: .venv cover
17
-	.venv/bin/coverage report --rcfile="covers/coverage.ini"
19
+	.venv/bin/coverage report
20
+
21
+htmlcov: .venv cover
22
+	.venv/bin/coverage html --directory="covers/htmlcov"

+ 584
- 0
covers/htmlcov/coverage_html.js View File

@@ -0,0 +1,584 @@
1
+// Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
2
+// For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
3
+
4
+// Coverage.py HTML report browser code.
5
+/*jslint browser: true, sloppy: true, vars: true, plusplus: true, maxerr: 50, indent: 4 */
6
+/*global coverage: true, document, window, $ */
7
+
8
+coverage = {};
9
+
10
+// Find all the elements with shortkey_* class, and use them to assign a shortcut key.
11
+coverage.assign_shortkeys = function () {
12
+    $("*[class*='shortkey_']").each(function (i, e) {
13
+        $.each($(e).attr("class").split(" "), function (i, c) {
14
+            if (/^shortkey_/.test(c)) {
15
+                $(document).bind('keydown', c.substr(9), function () {
16
+                    $(e).click();
17
+                });
18
+            }
19
+        });
20
+    });
21
+};
22
+
23
+// Create the events for the help panel.
24
+coverage.wire_up_help_panel = function () {
25
+    $("#keyboard_icon").click(function () {
26
+        // Show the help panel, and position it so the keyboard icon in the
27
+        // panel is in the same place as the keyboard icon in the header.
28
+        $(".help_panel").show();
29
+        var koff = $("#keyboard_icon").offset();
30
+        var poff = $("#panel_icon").position();
31
+        $(".help_panel").offset({
32
+            top: koff.top-poff.top,
33
+            left: koff.left-poff.left
34
+        });
35
+    });
36
+    $("#panel_icon").click(function () {
37
+        $(".help_panel").hide();
38
+    });
39
+};
40
+
41
+// Create the events for the filter box.
42
+coverage.wire_up_filter = function () {
43
+    // Cache elements.
44
+    var table = $("table.index");
45
+    var table_rows = table.find("tbody tr");
46
+    var table_row_names = table_rows.find("td.name a");
47
+    var no_rows = $("#no_rows");
48
+
49
+    // Create a duplicate table footer that we can modify with dynamic summed values.
50
+    var table_footer = $("table.index tfoot tr");
51
+    var table_dynamic_footer = table_footer.clone();
52
+    table_dynamic_footer.attr('class', 'total_dynamic hidden');
53
+    table_footer.after(table_dynamic_footer);
54
+
55
+    // Observe filter keyevents.
56
+    $("#filter").on("keyup change", $.debounce(150, function (event) {
57
+        var filter_value = $(this).val();
58
+
59
+        if (filter_value === "") {
60
+            // Filter box is empty, remove all filtering.
61
+            table_rows.removeClass("hidden");
62
+
63
+            // Show standard footer, hide dynamic footer.
64
+            table_footer.removeClass("hidden");
65
+            table_dynamic_footer.addClass("hidden");
66
+
67
+            // Hide placeholder, show table.
68
+            if (no_rows.length > 0) {
69
+                no_rows.hide();
70
+            }
71
+            table.show();
72
+
73
+        }
74
+        else {
75
+            // Filter table items by value.
76
+            var hidden = 0;
77
+            var shown = 0;
78
+
79
+            // Hide / show elements.
80
+            $.each(table_row_names, function () {
81
+                var element = $(this).parents("tr");
82
+
83
+                if ($(this).text().indexOf(filter_value) === -1) {
84
+                    // hide
85
+                    element.addClass("hidden");
86
+                    hidden++;
87
+                }
88
+                else {
89
+                    // show
90
+                    element.removeClass("hidden");
91
+                    shown++;
92
+                }
93
+            });
94
+
95
+            // Show placeholder if no rows will be displayed.
96
+            if (no_rows.length > 0) {
97
+                if (shown === 0) {
98
+                    // Show placeholder, hide table.
99
+                    no_rows.show();
100
+                    table.hide();
101
+                }
102
+                else {
103
+                    // Hide placeholder, show table.
104
+                    no_rows.hide();
105
+                    table.show();
106
+                }
107
+            }
108
+
109
+            // Manage dynamic header:
110
+            if (hidden > 0) {
111
+                // Calculate new dynamic sum values based on visible rows.
112
+                for (var column = 2; column < 20; column++) {
113
+                    // Calculate summed value.
114
+                    var cells = table_rows.find('td:nth-child(' + column + ')');
115
+                    if (!cells.length) {
116
+                        // No more columns...!
117
+                        break;
118
+                    }
119
+
120
+                    var sum = 0, numer = 0, denom = 0;
121
+                    $.each(cells.filter(':visible'), function () {
122
+                        var ratio = $(this).data("ratio");
123
+                        if (ratio) {
124
+                            var splitted = ratio.split(" ");
125
+                            numer += parseInt(splitted[0], 10);
126
+                            denom += parseInt(splitted[1], 10);
127
+                        }
128
+                        else {
129
+                            sum += parseInt(this.innerHTML, 10);
130
+                        }
131
+                    });
132
+
133
+                    // Get footer cell element.
134
+                    var footer_cell = table_dynamic_footer.find('td:nth-child(' + column + ')');
135
+
136
+                    // Set value into dynamic footer cell element.
137
+                    if (cells[0].innerHTML.indexOf('%') > -1) {
138
+                        // Percentage columns use the numerator and denominator,
139
+                        // and adapt to the number of decimal places.
140
+                        var match = /\.([0-9]+)/.exec(cells[0].innerHTML);
141
+                        var places = 0;
142
+                        if (match) {
143
+                            places = match[1].length;
144
+                        }
145
+                        var pct = numer * 100 / denom;
146
+                        footer_cell.text(pct.toFixed(places) + '%');
147
+                    }
148
+                    else {
149
+                        footer_cell.text(sum);
150
+                    }
151
+                }
152
+
153
+                // Hide standard footer, show dynamic footer.
154
+                table_footer.addClass("hidden");
155
+                table_dynamic_footer.removeClass("hidden");
156
+            }
157
+            else {
158
+                // Show standard footer, hide dynamic footer.
159
+                table_footer.removeClass("hidden");
160
+                table_dynamic_footer.addClass("hidden");
161
+            }
162
+        }
163
+    }));
164
+
165
+    // Trigger change event on setup, to force filter on page refresh
166
+    // (filter value may still be present).
167
+    $("#filter").trigger("change");
168
+};
169
+
170
+// Loaded on index.html
171
+coverage.index_ready = function ($) {
172
+    // Look for a cookie containing previous sort settings:
173
+    var sort_list = [];
174
+    var cookie_name = "COVERAGE_INDEX_SORT";
175
+    var i;
176
+
177
+    // This almost makes it worth installing the jQuery cookie plugin:
178
+    if (document.cookie.indexOf(cookie_name) > -1) {
179
+        var cookies = document.cookie.split(";");
180
+        for (i = 0; i < cookies.length; i++) {
181
+            var parts = cookies[i].split("=");
182
+
183
+            if ($.trim(parts[0]) === cookie_name && parts[1]) {
184
+                sort_list = eval("[[" + parts[1] + "]]");
185
+                break;
186
+            }
187
+        }
188
+    }
189
+
190
+    // Create a new widget which exists only to save and restore
191
+    // the sort order:
192
+    $.tablesorter.addWidget({
193
+        id: "persistentSort",
194
+
195
+        // Format is called by the widget before displaying:
196
+        format: function (table) {
197
+            if (table.config.sortList.length === 0 && sort_list.length > 0) {
198
+                // This table hasn't been sorted before - we'll use
199
+                // our stored settings:
200
+                $(table).trigger('sorton', [sort_list]);
201
+            }
202
+            else {
203
+                // This is not the first load - something has
204
+                // already defined sorting so we'll just update
205
+                // our stored value to match:
206
+                sort_list = table.config.sortList;
207
+            }
208
+        }
209
+    });
210
+
211
+    // Configure our tablesorter to handle the variable number of
212
+    // columns produced depending on report options:
213
+    var headers = [];
214
+    var col_count = $("table.index > thead > tr > th").length;
215
+
216
+    headers[0] = { sorter: 'text' };
217
+    for (i = 1; i < col_count-1; i++) {
218
+        headers[i] = { sorter: 'digit' };
219
+    }
220
+    headers[col_count-1] = { sorter: 'percent' };
221
+
222
+    // Enable the table sorter:
223
+    $("table.index").tablesorter({
224
+        widgets: ['persistentSort'],
225
+        headers: headers
226
+    });
227
+
228
+    coverage.assign_shortkeys();
229
+    coverage.wire_up_help_panel();
230
+    coverage.wire_up_filter();
231
+
232
+    // Watch for page unload events so we can save the final sort settings:
233
+    $(window).unload(function () {
234
+        document.cookie = cookie_name + "=" + sort_list.toString() + "; path=/";
235
+    });
236
+};
237
+
238
+// -- pyfile stuff --
239
+
240
+coverage.pyfile_ready = function ($) {
241
+    // If we're directed to a particular line number, highlight the line.
242
+    var frag = location.hash;
243
+    if (frag.length > 2 && frag[1] === 'n') {
244
+        $(frag).addClass('highlight');
245
+        coverage.set_sel(parseInt(frag.substr(2), 10));
246
+    }
247
+    else {
248
+        coverage.set_sel(0);
249
+    }
250
+
251
+    $(document)
252
+        .bind('keydown', 'j', coverage.to_next_chunk_nicely)
253
+        .bind('keydown', 'k', coverage.to_prev_chunk_nicely)
254
+        .bind('keydown', '0', coverage.to_top)
255
+        .bind('keydown', '1', coverage.to_first_chunk)
256
+        ;
257
+
258
+    $(".button_toggle_run").click(function (evt) {coverage.toggle_lines(evt.target, "run");});
259
+    $(".button_toggle_exc").click(function (evt) {coverage.toggle_lines(evt.target, "exc");});
260
+    $(".button_toggle_mis").click(function (evt) {coverage.toggle_lines(evt.target, "mis");});
261
+    $(".button_toggle_par").click(function (evt) {coverage.toggle_lines(evt.target, "par");});
262
+
263
+    coverage.assign_shortkeys();
264
+    coverage.wire_up_help_panel();
265
+
266
+    coverage.init_scroll_markers();
267
+
268
+    // Rebuild scroll markers after window high changing
269
+    $(window).resize(coverage.resize_scroll_markers);
270
+};
271
+
272
+coverage.toggle_lines = function (btn, cls) {
273
+    btn = $(btn);
274
+    var hide = "hide_"+cls;
275
+    if (btn.hasClass(hide)) {
276
+        $("#source ."+cls).removeClass(hide);
277
+        btn.removeClass(hide);
278
+    }
279
+    else {
280
+        $("#source ."+cls).addClass(hide);
281
+        btn.addClass(hide);
282
+    }
283
+};
284
+
285
+// Return the nth line div.
286
+coverage.line_elt = function (n) {
287
+    return $("#t" + n);
288
+};
289
+
290
+// Return the nth line number div.
291
+coverage.num_elt = function (n) {
292
+    return $("#n" + n);
293
+};
294
+
295
+// Return the container of all the code.
296
+coverage.code_container = function () {
297
+    return $(".linenos");
298
+};
299
+
300
+// Set the selection.  b and e are line numbers.
301
+coverage.set_sel = function (b, e) {
302
+    // The first line selected.
303
+    coverage.sel_begin = b;
304
+    // The next line not selected.
305
+    coverage.sel_end = (e === undefined) ? b+1 : e;
306
+};
307
+
308
+coverage.to_top = function () {
309
+    coverage.set_sel(0, 1);
310
+    coverage.scroll_window(0);
311
+};
312
+
313
+coverage.to_first_chunk = function () {
314
+    coverage.set_sel(0, 1);
315
+    coverage.to_next_chunk();
316
+};
317
+
318
+coverage.is_transparent = function (color) {
319
+    // Different browsers return different colors for "none".
320
+    return color === "transparent" || color === "rgba(0, 0, 0, 0)";
321
+};
322
+
323
+coverage.to_next_chunk = function () {
324
+    var c = coverage;
325
+
326
+    // Find the start of the next colored chunk.
327
+    var probe = c.sel_end;
328
+    var color, probe_line;
329
+    while (true) {
330
+        probe_line = c.line_elt(probe);
331
+        if (probe_line.length === 0) {
332
+            return;
333
+        }
334
+        color = probe_line.css("background-color");
335
+        if (!c.is_transparent(color)) {
336
+            break;
337
+        }
338
+        probe++;
339
+    }
340
+
341
+    // There's a next chunk, `probe` points to it.
342
+    var begin = probe;
343
+
344
+    // Find the end of this chunk.
345
+    var next_color = color;
346
+    while (next_color === color) {
347
+        probe++;
348
+        probe_line = c.line_elt(probe);
349
+        next_color = probe_line.css("background-color");
350
+    }
351
+    c.set_sel(begin, probe);
352
+    c.show_selection();
353
+};
354
+
355
+coverage.to_prev_chunk = function () {
356
+    var c = coverage;
357
+
358
+    // Find the end of the prev colored chunk.
359
+    var probe = c.sel_begin-1;
360
+    var probe_line = c.line_elt(probe);
361
+    if (probe_line.length === 0) {
362
+        return;
363
+    }
364
+    var color = probe_line.css("background-color");
365
+    while (probe > 0 && c.is_transparent(color)) {
366
+        probe--;
367
+        probe_line = c.line_elt(probe);
368
+        if (probe_line.length === 0) {
369
+            return;
370
+        }
371
+        color = probe_line.css("background-color");
372
+    }
373
+
374
+    // There's a prev chunk, `probe` points to its last line.
375
+    var end = probe+1;
376
+
377
+    // Find the beginning of this chunk.
378
+    var prev_color = color;
379
+    while (prev_color === color) {
380
+        probe--;
381
+        probe_line = c.line_elt(probe);
382
+        prev_color = probe_line.css("background-color");
383
+    }
384
+    c.set_sel(probe+1, end);
385
+    c.show_selection();
386
+};
387
+
388
+// Return the line number of the line nearest pixel position pos
389
+coverage.line_at_pos = function (pos) {
390
+    var l1 = coverage.line_elt(1),
391
+        l2 = coverage.line_elt(2),
392
+        result;
393
+    if (l1.length && l2.length) {
394
+        var l1_top = l1.offset().top,
395
+            line_height = l2.offset().top - l1_top,
396
+            nlines = (pos - l1_top) / line_height;
397
+        if (nlines < 1) {
398
+            result = 1;
399
+        }
400
+        else {
401
+            result = Math.ceil(nlines);
402
+        }
403
+    }
404
+    else {
405
+        result = 1;
406
+    }
407
+    return result;
408
+};
409
+
410
+// Returns 0, 1, or 2: how many of the two ends of the selection are on
411
+// the screen right now?
412
+coverage.selection_ends_on_screen = function () {
413
+    if (coverage.sel_begin === 0) {
414
+        return 0;
415
+    }
416
+
417
+    var top = coverage.line_elt(coverage.sel_begin);
418
+    var next = coverage.line_elt(coverage.sel_end-1);
419
+
420
+    return (
421
+        (top.isOnScreen() ? 1 : 0) +
422
+        (next.isOnScreen() ? 1 : 0)
423
+    );
424
+};
425
+
426
+coverage.to_next_chunk_nicely = function () {
427
+    coverage.finish_scrolling();
428
+    if (coverage.selection_ends_on_screen() === 0) {
429
+        // The selection is entirely off the screen: select the top line on
430
+        // the screen.
431
+        var win = $(window);
432
+        coverage.select_line_or_chunk(coverage.line_at_pos(win.scrollTop()));
433
+    }
434
+    coverage.to_next_chunk();
435
+};
436
+
437
+coverage.to_prev_chunk_nicely = function () {
438
+    coverage.finish_scrolling();
439
+    if (coverage.selection_ends_on_screen() === 0) {
440
+        var win = $(window);
441
+        coverage.select_line_or_chunk(coverage.line_at_pos(win.scrollTop() + win.height()));
442
+    }
443
+    coverage.to_prev_chunk();
444
+};
445
+
446
+// Select line number lineno, or if it is in a colored chunk, select the
447
+// entire chunk
448
+coverage.select_line_or_chunk = function (lineno) {
449
+    var c = coverage;
450
+    var probe_line = c.line_elt(lineno);
451
+    if (probe_line.length === 0) {
452
+        return;
453
+    }
454
+    var the_color = probe_line.css("background-color");
455
+    if (!c.is_transparent(the_color)) {
456
+        // The line is in a highlighted chunk.
457
+        // Search backward for the first line.
458
+        var probe = lineno;
459
+        var color = the_color;
460
+        while (probe > 0 && color === the_color) {
461
+            probe--;
462
+            probe_line = c.line_elt(probe);
463
+            if (probe_line.length === 0) {
464
+                break;
465
+            }
466
+            color = probe_line.css("background-color");
467
+        }
468
+        var begin = probe + 1;
469
+
470
+        // Search forward for the last line.
471
+        probe = lineno;
472
+        color = the_color;
473
+        while (color === the_color) {
474
+            probe++;
475
+            probe_line = c.line_elt(probe);
476
+            color = probe_line.css("background-color");
477
+        }
478
+
479
+        coverage.set_sel(begin, probe);
480
+    }
481
+    else {
482
+        coverage.set_sel(lineno);
483
+    }
484
+};
485
+
486
+coverage.show_selection = function () {
487
+    var c = coverage;
488
+
489
+    // Highlight the lines in the chunk
490
+    c.code_container().find(".highlight").removeClass("highlight");
491
+    for (var probe = c.sel_begin; probe > 0 && probe < c.sel_end; probe++) {
492
+        c.num_elt(probe).addClass("highlight");
493
+    }
494
+
495
+    c.scroll_to_selection();
496
+};
497
+
498
+coverage.scroll_to_selection = function () {
499
+    // Scroll the page if the chunk isn't fully visible.
500
+    if (coverage.selection_ends_on_screen() < 2) {
501
+        // Need to move the page. The html,body trick makes it scroll in all
502
+        // browsers, got it from http://stackoverflow.com/questions/3042651
503
+        var top = coverage.line_elt(coverage.sel_begin);
504
+        var top_pos = parseInt(top.offset().top, 10);
505
+        coverage.scroll_window(top_pos - 30);
506
+    }
507
+};
508
+
509
+coverage.scroll_window = function (to_pos) {
510
+    $("html,body").animate({scrollTop: to_pos}, 200);
511
+};
512
+
513
+coverage.finish_scrolling = function () {
514
+    $("html,body").stop(true, true);
515
+};
516
+
517
+coverage.init_scroll_markers = function () {
518
+    var c = coverage;
519
+    // Init some variables
520
+    c.lines_len = $('td.text p').length;
521
+    c.body_h = $('body').height();
522
+    c.header_h = $('div#header').height();
523
+    c.missed_lines = $('td.text p.mis, td.text p.par');
524
+
525
+    // Build html
526
+    c.resize_scroll_markers();
527
+};
528
+
529
+coverage.resize_scroll_markers = function () {
530
+    var c = coverage,
531
+        min_line_height = 3,
532
+        max_line_height = 10,
533
+        visible_window_h = $(window).height();
534
+
535
+    $('#scroll_marker').remove();
536
+    // Don't build markers if the window has no scroll bar.
537
+    if (c.body_h <= visible_window_h) {
538
+        return;
539
+    }
540
+
541
+    $("body").append("<div id='scroll_marker'>&nbsp;</div>");
542
+    var scroll_marker = $('#scroll_marker'),
543
+        marker_scale = scroll_marker.height() / c.body_h,
544
+        line_height = scroll_marker.height() / c.lines_len;
545
+
546
+    // Line height must be between the extremes.
547
+    if (line_height > min_line_height) {
548
+        if (line_height > max_line_height) {
549
+            line_height = max_line_height;
550
+        }
551
+    }
552
+    else {
553
+        line_height = min_line_height;
554
+    }
555
+
556
+    var previous_line = -99,
557
+        last_mark,
558
+        last_top;
559
+
560
+    c.missed_lines.each(function () {
561
+        var line_top = Math.round($(this).offset().top * marker_scale),
562
+            id_name = $(this).attr('id'),
563
+            line_number = parseInt(id_name.substring(1, id_name.length));
564
+
565
+        if (line_number === previous_line + 1) {
566
+            // If this solid missed block just make previous mark higher.
567
+            last_mark.css({
568
+                'height': line_top + line_height - last_top
569
+            });
570
+        }
571
+        else {
572
+            // Add colored line in scroll_marker block.
573
+            scroll_marker.append('<div id="m' + line_number + '" class="marker"></div>');
574
+            last_mark = $('#m' + line_number);
575
+            last_mark.css({
576
+                'height': line_height,
577
+                'top': line_top
578
+            });
579
+            last_top = line_top;
580
+        }
581
+
582
+        previous_line = line_number;
583
+    });
584
+};

+ 116
- 0
covers/htmlcov/index.html View File

@@ -0,0 +1,116 @@
1
+
2
+
3
+
4
+<!DOCTYPE html>
5
+<html>
6
+<head>
7
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
8
+    <title>Coverage report</title>
9
+    <link rel="stylesheet" href="style.css" type="text/css">
10
+    
11
+    <script type="text/javascript" src="jquery.min.js"></script>
12
+    <script type="text/javascript" src="jquery.ba-throttle-debounce.min.js"></script>
13
+    <script type="text/javascript" src="jquery.tablesorter.min.js"></script>
14
+    <script type="text/javascript" src="jquery.hotkeys.js"></script>
15
+    <script type="text/javascript" src="coverage_html.js"></script>
16
+    <script type="text/javascript">
17
+        jQuery(document).ready(coverage.index_ready);
18
+    </script>
19
+</head>
20
+<body class="indexfile">
21
+
22
+<div id="header">
23
+    <div class="content">
24
+        <h1>Coverage report:
25
+            <span class="pc_cov">100%</span>
26
+        </h1>
27
+
28
+        <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" />
29
+
30
+        <form id="filter_container">
31
+            <input id="filter" type="text" value="" placeholder="filter..." />
32
+        </form>
33
+    </div>
34
+</div>
35
+
36
+<div class="help_panel">
37
+    <img id="panel_icon" src="keybd_open.png" alt="Hide keyboard shortcuts" />
38
+    <p class="legend">Hot-keys on this page</p>
39
+    <div>
40
+    <p class="keyhelp">
41
+        <span class="key">n</span>
42
+        <span class="key">s</span>
43
+        <span class="key">m</span>
44
+        <span class="key">x</span>
45
+        
46
+        <span class="key">b</span>
47
+        <span class="key">p</span>
48
+        
49
+        <span class="key">c</span> &nbsp; change column sorting
50
+    </p>
51
+    </div>
52
+</div>
53
+
54
+<div id="index">
55
+    <table class="index">
56
+        <thead>
57
+            
58
+            <tr class="tablehead" title="Click to sort">
59
+                <th class="name left headerSortDown shortkey_n">Module</th>
60
+                <th class="shortkey_s">statements</th>
61
+                <th class="shortkey_m">missing</th>
62
+                <th class="shortkey_x">excluded</th>
63
+                
64
+                <th class="shortkey_b">branches</th>
65
+                <th class="shortkey_p">partial</th>
66
+                
67
+                <th class="right shortkey_c">coverage</th>
68
+            </tr>
69
+        </thead>
70
+        
71
+        <tfoot>
72
+            <tr class="total">
73
+                <td class="name left">Total</td>
74
+                <td>8</td>
75
+                <td>0</td>
76
+                <td>0</td>
77
+                
78
+                <td>0</td>
79
+                <td>0</td>
80
+                
81
+                <td class="right" data-ratio="8 8">100%</td>
82
+            </tr>
83
+        </tfoot>
84
+        <tbody>
85
+            
86
+            <tr class="file">
87
+                <td class="name left"><a href="onset___init___py.html">onset/__init__.py</a></td>
88
+                <td>8</td>
89
+                <td>0</td>
90
+                <td>0</td>
91
+                
92
+                <td>0</td>
93
+                <td>0</td>
94
+                
95
+                <td class="right" data-ratio="8 8">100%</td>
96
+            </tr>
97
+            
98
+        </tbody>
99
+    </table>
100
+
101
+    <p id="no_rows">
102
+        No items found using the specified filter.
103
+    </p>
104
+</div>
105
+
106
+<div id="footer">
107
+    <div class="content">
108
+        <p>
109
+            <a class="nav" href="https://coverage.readthedocs.io">coverage.py v4.5.2</a>,
110
+            created at 2018-12-07 11:01
111
+        </p>
112
+    </div>
113
+</div>
114
+
115
+</body>
116
+</html>

+ 9
- 0
covers/htmlcov/jquery.ba-throttle-debounce.min.js View File

@@ -0,0 +1,9 @@
1
+/*
2
+ * jQuery throttle / debounce - v1.1 - 3/7/2010
3
+ * http://benalman.com/projects/jquery-throttle-debounce-plugin/
4
+ *
5
+ * Copyright (c) 2010 "Cowboy" Ben Alman
6
+ * Dual licensed under the MIT and GPL licenses.
7
+ * http://benalman.com/about/license/
8
+ */
9
+(function(b,c){var $=b.jQuery||b.Cowboy||(b.Cowboy={}),a;$.throttle=a=function(e,f,j,i){var h,d=0;if(typeof f!=="boolean"){i=j;j=f;f=c}function g(){var o=this,m=+new Date()-d,n=arguments;function l(){d=+new Date();j.apply(o,n)}function k(){h=c}if(i&&!h){l()}h&&clearTimeout(h);if(i===c&&m>e){l()}else{if(f!==true){h=setTimeout(i?k:l,i===c?e-m:e)}}}if($.guid){g.guid=j.guid=j.guid||$.guid++}return g};$.debounce=function(d,e,f){return f===c?a(d,e,false):a(d,f,e!==false)}})(this);

+ 99
- 0
covers/htmlcov/jquery.hotkeys.js View File

@@ -0,0 +1,99 @@
1
+/*
2
+ * jQuery Hotkeys Plugin
3
+ * Copyright 2010, John Resig
4
+ * Dual licensed under the MIT or GPL Version 2 licenses.
5
+ *
6
+ * Based upon the plugin by Tzury Bar Yochay:
7
+ * http://github.com/tzuryby/hotkeys
8
+ *
9
+ * Original idea by:
10
+ * Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/
11
+*/
12
+
13
+(function(jQuery){
14
+
15
+	jQuery.hotkeys = {
16
+		version: "0.8",
17
+
18
+		specialKeys: {
19
+			8: "backspace", 9: "tab", 13: "return", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause",
20
+			20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home",
21
+			37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del",
22
+			96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7",
23
+			104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/",
24
+			112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8",
25
+			120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 191: "/", 224: "meta"
26
+		},
27
+
28
+		shiftNums: {
29
+			"`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&",
30
+			"8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ": ", "'": "\"", ",": "<",
31
+			".": ">",  "/": "?",  "\\": "|"
32
+		}
33
+	};
34
+
35
+	function keyHandler( handleObj ) {
36
+		// Only care when a possible input has been specified
37
+		if ( typeof handleObj.data !== "string" ) {
38
+			return;
39
+		}
40
+
41
+		var origHandler = handleObj.handler,
42
+			keys = handleObj.data.toLowerCase().split(" ");
43
+
44
+		handleObj.handler = function( event ) {
45
+			// Don't fire in text-accepting inputs that we didn't directly bind to
46
+			if ( this !== event.target && (/textarea|select/i.test( event.target.nodeName ) ||
47
+				 event.target.type === "text") ) {
48
+				return;
49
+			}
50
+
51
+			// Keypress represents characters, not special keys
52
+			var special = event.type !== "keypress" && jQuery.hotkeys.specialKeys[ event.which ],
53
+				character = String.fromCharCode( event.which ).toLowerCase(),
54
+				key, modif = "", possible = {};
55
+
56
+			// check combinations (alt|ctrl|shift+anything)
57
+			if ( event.altKey && special !== "alt" ) {
58
+				modif += "alt+";
59
+			}
60
+
61
+			if ( event.ctrlKey && special !== "ctrl" ) {
62
+				modif += "ctrl+";
63
+			}
64
+
65
+			// TODO: Need to make sure this works consistently across platforms
66
+			if ( event.metaKey && !event.ctrlKey && special !== "meta" ) {
67
+				modif += "meta+";
68
+			}
69
+
70
+			if ( event.shiftKey && special !== "shift" ) {
71
+				modif += "shift+";
72
+			}
73
+
74
+			if ( special ) {
75
+				possible[ modif + special ] = true;
76
+
77
+			} else {
78
+				possible[ modif + character ] = true;
79
+				possible[ modif + jQuery.hotkeys.shiftNums[ character ] ] = true;
80
+
81
+				// "$" can be triggered as "Shift+4" or "Shift+$" or just "$"
82
+				if ( modif === "shift+" ) {
83
+					possible[ jQuery.hotkeys.shiftNums[ character ] ] = true;
84
+				}
85
+			}
86
+
87
+			for ( var i = 0, l = keys.length; i < l; i++ ) {
88
+				if ( possible[ keys[i] ] ) {
89
+					return origHandler.apply( this, arguments );
90
+				}
91
+			}
92
+		};
93
+	}
94
+
95
+	jQuery.each([ "keydown", "keyup", "keypress" ], function() {
96
+		jQuery.event.special[ this ] = { add: keyHandler };
97
+	});
98
+
99
+})( jQuery );

+ 53
- 0
covers/htmlcov/jquery.isonscreen.js View File

@@ -0,0 +1,53 @@
1
+/* Copyright (c) 2010
2
+ * @author Laurence Wheway
3
+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
4
+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
5
+ *
6
+ * @version 1.2.0
7
+ */
8
+(function($) {
9
+	jQuery.extend({
10
+		isOnScreen: function(box, container) {
11
+			//ensure numbers come in as intgers (not strings) and remove 'px' is it's there
12
+			for(var i in box){box[i] = parseFloat(box[i])};
13
+			for(var i in container){container[i] = parseFloat(container[i])};
14
+
15
+			if(!container){
16
+				container = {
17
+					left: $(window).scrollLeft(),
18
+					top: $(window).scrollTop(),
19
+					width: $(window).width(),
20
+					height: $(window).height()
21
+				}
22
+			}
23
+
24
+			if(	box.left+box.width-container.left > 0 &&
25
+				box.left < container.width+container.left &&
26
+				box.top+box.height-container.top > 0 &&
27
+				box.top < container.height+container.top
28
+			) return true;
29
+			return false;
30
+		}
31
+	})
32
+
33
+
34
+	jQuery.fn.isOnScreen = function (container) {
35
+		for(var i in container){container[i] = parseFloat(container[i])};
36
+
37
+		if(!container){
38
+			container = {
39
+				left: $(window).scrollLeft(),
40
+				top: $(window).scrollTop(),
41
+				width: $(window).width(),
42
+				height: $(window).height()
43
+			}
44
+		}
45
+
46
+		if(	$(this).offset().left+$(this).width()-container.left > 0 &&
47
+			$(this).offset().left < container.width+container.left &&
48
+			$(this).offset().top+$(this).height()-container.top > 0 &&
49
+			$(this).offset().top < container.height+container.top
50
+		) return true;
51
+		return false;
52
+	}
53
+})(jQuery);

+ 5
- 0
covers/htmlcov/jquery.min.js
File diff suppressed because it is too large
View File


+ 2
- 0
covers/htmlcov/jquery.tablesorter.min.js
File diff suppressed because it is too large
View File


BIN
covers/htmlcov/keybd_closed.png View File


BIN
covers/htmlcov/keybd_open.png View File


+ 157
- 0
covers/htmlcov/onset___init___py.html View File

@@ -0,0 +1,157 @@
1
+
2
+
3
+
4
+<!DOCTYPE html>
5
+<html>
6
+<head>
7
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
8
+    
9
+    
10
+    <meta http-equiv="X-UA-Compatible" content="IE=emulateIE7" />
11
+    <title>Coverage for onset/__init__.py: 100%</title>
12
+    <link rel="stylesheet" href="style.css" type="text/css">
13
+    
14
+    <script type="text/javascript" src="jquery.min.js"></script>
15
+    <script type="text/javascript" src="jquery.hotkeys.js"></script>
16
+    <script type="text/javascript" src="jquery.isonscreen.js"></script>
17
+    <script type="text/javascript" src="coverage_html.js"></script>
18
+    <script type="text/javascript">
19
+        jQuery(document).ready(coverage.pyfile_ready);
20
+    </script>
21
+</head>
22
+<body class="pyfile">
23
+
24
+<div id="header">
25
+    <div class="content">
26
+        <h1>Coverage for <b>onset/__init__.py</b> :
27
+            <span class="pc_cov">100%</span>
28
+        </h1>
29
+
30
+        <img id="keyboard_icon" src="keybd_closed.png" alt="Show keyboard shortcuts" />
31
+
32
+        <h2 class="stats">
33
+            8 statements &nbsp;
34
+            <span class="run hide_run shortkey_r button_toggle_run">8 run</span>
35
+            <span class="mis shortkey_m button_toggle_mis">0 missing</span>
36
+            <span class="exc shortkey_x button_toggle_exc">0 excluded</span>
37
+
38
+            
39
+                <span class="par run hide_run shortkey_p button_toggle_par">0 partial</span>
40
+            
41
+        </h2>
42
+    </div>
43
+</div>
44
+
45
+<div class="help_panel">
46
+    <img id="panel_icon" src="keybd_open.png" alt="Hide keyboard shortcuts" />
47
+    <p class="legend">Hot-keys on this page</p>
48
+    <div>
49
+    <p class="keyhelp">
50
+        <span class="key">r</span>
51
+        <span class="key">m</span>
52
+        <span class="key">x</span>
53
+        <span class="key">p</span> &nbsp; toggle line displays
54
+    </p>
55
+    <p class="keyhelp">
56
+        <span class="key">j</span>
57
+        <span class="key">k</span> &nbsp; next/prev highlighted chunk
58
+    </p>
59
+    <p class="keyhelp">
60
+        <span class="key">0</span> &nbsp; (zero) top of page
61
+    </p>
62
+    <p class="keyhelp">
63
+        <span class="key">1</span> &nbsp; (one) first highlighted chunk
64
+    </p>
65
+    </div>
66
+</div>
67
+
68
+<div id="source">
69
+    <table>
70
+        <tr>
71
+            <td class="linenos">
72
+<p id="n1" class="pln"><a href="#n1">1</a></p>
73
+<p id="n2" class="pln"><a href="#n2">2</a></p>
74
+<p id="n3" class="pln"><a href="#n3">3</a></p>
75
+<p id="n4" class="stm run hide_run"><a href="#n4">4</a></p>
76
+<p id="n5" class="pln"><a href="#n5">5</a></p>
77
+<p id="n6" class="pln"><a href="#n6">6</a></p>
78
+<p id="n7" class="pln"><a href="#n7">7</a></p>
79
+<p id="n8" class="pln"><a href="#n8">8</a></p>
80
+<p id="n9" class="stm run hide_run"><a href="#n9">9</a></p>
81
+<p id="n10" class="pln"><a href="#n10">10</a></p>
82
+<p id="n11" class="pln"><a href="#n11">11</a></p>
83
+<p id="n12" class="stm run hide_run"><a href="#n12">12</a></p>
84
+<p id="n13" class="pln"><a href="#n13">13</a></p>
85
+<p id="n14" class="pln"><a href="#n14">14</a></p>
86
+<p id="n15" class="pln"><a href="#n15">15</a></p>
87
+<p id="n16" class="pln"><a href="#n16">16</a></p>
88
+<p id="n17" class="stm run hide_run"><a href="#n17">17</a></p>
89
+<p id="n18" class="pln"><a href="#n18">18</a></p>
90
+<p id="n19" class="pln"><a href="#n19">19</a></p>
91
+<p id="n20" class="stm run hide_run"><a href="#n20">20</a></p>
92
+<p id="n21" class="pln"><a href="#n21">21</a></p>
93
+<p id="n22" class="pln"><a href="#n22">22</a></p>
94
+<p id="n23" class="pln"><a href="#n23">23</a></p>
95
+<p id="n24" class="pln"><a href="#n24">24</a></p>
96
+<p id="n25" class="stm run hide_run"><a href="#n25">25</a></p>
97
+<p id="n26" class="pln"><a href="#n26">26</a></p>
98
+<p id="n27" class="pln"><a href="#n27">27</a></p>
99
+<p id="n28" class="stm run hide_run"><a href="#n28">28</a></p>
100
+<p id="n29" class="pln"><a href="#n29">29</a></p>
101
+<p id="n30" class="pln"><a href="#n30">30</a></p>
102
+<p id="n31" class="pln"><a href="#n31">31</a></p>
103
+<p id="n32" class="pln"><a href="#n32">32</a></p>
104
+<p id="n33" class="stm run hide_run"><a href="#n33">33</a></p>
105
+
106
+            </td>
107
+            <td class="text">
108
+<p id="t1" class="pln"><span class="str">"""Set operations."""</span><span class="strut">&nbsp;</span></p>
109
+<p id="t2" class="pln"><span class="strut">&nbsp;</span></p>
110
+<p id="t3" class="pln"><span class="strut">&nbsp;</span></p>
111
+<p id="t4" class="stm run hide_run"><span class="key">def</span> <span class="nam">union</span><span class="op">(</span><span class="nam">s</span><span class="op">:</span> <span class="nam">set</span><span class="op">,</span> <span class="nam">t</span><span class="op">:</span> <span class="nam">set</span><span class="op">)</span> <span class="op">-></span> <span class="key">None</span><span class="op">:</span><span class="strut">&nbsp;</span></p>
112
+<p id="t5" class="pln">    <span class="str">"""Return set `s` with elements added from `t`.</span><span class="strut">&nbsp;</span></p>
113
+<p id="t6" class="pln"><span class="str">    >>> s, t = {1, 2, 3}, {1, 3, 5}</span><span class="strut">&nbsp;</span></p>
114
+<p id="t7" class="pln"><span class="str">    >>> union(s, t); s</span><span class="strut">&nbsp;</span></p>
115
+<p id="t8" class="pln"><span class="str">    {1, 2, 3, 5}"""</span><span class="strut">&nbsp;</span></p>
116
+<p id="t9" class="stm run hide_run">    <span class="nam">s</span><span class="op">.</span><span class="nam">update</span><span class="op">(</span><span class="nam">t</span><span class="op">)</span><span class="strut">&nbsp;</span></p>
117
+<p id="t10" class="pln"><span class="strut">&nbsp;</span></p>
118
+<p id="t11" class="pln"><span class="strut">&nbsp;</span></p>
119
+<p id="t12" class="stm run hide_run"><span class="key">def</span> <span class="nam">difference</span><span class="op">(</span><span class="nam">s</span><span class="op">:</span> <span class="nam">set</span><span class="op">,</span> <span class="nam">t</span><span class="op">:</span> <span class="nam">set</span><span class="op">)</span> <span class="op">-></span> <span class="key">None</span><span class="op">:</span><span class="strut">&nbsp;</span></p>
120
+<p id="t13" class="pln">    <span class="str">"""Return set `s` after removing elements from `t`</span><span class="strut">&nbsp;</span></p>
121
+<p id="t14" class="pln"><span class="str">    >>> s, t = {1, 2, 3}, {1, 3, 5}</span><span class="strut">&nbsp;</span></p>
122
+<p id="t15" class="pln"><span class="str">    >>> difference(s, t); s</span><span class="strut">&nbsp;</span></p>
123
+<p id="t16" class="pln"><span class="str">    {2}"""</span><span class="strut">&nbsp;</span></p>
124
+<p id="t17" class="stm run hide_run">    <span class="nam">s</span><span class="op">.</span><span class="nam">difference_update</span><span class="op">(</span><span class="nam">t</span><span class="op">)</span><span class="strut">&nbsp;</span></p>
125
+<p id="t18" class="pln"><span class="strut">&nbsp;</span></p>
126
+<p id="t19" class="pln"><span class="strut">&nbsp;</span></p>
127
+<p id="t20" class="stm run hide_run"><span class="key">def</span> <span class="nam">intersection</span><span class="op">(</span><span class="nam">s</span><span class="op">:</span> <span class="nam">set</span><span class="op">,</span> <span class="nam">t</span><span class="op">:</span> <span class="nam">set</span><span class="op">)</span> <span class="op">-></span> <span class="key">None</span><span class="op">:</span><span class="strut">&nbsp;</span></p>
128
+<p id="t21" class="pln">    <span class="str">"""Return set `s` keeping only elements found in `t`.</span><span class="strut">&nbsp;</span></p>
129
+<p id="t22" class="pln"><span class="str">    >>> s, t = {1, 2, 3}, {1, 3, 5}</span><span class="strut">&nbsp;</span></p>
130
+<p id="t23" class="pln"><span class="str">    >>> intersection(s, t); s</span><span class="strut">&nbsp;</span></p>
131
+<p id="t24" class="pln"><span class="str">    {1, 3}"""</span><span class="strut">&nbsp;</span></p>
132
+<p id="t25" class="stm run hide_run">    <span class="nam">s</span><span class="op">.</span><span class="nam">intersection_update</span><span class="op">(</span><span class="nam">t</span><span class="op">)</span><span class="strut">&nbsp;</span></p>
133
+<p id="t26" class="pln"><span class="strut">&nbsp;</span></p>
134
+<p id="t27" class="pln"><span class="strut">&nbsp;</span></p>
135
+<p id="t28" class="stm run hide_run"><span class="key">def</span> <span class="nam">disjunction</span><span class="op">(</span><span class="nam">s</span><span class="op">:</span> <span class="nam">set</span><span class="op">,</span> <span class="nam">t</span><span class="op">:</span> <span class="nam">set</span><span class="op">)</span> <span class="op">-></span> <span class="key">None</span><span class="op">:</span><span class="strut">&nbsp;</span></p>
136
+<p id="t29" class="pln">    <span class="str">"""Return set `s` with elements from `s` or `t` but not both.</span><span class="strut">&nbsp;</span></p>
137
+<p id="t30" class="pln"><span class="str">    >>> s, t = {1, 2, 3}, {1, 3, 5}</span><span class="strut">&nbsp;</span></p>
138
+<p id="t31" class="pln"><span class="str">    >>> disjunction(s, t); s</span><span class="strut">&nbsp;</span></p>
139
+<p id="t32" class="pln"><span class="str">    {2, 5}"""</span><span class="strut">&nbsp;</span></p>
140
+<p id="t33" class="stm run hide_run">    <span class="nam">s</span><span class="op">.</span><span class="nam">symmetric_difference_update</span><span class="op">(</span><span class="nam">t</span><span class="op">)</span><span class="strut">&nbsp;</span></p>
141
+
142
+            </td>
143
+        </tr>
144
+    </table>
145
+</div>
146
+
147
+<div id="footer">
148
+    <div class="content">
149
+        <p>
150
+            <a class="nav" href="index.html">&#xab; index</a> &nbsp; &nbsp; <a class="nav" href="https://coverage.readthedocs.io">coverage.py v4.5.2</a>,
151
+            created at 2018-12-07 10:58
152
+        </p>
153
+    </div>
154
+</div>
155
+
156
+</body>
157
+</html>

+ 1
- 0
covers/htmlcov/status.json View File

@@ -0,0 +1 @@
1
+{"format":1,"version":"4.5.2","settings":"7d0be086f998137108145983730107fb","files":{"onset___init___py":{"hash":"a890bd8062f46e09cafc3e8e4b80461a","index":{"nums":[1,8,0,0,0,0,0],"html_filename":"onset___init___py.html","relative_filename":"onset/__init__.py"}}}}

+ 375
- 0
covers/htmlcov/style.css View File

@@ -0,0 +1,375 @@
1
+/* Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 */
2
+/* For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt */
3
+
4
+/* CSS styles for coverage.py. */
5
+
6
+/* Page-wide styles */
7
+html, body, h1, h2, h3, p, table, td, th {
8
+    margin: 0;
9
+    padding: 0;
10
+    border: 0;
11
+    outline: 0;
12
+    font-weight: inherit;
13
+    font-style: inherit;
14
+    font-size: 100%;
15
+    font-family: inherit;
16
+    vertical-align: baseline;
17
+    }
18
+
19
+/* Set baseline grid to 16 pt. */
20
+body {
21
+    font-family: georgia, serif;
22
+    font-size: 1em;
23
+    }
24
+
25
+html>body {
26
+    font-size: 16px;
27
+    }
28
+
29
+/* Set base font size to 12/16 */
30
+p {
31
+    font-size: .75em;           /* 12/16 */
32
+    line-height: 1.33333333em;  /* 16/12 */
33
+    }
34
+
35
+table {
36
+    border-collapse: collapse;
37
+    }
38
+td {
39
+    vertical-align: top;
40
+}
41
+table tr.hidden {
42
+    display: none !important;
43
+    }
44
+
45
+p#no_rows {
46
+    display: none;
47
+    font-size: 1.2em;
48
+    }
49
+
50
+a.nav {
51
+    text-decoration: none;
52
+    color: inherit;
53
+    }
54
+a.nav:hover {
55
+    text-decoration: underline;
56
+    color: inherit;
57
+    }
58
+
59
+/* Page structure */
60
+#header {
61
+    background: #f8f8f8;
62
+    width: 100%;
63
+    border-bottom: 1px solid #eee;
64
+    }
65
+
66
+#source {
67
+    padding: 1em;
68
+    font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
69
+    }
70
+
71
+.indexfile #footer {
72
+    margin: 1em 3em;
73
+    }
74
+
75
+.pyfile #footer {
76
+    margin: 1em 1em;
77
+    }
78
+
79
+#footer .content {
80
+    padding: 0;
81
+    font-size: 85%;
82
+    font-family: verdana, sans-serif;
83
+    color: #666666;
84
+    font-style: italic;
85
+    }
86
+
87
+#index {
88
+    margin: 1em 0 0 3em;
89
+    }
90
+
91
+/* Header styles */
92
+#header .content {
93
+    padding: 1em 3em;
94
+    }
95
+
96
+h1 {
97
+    font-size: 1.25em;
98
+    display: inline-block;
99
+}
100
+
101
+#filter_container {
102
+    display: inline-block;
103
+    float: right;
104
+    margin: 0 2em 0 0;
105
+}
106
+#filter_container input {
107
+    width: 10em;
108
+}
109
+
110
+h2.stats {
111
+    margin-top: .5em;
112
+    font-size: 1em;
113
+}
114
+.stats span {
115
+    border: 1px solid;
116
+    padding: .1em .25em;
117
+    margin: 0 .1em;
118
+    cursor: pointer;
119
+    border-color: #999 #ccc #ccc #999;
120
+}
121
+.stats span.hide_run, .stats span.hide_exc,
122
+.stats span.hide_mis, .stats span.hide_par,
123
+.stats span.par.hide_run.hide_par {
124
+    border-color: #ccc #999 #999 #ccc;
125
+}
126
+.stats span.par.hide_run {
127
+    border-color: #999 #ccc #ccc #999;
128
+}
129
+
130
+.stats span.run {
131
+    background: #ddffdd;
132
+}
133
+.stats span.exc {
134
+    background: #eeeeee;
135
+}
136
+.stats span.mis {
137
+    background: #ffdddd;
138
+}
139
+.stats span.hide_run {
140
+    background: #eeffee;
141
+}
142
+.stats span.hide_exc {
143
+    background: #f5f5f5;
144
+}
145
+.stats span.hide_mis {
146
+    background: #ffeeee;
147
+}
148
+.stats span.par {
149
+    background: #ffffaa;
150
+}
151
+.stats span.hide_par {
152
+    background: #ffffcc;
153
+}
154
+
155
+/* Help panel */
156
+#keyboard_icon {
157
+    float: right;
158
+    margin: 5px;
159
+    cursor: pointer;
160
+}
161
+
162
+.help_panel {
163
+    position: absolute;
164
+    background: #ffffcc;
165
+    padding: .5em;
166
+    border: 1px solid #883;
167
+    display: none;
168
+}
169
+
170
+.indexfile .help_panel {
171
+    width: 20em; height: 4em;
172
+}
173
+
174
+.pyfile .help_panel {
175
+    width: 16em; height: 8em;
176
+}
177
+
178
+.help_panel .legend {
179
+    font-style: italic;
180
+    margin-bottom: 1em;
181
+}
182
+
183
+#panel_icon {
184
+    float: right;
185
+    cursor: pointer;
186
+}
187
+
188
+.keyhelp {
189
+    margin: .75em;
190
+}
191
+
192
+.keyhelp .key {
193
+    border: 1px solid black;
194
+    border-color: #888 #333 #333 #888;
195
+    padding: .1em .35em;
196
+    font-family: monospace;
197
+    font-weight: bold;
198
+    background: #eee;
199
+}
200
+
201
+/* Source file styles */
202
+.linenos p {
203
+    text-align: right;
204
+    margin: 0;
205
+    padding: 0 .5em;
206
+    color: #999999;
207
+    font-family: verdana, sans-serif;
208
+    font-size: .625em;   /* 10/16 */
209
+    line-height: 1.6em;  /* 16/10 */
210
+    }
211
+.linenos p.highlight {
212
+    background: #ffdd00;
213
+    }
214
+.linenos p a {
215
+    text-decoration: none;
216
+    color: #999999;
217
+    }
218
+.linenos p a:hover {
219
+    text-decoration: underline;
220
+    color: #999999;
221
+    }
222
+
223
+td.text {
224
+    width: 100%;
225
+    }
226
+.text p {
227
+    margin: 0;
228
+    padding: 0 0 0 .5em;
229
+    border-left: 2px solid #ffffff;
230
+    white-space: pre;
231
+    position: relative;
232
+    }
233
+
234
+.text p.mis {
235
+    background: #ffdddd;
236
+    border-left: 2px solid #ff0000;
237
+    }
238
+.text p.run, .text p.run.hide_par {
239
+    background: #ddffdd;
240
+    border-left: 2px solid #00ff00;
241
+    }
242
+.text p.exc {
243
+    background: #eeeeee;
244
+    border-left: 2px solid #808080;
245
+    }
246
+.text p.par, .text p.par.hide_run {
247
+    background: #ffffaa;
248
+    border-left: 2px solid #eeee99;
249
+    }
250
+.text p.hide_run, .text p.hide_exc, .text p.hide_mis, .text p.hide_par,
251
+.text p.hide_run.hide_par {
252
+    background: inherit;
253
+    }
254
+
255
+.text span.annotate {
256
+    font-family: georgia;
257
+    color: #666;
258
+    float: right;
259
+    padding-right: .5em;
260
+    }
261
+.text p.hide_par span.annotate {
262
+    display: none;
263
+    }
264
+.text span.annotate.long {
265
+    display: none;
266
+    }
267
+.text p:hover span.annotate.long {
268
+    display: block;
269
+    max-width: 50%;
270
+    white-space: normal;
271
+    float: right;
272
+    position: absolute;
273
+    top: 1.75em;
274
+    right: 1em;
275
+    width: 30em;
276
+    height: auto;
277
+    color: #333;
278
+    background: #ffffcc;
279
+    border: 1px solid #888;
280
+    padding: .25em .5em;
281
+    z-index: 999;
282
+    border-radius: .2em;
283
+    box-shadow: #cccccc .2em .2em .2em;
284
+    }
285
+
286
+/* Syntax coloring */
287
+.text .com {
288
+    color: green;
289
+    font-style: italic;
290
+    line-height: 1px;
291
+    }
292
+.text .key {
293
+    font-weight: bold;
294
+    line-height: 1px;
295
+    }
296
+.text .str {
297
+    color: #000080;
298
+    }
299
+
300
+/* index styles */
301
+#index td, #index th {
302
+    text-align: right;
303
+    width: 5em;
304
+    padding: .25em .5em;
305
+    border-bottom: 1px solid #eee;
306
+    }
307
+#index th {
308
+    font-style: italic;
309
+    color: #333;
310
+    border-bottom: 1px solid #ccc;
311
+    cursor: pointer;
312
+    }
313
+#index th:hover {
314
+    background: #eee;
315
+    border-bottom: 1px solid #999;
316
+    }
317
+#index td.left, #index th.left {
318
+    padding-left: 0;
319
+    }
320
+#index td.right, #index th.right {
321
+    padding-right: 0;
322
+    }
323
+#index th.headerSortDown, #index th.headerSortUp {
324
+    border-bottom: 1px solid #000;
325
+    white-space: nowrap;
326
+    background: #eee;
327
+    }
328
+#index th.headerSortDown:after {
329
+    content: " ↓";
330
+}
331
+#index th.headerSortUp:after {
332
+    content: " ↑";
333
+}
334
+#index td.name, #index th.name {
335
+    text-align: left;
336
+    width: auto;
337
+    }
338
+#index td.name a {
339
+    text-decoration: none;
340
+    color: #000;
341
+    }
342
+#index tr.total,
343
+#index tr.total_dynamic {
344
+    }
345
+#index tr.total td,
346
+#index tr.total_dynamic td {
347
+    font-weight: bold;
348
+    border-top: 1px solid #ccc;
349
+    border-bottom: none;
350
+    }
351
+#index tr.file:hover {
352
+    background: #eeeeee;
353
+    }
354
+#index tr.file:hover td.name {
355
+    text-decoration: underline;
356
+    color: #000;
357
+    }
358
+
359
+/* scroll marker styles */
360
+#scroll_marker {
361
+    position: fixed;
362
+    right: 0;
363
+    top: 0;
364
+    width: 16px;
365
+    height: 100%;
366
+    background: white;
367
+    border-left: 1px solid #eee;
368
+    }
369
+
370
+#scroll_marker .marker {
371
+    background: #eedddd;
372
+    position: absolute;
373
+    min-height: 3px;
374
+    width: 100%;
375
+    }

+ 8
- 4
devs/Makefile View File

@@ -1,13 +1,17 @@
1 1
 init-devs: .venv
2
-	.venv/bin/pip install -e .
3 2
 	.venv/bin/pip install '.[devs]'
3
+	.venv/bin/pip install --editable .
4 4
 
5
-clean-devs:
6
-	find . -name '*~' -exec rm -f {} +
5
+check-devs: .venv
6
+	.venv/bin/python setup.py check --metadata | grep -v "running check" || true
7
+
8
+clean-devs: .venv
9
+	.venv/bin/python setup.py clean
7 10
 	find . -name '*.pyc' -exec rm -f {} +
8 11
 	find . -name '*.pyo' -exec rm -f {} +
9 12
 	find . -name '*.egg' -exec rm -f {} +
10 13
 	find . -name '*.egg-info' -exec rm -fr {} +
11 14
 	find . -name '__pycache__' -exec rm -fr {} +
12 15
 
13
-commit-devs: ;
16
+commit-devs: .venv
17
+	.venv/bin/python setup.py check --strict --metadata

+ 4
- 3
formats/Makefile View File

@@ -1,11 +1,12 @@
1
-.PHONY: format
2
-
3 1
 init-formats: .venv
4 2
 	.venv/bin/pip install '.[formats]'
3
+	ln -fs 'formats/black.ini' 'black.ini'
5 4
 
6 5
 clean-formats: ;
7 6
 
7
+check-formats: ;
8
+
8 9
 commit-formats: format;
9 10
 
10 11
 format: .venv
11
-	.venv/bin/black --config=formats/black.ini .
12
+	.venv/bin/black --config='black.ini' .

+ 1
- 1
formats/black.ini View File

@@ -1,2 +1,2 @@
1 1
 [tool.black]
2
-line-length = 88
2
+line-length = 79

+ 2
- 0
hooks/Makefile View File

@@ -1,6 +1,8 @@
1 1
 init-hooks:
2 2
 	git config --global core.hooksPath hooks/
3 3
 
4
+check-hooks: ;
5
+
4 6
 clean-hooks: ;
5 7
 
6 8
 commit-hooks: ;

+ 1
- 0
ipython.py View File

@@ -0,0 +1 @@
1
+shells/ipython.py

+ 6
- 5
lints/Makefile View File

@@ -1,14 +1,15 @@
1
-.PHONY: lint
2
-
3 1
 NAME = $(shell .venv/bin/python setup.py --name)
4 2
 
5 3
 init-lints: .venv
6 4
 	.venv/bin/pip install '.[lints]'
5
+	ln -fs 'lints/pylint.ini' 'pylintrc'
6
+
7
+clean-lints: ;
7 8
 
8
-clean-lints:
9
-	find . -name '.mypy_cache' -exec rm -fr {} +
9
+check-lints: .venv
10
+	.venv/bin/pylint --errors-only ${NAME} | grep ".py" || true
10 11
 
11 12
 commit-lints: lint;
12 13
 
13 14
 lint: .venv
14
-	.venv/bin/pylint --rcfile='lints/pylint.ini' ${NAME}
15
+	.venv/bin/pylint ${NAME}

+ 1
- 0
mypy.ini View File

@@ -0,0 +1 @@
1
+types/mypy.ini

+ 2
- 2
packages/Makefile View File

@@ -1,5 +1,3 @@
1
-.PHONY: package upload
2
-
3 1
 init-packages: .venv
4 2
 	.venv/bin/pip install '.[packages]'
5 3
 
@@ -7,6 +5,8 @@ clean-packages:
7 5
 	rm -rf build/lib/
8 6
 	rm -rf dist/*.whl
9 7
 
8
+check-packages: ;
9
+
10 10
 commit-packages: package;
11 11
 
12 12
 package: .venv clean-packages

+ 1
- 0
pylintrc View File

@@ -0,0 +1 @@
1
+lints/pylint.ini

+ 1
- 0
pytest.ini View File

@@ -0,0 +1 @@
1
+tests/pytest.ini

+ 2
- 0
scripts/Makefile View File

@@ -2,4 +2,6 @@ init-scripts: ;
2 2
 
3 3
 clean-scripts: ;
4 4
 
5
+check-scripts: ;
6
+
5 7
 commit-scripts: ;

+ 5
- 1
scripts/console.py View File

@@ -38,7 +38,11 @@ def main(args=None):
38 38
     steps = opts.steps
39 39
 
40 40
     if (len(steps) % 2) != 1:
41
-        sys.exit("Error: the number of steps should be odd. Got: {}".format(len(steps)))
41
+        sys.exit(
42
+            "Error: the number of steps should be odd. Got: {}".format(
43
+                len(steps)
44
+            )
45
+        )
42 46
 
43 47
     state = from_file(steps.pop(0))
44 48
 

+ 3
- 2
setup.py View File

@@ -16,7 +16,7 @@ def requires(requirements="requirements.txt"):
16 16
 
17 17
 info = dict(
18 18
     name="onset",
19
-    version="1.0.11",
19
+    version="1.0.12",
20 20
     license="AGPL-3.0",
21 21
     author="Médéric Hurier",
22 22
     author_email="dev@fmind.me",
@@ -34,7 +34,8 @@ info = dict(
34 34
         "Programming Language :: Python :: 3",
35 35
     ],
36 36
     extras_require={
37
-        os.path.dirname(f): requires(f) for f in glob.glob("*/requirements.txt")
37
+        os.path.dirname(f): requires(f)
38
+        for f in glob.glob("*/requirements.txt")
38 39
     },
39 40
     python_requires=">=3",
40 41
     install_requires=requires(),

+ 4
- 1
shells/Makefile View File

@@ -1,9 +1,12 @@
1 1
 init-shells: .venv
2 2
 	.venv/bin/pip install '.[shells]'
3
+	ln -fs 'shells/ipython.py' 'ipython.py'
3 4
 
4 5
 clean-shells: ;
5 6
 
7
+check-shells: ;
8
+
6 9
 commit-shells: ;
7 10
 
8 11
 shell: .venv
9
-	.venv/bin/ipython --config='shells/ipython.py'
12
+	.venv/bin/ipython --config='ipython.py'

+ 7
- 6
shells/ipython.py View File

@@ -4,13 +4,14 @@ from traitlets.config import get_config
4 4
 
5 5
 c = get_config()
6 6
 
7
-c.TerminalIPythonApp.force_interact = True
7
+c.InteractiveShellApp.extensions = ["autoreload"]
8 8
 
9
-c.TerminalInteractiveShell.colors = "Linux"
10
-c.TerminalInteractiveShell.editing_mode = "vi"
11
-c.TerminalInteractiveShell.confirm_exit = False
9
+c.InteractiveShellApp.exec_lines = [
10
+    "from IPython.lib import deepreload as rl",
11
+    "%autoreload 2",
12
+]
12 13
 
13
-c.InteractiveShellApp.extensions = ["autoreload"]
14
-c.InteractiveShellApp.exec_lines = ["%autoreload 2"]
14
+c.TerminalIPythonApp.force_interact = True
15 15
 
16
+c.TerminalInteractiveShell.confirm_exit = False
16 17
 c.TerminalInteractiveShell.extra_open_editor_shortcuts = True

+ 5
- 3
tests/Makefile View File

@@ -1,13 +1,15 @@
1
-.PHONY: test
2
-
3 1
 init-tests: .venv
4 2
 	.venv/bin/pip install '.[tests]'
3
+	ln -fs 'tests/pytest.ini' 'pytest.ini'
5 4
 
6 5
 clean-tests:
7 6
 	find . -name '.hypothesis' -exec rm -fr {} +
8 7
 	find . -name '.pytest_cache' -exec rm -fr {} +
9 8
 
9
+check-tests: .venv
10
+	.venv/bin/pytest --quiet --tb=line | grep ".py" || true
11
+
10 12
 commit-tests: test;
11 13
 
12 14
 test: .venv
13
-	.venv/bin/pytest -c tests/pytest.ini
15
+	.venv/bin/pytest

+ 5
- 3
types/Makefile View File

@@ -1,12 +1,14 @@
1
-.PHONY: type
2
-
3 1
 init-types: .venv
4 2
 	.venv/bin/pip install '.[types]'
3
+	ln -fs 'types/mypy.ini' 'mypy.ini'
5 4
 
6 5
 clean-types:
7 6
 	find . -name '.mypy_cache' -exec rm -fr {} +
8 7
 
8
+check-types: .venv
9
+	.venv/bin/mypy . | grep ".py" || true
10
+
9 11
 commit-types: type;
10 12
 
11 13
 type: .venv
12
-	.venv/bin/mypy . --config-file=types/mypy.ini
14
+	.venv/bin/mypy .