summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2022-06-09 11:55:32 -0600
committerGitHub <noreply@github.com>2022-06-09 11:55:32 -0600
commit5ea81775e0d2d13a4fec6bab882002e050bd3da1 (patch)
treed2dc068c7c06c22393841ddc0dd7ee011996249f /tools
parent9d6b102617a92ad41964a5611c8dec87d3053a9f (diff)
parent5447192c8dc5d43d837b93ed5c5d47457e367669 (diff)
downloadnumpy-5ea81775e0d2d13a4fec6bab882002e050bd3da1.tar.gz
Merge branch 'main' into bugfix_16492_segfault_on_pyfragments
Diffstat (limited to 'tools')
-rw-r--r--tools/allocation_tracking/README.md8
-rw-r--r--tools/allocation_tracking/alloc_hook.pyx42
-rw-r--r--tools/allocation_tracking/setup.py9
-rw-r--r--tools/allocation_tracking/sorttable.js493
-rw-r--r--tools/allocation_tracking/track_allocations.py140
-rwxr-xr-xtools/changelog.py64
-rwxr-xr-xtools/ci/push_docs_to_repo.py5
-rwxr-xr-xtools/ci/test_all_newsfragments_used.py2
-rw-r--r--tools/commitstats.py2
-rwxr-xr-xtools/cythonize.py40
-rw-r--r--tools/download-wheels.py56
-rw-r--r--tools/find_deprecated_escaped_characters.py5
-rwxr-xr-xtools/functions_missing_types.py134
-rw-r--r--tools/gitpod/Dockerfile101
-rw-r--r--tools/gitpod/gitpod.Dockerfile49
-rw-r--r--tools/gitpod/settings.json8
-rw-r--r--tools/gitpod/workspace_config58
-rw-r--r--tools/lint_diff.ini5
-rw-r--r--tools/linter.py85
-rw-r--r--tools/list_installed_dll_dependencies_cygwin.sh35
-rw-r--r--tools/list_numpy_dlls.sh9
-rw-r--r--tools/npy_tempita/__init__.py2
-rw-r--r--tools/openblas_support.py205
-rwxr-xr-xtools/pypy-test.sh49
-rw-r--r--tools/rebase_installed_dlls_cygwin.sh5
-rw-r--r--tools/refguide_check.py88
-rw-r--r--tools/swig/README2
-rw-r--r--tools/swig/numpy.i196
-rw-r--r--tools/swig/pyfragments.swg15
-rwxr-xr-xtools/swig/test/testFarray.py22
-rwxr-xr-xtools/travis-before-install.sh17
-rwxr-xr-xtools/travis-sorter.py287
-rwxr-xr-xtools/travis-test.sh35
-rw-r--r--tools/wheels/LICENSE_linux.txt880
-rw-r--r--tools/wheels/LICENSE_osx.txt789
-rw-r--r--tools/wheels/LICENSE_win32.txt938
-rw-r--r--tools/wheels/check_license.py55
-rw-r--r--tools/wheels/cibw_before_build.sh58
-rw-r--r--tools/wheels/cibw_test_command.sh19
-rw-r--r--tools/wheels/gfortran_utils.sh168
-rw-r--r--tools/wheels/upload_wheels.sh58
41 files changed, 4078 insertions, 1160 deletions
diff --git a/tools/allocation_tracking/README.md b/tools/allocation_tracking/README.md
index fd4f2c871..6cc4c2a58 100644
--- a/tools/allocation_tracking/README.md
+++ b/tools/allocation_tracking/README.md
@@ -1,11 +1,7 @@
-Example for using the `PyDataMem_SetEventHook` to track allocations inside numpy.
-
-`alloc_hook.pyx` implements a hook in Cython that calls back into a python
-function. `track_allocations.py` uses it for a simple listing of allocations.
-It can be built with the `setup.py` file in this folder.
-
Note that since Python 3.6 the builtin tracemalloc module can be used to
track allocations inside numpy.
Numpy places its CPU memory allocations into the `np.lib.tracemalloc_domain`
domain.
See https://docs.python.org/3/library/tracemalloc.html.
+
+The tool that used to be here has been deprecated.
diff --git a/tools/allocation_tracking/alloc_hook.pyx b/tools/allocation_tracking/alloc_hook.pyx
deleted file mode 100644
index eeefe1704..000000000
--- a/tools/allocation_tracking/alloc_hook.pyx
+++ /dev/null
@@ -1,42 +0,0 @@
-# A cython wrapper for using python functions as callbacks for
-# PyDataMem_SetEventHook.
-
-cimport numpy as np
-
-cdef extern from "Python.h":
- object PyLong_FromVoidPtr(void *)
- void *PyLong_AsVoidPtr(object)
-
-ctypedef void PyDataMem_EventHookFunc(void *inp, void *outp, size_t size,
- void *user_data)
-cdef extern from "numpy/arrayobject.h":
- PyDataMem_EventHookFunc * \
- PyDataMem_SetEventHook(PyDataMem_EventHookFunc *newhook,
- void *user_data, void **old_data)
-
-np.import_array()
-
-cdef void pyhook(void *old, void *new, size_t size, void *user_data):
- cdef object pyfunc = <object> user_data
- pyfunc(PyLong_FromVoidPtr(old),
- PyLong_FromVoidPtr(new),
- size)
-
-class NumpyAllocHook:
- def __init__(self, callback):
- self.callback = callback
-
- def __enter__(self):
- cdef void *old_hook, *old_data
- old_hook = <void *> \
- PyDataMem_SetEventHook(<PyDataMem_EventHookFunc *> pyhook,
- <void *> self.callback,
- <void **> &old_data)
- self.old_hook = PyLong_FromVoidPtr(old_hook)
- self.old_data = PyLong_FromVoidPtr(old_data)
-
- def __exit__(self):
- PyDataMem_SetEventHook(<PyDataMem_EventHookFunc *> \
- PyLong_AsVoidPtr(self.old_hook),
- <void *> PyLong_AsVoidPtr(self.old_data),
- <void **> 0)
diff --git a/tools/allocation_tracking/setup.py b/tools/allocation_tracking/setup.py
deleted file mode 100644
index 4462f9f4e..000000000
--- a/tools/allocation_tracking/setup.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from distutils.core import setup
-from distutils.extension import Extension
-from Cython.Distutils import build_ext
-import numpy
-
-setup(
- cmdclass = {'build_ext': build_ext},
- ext_modules = [Extension("alloc_hook", ["alloc_hook.pyx"],
- include_dirs=[numpy.get_include()])])
diff --git a/tools/allocation_tracking/sorttable.js b/tools/allocation_tracking/sorttable.js
deleted file mode 100644
index c9528873e..000000000
--- a/tools/allocation_tracking/sorttable.js
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- SortTable
- version 2
- 7th April 2007
- Stuart Langridge, https://www.kryogenix.org/code/browser/sorttable/
-
- Instructions:
- Download this file
- Add <script src="sorttable.js"></script> to your HTML
- Add class="sortable" to any table you'd like to make sortable
- Click on the headers to sort
-
- Thanks to many, many people for contributions and suggestions.
- Licenced as X11: https://www.kryogenix.org/code/browser/licence.html
- This basically means: do what you want with it.
-*/
-
-
-var stIsIE = /*@cc_on!@*/false;
-
-sorttable = {
- init: function() {
- // quit if this function has already been called
- if (arguments.callee.done) return;
- // flag this function so we don't do the same thing twice
- arguments.callee.done = true;
- // kill the timer
- if (_timer) clearInterval(_timer);
-
- if (!document.createElement || !document.getElementsByTagName) return;
-
- sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/;
-
- forEach(document.getElementsByTagName('table'), function(table) {
- if (table.className.search(/\bsortable\b/) != -1) {
- sorttable.makeSortable(table);
- }
- });
-
- },
-
- makeSortable: function(table) {
- if (table.getElementsByTagName('thead').length == 0) {
- // table doesn't have a tHead. Since it should have, create one and
- // put the first table row in it.
- the = document.createElement('thead');
- the.appendChild(table.rows[0]);
- table.insertBefore(the,table.firstChild);
- }
- // Safari doesn't support table.tHead, sigh
- if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0];
-
- if (table.tHead.rows.length != 1) return; // can't cope with two header rows
-
- // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as
- // "total" rows, for example). This is B&R, since what you're supposed
- // to do is put them in a tfoot. So, if there are sortbottom rows,
- // for backwards compatibility, move them to tfoot (creating it if needed).
- sortbottomrows = [];
- for (var i=0; i<table.rows.length; i++) {
- if (table.rows[i].className.search(/\bsortbottom\b/) != -1) {
- sortbottomrows[sortbottomrows.length] = table.rows[i];
- }
- }
- if (sortbottomrows) {
- if (table.tFoot == null) {
- // table doesn't have a tfoot. Create one.
- tfo = document.createElement('tfoot');
- table.appendChild(tfo);
- }
- for (var i=0; i<sortbottomrows.length; i++) {
- tfo.appendChild(sortbottomrows[i]);
- }
- delete sortbottomrows;
- }
-
- // work through each column and calculate its type
- headrow = table.tHead.rows[0].cells;
- for (var i=0; i<headrow.length; i++) {
- // manually override the type with a sorttable_type attribute
- if (!headrow[i].className.match(/\bsorttable_nosort\b/)) { // skip this col
- mtch = headrow[i].className.match(/\bsorttable_([a-z0-9]+)\b/);
- if (mtch) { override = mtch[1]; }
- if (mtch && typeof sorttable["sort_"+override] == 'function') {
- headrow[i].sorttable_sortfunction = sorttable["sort_"+override];
- } else {
- headrow[i].sorttable_sortfunction = sorttable.guessType(table,i);
- }
- // make it clickable to sort
- headrow[i].sorttable_columnindex = i;
- headrow[i].sorttable_tbody = table.tBodies[0];
- dean_addEvent(headrow[i],"click", function(e) {
-
- if (this.className.search(/\bsorttable_sorted\b/) != -1) {
- // if we're already sorted by this column, just
- // reverse the table, which is quicker
- sorttable.reverse(this.sorttable_tbody);
- this.className = this.className.replace('sorttable_sorted',
- 'sorttable_sorted_reverse');
- this.removeChild(document.getElementById('sorttable_sortfwdind'));
- sortrevind = document.createElement('span');
- sortrevind.id = "sorttable_sortrevind";
- sortrevind.innerHTML = stIsIE ? '&nbsp<font face="webdings">5</font>' : '&nbsp;&#x25B4;';
- this.appendChild(sortrevind);
- return;
- }
- if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) {
- // if we're already sorted by this column in reverse, just
- // re-reverse the table, which is quicker
- sorttable.reverse(this.sorttable_tbody);
- this.className = this.className.replace('sorttable_sorted_reverse',
- 'sorttable_sorted');
- this.removeChild(document.getElementById('sorttable_sortrevind'));
- sortfwdind = document.createElement('span');
- sortfwdind.id = "sorttable_sortfwdind";
- sortfwdind.innerHTML = stIsIE ? '&nbsp<font face="webdings">6</font>' : '&nbsp;&#x25BE;';
- this.appendChild(sortfwdind);
- return;
- }
-
- // remove sorttable_sorted classes
- theadrow = this.parentNode;
- forEach(theadrow.childNodes, function(cell) {
- if (cell.nodeType == 1) { // an element
- cell.className = cell.className.replace('sorttable_sorted_reverse','');
- cell.className = cell.className.replace('sorttable_sorted','');
- }
- });
- sortfwdind = document.getElementById('sorttable_sortfwdind');
- if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); }
- sortrevind = document.getElementById('sorttable_sortrevind');
- if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); }
-
- this.className += ' sorttable_sorted';
- sortfwdind = document.createElement('span');
- sortfwdind.id = "sorttable_sortfwdind";
- sortfwdind.innerHTML = stIsIE ? '&nbsp<font face="webdings">6</font>' : '&nbsp;&#x25BE;';
- this.appendChild(sortfwdind);
-
- // build an array to sort. This is a Schwartzian transform thing,
- // i.e., we "decorate" each row with the actual sort key,
- // sort based on the sort keys, and then put the rows back in order
- // which is a lot faster because you only do getInnerText once per row
- row_array = [];
- col = this.sorttable_columnindex;
- rows = this.sorttable_tbody.rows;
- for (var j=0; j<rows.length; j++) {
- row_array[row_array.length] = [sorttable.getInnerText(rows[j].cells[col]), rows[j]];
- }
- /* If you want a stable sort, uncomment the following line */
- //sorttable.shaker_sort(row_array, this.sorttable_sortfunction);
- /* and comment out this one */
- row_array.sort(this.sorttable_sortfunction);
-
- tb = this.sorttable_tbody;
- for (var j=0; j<row_array.length; j++) {
- tb.appendChild(row_array[j][1]);
- }
-
- delete row_array;
- });
- }
- }
- },
-
- guessType: function(table, column) {
- // guess the type of a column based on its first non-blank row
- sortfn = sorttable.sort_alpha;
- for (var i=0; i<table.tBodies[0].rows.length; i++) {
- text = sorttable.getInnerText(table.tBodies[0].rows[i].cells[column]);
- if (text != '') {
- if (text.match(/^-?[£$¤]?[\d,.]+%?$/)) {
- return sorttable.sort_numeric;
- }
- // check for a date: dd/mm/yyyy or dd/mm/yy
- // can have / or . or - as separator
- // can be mm/dd as well
- possdate = text.match(sorttable.DATE_RE)
- if (possdate) {
- // looks like a date
- first = parseInt(possdate[1]);
- second = parseInt(possdate[2]);
- if (first > 12) {
- // definitely dd/mm
- return sorttable.sort_ddmm;
- } else if (second > 12) {
- return sorttable.sort_mmdd;
- } else {
- // looks like a date, but we can't tell which, so assume
- // that it's dd/mm (English imperialism!) and keep looking
- sortfn = sorttable.sort_ddmm;
- }
- }
- }
- }
- return sortfn;
- },
-
- getInnerText: function(node) {
- // gets the text we want to use for sorting for a cell.
- // strips leading and trailing whitespace.
- // this is *not* a generic getInnerText function; it's special to sorttable.
- // for example, you can override the cell text with a customkey attribute.
- // it also gets .value for <input> fields.
-
- hasInputs = (typeof node.getElementsByTagName == 'function') &&
- node.getElementsByTagName('input').length;
-
- if (node.getAttribute("sorttable_customkey") != null) {
- return node.getAttribute("sorttable_customkey");
- }
- else if (typeof node.textContent != 'undefined' && !hasInputs) {
- return node.textContent.replace(/^\s+|\s+$/g, '');
- }
- else if (typeof node.innerText != 'undefined' && !hasInputs) {
- return node.innerText.replace(/^\s+|\s+$/g, '');
- }
- else if (typeof node.text != 'undefined' && !hasInputs) {
- return node.text.replace(/^\s+|\s+$/g, '');
- }
- else {
- switch (node.nodeType) {
- case 3:
- if (node.nodeName.toLowerCase() == 'input') {
- return node.value.replace(/^\s+|\s+$/g, '');
- }
- case 4:
- return node.nodeValue.replace(/^\s+|\s+$/g, '');
- break;
- case 1:
- case 11:
- var innerText = '';
- for (var i = 0; i < node.childNodes.length; i++) {
- innerText += sorttable.getInnerText(node.childNodes[i]);
- }
- return innerText.replace(/^\s+|\s+$/g, '');
- break;
- default:
- return '';
- }
- }
- },
-
- reverse: function(tbody) {
- // reverse the rows in a tbody
- newrows = [];
- for (var i=0; i<tbody.rows.length; i++) {
- newrows[newrows.length] = tbody.rows[i];
- }
- for (var i=newrows.length-1; i>=0; i--) {
- tbody.appendChild(newrows[i]);
- }
- delete newrows;
- },
-
- /* sort functions
- each sort function takes two parameters, a and b
- you are comparing a[0] and b[0] */
- sort_numeric: function(a,b) {
- aa = parseFloat(a[0].replace(/[^0-9.-]/g,''));
- if (isNaN(aa)) aa = 0;
- bb = parseFloat(b[0].replace(/[^0-9.-]/g,''));
- if (isNaN(bb)) bb = 0;
- return aa-bb;
- },
- sort_alpha: function(a,b) {
- if (a[0]==b[0]) return 0;
- if (a[0]<b[0]) return -1;
- return 1;
- },
- sort_ddmm: function(a,b) {
- mtch = a[0].match(sorttable.DATE_RE);
- y = mtch[3]; m = mtch[2]; d = mtch[1];
- if (m.length == 1) m = '0'+m;
- if (d.length == 1) d = '0'+d;
- dt1 = y+m+d;
- mtch = b[0].match(sorttable.DATE_RE);
- y = mtch[3]; m = mtch[2]; d = mtch[1];
- if (m.length == 1) m = '0'+m;
- if (d.length == 1) d = '0'+d;
- dt2 = y+m+d;
- if (dt1==dt2) return 0;
- if (dt1<dt2) return -1;
- return 1;
- },
- sort_mmdd: function(a,b) {
- mtch = a[0].match(sorttable.DATE_RE);
- y = mtch[3]; d = mtch[2]; m = mtch[1];
- if (m.length == 1) m = '0'+m;
- if (d.length == 1) d = '0'+d;
- dt1 = y+m+d;
- mtch = b[0].match(sorttable.DATE_RE);
- y = mtch[3]; d = mtch[2]; m = mtch[1];
- if (m.length == 1) m = '0'+m;
- if (d.length == 1) d = '0'+d;
- dt2 = y+m+d;
- if (dt1==dt2) return 0;
- if (dt1<dt2) return -1;
- return 1;
- },
-
- shaker_sort: function(list, comp_func) {
- // A stable sort function to allow multi-level sorting of data
- // see: https://en.wikipedia.org/wiki/Cocktail_shaker_sort
- // thanks to Joseph Nahmias
- var b = 0;
- var t = list.length - 1;
- var swap = true;
-
- while(swap) {
- swap = false;
- for(var i = b; i < t; ++i) {
- if ( comp_func(list[i], list[i+1]) > 0 ) {
- var q = list[i]; list[i] = list[i+1]; list[i+1] = q;
- swap = true;
- }
- } // for
- t--;
-
- if (!swap) break;
-
- for(var i = t; i > b; --i) {
- if ( comp_func(list[i], list[i-1]) < 0 ) {
- var q = list[i]; list[i] = list[i-1]; list[i-1] = q;
- swap = true;
- }
- } // for
- b++;
-
- } // while(swap)
- }
-}
-
-/* ******************************************************************
- Supporting functions: bundled here to avoid depending on a library
- ****************************************************************** */
-
-// Dean Edwards/Matthias Miller/John Resig
-
-/* for Mozilla/Opera9 */
-if (document.addEventListener) {
- document.addEventListener("DOMContentLoaded", sorttable.init, false);
-}
-
-/* for Internet Explorer */
-/*@cc_on @*/
-/*@if (@_win32)
- document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
- var script = document.getElementById("__ie_onload");
- script.onreadystatechange = function() {
- if (this.readyState == "complete") {
- sorttable.init(); // call the onload handler
- }
- };
-/*@end @*/
-
-/* for Safari */
-if (/WebKit/i.test(navigator.userAgent)) { // sniff
- var _timer = setInterval(function() {
- if (/loaded|complete/.test(document.readyState)) {
- sorttable.init(); // call the onload handler
- }
- }, 10);
-}
-
-/* for other browsers */
-window.onload = sorttable.init;
-
-// written by Dean Edwards, 2005
-// with input from Tino Zijdel, Matthias Miller, Diego Perini
-
-// http://dean.edwards.name/weblog/2005/10/add-event/
-
-function dean_addEvent(element, type, handler) {
- if (element.addEventListener) {
- element.addEventListener(type, handler, false);
- } else {
- // assign each event handler a unique ID
- if (!handler.$$guid) handler.$$guid = dean_addEvent.guid++;
- // create a hash table of event types for the element
- if (!element.events) element.events = {};
- // create a hash table of event handlers for each element/event pair
- var handlers = element.events[type];
- if (!handlers) {
- handlers = element.events[type] = {};
- // store the existing event handler (if there is one)
- if (element["on" + type]) {
- handlers[0] = element["on" + type];
- }
- }
- // store the event handler in the hash table
- handlers[handler.$$guid] = handler;
- // assign a global event handler to do all the work
- element["on" + type] = handleEvent;
- }
-};
-// a counter used to create unique IDs
-dean_addEvent.guid = 1;
-
-function removeEvent(element, type, handler) {
- if (element.removeEventListener) {
- element.removeEventListener(type, handler, false);
- } else {
- // delete the event handler from the hash table
- if (element.events && element.events[type]) {
- delete element.events[type][handler.$$guid];
- }
- }
-};
-
-function handleEvent(event) {
- var returnValue = true;
- // grab the event object (IE uses a global event object)
- event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);
- // get a reference to the hash table of event handlers
- var handlers = this.events[event.type];
- // execute each event handler
- for (var i in handlers) {
- this.$$handleEvent = handlers[i];
- if (this.$$handleEvent(event) === false) {
- returnValue = false;
- }
- }
- return returnValue;
-};
-
-function fixEvent(event) {
- // add W3C standard event methods
- event.preventDefault = fixEvent.preventDefault;
- event.stopPropagation = fixEvent.stopPropagation;
- return event;
-};
-fixEvent.preventDefault = function() {
- this.returnValue = false;
-};
-fixEvent.stopPropagation = function() {
- this.cancelBubble = true;
-}
-
-// Dean's forEach: http://dean.edwards.name/base/forEach.js
-/*
- forEach, version 1.0
- Copyright 2006, Dean Edwards
- License: https://www.opensource.org/licenses/mit-license.php
-*/
-
-// array-like enumeration
-if (!Array.forEach) { // mozilla already supports this
- Array.forEach = function(array, block, context) {
- for (var i = 0; i < array.length; i++) {
- block.call(context, array[i], i, array);
- }
- };
-}
-
-// generic enumeration
-Function.prototype.forEach = function(object, block, context) {
- for (var key in object) {
- if (typeof this.prototype[key] == "undefined") {
- block.call(context, object[key], key, object);
- }
- }
-};
-
-// character enumeration
-String.forEach = function(string, block, context) {
- Array.forEach(string.split(""), function(chr, index) {
- block.call(context, chr, index, string);
- });
-};
-
-// globally resolve forEach enumeration
-var forEach = function(object, block, context) {
- if (object) {
- var resolve = Object; // default
- if (object instanceof Function) {
- // functions have a "length" property
- resolve = Function;
- } else if (object.forEach instanceof Function) {
- // the object implements a custom forEach method so use that
- object.forEach(block, context);
- return;
- } else if (typeof object == "string") {
- // the object is a string
- resolve = String;
- } else if (typeof object.length == "number") {
- // the object is array-like
- resolve = Array;
- }
- resolve.forEach(object, block, context);
- }
-};
-
diff --git a/tools/allocation_tracking/track_allocations.py b/tools/allocation_tracking/track_allocations.py
deleted file mode 100644
index 2a80d8f87..000000000
--- a/tools/allocation_tracking/track_allocations.py
+++ /dev/null
@@ -1,140 +0,0 @@
-import numpy as np
-import gc
-import inspect
-from alloc_hook import NumpyAllocHook
-
-class AllocationTracker:
- def __init__(self, threshold=0):
- '''track numpy allocations of size threshold bytes or more.'''
-
- self.threshold = threshold
-
- # The total number of bytes currently allocated with size above
- # threshold
- self.total_bytes = 0
-
- # We buffer requests line by line and move them into the allocation
- # trace when a new line occurs
- self.current_line = None
- self.pending_allocations = []
-
- self.blocksizes = {}
-
- # list of (lineinfo, bytes allocated, bytes freed, # allocations, #
- # frees, maximum memory usage, long-lived bytes allocated)
- self.allocation_trace = []
-
- self.numpy_hook = NumpyAllocHook(self.hook)
-
- def __enter__(self):
- self.numpy_hook.__enter__()
-
- def __exit__(self, type, value, traceback):
- self.check_line_changed() # forces pending events to be handled
- self.numpy_hook.__exit__()
-
- def hook(self, inptr, outptr, size):
- # minimize the chances that the garbage collector kicks in during a
- # cython __dealloc__ call and causes a double delete of the current
- # object. To avoid this fully the hook would have to avoid all python
- # api calls, e.g. by being implemented in C like python 3.4's
- # tracemalloc module
- gc_on = gc.isenabled()
- gc.disable()
- if outptr == 0: # it's a free
- self.free_cb(inptr)
- elif inptr != 0: # realloc
- self.realloc_cb(inptr, outptr, size)
- else: # malloc
- self.alloc_cb(outptr, size)
- if gc_on:
- gc.enable()
-
- def alloc_cb(self, ptr, size):
- if size >= self.threshold:
- self.check_line_changed()
- self.blocksizes[ptr] = size
- self.pending_allocations.append(size)
-
- def free_cb(self, ptr):
- size = self.blocksizes.pop(ptr, 0)
- if size:
- self.check_line_changed()
- self.pending_allocations.append(-size)
-
- def realloc_cb(self, newptr, oldptr, size):
- if (size >= self.threshold) or (oldptr in self.blocksizes):
- self.check_line_changed()
- oldsize = self.blocksizes.pop(oldptr, 0)
- self.pending_allocations.append(size - oldsize)
- self.blocksizes[newptr] = size
-
- def get_code_line(self):
- # first frame is this line, then check_line_changed(), then 2 callbacks,
- # then actual code.
- try:
- return inspect.stack()[4][1:]
- except Exception:
- return inspect.stack()[0][1:]
-
- def check_line_changed(self):
- line = self.get_code_line()
- if line != self.current_line and (self.current_line is not None):
- # move pending events into the allocation_trace
- max_size = self.total_bytes
- bytes_allocated = 0
- bytes_freed = 0
- num_allocations = 0
- num_frees = 0
- before_size = self.total_bytes
- for allocation in self.pending_allocations:
- self.total_bytes += allocation
- if allocation > 0:
- bytes_allocated += allocation
- num_allocations += 1
- else:
- bytes_freed += -allocation
- num_frees += 1
- max_size = max(max_size, self.total_bytes)
- long_lived = max(self.total_bytes - before_size, 0)
- self.allocation_trace.append((self.current_line, bytes_allocated,
- bytes_freed, num_allocations,
- num_frees, max_size, long_lived))
- # clear pending allocations
- self.pending_allocations = []
- # move to the new line
- self.current_line = line
-
- def write_html(self, filename):
- with open(filename, "w") as f:
- f.write('<HTML><HEAD><script src="sorttable.js"></script></HEAD><BODY>\n')
- f.write('<TABLE class="sortable" width=100%>\n')
- f.write("<TR>\n")
- cols = "event#,lineinfo,bytes allocated,bytes freed,#allocations,#frees,max memory usage,long lived bytes".split(',')
- for header in cols:
- f.write(" <TH>{0}</TH>".format(header))
- f.write("\n</TR>\n")
- for idx, event in enumerate(self.allocation_trace):
- f.write("<TR>\n")
- event = [idx] + list(event)
- for col, val in zip(cols, event):
- if col == 'lineinfo':
- # special handling
- try:
- filename, line, module, code, index = val
- val = "{0}({1}): {2}".format(filename, line, code[index])
- except Exception:
- # sometimes this info is not available (from eval()?)
- val = str(val)
- f.write(" <TD>{0}</TD>".format(val))
- f.write("\n</TR>\n")
- f.write("</TABLE></BODY></HTML>\n")
-
-
-if __name__ == '__main__':
- tracker = AllocationTracker(1000)
- with tracker:
- for i in range(100):
- np.zeros(i * 100)
- np.zeros(i * 200)
- tracker.write_html("allocations.html")
diff --git a/tools/changelog.py b/tools/changelog.py
index 92f33af24..7b7e66ddb 100755
--- a/tools/changelog.py
+++ b/tools/changelog.py
@@ -1,5 +1,4 @@
#!/usr/bin/env python3
-# -*- encoding:utf-8 -*-
"""
Script to generate contributor and pull request lists
@@ -22,6 +21,7 @@ Dependencies
- gitpython
- pygithub
+- git >= 2.29.0
Some code was copied from scipy `tools/gh_list.py` and `tools/authors.py`.
@@ -39,38 +39,44 @@ import re
from git import Repo
from github import Github
-if sys.version_info[:2] < (3, 6):
- raise RuntimeError("Python version must be >= 3.6")
-
this_repo = Repo(os.path.join(os.path.dirname(__file__), ".."))
author_msg =\
-u"""
+"""
A total of %d people contributed to this release. People with a "+" by their
names contributed a patch for the first time.
"""
pull_request_msg =\
-u"""
+"""
A total of %d pull requests were merged for this release.
"""
+
def get_authors(revision_range):
- pat = u'^.*\\t(.*)$'
lst_release, cur_release = [r.strip() for r in revision_range.split('..')]
+ authors_pat = r'^.*\t(.*)$'
+
+ # authors and co-authors in current and previous releases.
+ grp1 = '--group=author'
+ grp2 = '--group=trailer:co-authored-by'
+ cur = this_repo.git.shortlog('-s', grp1, grp2, revision_range)
+ pre = this_repo.git.shortlog('-s', grp1, grp2, lst_release)
+ authors_cur = set(re.findall(authors_pat, cur, re.M))
+ authors_pre = set(re.findall(authors_pat, pre, re.M))
- # authors, in current release and previous to current release.
- cur = set(re.findall(pat, this_repo.git.shortlog('-s', revision_range),
- re.M))
- pre = set(re.findall(pat, this_repo.git.shortlog('-s', lst_release),
- re.M))
+ # Ignore the bot Homu.
+ authors_cur.discard('Homu')
+ authors_pre.discard('Homu')
- # Homu is the author of auto merges, clean him out.
- cur.discard('Homu')
- pre.discard('Homu')
+ # Ignore the bot dependabot-preview
+ authors_cur.discard('dependabot-preview')
+ authors_pre.discard('dependabot-preview')
# Append '+' to new authors.
- authors = [s + u' +' for s in cur - pre] + [s for s in cur & pre]
+ authors_new = [s + ' +' for s in authors_cur - authors_pre]
+ authors_old = [s for s in authors_cur & authors_pre]
+ authors = authors_new + authors_old
authors.sort()
return authors
@@ -81,18 +87,18 @@ def get_pull_requests(repo, revision_range):
# From regular merges
merges = this_repo.git.log(
'--oneline', '--merges', revision_range)
- issues = re.findall(u"Merge pull request \\#(\\d*)", merges)
+ issues = re.findall(r"Merge pull request \#(\d*)", merges)
prnums.extend(int(s) for s in issues)
# From Homu merges (Auto merges)
- issues = re. findall(u"Auto merge of \\#(\\d*)", merges)
+ issues = re. findall(r"Auto merge of \#(\d*)", merges)
prnums.extend(int(s) for s in issues)
# From fast forward squash-merges
commits = this_repo.git.log(
'--oneline', '--no-merges', '--first-parent', revision_range)
- issues = re.findall(u'^.*\\(\\#(\\d+)\\)$', commits, re.M)
- prnums.extend(int(s) for s in issues)
+ issues = re.findall(r'^.*\((\#|gh-|gh-\#)(\d+)\)$', commits, re.M)
+ prnums.extend(int(s[1]) for s in issues)
# get PR data from github repo
prnums.sort()
@@ -108,31 +114,31 @@ def main(token, revision_range):
# document authors
authors = get_authors(revision_range)
- heading = u"Contributors"
+ heading = "Contributors"
print()
print(heading)
- print(u"="*len(heading))
+ print("="*len(heading))
print(author_msg % len(authors))
for s in authors:
- print(u'* ' + s)
+ print('* ' + s)
# document pull requests
pull_requests = get_pull_requests(github_repo, revision_range)
- heading = u"Pull requests merged"
- pull_msg = u"* `#{0} <{1}>`__: {2}"
+ heading = "Pull requests merged"
+ pull_msg = "* `#{0} <{1}>`__: {2}"
print()
print(heading)
- print(u"="*len(heading))
+ print("="*len(heading))
print(pull_request_msg % len(pull_requests))
for pull in pull_requests:
- title = re.sub(u"\\s+", u" ", pull.title.strip())
+ title = re.sub(r"\s+", " ", pull.title.strip())
if len(title) > 60:
- remainder = re.sub(u"\\s.*$", u"...", title[60:])
+ remainder = re.sub(r"\s.*$", "...", title[60:])
if len(remainder) > 20:
- remainder = title[:80] + u"..."
+ remainder = title[:80] + "..."
else:
title = title[:60] + remainder
print(pull_msg.format(pull.number, pull.html_url, title))
diff --git a/tools/ci/push_docs_to_repo.py b/tools/ci/push_docs_to_repo.py
index ae5305484..058f748ec 100755
--- a/tools/ci/push_docs_to_repo.py
+++ b/tools/ci/push_docs_to_repo.py
@@ -45,6 +45,9 @@ workdir = tempfile.mkdtemp()
os.chdir(workdir)
run(['git', 'init'])
+# ensure the working branch is called "main"
+# (`--initial-branch=main` appared to have failed on older git versions):
+run(['git', 'checkout', '-b', 'main'])
run(['git', 'remote', 'add', 'origin', args.remote])
run(['git', 'config', '--local', 'user.name', args.committer])
run(['git', 'config', '--local', 'user.email', args.email])
@@ -56,7 +59,7 @@ run(['git', 'commit', '--allow-empty', '-m', args.message], stdout=False)
print('- uploading as %s <%s>' % (args.committer, args.email))
if args.force:
- run(['git', 'push', 'origin', 'master', '--force'])
+ run(['git', 'push', 'origin', 'main', '--force'])
else:
print('\n!! No `--force` argument specified; aborting')
print('!! Before enabling that flag, make sure you know what it does\n')
diff --git a/tools/ci/test_all_newsfragments_used.py b/tools/ci/test_all_newsfragments_used.py
index c2e031549..62c9a05f9 100755
--- a/tools/ci/test_all_newsfragments_used.py
+++ b/tools/ci/test_all_newsfragments_used.py
@@ -12,5 +12,5 @@ fragments.remove("template.rst")
if fragments:
print("The following files were not found by towncrier:")
- print(" " + " \n".join(fragments))
+ print(" " + "\n ".join(fragments))
sys.exit(1)
diff --git a/tools/commitstats.py b/tools/commitstats.py
index 14c37d4d2..534f0a1b8 100644
--- a/tools/commitstats.py
+++ b/tools/commitstats.py
@@ -4,7 +4,7 @@ import re
import numpy as np
import os
-names = re.compile(r'r\d+\s[|]\s(.*)\s[|]\s200')
+names = re.compile(r'r\d+\s\|\s(.*)\s\|\s200')
def get_count(filename, repo):
mystr = open(filename).read()
diff --git a/tools/cythonize.py b/tools/cythonize.py
index 65b79f716..002b2fad7 100755
--- a/tools/cythonize.py
+++ b/tools/cythonize.py
@@ -40,12 +40,6 @@ HASH_FILE = 'cythonize.dat'
DEFAULT_ROOT = 'numpy'
VENDOR = 'NumPy'
-# WindowsError is not defined on unix systems
-try:
- WindowsError
-except NameError:
- WindowsError = None
-
#
# Rules
#
@@ -54,28 +48,8 @@ def process_pyx(fromfile, tofile):
if tofile.endswith('.cxx'):
flags.append('--cplus')
- try:
- # try the cython in the installed python first (somewhat related to scipy/scipy#2397)
- from Cython.Compiler.Version import version as cython_version
- except ImportError:
- # The `cython` command need not point to the version installed in the
- # Python running this script, so raise an error to avoid the chance of
- # using the wrong version of Cython.
- raise OSError('Cython needs to be installed in Python as a module')
- else:
- # check the version, and invoke through python
- from distutils.version import LooseVersion
-
- # Cython 0.29.14 is required for Python 3.8 and there are
- # other fixes in the 0.29 series that are needed even for earlier
- # Python versions.
- # Note: keep in sync with that in pyproject.toml
- required_version = LooseVersion('0.29.14')
-
- if LooseVersion(cython_version) < required_version:
- raise RuntimeError(f'Building {VENDOR} requires Cython >= {required_version}')
- subprocess.check_call(
- [sys.executable, '-m', 'cython'] + flags + ["-o", tofile, fromfile])
+ subprocess.check_call(
+ [sys.executable, '-m', 'cython'] + flags + ["-o", tofile, fromfile])
def process_tempita_pyx(fromfile, tofile):
@@ -136,7 +110,7 @@ rules = {
# Hash db
#
def load_hashes(filename):
- # Return { filename : (sha1 of input, sha1 of output) }
+ # Return { filename : (sha256 of input, sha256 of output) }
if os.path.isfile(filename):
hashes = {}
with open(filename, 'r') as f:
@@ -152,8 +126,8 @@ def save_hashes(hash_db, filename):
for key, value in sorted(hash_db.items()):
f.write("%s %s %s\n" % (key, value[0], value[1]))
-def sha1_of_file(filename):
- h = hashlib.sha1()
+def sha256_of_file(filename):
+ h = hashlib.sha256()
with open(filename, "rb") as f:
h.update(f.read())
return h.hexdigest()
@@ -169,8 +143,8 @@ def normpath(path):
return path
def get_hash(frompath, topath):
- from_hash = sha1_of_file(frompath)
- to_hash = sha1_of_file(topath) if os.path.exists(topath) else None
+ from_hash = sha256_of_file(frompath)
+ to_hash = sha256_of_file(topath) if os.path.exists(topath) else None
return (from_hash, to_hash)
def process(path, fromfile, tofile, processor_function, hash_db):
diff --git a/tools/download-wheels.py b/tools/download-wheels.py
index 941440ca9..41e1e9e5d 100644
--- a/tools/download-wheels.py
+++ b/tools/download-wheels.py
@@ -1,9 +1,28 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
"""
-Download NumPy wheels from Anaconda staging area.
+Script to download NumPy wheels from the Anaconda staging area.
+
+Usage::
+
+ $ ./tools/download-wheels.py <version> -w <optional-wheelhouse>
+
+The default wheelhouse is ``release/installers``.
+
+Dependencies
+------------
+
+- beautifulsoup4
+- urllib3
+
+Examples
+--------
+
+While in the repository root::
+
+ $ python tools/download-wheels.py 1.19.0
+ $ python tools/download-wheels.py 1.19.0 -w ~/wheelhouse
"""
-import sys
import os
import re
import shutil
@@ -12,11 +31,18 @@ import argparse
import urllib3
from bs4 import BeautifulSoup
-__version__ = '0.1'
+__version__ = "0.1"
# Edit these for other projects.
-STAGING_URL = 'https://anaconda.org/multibuild-wheels-staging/numpy'
-PREFIX = 'numpy'
+STAGING_URL = "https://anaconda.org/multibuild-wheels-staging/numpy"
+PREFIX = "numpy"
+
+# Name endings of the files to download.
+WHL = r"-.*\.whl$"
+ZIP = r"\.zip$"
+GZIP = r"\.tar\.gz$"
+SUFFIX = rf"({WHL}|{GZIP}|{ZIP})"
+
def get_wheel_names(version):
""" Get wheel names from Anaconda HTML directory.
@@ -30,11 +56,11 @@ def get_wheel_names(version):
The release version. For instance, "1.18.3".
"""
- http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED')
- tmpl = re.compile(rf"^.*{PREFIX}-{version}-.*\.whl$")
+ http = urllib3.PoolManager(cert_reqs="CERT_REQUIRED")
+ tmpl = re.compile(rf"^.*{PREFIX}-{version}{SUFFIX}")
index_url = f"{STAGING_URL}/files"
- index_html = http.request('GET', index_url)
- soup = BeautifulSoup(index_html.data, 'html.parser')
+ index_html = http.request("GET", index_url)
+ soup = BeautifulSoup(index_html.data, "html.parser")
return soup.findAll(text=tmpl)
@@ -52,24 +78,24 @@ def download_wheels(version, wheelhouse):
Directory in which to download the wheels.
"""
- http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED')
+ http = urllib3.PoolManager(cert_reqs="CERT_REQUIRED")
wheel_names = get_wheel_names(version)
for i, wheel_name in enumerate(wheel_names):
wheel_url = f"{STAGING_URL}/{version}/download/{wheel_name}"
wheel_path = os.path.join(wheelhouse, wheel_name)
- with open(wheel_path, 'wb') as f:
- with http.request('GET', wheel_url, preload_content=False,) as r:
+ with open(wheel_path, "wb") as f:
+ with http.request("GET", wheel_url, preload_content=False,) as r:
print(f"{i + 1:<4}{wheel_name}")
shutil.copyfileobj(r, f)
print(f"\nTotal files downloaded: {len(wheel_names)}")
-if __name__ == '__main__':
+if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument(
"version",
- help="NumPy version to download.")
+ help="NumPy version to download.")
parser.add_argument(
"-w", "--wheelhouse",
default=os.path.join(os.getcwd(), "release", "installers"),
diff --git a/tools/find_deprecated_escaped_characters.py b/tools/find_deprecated_escaped_characters.py
index 22efaae65..d7225b8e8 100644
--- a/tools/find_deprecated_escaped_characters.py
+++ b/tools/find_deprecated_escaped_characters.py
@@ -7,7 +7,7 @@ were accepted before. For instance, '\(' was previously accepted but must now
be written as '\\(' or r'\('.
"""
-import sys
+
def main(root):
"""Find deprecated escape sequences.
@@ -56,9 +56,6 @@ def main(root):
if __name__ == "__main__":
from argparse import ArgumentParser
- if sys.version_info[:2] < (3, 6):
- raise RuntimeError("Python version must be >= 3.6")
-
parser = ArgumentParser(description="Find deprecated escaped characters")
parser.add_argument('root', help='directory or file to be checked')
args = parser.parse_args()
diff --git a/tools/functions_missing_types.py b/tools/functions_missing_types.py
new file mode 100755
index 000000000..99c6887a9
--- /dev/null
+++ b/tools/functions_missing_types.py
@@ -0,0 +1,134 @@
+#!/usr/bin/env python
+"""Find the functions in a module missing type annotations.
+
+To use it run
+
+./functions_missing_types.py <module>
+
+and it will print out a list of functions in the module that don't
+have types.
+
+"""
+import argparse
+import ast
+import importlib
+import os
+
+NUMPY_ROOT = os.path.dirname(os.path.join(
+ os.path.abspath(__file__), "..",
+))
+
+# Technically "public" functions (they don't start with an underscore)
+# that we don't want to include.
+EXCLUDE_LIST = {
+ "numpy": {
+ # Stdlib modules in the namespace by accident
+ "absolute_import",
+ "division",
+ "print_function",
+ "warnings",
+ "sys",
+ "os",
+ "math",
+ # Accidentally public, deprecated, or shouldn't be used
+ "Tester",
+ "add_docstring",
+ "add_newdoc",
+ "add_newdoc_ufunc",
+ "core",
+ "compat",
+ "fastCopyAndTranspose",
+ "get_array_wrap",
+ "int_asbuffer",
+ "numarray",
+ "oldnumeric",
+ "safe_eval",
+ "set_numeric_ops",
+ "test",
+ "typeDict",
+ # Builtins
+ "bool",
+ "complex",
+ "float",
+ "int",
+ "long",
+ "object",
+ "str",
+ "unicode",
+ # More standard names should be preferred
+ "alltrue", # all
+ "sometrue", # any
+ }
+}
+
+
+class FindAttributes(ast.NodeVisitor):
+ """Find top-level attributes/functions/classes in stubs files.
+
+ Do this by walking the stubs ast. See e.g.
+
+ https://greentreesnakes.readthedocs.io/en/latest/index.html
+
+ for more information on working with Python's ast.
+
+ """
+
+ def __init__(self):
+ self.attributes = set()
+
+ def visit_FunctionDef(self, node):
+ if node.name == "__getattr__":
+ # Not really a module member.
+ return
+ self.attributes.add(node.name)
+ # Do not call self.generic_visit; we are only interested in
+ # top-level functions.
+ return
+
+ def visit_ClassDef(self, node):
+ if not node.name.startswith("_"):
+ self.attributes.add(node.name)
+ return
+
+ def visit_AnnAssign(self, node):
+ self.attributes.add(node.target.id)
+
+
+def find_missing(module_name):
+ module_path = os.path.join(
+ NUMPY_ROOT,
+ module_name.replace(".", os.sep),
+ "__init__.pyi",
+ )
+
+ module = importlib.import_module(module_name)
+ module_attributes = {
+ attribute for attribute in dir(module) if not attribute.startswith("_")
+ }
+
+ if os.path.isfile(module_path):
+ with open(module_path) as f:
+ tree = ast.parse(f.read())
+ ast_visitor = FindAttributes()
+ ast_visitor.visit(tree)
+ stubs_attributes = ast_visitor.attributes
+ else:
+ # No stubs for this module yet.
+ stubs_attributes = set()
+
+ exclude_list = EXCLUDE_LIST.get(module_name, set())
+
+ missing = module_attributes - stubs_attributes - exclude_list
+ print("\n".join(sorted(missing)))
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("module")
+ args = parser.parse_args()
+
+ find_missing(args.module)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tools/gitpod/Dockerfile b/tools/gitpod/Dockerfile
new file mode 100644
index 000000000..592a5ee0a
--- /dev/null
+++ b/tools/gitpod/Dockerfile
@@ -0,0 +1,101 @@
+#
+# Dockerfile for NumPy development
+#
+# Usage:
+# -------
+#
+# To make a local build of the container, from the 'Docker-dev' directory:
+# docker build --rm -f "Dockerfile" -t <build-tag> "."
+#
+# To use the container use the following command. It assumes that you are in
+# the root folder of the NumPy git repository, making it available as
+# /home/numpy in the container. Whatever changes you make to that directory
+# are visible in the host and container.
+# The docker image is retrieved from the NumPy dockerhub repository
+#
+# docker run --rm -it -v $(pwd):/home/numpy numpy/numpy-dev:<image-tag>
+#
+# By default the container will activate the conda environment numpy-dev
+# which contains all the dependencies needed for NumPy development
+#
+# To build NumPy run: python setup.py build_ext --inplace
+#
+# To run the tests use: python runtests.py
+#
+# This image is based on: Ubuntu 20.04 (focal)
+# https://hub.docker.com/_/ubuntu/?tab=tags&name=focal
+# OS/ARCH: linux/amd64
+FROM gitpod/workspace-base:latest
+
+ARG MAMBAFORGE_VERSION="4.11.0-0"
+ARG CONDA_ENV=numpy-dev
+
+
+# ---- Configure environment ----
+ENV CONDA_DIR=/home/gitpod/mambaforge3 \
+ SHELL=/bin/bash
+ENV PATH=${CONDA_DIR}/bin:$PATH \
+ WORKSPACE=/workspace/numpy
+
+
+# -----------------------------------------------------------------------------
+# ---- Creating as root - note: make sure to change to gitpod in the end ----
+USER root
+
+# hadolint ignore=DL3008
+RUN apt-get update && \
+ apt-get install -yq --no-install-recommends \
+ ca-certificates \
+ dirmngr \
+ dvisvgm \
+ gnupg \
+ gpg-agent \
+ texlive-latex-extra \
+ vim && \
+ # this needs to be done after installing dirmngr
+ apt-key adv --keyserver keyserver.ubuntu.com --recv-key C99B11DEB97541F0 && \
+ apt-add-repository https://cli.github.com/packages && \
+ apt-get install -yq --no-install-recommends \
+ gh && \
+ locale-gen en_US.UTF-8 && \
+ apt-get clean && \
+ rm -rf /var/cache/apt/* &&\
+ rm -rf /var/lib/apt/lists/* &&\
+ rm -rf /tmp/*
+
+# Allows this Dockerfile to activate conda environments
+SHELL ["/bin/bash", "--login", "-o", "pipefail", "-c"]
+
+# -----------------------------------------------------------------------------
+# ---- Installing mamba ----
+RUN wget -q -O mambaforge3.sh \
+ "https://github.com/conda-forge/miniforge/releases/download/$MAMBAFORGE_VERSION/Mambaforge-$MAMBAFORGE_VERSION-Linux-x86_64.sh" && \
+ bash mambaforge3.sh -p ${CONDA_DIR} -b && \
+ rm mambaforge3.sh
+
+# -----------------------------------------------------------------------------
+# ---- Copy needed files ----
+# basic workspace configurations
+COPY ./tools/gitpod/workspace_config /usr/local/bin/workspace_config
+
+RUN chmod a+rx /usr/local/bin/workspace_config && \
+ workspace_config
+
+# Copy conda environment file into the container - this needs to exists inside
+# the container to create a conda environment from it
+COPY environment.yml /tmp/environment.yml
+
+# -----------------------------------------------------------------------------
+# ---- Create conda environment ----
+# Install NumPy dependencies
+RUN mamba env create -f /tmp/environment.yml && \
+ conda activate ${CONDA_ENV} && \
+ mamba install ccache -y && \
+ # needed for docs rendering later on
+ python -m pip install --no-cache-dir sphinx-autobuild && \
+ conda clean --all -f -y && \
+ rm -rf /tmp/*
+
+# -----------------------------------------------------------------------------
+# Always make sure we are not root
+USER gitpod \ No newline at end of file
diff --git a/tools/gitpod/gitpod.Dockerfile b/tools/gitpod/gitpod.Dockerfile
new file mode 100644
index 000000000..8dac0d597
--- /dev/null
+++ b/tools/gitpod/gitpod.Dockerfile
@@ -0,0 +1,49 @@
+# Doing a local shallow clone - keeps the container secure
+# and much slimmer than using COPY directly or making a
+# remote clone
+ARG BASE_CONTAINER="numpy/numpy-dev:latest"
+FROM gitpod/workspace-base:latest as clone
+
+COPY --chown=gitpod . /tmp/numpy_repo
+
+# the clone should be deep enough for versioneer to work
+RUN git clone --shallow-since=2021-05-22 file:////tmp/numpy_repo /tmp/numpy
+
+# -----------------------------------------------------------------------------
+# Using the numpy-dev Docker image as a base
+# This way, we ensure we have all the needed compilers and dependencies
+# while reducing the build time
+FROM ${BASE_CONTAINER} as build
+
+# -----------------------------------------------------------------------------
+USER root
+
+# -----------------------------------------------------------------------------
+# ---- ENV variables ----
+# ---- Directories needed ----
+ENV WORKSPACE=/workspace/numpy/ \
+ CONDA_ENV=numpy-dev
+
+# Allows this Dockerfile to activate conda environments
+SHELL ["/bin/bash", "--login", "-o", "pipefail", "-c"]
+
+# Copy over the shallow clone
+COPY --from=clone --chown=gitpod /tmp/numpy ${WORKSPACE}
+
+# Everything happens in the /workspace/numpy directory
+WORKDIR ${WORKSPACE}
+
+# Build numpy to populate the cache used by ccache
+RUN git config --global --add safe.directory /workspace/numpy
+RUN git submodule update --init --depth=1 -- numpy/core/src/umath/svml
+RUN conda activate ${CONDA_ENV} && \
+ python setup.py build_ext --inplace && \
+ ccache -s
+
+# Gitpod will load the repository into /workspace/numpy. We remove the
+# directory from the image to prevent conflicts
+RUN rm -rf ${WORKSPACE}
+
+# -----------------------------------------------------------------------------
+# Always return to non privileged user
+USER gitpod
diff --git a/tools/gitpod/settings.json b/tools/gitpod/settings.json
new file mode 100644
index 000000000..50296336d
--- /dev/null
+++ b/tools/gitpod/settings.json
@@ -0,0 +1,8 @@
+{
+ "restructuredtext.updateOnTextChanged": "true",
+ "restructuredtext.updateDelay": 300,
+ "restructuredtext.linter.disabledLinters": ["doc8","rst-lint", "rstcheck"],
+ "python.defaultInterpreterPath": "/home/gitpod/mambaforge3/envs/numpy-dev/bin/python",
+ "esbonio.sphinx.buildDir": "${workspaceRoot}/doc/build/html",
+ "esbonio.sphinx.confDir": ""
+} \ No newline at end of file
diff --git a/tools/gitpod/workspace_config b/tools/gitpod/workspace_config
new file mode 100644
index 000000000..aa859c9be
--- /dev/null
+++ b/tools/gitpod/workspace_config
@@ -0,0 +1,58 @@
+#!/bin/bash
+# Basic configurations for the workspace
+
+set -e
+
+# gitpod/workspace-base needs at least one file here
+touch /home/gitpod/.bashrc.d/empty
+
+# Add git aliases
+git config --global alias.co checkout
+git config --global alias.ci commit
+git config --global alias.st status
+git config --global alias.br branch
+git config --global alias.hist "log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short"
+git config --global alias.type 'cat-file -t'
+git config --global alias.dump 'cat-file -p'
+
+# Enable basic vim defaults in ~/.vimrc
+echo "filetype plugin indent on" >>~/.vimrc
+echo "set colorcolumn=80" >>~/.vimrc
+echo "set number" >>~/.vimrc
+echo "syntax enable" >>~/.vimrc
+
+# Vanity custom bash prompt - makes it more legible
+echo "PS1='\[\e]0;\u \w\a\]\[\033[01;36m\]\u\[\033[m\] > \[\033[38;5;141m\]\w\[\033[m\] \\$ '" >>~/.bashrc
+
+# Enable prompt color in the skeleton .bashrc
+# hadolint ignore=SC2016
+sed -i 's/^#force_color_prompt=yes/force_color_prompt=yes/' /etc/skel/.bashrc
+
+# .gitpod.yml is configured to install NumPy from /workspace/numpy
+echo "export PYTHONPATH=${WORKSPACE}" >>~/.bashrc
+
+# make conda activate command available from /bin/bash (login and interactive)
+if [[ ! -f "/etc/profile.d/conda.sh" ]]; then
+ ln -s ${CONDA_DIR}/etc/profile.d/conda.sh /etc/profile.d/conda.sh
+fi
+echo ". ${CONDA_DIR}/etc/profile.d/conda.sh" >>~/.bashrc
+echo "conda activate numpy-dev" >>~/.bashrc
+
+# Enable prompt color in the skeleton .bashrc
+# hadolint ignore=SC2016
+sed -i 's/^#force_color_prompt=yes/force_color_prompt=yes/' /etc/skel/.bashrc
+
+# .gitpod.yml is configured to install numpy from /workspace/numpy
+echo "export PYTHONPATH=/workspace/numpy" >>~/.bashrc
+
+# Set up ccache for compilers for this Dockerfile
+# REF: https://github.com/conda-forge/compilers-feedstock/issues/31
+echo "conda activate numpy-dev" >>~/.startuprc
+echo "export CC=\"ccache \$CC\"" >>~/.startuprc
+echo "export CXX=\"ccache \$CXX\"" >>~/.startuprc
+echo "export F77=\"ccache \$F77\"" >>~/.startuprc
+echo "export F90=\"ccache \$F90\"" >>~/.startuprc
+echo "export GFORTRAN=\"ccache \$GFORTRAN\"" >>~/.startuprc
+echo "export FC=\"ccache \$FC\"" >>~/.startuprc
+echo "source ~/.startuprc" >>~/.profile
+echo "source ~/.startuprc" >>~/.bashrc
diff --git a/tools/lint_diff.ini b/tools/lint_diff.ini
new file mode 100644
index 000000000..9e31050b7
--- /dev/null
+++ b/tools/lint_diff.ini
@@ -0,0 +1,5 @@
+[pycodestyle]
+max_line_length = 79
+statistics = True
+ignore = E121,E122,E123,E125,E126,E127,E128,E226,E241,E251,E265,E266,E302,E402,E704,E712,E721,E731,E741,W291,W293,W391,W503,W504
+exclude = numpy/__config__.py,numpy/typing/tests/data
diff --git a/tools/linter.py b/tools/linter.py
new file mode 100644
index 000000000..0031ff83a
--- /dev/null
+++ b/tools/linter.py
@@ -0,0 +1,85 @@
+import os
+import sys
+import subprocess
+from argparse import ArgumentParser
+from git import Repo, exc
+
+CONFIG = os.path.join(
+ os.path.abspath(os.path.dirname(__file__)),
+ 'lint_diff.ini',
+)
+
+# NOTE: The `diff` and `exclude` options of pycodestyle seem to be
+# incompatible, so instead just exclude the necessary files when
+# computing the diff itself.
+EXCLUDE = (
+ "numpy/typing/tests/data/",
+ "numpy/typing/_char_codes.py",
+ "numpy/__config__.py",
+ "numpy/f2py",
+)
+
+
+class DiffLinter:
+ def __init__(self, branch):
+ self.branch = branch
+ self.repo = Repo('.')
+ self.head = self.repo.head.commit
+
+ def get_branch_diff(self, uncommitted = False):
+ """
+ Determine the first common ancestor commit.
+ Find diff between branch and FCA commit.
+ Note: if `uncommitted` is set, check only
+ uncommitted changes
+ """
+ try:
+ commit = self.repo.merge_base(self.branch, self.head)[0]
+ except exc.GitCommandError:
+ print(f"Branch with name `{self.branch}` does not exist")
+ sys.exit(1)
+
+ exclude = [f':(exclude){i}' for i in EXCLUDE]
+ if uncommitted:
+ diff = self.repo.git.diff(
+ self.head, '--unified=0', '***.py', *exclude
+ )
+ else:
+ diff = self.repo.git.diff(
+ commit, self.head, '--unified=0', '***.py', *exclude
+ )
+ return diff
+
+ def run_pycodestyle(self, diff):
+ """
+ Original Author: Josh Wilson (@person142)
+ Source:
+ https://github.com/scipy/scipy/blob/main/tools/lint_diff.py
+ Run pycodestyle on the given diff.
+ """
+ res = subprocess.run(
+ ['pycodestyle', '--diff', '--config', CONFIG],
+ input=diff,
+ stdout=subprocess.PIPE,
+ encoding='utf-8',
+ )
+ return res.returncode, res.stdout
+
+ def run_lint(self, uncommitted):
+ diff = self.get_branch_diff(uncommitted)
+ retcode, errors = self.run_pycodestyle(diff)
+
+ errors and print(errors)
+
+ sys.exit(retcode)
+
+
+if __name__ == '__main__':
+ parser = ArgumentParser()
+ parser.add_argument("--branch", type=str, default='main',
+ help="The branch to diff against")
+ parser.add_argument("--uncommitted", action='store_true',
+ help="Check only uncommitted changes")
+ args = parser.parse_args()
+
+ DiffLinter(args.branch).run_lint(args.uncommitted)
diff --git a/tools/list_installed_dll_dependencies_cygwin.sh b/tools/list_installed_dll_dependencies_cygwin.sh
new file mode 100644
index 000000000..ee06ae0d0
--- /dev/null
+++ b/tools/list_installed_dll_dependencies_cygwin.sh
@@ -0,0 +1,35 @@
+#!/bin/dash
+# Check permissions and dependencies on installed DLLs
+# DLLs need execute permissions to be used
+# DLLs must be able to find their dependencies
+# This checks both of those, then does a direct test
+# The best way of checking whether a C extension module is importable
+# is trying to import it. The rest is trying to give reasons why it
+# isn't importing.
+#
+# One of the tools and the extension for shared libraries are
+# Cygwin-specific, but the rest should work on most platforms with
+# /bin/sh
+
+py_ver=${1}
+dll_list=`/bin/dash tools/list_numpy_dlls.sh ${py_ver}`
+echo "Checks for existence, permissions and file type"
+ls -l ${dll_list}
+file ${dll_list}
+echo "Dependency checks"
+ldd ${dll_list} | grep -F -e " => not found" && exit 1
+cygcheck ${dll_list} >cygcheck_dll_list 2>cygcheck_missing_deps
+grep -F -e "cygcheck: track_down: could not find " cygcheck_missing_deps && exit 1
+echo "Import tests"
+mkdir -p dist/
+cd dist/
+for name in ${dll_list};
+do
+ echo ${name}
+ ext_module=`echo ${name} | \
+ sed -E \
+ -e "s/^\/+(home|usr).*?site-packages\/+//" \
+ -e "s/.cpython-3.m?-x86(_64)?-cygwin.dll$//" \
+ -e "s/\//./g"`
+ python${py_ver} -c "import ${ext_module}"
+done
diff --git a/tools/list_numpy_dlls.sh b/tools/list_numpy_dlls.sh
new file mode 100644
index 000000000..fedd2097b
--- /dev/null
+++ b/tools/list_numpy_dlls.sh
@@ -0,0 +1,9 @@
+#!/bin/dash
+# Print the list of dlls installed by NumPy
+
+py_ver=${1}
+site_packages=`python${py_ver} -m pip show numpy | \
+ grep Location | cut -d " " -f 2 -`;
+dll_list=`for name in $(python${py_ver} -m pip show -f numpy | \
+ grep -F .dll); do echo ${site_packages}/${name}; done`
+echo ${dll_list}
diff --git a/tools/npy_tempita/__init__.py b/tools/npy_tempita/__init__.py
index 50a995104..fedcd91f4 100644
--- a/tools/npy_tempita/__init__.py
+++ b/tools/npy_tempita/__init__.py
@@ -705,7 +705,7 @@ lead_whitespace_re = re.compile(r'^[\t ]*\n')
def trim_lex(tokens):
r"""
- Takes a lexed set of tokens, and removes whitespace when there is
+ Takes a lexed list of tokens, and removes whitespace when there is
a directive on a line by itself:
>>> tokens = lex('{{if x}}\nx\n{{endif}}\ny', trim_whitespace=False)
diff --git a/tools/openblas_support.py b/tools/openblas_support.py
index cbb6a5e43..ce677f9a5 100644
--- a/tools/openblas_support.py
+++ b/tools/openblas_support.py
@@ -2,6 +2,7 @@ import glob
import hashlib
import os
import platform
+import sysconfig
import sys
import shutil
import tarfile
@@ -10,52 +11,39 @@ import zipfile
from tempfile import mkstemp, gettempdir
from urllib.request import urlopen, Request
+from urllib.error import HTTPError
-OPENBLAS_V = '0.3.9'
-# Temporary build of OpenBLAS to test a fix for dynamic detection of CPU
-OPENBLAS_LONG = 'v0.3.7-527-g79fd006c' # the 0.3.7 is misleading
+OPENBLAS_V = '0.3.20'
+OPENBLAS_LONG = 'v0.3.20'
BASE_LOC = 'https://anaconda.org/multibuild-wheels-staging/openblas-libs'
BASEURL = f'{BASE_LOC}/{OPENBLAS_LONG}/download'
-ARCHITECTURES = ['', 'windows', 'darwin', 'aarch64', 'x86_64', 'i686', 'ppc64le', 's390x']
-sha256_vals = {
-"openblas-v0.3.7-527-g79fd006c-win_amd64-gcc_7_1_0.zip": "7249d68c02e6b6339e06edfeab1fecddf29ee1e67a3afaa77917c320c43de840",
-"openblas64_-v0.3.7-527-g79fd006c-win_amd64-gcc_7_1_0.zip": "6488e0961a5926e47242f63b63b41cfdd661e6f1d267e8e313e397cde4775c17",
-"openblas-v0.3.7-527-g79fd006c-win32-gcc_7_1_0.zip": "5fb0867ca70b1d0fdbf68dd387c0211f26903d74631420e4aabb49e94aa3930d",
-"openblas-v0.3.7-527-g79fd006c-macosx_10_9_x86_64-gf_1becaaa.tar.gz": "69434bd626bbc495da9ce8c36b005d140c75e3c47f94e88c764a199e820f9259",
-"openblas64_-v0.3.7-527-g79fd006c-macosx_10_9_x86_64-gf_1becaaa.tar.gz": "093f6d953e3fa76a86809be67bd1f0b27656671b5a55b233169cfaa43fd63e22",
-"openblas-v0.3.7-527-g79fd006c-manylinux2014_aarch64.tar.gz": "42676c69dc48cd6e412251b39da6b955a5a0e00323ddd77f9137f7c259d35319",
-"openblas64_-v0.3.7-527-g79fd006c-manylinux2014_aarch64.tar.gz": "5aec167af4052cf5e9e3e416c522d9794efabf03a2aea78b9bb3adc94f0b73d8",
-"openblas-v0.3.7-527-g79fd006c-manylinux2010_x86_64.tar.gz": "fa67c6cc29d4cc5c70a147c80526243239a6f95fc3feadcf83a78176cd9c526b",
-"openblas64_-v0.3.7-527-g79fd006c-manylinux2010_x86_64.tar.gz": "9ad34e89a5307dcf5823bf5c020580d0559a0c155fe85b44fc219752e61852b0",
-"openblas-v0.3.7-527-g79fd006c-manylinux2010_i686.tar.gz": "0b8595d316c8b7be84ab1f1d5a0c89c1b35f7c987cdaf61d441bcba7ab4c7439",
-"openblas-v0.3.7-527-g79fd006c-manylinux2014_ppc64le.tar.gz": "3e1c7d6472c34e7210e3605be4bac9ddd32f613d44297dc50cf2d067e720c4a9",
-"openblas64_-v0.3.7-527-g79fd006c-manylinux2014_ppc64le.tar.gz": "a0885873298e21297a04be6cb7355a585df4fa4873e436b4c16c0a18fc9073ea",
-"openblas-v0.3.7-527-g79fd006c-manylinux2014_s390x.tar.gz": "79b454320817574e20499d58f05259ed35213bea0158953992b910607b17f240",
-"openblas64_-v0.3.7-527-g79fd006c-manylinux2014_s390x.tar.gz": "9fddbebf5301518fc4a5d2022a61886544a0566868c8c014359a1ee6b17f2814",
-"openblas-v0.3.7-527-g79fd006c-manylinux1_i686.tar.gz": "24fb92684ec4676185fff5c9340f50c3db6075948bcef760e9c715a8974e4680",
-"openblas-v0.3.7-527-g79fd006c-manylinux1_x86_64.tar.gz": "ebb8236b57a1b4075fd5cdc3e9246d2900c133a42482e5e714d1e67af5d00e62",
-"openblas-v0.3.7-527-g79fd006c-manylinux1_i686.tar.gz": "24fb92684ec4676185fff5c9340f50c3db6075948bcef760e9c715a8974e4680",
-"openblas-v0.3.7-527-g79fd006c-manylinux1_x86_64.tar.gz": "ebb8236b57a1b4075fd5cdc3e9246d2900c133a42482e5e714d1e67af5d00e62",
-"openblas-v0.3.7-527-g79fd006c-manylinux1_i686.tar.gz": "24fb92684ec4676185fff5c9340f50c3db6075948bcef760e9c715a8974e4680",
-"openblas-v0.3.7-527-g79fd006c-manylinux1_x86_64.tar.gz": "ebb8236b57a1b4075fd5cdc3e9246d2900c133a42482e5e714d1e67af5d00e62",
-}
+SUPPORTED_PLATFORMS = [
+ 'linux-aarch64',
+ 'linux-x86_64',
+ 'linux-i686',
+ 'linux-ppc64le',
+ 'linux-s390x',
+ 'win-amd64',
+ 'win-32',
+ 'macosx-x86_64',
+ 'macosx-arm64',
+]
+IS_32BIT = sys.maxsize < 2**32
-IS_32BIT = sys.maxsize < 2**32
+def get_plat():
+ plat = sysconfig.get_platform()
+ plat_split = plat.split("-")
+ arch = plat_split[-1]
+ if arch == "win32":
+ plat = "win-32"
+ elif arch in ["universal2", "intel"]:
+ plat = f"macosx-{platform.uname().machine}"
+ elif len(plat_split) > 2:
+ plat = f"{plat_split[0]}-{arch}"
+ assert plat in SUPPORTED_PLATFORMS, f'invalid platform {plat}'
+ return plat
-def get_arch():
- if platform.system() == 'Windows':
- ret = 'windows'
- elif platform.system() == 'Darwin':
- ret = 'darwin'
- else:
- ret = platform.uname().machine
- # What do 32 bit machines report?
- # If they are a docker, they can report x86_64
- if 'x86' in ret and IS_32BIT:
- arch = 'i686'
- assert ret in ARCHITECTURES, f'invalid architecture {ret}'
- return ret
def get_ilp64():
if os.environ.get("NPY_USE_BLAS_ILP64", "0") == "0":
@@ -64,6 +52,7 @@ def get_ilp64():
raise RuntimeError("NPY_USE_BLAS_ILP64 set on 32-bit arch")
return "64_"
+
def get_manylinux(arch):
if arch in ('x86_64', 'i686'):
default = '2010'
@@ -71,36 +60,44 @@ def get_manylinux(arch):
default = '2014'
ret = os.environ.get("MB_ML_VER", default)
# XXX For PEP 600 this can be a glibc version
- assert ret in ('1', '2010', '2014'), f'invalid MB_ML_VER {ret}'
+ assert ret in ('1', '2010', '2014', '_2_24'), f'invalid MB_ML_VER {ret}'
return ret
-def download_openblas(target, arch, ilp64):
- ml_ver = get_manylinux(arch)
+def download_openblas(target, plat, ilp64):
+ osname, arch = plat.split("-")
fnsuffix = {None: "", "64_": "64_"}[ilp64]
filename = ''
- headers = {'User-Agent': ('Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 ; '
- '(KHTML, like Gecko) Chrome/41.0.2228.0 '
- 'Safari/537.3')}
- if arch in ('aarch64', 'ppc64le', 's390x', 'x86_64', 'i686'):
+ headers = {'User-Agent':
+ ('Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 ; '
+ '(KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.3')}
+ suffix = None
+ if osname == "linux":
+ ml_ver = get_manylinux(arch)
suffix = f'manylinux{ml_ver}_{arch}.tar.gz'
- filename = f'{BASEURL}/openblas{fnsuffix}-{OPENBLAS_LONG}-{suffix}'
typ = 'tar.gz'
- elif arch == 'darwin':
+ elif plat == 'macosx-x86_64':
suffix = 'macosx_10_9_x86_64-gf_1becaaa.tar.gz'
- filename = f'{BASEURL}/openblas{fnsuffix}-{OPENBLAS_LONG}-{suffix}'
typ = 'tar.gz'
- elif arch == 'windows':
- if IS_32BIT:
- suffix = 'win32-gcc_7_1_0.zip'
+ elif plat == 'macosx-arm64':
+ suffix = 'macosx_11_0_arm64-gf_f26990f.tar.gz'
+ typ = 'tar.gz'
+ elif osname == 'win':
+ if plat == "win-32":
+ suffix = 'win32-gcc_8_1_0.zip'
else:
- suffix = 'win_amd64-gcc_7_1_0.zip'
- filename = f'{BASEURL}/openblas{fnsuffix}-{OPENBLAS_LONG}-{suffix}'
+ suffix = 'win_amd64-gcc_8_1_0.zip'
typ = 'zip'
- if not filename:
+
+ if not suffix:
return None
+ filename = f'{BASEURL}/openblas{fnsuffix}-{OPENBLAS_LONG}-{suffix}'
req = Request(url=filename, headers=headers)
- response = urlopen(req)
+ try:
+ response = urlopen(req)
+ except HTTPError:
+ print(f'Could not download "{filename}"', file=sys.stderr)
+ raise
length = response.getheader('content-length')
if response.status != 200:
print(f'Could not download "{filename}"', file=sys.stderr)
@@ -109,19 +106,13 @@ def download_openblas(target, arch, ilp64):
data = response.read()
# Verify hash
key = os.path.basename(filename)
- sha256_returned = hashlib.sha256(data).hexdigest()
- if key not in sha256_vals:
- raise ValueError(
- f'key "{key}" with hash "{sha256_returned}" not in sha256_vals')
- sha256_expected = sha256_vals[key]
- if sha256_returned != sha256_expected:
- raise ValueError(f'sha256 hash mismatch for filename {filename}')
print("Saving to file", file=sys.stderr)
with open(target, 'wb') as fid:
fid.write(data)
return typ
-def setup_openblas(arch=get_arch(), ilp64=get_ilp64()):
+
+def setup_openblas(plat=get_plat(), ilp64=get_ilp64()):
'''
Download and setup an openblas library for building. If successful,
the configuration script will find it automatically.
@@ -133,34 +124,40 @@ def setup_openblas(arch=get_arch(), ilp64=get_ilp64()):
To determine success, do ``os.path.exists(msg)``
'''
_, tmp = mkstemp()
- if not arch:
- raise ValueError('unknown architecture')
- typ = download_openblas(tmp, arch, ilp64)
+ if not plat:
+ raise ValueError('unknown platform')
+ typ = download_openblas(tmp, plat, ilp64)
if not typ:
return ''
- if arch == 'windows':
+ osname, arch = plat.split("-")
+ if osname == 'win':
if not typ == 'zip':
- return 'expecting to download zipfile on windows, not %s' % str(typ)
+ return f'expecting to download zipfile on windows, not {typ}'
return unpack_windows_zip(tmp)
else:
if not typ == 'tar.gz':
return 'expecting to download tar.gz, not %s' % str(typ)
return unpack_targz(tmp)
+
def unpack_windows_zip(fname):
with zipfile.ZipFile(fname, 'r') as zf:
# Get the openblas.a file, but not openblas.dll.a nor openblas.dev.a
lib = [x for x in zf.namelist() if OPENBLAS_LONG in x and
- x.endswith('a') and not x.endswith('dll.a') and
- not x.endswith('dev.a')]
+ x.endswith('a') and not x.endswith('dll.a') and
+ not x.endswith('dev.a')]
if not lib:
return 'could not find libopenblas_%s*.a ' \
'in downloaded zipfile' % OPENBLAS_LONG
- target = os.path.join(gettempdir(), 'openblas.a')
+ if get_ilp64() is None:
+ target = os.path.join(gettempdir(), 'openblas.a')
+ else:
+ target = os.path.join(gettempdir(), 'openblas64_.a')
with open(target, 'wb') as fid:
fid.write(zf.read(lib[0]))
return target
+
def unpack_targz(fname):
target = os.path.join(gettempdir(), 'openblas')
if not os.path.exists(target):
@@ -171,6 +168,7 @@ def unpack_targz(fname):
extract_tarfile_to(zf, target, prefix)
return target
+
def extract_tarfile_to(tarfileobj, target_path, archive_path):
"""Extract TarFile contents under archive_path/ to target_path/"""
@@ -194,6 +192,7 @@ def extract_tarfile_to(tarfileobj, target_path, archive_path):
tarfileobj.extractall(target_path, members=get_members())
+
def make_init(dirname):
'''
Create a _distributor_init.py file for OpenBlas
@@ -228,39 +227,54 @@ def make_init(dirname):
DLL_filenames.append(filename)
if len(DLL_filenames) > 1:
import warnings
- warnings.warn("loaded more than 1 DLL from .libs:\\n%s" %
- "\\n".join(DLL_filenames),
+ warnings.warn("loaded more than 1 DLL from .libs:"
+ "\\n%s" % "\\n".join(DLL_filenames),
stacklevel=1)
"""))
-def test_setup(arches):
+
+def test_setup(plats):
'''
Make sure all the downloadable files exist and can be opened
'''
def items():
- for arch in arches:
- yield arch, None
- if arch not in ('i686'):
- yield arch, '64_'
+ """ yields all combinations of arch, ilp64
+ """
+ for plat in plats:
+ yield plat, None
+ osname, arch = plat.split("-")
+ if arch not in ('i686', 'arm64', '32'):
+ yield plat, '64_'
+ if osname == "linux" and arch in ('i686', 'x86_64'):
+ oldval = os.environ.get('MB_ML_VER', None)
+ os.environ['MB_ML_VER'] = '1'
+ yield plat, None
+ # Once we create x86_64 and i686 manylinux2014 wheels...
+ # os.environ['MB_ML_VER'] = '2014'
+ # yield arch, None, False
+ if oldval:
+ os.environ['MB_ML_VER'] = oldval
+ else:
+ os.environ.pop('MB_ML_VER')
errs = []
- for arch, ilp64 in items():
- if arch == '':
+ for plat, ilp64 in items():
+ osname, _ = plat.split("-")
+ if plat not in plats:
continue
-
target = None
try:
try:
- target = setup_openblas(arch, ilp64)
+ target = setup_openblas(plat, ilp64)
except Exception as e:
- print(f'Could not setup {arch}:')
- print(str(e))
+ print(f'Could not setup {plat} with ilp64 {ilp64}, ')
+ print(e)
errs.append(e)
continue
if not target:
- raise RuntimeError(f'Could not setup {arch}')
+ raise RuntimeError(f'Could not setup {plat}')
print(target)
- if arch == 'windows':
+ if osname == 'win':
if not target.endswith('.a'):
raise RuntimeError("Not .a extracted!")
else:
@@ -290,28 +304,31 @@ def test_version(expected_version, ilp64=get_ilp64()):
get_config = dll.openblas_get_config64_
else:
get_config = dll.openblas_get_config
- get_config.restype=ctypes.c_char_p
+ get_config.restype = ctypes.c_char_p
res = get_config()
print('OpenBLAS get_config returned', str(res))
if not expected_version:
expected_version = OPENBLAS_V
check_str = b'OpenBLAS %s' % expected_version.encode()
print(check_str)
- assert check_str in res, '%s not found in %s' %(expected_version, res)
+ assert check_str in res, f'{expected_version} not found in {res}'
if ilp64:
assert b"USE64BITINT" in res
else:
assert b"USE64BITINT" not in res
+
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(
- description='Download and expand an OpenBLAS archive for this ' \
+ description='Download and expand an OpenBLAS archive for this '
'architecture')
parser.add_argument('--test', nargs='*', default=None,
- help='Test different architectures. "all", or any of %s' % ARCHITECTURES)
+ help='Test different architectures. "all", or any of '
+ f'{SUPPORTED_PLATFORMS}')
parser.add_argument('--check_version', nargs='?', default='',
- help='Check provided OpenBLAS version string against available OpenBLAS')
+ help='Check provided OpenBLAS version string '
+ 'against available OpenBLAS')
args = parser.parse_args()
if args.check_version != '':
test_version(args.check_version)
@@ -319,6 +336,6 @@ if __name__ == '__main__':
print(setup_openblas())
else:
if len(args.test) == 0 or 'all' in args.test:
- test_setup(ARCHITECTURES)
+ test_setup(SUPPORTED_PLATFORMS)
else:
test_setup(args.test)
diff --git a/tools/pypy-test.sh b/tools/pypy-test.sh
deleted file mode 100755
index e24d7a99d..000000000
--- a/tools/pypy-test.sh
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env bash
-
-# Exit if a command fails
-set -e
-set -o pipefail
-# Print expanded commands
-set -x
-
-sudo apt-get -yq update
-sudo apt-get -yq install gfortran-5
-export F77=gfortran-5
-export F90=gfortran-5
-
-# Download the proper OpenBLAS x64 precompiled library
-target=$(python3 tools/openblas_support.py)
-ls -lR "$target"
-echo getting OpenBLAS into $target
-export LD_LIBRARY_PATH=$target/lib
-export LIB=$target/lib
-export INCLUDE=$target/include
-
-# Use a site.cfg to build with local openblas
-cat << EOF > site.cfg
-[openblas]
-libraries = openblas
-library_dirs = $target/lib:$LIB
-include_dirs = $target/lib:$LIB
-runtime_library_dirs = $target/lib
-EOF
-
-echo getting PyPy 3.6-v7.3.1
-wget -q https://downloads.python.org/pypy/pypy3.6-v7.3.1-linux64.tar.bz2 -O pypy.tar.bz2
-mkdir -p pypy3
-(cd pypy3; tar --strip-components=1 -xf ../pypy.tar.bz2)
-pypy3/bin/pypy3 -mensurepip
-pypy3/bin/pypy3 -m pip install --upgrade pip setuptools wheel
-pypy3/bin/pypy3 -m pip install --user -r test_requirements.txt --no-warn-script-location
-
-echo
-echo pypy3 version
-pypy3/bin/pypy3 -c "import sys; print(sys.version)"
-echo
-
-pypy3/bin/pypy3 runtests.py --debug-info --show-build-log -v -- -rsx \
- --junitxml=junit/test-results.xml --durations 10
-
-echo Make sure the correct openblas has been linked in
-pypy3/bin/pypy3 -mpip install --no-build-isolation .
-pypy3/bin/pypy3 tools/openblas_support.py --check_version
diff --git a/tools/rebase_installed_dlls_cygwin.sh b/tools/rebase_installed_dlls_cygwin.sh
new file mode 100644
index 000000000..f772879d9
--- /dev/null
+++ b/tools/rebase_installed_dlls_cygwin.sh
@@ -0,0 +1,5 @@
+#!/bin/dash
+# Rebase the dlls installed by NumPy
+
+py_ver=${1}
+/usr/bin/rebase --database --oblivious `/bin/dash tools/list_numpy_dlls.sh ${py_ver}`
diff --git a/tools/refguide_check.py b/tools/refguide_check.py
index b3891c5cb..47a77ab6d 100644
--- a/tools/refguide_check.py
+++ b/tools/refguide_check.py
@@ -19,11 +19,12 @@ another function, or deprecated, or ...)
Another use of this helper script is to check validity of code samples
in docstrings::
- $ python refguide_check.py --doctests ma
+ $ python tools/refguide_check.py --doctests ma
or in RST-based documentations::
- $ python refguide_check.py --rst docs
+ $ python tools/refguide_check.py --rst doc/source
+
"""
import copy
import doctest
@@ -71,7 +72,6 @@ BASE_MODULE = "numpy"
PUBLIC_SUBMODULES = [
'core',
- 'doc.structured_arrays',
'f2py',
'linalg',
'lib',
@@ -93,18 +93,29 @@ OTHER_MODULE_DOCS = {
# these names are known to fail doctesting and we like to keep it that way
# e.g. sometimes pseudocode is acceptable etc
-DOCTEST_SKIPLIST = set([
+#
+# Optionally, a subset of methods can be skipped by setting dict-values
+# to a container of method-names
+DOCTEST_SKIPDICT = {
# cases where NumPy docstrings import things from SciPy:
- 'numpy.lib.vectorize',
- 'numpy.random.standard_gamma',
- 'numpy.random.gamma',
- 'numpy.random.vonmises',
- 'numpy.random.power',
- 'numpy.random.zipf',
+ 'numpy.lib.vectorize': None,
+ 'numpy.random.standard_gamma': None,
+ 'numpy.random.gamma': None,
+ 'numpy.random.vonmises': None,
+ 'numpy.random.power': None,
+ 'numpy.random.zipf': None,
+ # cases where NumPy docstrings import things from other 3'rd party libs:
+ 'numpy.core.from_dlpack': None,
# remote / local file IO with DataSource is problematic in doctest:
- 'numpy.lib.DataSource',
- 'numpy.lib.Repository',
-])
+ 'numpy.lib.DataSource': None,
+ 'numpy.lib.Repository': None,
+}
+if sys.version_info < (3, 9):
+ DOCTEST_SKIPDICT.update({
+ "numpy.core.ndarray": {"__class_getitem__"},
+ "numpy.core.dtype": {"__class_getitem__"},
+ "numpy.core.number": {"__class_getitem__"},
+ })
# Skip non-numpy RST files, historical release notes
# Any single-directory exact match will skip the directory and all subdirs.
@@ -118,10 +129,18 @@ RST_SKIPLIST = [
'changelog',
'doc/release',
'doc/source/release',
+ 'doc/release/upcoming_changes',
'c-info.ufunc-tutorial.rst',
'c-info.python-as-glue.rst',
'f2py.getting-started.rst',
+ 'f2py-examples.rst',
'arrays.nditer.cython.rst',
+ # See PR 17222, these should be fixed
+ 'basics.dispatch.rst',
+ 'basics.subclassing.rst',
+ 'basics.interoperability.rst',
+ 'misc.rst',
+ 'TESTS.rst'
]
# these names are not required to be present in ALL despite being in
@@ -157,9 +176,8 @@ def short_path(path, cwd=None):
Parameters
----------
- path: str or None
-
- cwd: str or None
+ path : str or None
+ cwd : str or None
Returns
-------
@@ -260,7 +278,7 @@ def get_all_dict(module):
except ValueError:
pass
if not all_dict:
- # Must be a pure documentation module like doc.structured_arrays
+ # Must be a pure documentation module
all_dict.append('__doc__')
# Modules are almost always private; real submodules need a separate
@@ -296,7 +314,7 @@ def compare(all_dict, others, names, module_name):
List of non deprecated sub modules for module_name
others : list
List of sub modules for module_name
- names : set
+ names : set
Set of function names or special directives present in
docstring of module_name
module_name : ModuleType
@@ -335,8 +353,8 @@ def is_deprecated(f):
"""
Check if module `f` is deprecated
- Parameter
- ---------
+ Parameters
+ ----------
f : ModuleType
Returns
@@ -388,8 +406,8 @@ def check_items(all_dict, names, deprecated, others, module_name, dots=True):
output += "Objects in refguide: %i\n\n" % num_ref
only_all, only_ref, missing = compare(all_dict, others, names, module_name)
- dep_in_ref = set(only_ref).intersection(deprecated)
- only_ref = set(only_ref).difference(deprecated)
+ dep_in_ref = only_ref.intersection(deprecated)
+ only_ref = only_ref.difference(deprecated)
if len(dep_in_ref) > 0:
output += "Deprecated objects in refguide::\n\n"
@@ -771,13 +789,12 @@ def _run_doctests(tests, full_name, verbose, doctest_warnings):
Parameters
----------
- tests: list
+ tests : list
full_name : str
verbose : bool
-
- doctest_warning : bool
+ doctest_warnings : bool
Returns
-------
@@ -863,8 +880,12 @@ def check_doctests(module, verbose, ns=None,
for name in get_all_dict(module)[0]:
full_name = module.__name__ + '.' + name
- if full_name in DOCTEST_SKIPLIST:
- continue
+ if full_name in DOCTEST_SKIPDICT:
+ skip_methods = DOCTEST_SKIPDICT[full_name]
+ if skip_methods is None:
+ continue
+ else:
+ skip_methods = None
try:
obj = getattr(module, name)
@@ -885,6 +906,10 @@ def check_doctests(module, verbose, ns=None,
traceback.format_exc()))
continue
+ if skip_methods is not None:
+ tests = [i for i in tests if
+ i.name.partition(".")[2] not in skip_methods]
+
success, output = _run_doctests(tests, full_name, verbose,
doctest_warnings)
@@ -965,7 +990,7 @@ def check_doctests_testfile(fname, verbose, ns=None,
results = []
_, short_name = os.path.split(fname)
- if short_name in DOCTEST_SKIPLIST:
+ if short_name in DOCTEST_SKIPDICT:
return results
full_name = fname
@@ -1144,7 +1169,12 @@ def main(argv):
init_matplotlib()
for submodule_name in module_names:
- module_name = BASE_MODULE + '.' + submodule_name
+ prefix = BASE_MODULE + '.'
+ if not submodule_name.startswith(prefix):
+ module_name = prefix + submodule_name
+ else:
+ module_name = submodule_name
+
__import__(module_name)
module = sys.modules[module_name]
diff --git a/tools/swig/README b/tools/swig/README
index 7fa0599c6..c539c597f 100644
--- a/tools/swig/README
+++ b/tools/swig/README
@@ -15,7 +15,7 @@ system used here, can be found in the NumPy reference guide.
Testing
-------
The tests are a good example of what we are trying to do with numpy.i.
-The files related to testing are are in the test subdirectory::
+The files related to testing are in the test subdirectory::
Vector.h
Vector.cxx
diff --git a/tools/swig/numpy.i b/tools/swig/numpy.i
index 8416e82f3..0ef92bab1 100644
--- a/tools/swig/numpy.i
+++ b/tools/swig/numpy.i
@@ -114,8 +114,8 @@
if (py_obj == NULL ) return "C NULL value";
if (py_obj == Py_None ) return "Python None" ;
if (PyCallable_Check(py_obj)) return "callable" ;
- if (PyString_Check( py_obj)) return "string" ;
- if (PyInt_Check( py_obj)) return "int" ;
+ if (PyBytes_Check( py_obj)) return "string" ;
+ if (PyLong_Check( py_obj)) return "int" ;
if (PyFloat_Check( py_obj)) return "float" ;
if (PyDict_Check( py_obj)) return "dict" ;
if (PyList_Check( py_obj)) return "list" ;
@@ -524,7 +524,7 @@
return success;
}
- /* Require the given PyArrayObject to to be Fortran ordered. If the
+ /* Require the given PyArrayObject to be Fortran ordered. If the
* the PyArrayObject is already Fortran ordered, do nothing. Else,
* set the Fortran ordering flag and recompute the strides.
*/
@@ -2002,7 +2002,7 @@
(PyObject* array = NULL)
{
npy_intp dims[1];
- if (!PyInt_Check($input))
+ if (!PyLong_Check($input))
{
const char* typestring = pytype_string($input);
PyErr_Format(PyExc_TypeError,
@@ -2010,7 +2010,8 @@
typestring);
SWIG_fail;
}
- $2 = (DIM_TYPE) PyInt_AsLong($input);
+ $2 = (DIM_TYPE) PyLong_AsSsize_t($input);
+ if ($2 == -1 && PyErr_Occurred()) SWIG_fail;
dims[0] = (npy_intp) $2;
array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
if (!array) SWIG_fail;
@@ -2030,7 +2031,7 @@
(PyObject* array = NULL)
{
npy_intp dims[1];
- if (!PyInt_Check($input))
+ if (!PyLong_Check($input))
{
const char* typestring = pytype_string($input);
PyErr_Format(PyExc_TypeError,
@@ -2038,7 +2039,8 @@
typestring);
SWIG_fail;
}
- $1 = (DIM_TYPE) PyInt_AsLong($input);
+ $1 = (DIM_TYPE) PyLong_AsSsize_t($input);
+ if ($1 == -1 && PyErr_Occurred()) SWIG_fail;
dims[0] = (npy_intp) $1;
array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
if (!array) SWIG_fail;
@@ -2492,9 +2494,9 @@
if (!array) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
- PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+ PyObject* cap = PyCapsule_New((void*)(*$2), SWIGPY_CAPSULE_NAME, free_cap);
%#else
- PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$2), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
@@ -2562,9 +2564,9 @@
if (!array) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
- PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+ PyObject* cap = PyCapsule_New((void*)(*$3), SWIGPY_CAPSULE_NAME, free_cap);
%#else
- PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$3), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
@@ -2632,9 +2634,9 @@
if (!array || !require_fortran(array)) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
- PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+ PyObject* cap = PyCapsule_New((void*)(*$3), SWIGPY_CAPSULE_NAME, free_cap);
%#else
- PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$3), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
@@ -2706,9 +2708,9 @@
if (!array) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
- PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+ PyObject* cap = PyCapsule_New((void*)(*$4), SWIGPY_CAPSULE_NAME, free_cap);
%#else
- PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$4), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
@@ -2780,9 +2782,9 @@
if (!array || !require_fortran(array)) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
- PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+ PyObject* cap = PyCapsule_New((void*)(*$4), SWIGPY_CAPSULE_NAME, free_cap);
%#else
- PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$4), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
@@ -2856,161 +2858,9 @@
if (!array) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
- PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+ PyObject* cap = PyCapsule_New((void*)(*$5), SWIGPY_CAPSULE_NAME, free_cap);
%#else
- PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
-%#endif
-
-%#if NPY_API_VERSION < 0x00000007
- PyArray_BASE(array) = cap;
-%#else
- PyArray_SetBaseObject(array,cap);
-%#endif
-
- $result = SWIG_Python_AppendOutput($result,obj);
-}
-
-/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
- DIM_TYPE* DIM3, DIM_TYPE* DIM4)
- */
-%typemap(in,numinputs=0)
- (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 )
- (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
-{
- $1 = &data_temp;
- $2 = &dim1_temp;
- $3 = &dim2_temp;
- $4 = &dim3_temp;
- $5 = &dim4_temp;
-}
-%typemap(argout,
- fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
- (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
-{
- npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
- PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
- PyArrayObject* array = (PyArrayObject*) obj;
-
- if (!array || !require_fortran(array)) SWIG_fail;
-
-%#ifdef SWIGPY_USE_CAPSULE
- PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
-%#else
- PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
-%#endif
-
-%#if NPY_API_VERSION < 0x00000007
- PyArray_BASE(array) = cap;
-%#else
- PyArray_SetBaseObject(array,cap);
-%#endif
-
- $result = SWIG_Python_AppendOutput($result,obj);
-}
-
-/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
- DATA_TYPE** ARGOUTVIEWM_FARRAY4)
- */
-%typemap(in,numinputs=0)
- (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_FARRAY4)
- (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL )
-{
- $1 = &dim1_temp;
- $2 = &dim2_temp;
- $3 = &dim3_temp;
- $4 = &dim4_temp;
- $5 = &data_temp;
-}
-%typemap(argout,
- fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
- (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4)
-{
- npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
- PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
- PyArrayObject* array = (PyArrayObject*) obj;
-
- if (!array || !require_fortran(array)) SWIG_fail;
-
-%#ifdef SWIGPY_USE_CAPSULE
- PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
-%#else
- PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
-%#endif
-
-%#if NPY_API_VERSION < 0x00000007
- PyArray_BASE(array) = cap;
-%#else
- PyArray_SetBaseObject(array,cap);
-%#endif
-
- $result = SWIG_Python_AppendOutput($result,obj);
-}
-
-/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
- DIM_TYPE* DIM3, DIM_TYPE* DIM4)
- */
-%typemap(in,numinputs=0)
- (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 )
- (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
-{
- $1 = &data_temp;
- $2 = &dim1_temp;
- $3 = &dim2_temp;
- $4 = &dim3_temp;
- $5 = &dim4_temp;
-}
-%typemap(argout,
- fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
- (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
-{
- npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
- PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
- PyArrayObject* array = (PyArrayObject*) obj;
-
- if (!array) SWIG_fail;
-
-%#ifdef SWIGPY_USE_CAPSULE
- PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
-%#else
- PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
-%#endif
-
-%#if NPY_API_VERSION < 0x00000007
- PyArray_BASE(array) = cap;
-%#else
- PyArray_SetBaseObject(array,cap);
-%#endif
-
- $result = SWIG_Python_AppendOutput($result,obj);
-}
-
-/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
- DATA_TYPE** ARGOUTVIEWM_ARRAY4)
- */
-%typemap(in,numinputs=0)
- (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_ARRAY4)
- (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL )
-{
- $1 = &dim1_temp;
- $2 = &dim2_temp;
- $3 = &dim3_temp;
- $4 = &dim4_temp;
- $5 = &data_temp;
-}
-%typemap(argout,
- fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
- (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4)
-{
- npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
- PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
- PyArrayObject* array = (PyArrayObject*) obj;
-
- if (!array) SWIG_fail;
-
-%#ifdef SWIGPY_USE_CAPSULE
- PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
-%#else
- PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$5), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
@@ -3084,9 +2934,9 @@
if (!array || !require_fortran(array)) SWIG_fail;
%#ifdef SWIGPY_USE_CAPSULE
- PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+ PyObject* cap = PyCapsule_New((void*)(*$5), SWIGPY_CAPSULE_NAME, free_cap);
%#else
- PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+ PyObject* cap = PyCObject_FromVoidPtr((void*)(*$5), free);
%#endif
%#if NPY_API_VERSION < 0x00000007
diff --git a/tools/swig/pyfragments.swg b/tools/swig/pyfragments.swg
index c3ca8f125..6d3e6ff41 100644
--- a/tools/swig/pyfragments.swg
+++ b/tools/swig/pyfragments.swg
@@ -22,12 +22,9 @@
SWIGINTERN int
SWIG_AsVal_dec(long)(PyObject * obj, long * val)
{
- if (PyInt_Check(obj)) {
- if (val) *val = PyInt_AsLong(obj);
- return SWIG_OK;
- } else if (PyLong_Check(obj)) {
+ if (PyLong_Check(obj)) {
long v = PyLong_AsLong(obj);
- if (!PyErr_Occurred()) {
+ if (v != -1 || !PyErr_Occurred()) {
if (val) *val = v;
return SWIG_OK;
} else {
@@ -37,8 +34,8 @@
%#ifdef SWIG_PYTHON_CAST_MODE
{
int dispatch = 0;
- long v = PyInt_AsLong(obj);
- if (!PyErr_Occurred()) {
+ long v = PyLong_AsLong(obj);
+ if (v != -1 || !PyErr_Occurred()) {
if (val) *val = v;
return SWIG_AddCast(SWIG_OK);
} else {
@@ -56,7 +53,7 @@
%#endif
if (!PyArray_IsScalar(obj,Integer)) return SWIG_TypeError;
if (!val) return SWIG_OK;
- PyArray_Descr * longDescr = PyArray_DescrNewFromType(NPY_LONG);
+ PyArray_Descr * longDescr = PyArray_DescrFromType(NPY_LONG);
PyArray_CastScalarToCtype(obj, (void*)val, longDescr);
Py_DECREF(longDescr);
return SWIG_OK;
@@ -107,7 +104,7 @@
%#endif
if (!PyArray_IsScalar(obj,Integer)) return SWIG_TypeError;
if (!val) return SWIG_OK;
- PyArray_Descr * ulongDescr = PyArray_DescrNewFromType(NPY_ULONG);
+ PyArray_Descr * ulongDescr = PyArray_DescrFromType(NPY_ULONG);
PyArray_CastScalarToCtype(obj, (void*)val, ulongDescr);
Py_DECREF(ulongDescr);
return SWIG_OK;
diff --git a/tools/swig/test/testFarray.py b/tools/swig/test/testFarray.py
index 43a6003f4..29bf96fe2 100755
--- a/tools/swig/test/testFarray.py
+++ b/tools/swig/test/testFarray.py
@@ -28,7 +28,7 @@ class FarrayTestCase(unittest.TestCase):
def testConstructor1(self):
"Test Farray size constructor"
- self.failUnless(isinstance(self.array, Farray.Farray))
+ self.assertTrue(isinstance(self.array, Farray.Farray))
def testConstructor2(self):
"Test Farray copy constructor"
@@ -36,7 +36,7 @@ class FarrayTestCase(unittest.TestCase):
for j in range(self.ncols):
self.array[i, j] = i + j
arrayCopy = Farray.Farray(self.array)
- self.failUnless(arrayCopy == self.array)
+ self.assertTrue(arrayCopy == self.array)
def testConstructorBad1(self):
"Test Farray size constructor, negative nrows"
@@ -48,15 +48,15 @@ class FarrayTestCase(unittest.TestCase):
def testNrows(self):
"Test Farray nrows method"
- self.failUnless(self.array.nrows() == self.nrows)
+ self.assertTrue(self.array.nrows() == self.nrows)
def testNcols(self):
"Test Farray ncols method"
- self.failUnless(self.array.ncols() == self.ncols)
+ self.assertTrue(self.array.ncols() == self.ncols)
def testLen(self):
"Test Farray __len__ method"
- self.failUnless(len(self.array) == self.nrows*self.ncols)
+ self.assertTrue(len(self.array) == self.nrows*self.ncols)
def testSetGet(self):
"Test Farray __setitem__, __getitem__ methods"
@@ -67,7 +67,7 @@ class FarrayTestCase(unittest.TestCase):
self.array[i, j] = i*j
for i in range(m):
for j in range(n):
- self.failUnless(self.array[i, j] == i*j)
+ self.assertTrue(self.array[i, j] == i*j)
def testSetBad1(self):
"Test Farray __setitem__ method, negative row"
@@ -113,7 +113,7 @@ class FarrayTestCase(unittest.TestCase):
for i in range(self.nrows):
for j in range(self.ncols):
self.array[i, j] = i+j
- self.failUnless(self.array.asString() == result)
+ self.assertTrue(self.array.asString() == result)
def testStr(self):
"Test Farray __str__ method"
@@ -127,7 +127,7 @@ class FarrayTestCase(unittest.TestCase):
for i in range(self.nrows):
for j in range(self.ncols):
self.array[i, j] = i-j
- self.failUnless(str(self.array) == result)
+ self.assertTrue(str(self.array) == result)
def testView(self):
"Test Farray view method"
@@ -135,11 +135,11 @@ class FarrayTestCase(unittest.TestCase):
for j in range(self.ncols):
self.array[i, j] = i+j
a = self.array.view()
- self.failUnless(isinstance(a, np.ndarray))
- self.failUnless(a.flags.f_contiguous)
+ self.assertTrue(isinstance(a, np.ndarray))
+ self.assertTrue(a.flags.f_contiguous)
for i in range(self.nrows):
for j in range(self.ncols):
- self.failUnless(a[i, j] == i+j)
+ self.assertTrue(a[i, j] == i+j)
######################################################################
diff --git a/tools/travis-before-install.sh b/tools/travis-before-install.sh
index e468dd932..056e97472 100755
--- a/tools/travis-before-install.sh
+++ b/tools/travis-before-install.sh
@@ -9,18 +9,25 @@ free -m
df -h
ulimit -a
+sudo apt update
+sudo apt install gfortran eatmydata libgfortran5
+
+if [ "$USE_DEBUG" ]
+then
+ sudo apt install python3-dbg python3-dev python3-setuptools
+fi
+
mkdir builds
pushd builds
# Build into own virtualenv
# We therefore control our own environment, avoid travis' numpy
-pip install -U virtualenv
if [ -n "$USE_DEBUG" ]
then
- virtualenv --python=$(which python3-dbg) venv
+ python3-dbg -m venv venv
else
- virtualenv --python=python venv
+ python -m venv venv
fi
source venv/bin/activate
@@ -29,7 +36,7 @@ gcc --version
popd
-pip install --upgrade pip
+pip install --upgrade pip 'setuptools<49.2.0' wheel
# 'setuptools', 'wheel' and 'cython' are build dependencies. This information
# is stored in pyproject.toml, but there is not yet a standard way to install
@@ -41,7 +48,7 @@ pip install --upgrade pip
# A specific version of cython is required, so we read the cython package
# requirement using `grep cython test_requirements.txt` instead of simply
# writing 'pip install setuptools wheel cython'.
-pip install setuptools wheel `grep cython test_requirements.txt`
+pip install `grep cython test_requirements.txt`
if [ -n "$DOWNLOAD_OPENBLAS" ]; then
pwd
diff --git a/tools/travis-sorter.py b/tools/travis-sorter.py
new file mode 100755
index 000000000..416f9fe76
--- /dev/null
+++ b/tools/travis-sorter.py
@@ -0,0 +1,287 @@
+#!/usr/bin/env python3
+"""
+Run with a repo/build number or list of Travis CI build times to show the optimal build
+order to run faster and make full use of all available parallel build jobs.
+
+Requires the Travis Client CLI
+
+https://github.com/travis-ci/travis.rb#installation
+
+# Example
+
+$ # Check build 22 of hugovk/numpy, and skip the first job (it's a single stage)
+$ travis-sorter.py hugovk/numpy 22 --skip 1
+travis show -r hugovk/numpy 22
+[8, 7, 8, 10, 9, 18, 8, 11, 8, 10, 8, 8, 17, 8, 26]
+[7, 8, 10, 9, 18, 8, 11, 8, 10, 8, 8, 17, 8, 26]
+Before:
+
+ID Duration in mins
+ 1 *******
+ 2 ********
+ 3 **********
+ 4 *********
+ 5 ******************
+ 6 ********
+ 7 ***********
+ 8 ********
+ 9 **********
+10 ********
+11 ********
+12 *****************
+13 ********
+14 **************************
+End: 46
+ ----------------------------------------------
+
+After:
+
+ID Duration in mins
+14 **************************
+ 5 ******************
+12 *****************
+ 7 ***********
+ 3 **********
+ 9 **********
+ 4 *********
+ 2 ********
+ 6 ********
+ 8 ********
+10 ********
+11 ********
+13 ********
+ 1 *******
+End: 34
+ ----------------------------------
+
+# Example
+
+$ python travis-sorter.py 4 4 4 4 4 12 19
+
+Before:
+
+****
+****
+****
+****
+****
+ ************
+ *******************
+12345678901234567890123 = 23 minutes
+
+After:
+
+*******************
+************
+****
+****
+****
+ ****
+ ****
+1234567890123456789 = 19 minutes
+"""
+import argparse
+import re
+import subprocess
+import sys
+
+count = 1
+
+
+def summarise(jobs):
+ end = 0
+ print("ID Duration in mins")
+ for job in jobs:
+ before = " " * job.started
+ active = "*" * job.length
+ print("{:2d} {}{}".format(job.id, before, active))
+ if job.started + job.length > end:
+ end = job.started + job.length
+ # for job in jobs:
+ # print(job)
+ print("End:", end)
+ print(" " + "-" * end)
+
+
+class Job:
+ def __init__(self, length):
+ global count
+ self.id = count
+ count += 1
+ self.length = length
+ self.started = -1
+ self.status = "not started"
+ self.ended = False
+
+ def __str__(self):
+ return "{}\tLength: {}\tStarted: {}\tEnded: {}".format(
+ self.id, self.length, self.started, self.ended
+ )
+
+
+def count_status(jobs, status):
+ number = 0
+ for job in jobs:
+ if job.status == status:
+ number += 1
+ return number
+
+
+def simulate(jobs, limit):
+
+ time = 0
+
+ # summarise(jobs)
+
+ while True:
+ # Check if any have ended
+ for job in jobs:
+ if job.status == "active":
+ if time >= job.started + job.length:
+ # print("{}/{} Finished:".format(count_status(jobs, "active"), limit))
+ job.ended = time
+ job.status = "finished"
+ # print(job)
+
+ # Check if any can start
+ for job in jobs:
+ if job.status == "not started":
+ if count_status(jobs, "active") < limit:
+ # print("{}/{} Starting:".format(count_status(jobs, "active"), limit))
+ job.started = time
+ job.status = "active"
+ # print(job)
+
+ time += 1
+
+ # Exit loop?
+ if count_status(jobs, "finished") == len(jobs):
+ break
+
+ summarise(jobs)
+
+
+def do_thing(repo, number):
+ cmd = f"travis show -r {repo} {number or ''}"
+ # cmd = f"travis show --com -r {repo} {number or ''}"
+ print(cmd)
+
+ exitcode = 0
+ # For offline testing
+ output = """Build #4: Upgrade Python syntax with pyupgrade https://github.com/asottile/pyupgrade
+State: passed
+Type: push
+Branch: add-3.7
+Compare URL: https://github.com/hugovk/diff-cover/compare/4ae7cf97c6fa...7eeddb300175
+Duration: 16 min 7 sec
+Started: 2018-10-17 19:03:01
+Finished: 2018-10-17 19:09:53
+
+#4.1 passed: 1 min os: linux, env: TOXENV=py27, python: 2.7
+#4.2 passed: 1 min 43 sec os: linux, env: TOXENV=py34, python: 3.4
+#4.3 passed: 1 min 52 sec os: linux, env: TOXENV=py35, python: 3.5
+#4.4 passed: 1 min 38 sec os: linux, env: TOXENV=py36, python: 3.6
+#4.5 passed: 1 min 47 sec os: linux, env: TOXENV=py37, python: 3.7
+#4.6 passed: 4 min 35 sec os: linux, env: TOXENV=pypy, python: pypy
+#4.7 passed: 3 min 17 sec os: linux, env: TOXENV=pypy3, python: pypy3"""
+
+ # For offline testing
+ output = """Build #9: :arrows_clockwise: [EngCom] Public Pull Requests - 2.3-develop
+State: errored
+Type: push
+Branch: 2.3-develop
+Compare URL: https://github.com/hugovk/magento2/compare/80469a61e061...77af5d65ef4f
+Duration: 4 hrs 12 min 13 sec
+Started: 2018-10-27 17:50:51
+Finished: 2018-10-27 18:54:14
+
+#9.1 passed: 3 min 30 sec os: linux, env: TEST_SUITE=unit, php: 7.1
+#9.2 passed: 3 min 35 sec os: linux, env: TEST_SUITE=unit, php: 7.2
+#9.3 passed: 3 min 41 sec os: linux, env: TEST_SUITE=static, php: 7.2
+#9.4 passed: 8 min 48 sec os: linux, env: TEST_SUITE=js GRUNT_COMMAND=spec, php: 7.2
+#9.5 passed: 3 min 24 sec os: linux, env: TEST_SUITE=js GRUNT_COMMAND=static, php: 7.2
+#9.6 errored: 50 min os: linux, env: TEST_SUITE=integration INTEGRATION_INDEX=1, php: 7.1
+#9.7 passed: 49 min 25 sec os: linux, env: TEST_SUITE=integration INTEGRATION_INDEX=1, php: 7.2
+#9.8 passed: 31 min 54 sec os: linux, env: TEST_SUITE=integration INTEGRATION_INDEX=2, php: 7.1
+#9.9 passed: 31 min 24 sec os: linux, env: TEST_SUITE=integration INTEGRATION_INDEX=2, php: 7.2
+#9.10 passed: 27 min 23 sec os: linux, env: TEST_SUITE=integration INTEGRATION_INDEX=3, php: 7.1
+#9.11 passed: 26 min 9 sec os: linux, env: TEST_SUITE=integration INTEGRATION_INDEX=3, php: 7.2
+#9.12 passed: 13 min os: linux, env: TEST_SUITE=functional, php: 7.2"""
+
+ # Real use
+ exitcode, output = subprocess.getstatusoutput(cmd)
+
+ # print(exitcode)
+ # print(output)
+ if exitcode != 0:
+ print(output)
+ sys.exit(exitcode)
+
+ minutes = []
+ matches = re.findall(r"(pass|fail|error)ed.* (\d+) min (\d+)? ", output)
+ for match in matches:
+ status, m, s = match
+ s = 0 if s == "" else int(s)
+ s += int(m) * 60
+ minutes.append(round(s / 60))
+
+ # print(minutes)
+ return minutes
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(
+ description="Either give minutes for --jobs (3 5 3 2 5), "
+ "or --repo slug (hugovk/test) and build --number (5)",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser.add_argument(
+ "input",
+ nargs="+",
+ help="Either: times for each build job (minutes), "
+ "or an org/repo slug and optionally build number",
+ )
+ parser.add_argument(
+ "-l", "--limit", type=int, default=5, help="Concurrent jobs limit"
+ )
+ parser.add_argument(
+ "-s", "--skip", type=int, default=0, help="Skip X jobs at the start"
+ )
+ args = parser.parse_args()
+
+ # If all ints
+ try:
+ for x in args.input:
+ int(x)
+ job_times = args.input
+ except ValueError:
+ try:
+ number = args.input[1]
+ except IndexError:
+ number = None
+ job_times = do_thing(args.input[0], number)
+
+ job_times = job_times[args.skip :]
+ # print(job_times)
+
+ print("Before:")
+ print()
+
+ jobs = []
+ for job_time in job_times:
+ job = Job(job_time)
+ jobs.append(job)
+
+ simulate(jobs, args.limit)
+
+ print()
+ print("After:")
+ print()
+
+ # Sort with longest first
+ jobs.sort(key=lambda job: job.length, reverse=True)
+ # Reset status
+ for job in jobs:
+ job.status = "not started"
+
+ simulate(jobs, args.limit)
diff --git a/tools/travis-test.sh b/tools/travis-test.sh
index 225cbfa0c..db5b3f744 100755
--- a/tools/travis-test.sh
+++ b/tools/travis-test.sh
@@ -36,21 +36,33 @@ setup_base()
sysflags="$($PYTHON -c "from distutils import sysconfig; \
print (sysconfig.get_config_var('CFLAGS'))")"
export CFLAGS="$sysflags $werrors -Wlogical-op -Wno-sign-compare"
+ # SIMD extensions that need to be tested on both runtime and compile-time via (test_simd.py)
+ # any specified features will be ignored if they're not supported by compiler or platform
+ # note: it almost the same default value of --simd-test execpt adding policy `$werror` to treat all
+ # warnings as errors
+ simd_test="\$werror BASELINE SSE2 SSE42 XOP FMA4 (FMA3 AVX2) AVX512F AVX512_SKX VSX VSX2 VSX3 NEON ASIMD"
# We used to use 'setup.py install' here, but that has the terrible
# behaviour that if a copy of the package is already installed in the
# install location, then the new copy just gets dropped on top of it.
# Travis typically has a stable numpy release pre-installed, and if we
# don't remove it, then we can accidentally end up e.g. running old
# test modules that were in the stable release but have been removed
- # from master. (See gh-2765, gh-2768.) Using 'pip install' also has
+ # from main. (See gh-2765, gh-2768.) Using 'pip install' also has
# the advantage that it tests that numpy is 'pip install' compatible,
# see e.g. gh-2766...
if [ -z "$USE_DEBUG" ]; then
- $PIP install -v . 2>&1 | tee log
+ # activates '-Werror=undef' when DEBUG isn't enabled since _cffi_backend'
+ # extension breaks the build due to the following error:
+ #
+ # error: "HAVE_FFI_PREP_CIF_VAR" is not defined, evaluates to 0 [-Werror=undef]
+ # #if !HAVE_FFI_PREP_CIF_VAR && defined(__arm64__) && defined(__APPLE__)
+ #
+ export CFLAGS="$CFLAGS -Werror=undef"
+ $PYTHON setup.py build --simd-test "$simd_test" install 2>&1 | tee log
else
# The job run with USE_DEBUG=1 on travis needs this.
export CFLAGS=$CFLAGS" -Wno-maybe-uninitialized"
- $PYTHON setup.py build build_src --verbose-cfg build_ext --inplace 2>&1 | tee log
+ $PYTHON setup.py build --simd-test "$simd_test" build_src --verbose-cfg build_ext --inplace 2>&1 | tee log
fi
grep -v "_configtest" log \
| grep -vE "ld returned 1|no files found matching" \
@@ -71,17 +83,12 @@ run_test()
# in test_requirements.txt) does not provide a wheel, and the source tar
# file does not install correctly when Python's optimization level is set
# to strip docstrings (see https://github.com/eliben/pycparser/issues/291).
- PYTHONOPTIMIZE="" $PIP install -r test_requirements.txt
+ PYTHONOPTIMIZE="" $PIP install -r test_requirements.txt pyinstaller
+ DURATIONS_FLAG="--durations 10"
if [ -n "$USE_DEBUG" ]; then
export PYTHONPATH=$PWD
- fi
-
- # pytest aborts when running --durations with python3.6-dbg, so only enable
- # it for non-debug tests. That is a cPython bug fixed in later versions of
- # python3.7 but python3.7-dbg is not currently available on travisCI.
- if [ -z "$USE_DEBUG" ]; then
- DURATIONS_FLAG="--durations 10"
+ export MYPYPATH=$PWD
fi
if [ -n "$RUN_COVERAGE" ]; then
@@ -104,7 +111,7 @@ run_test()
export PYTHONWARNINGS="ignore::DeprecationWarning:virtualenv"
$PYTHON -b ../runtests.py -n -v --mode=full $DURATIONS_FLAG $COVERAGE_FLAG
else
- $PYTHON ../runtests.py -n -v $DURATIONS_FLAG
+ $PYTHON ../runtests.py -n -v $DURATIONS_FLAG -- -rs
fi
if [ -n "$RUN_COVERAGE" ]; then
@@ -158,7 +165,7 @@ if [ -n "$USE_WHEEL" ] && [ $# -eq 0 ]; then
fi
$PYTHON setup.py build --warn-error build_src --verbose-cfg bdist_wheel
# Make another virtualenv to install into
- virtualenv --python=`which $PYTHON` venv-for-wheel
+ $PYTHON -m venv venv-for-wheel
. venv-for-wheel/bin/activate
# Move out of source directory to avoid finding local numpy
pushd dist
@@ -174,7 +181,7 @@ elif [ -n "$USE_SDIST" ] && [ $# -eq 0 ]; then
export CFLAGS=$CFLAGS" -Wno-sign-compare -Wno-unused-result"
$PYTHON setup.py sdist
# Make another virtualenv to install into
- virtualenv --python=`which $PYTHON` venv-for-wheel
+ $PYTHON -m venv venv-for-wheel
. venv-for-wheel/bin/activate
# Move out of source directory to avoid finding local numpy
pushd dist
diff --git a/tools/wheels/LICENSE_linux.txt b/tools/wheels/LICENSE_linux.txt
new file mode 100644
index 000000000..9ea808afc
--- /dev/null
+++ b/tools/wheels/LICENSE_linux.txt
@@ -0,0 +1,880 @@
+
+----
+
+This binary distribution of NumPy also bundles the following software:
+
+
+Name: OpenBLAS
+Files: .libs/libopenb*.so
+Description: bundled as a dynamically linked library
+Availability: https://github.com/xianyi/OpenBLAS/
+License: 3-clause BSD
+ Copyright (c) 2011-2014, The OpenBLAS Project
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. Neither the name of the OpenBLAS project nor the names of
+ its contributors may be used to endorse or promote products
+ derived from this software without specific prior written
+ permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+Name: LAPACK
+Files: .libs/libopenb*.so
+Description: bundled in OpenBLAS
+Availability: https://github.com/xianyi/OpenBLAS/
+License 3-clause BSD
+ Copyright (c) 1992-2013 The University of Tennessee and The University
+ of Tennessee Research Foundation. All rights
+ reserved.
+ Copyright (c) 2000-2013 The University of California Berkeley. All
+ rights reserved.
+ Copyright (c) 2006-2013 The University of Colorado Denver. All rights
+ reserved.
+
+ $COPYRIGHT$
+
+ Additional copyrights may follow
+
+ $HEADER$
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer listed
+ in this license in the documentation and/or other materials
+ provided with the distribution.
+
+ - Neither the name of the copyright holders nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ The copyright holders provide no reassurances that the source code
+ provided does not infringe any patent, copyright, or any other
+ intellectual property rights of third parties. The copyright holders
+ disclaim any liability to any recipient for claims brought against
+ recipient by any third party for infringement of that parties
+ intellectual property rights.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+Name: GCC runtime library
+Files: .libs/libgfortran*.so
+Description: dynamically linked to files compiled with gcc
+Availability: https://gcc.gnu.org/viewcvs/gcc/
+License: GPLv3 + runtime exception
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+
+ Libgfortran is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgfortran is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>.
+
+----
+
+Full text of license texts referred to above follows (that they are
+listed below does not necessarily imply the conditions apply to the
+present binary release):
+
+----
+
+GCC RUNTIME LIBRARY EXCEPTION
+
+Version 3.1, 31 March 2009
+
+Copyright (C) 2009 Free Software Foundation, Inc. <http://fsf.org/>
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+This GCC Runtime Library Exception ("Exception") is an additional
+permission under section 7 of the GNU General Public License, version
+3 ("GPLv3"). It applies to a given file (the "Runtime Library") that
+bears a notice placed by the copyright holder of the file stating that
+the file is governed by GPLv3 along with this Exception.
+
+When you use GCC to compile a program, GCC may combine portions of
+certain GCC header files and runtime libraries with the compiled
+program. The purpose of this Exception is to allow compilation of
+non-GPL (including proprietary) programs to use, in this way, the
+header files and runtime libraries covered by this Exception.
+
+0. Definitions.
+
+A file is an "Independent Module" if it either requires the Runtime
+Library for execution after a Compilation Process, or makes use of an
+interface provided by the Runtime Library, but is not otherwise based
+on the Runtime Library.
+
+"GCC" means a version of the GNU Compiler Collection, with or without
+modifications, governed by version 3 (or a specified later version) of
+the GNU General Public License (GPL) with the option of using any
+subsequent versions published by the FSF.
+
+"GPL-compatible Software" is software whose conditions of propagation,
+modification and use would permit combination with GCC in accord with
+the license of GCC.
+
+"Target Code" refers to output from any compiler for a real or virtual
+target processor architecture, in executable form or suitable for
+input to an assembler, loader, linker and/or execution
+phase. Notwithstanding that, Target Code does not include data in any
+format that is used as a compiler intermediate representation, or used
+for producing a compiler intermediate representation.
+
+The "Compilation Process" transforms code entirely represented in
+non-intermediate languages designed for human-written code, and/or in
+Java Virtual Machine byte code, into Target Code. Thus, for example,
+use of source code generators and preprocessors need not be considered
+part of the Compilation Process, since the Compilation Process can be
+understood as starting with the output of the generators or
+preprocessors.
+
+A Compilation Process is "Eligible" if it is done using GCC, alone or
+with other GPL-compatible software, or if it is done without using any
+work based on GCC. For example, using non-GPL-compatible Software to
+optimize any GCC intermediate representations would not qualify as an
+Eligible Compilation Process.
+
+1. Grant of Additional Permission.
+
+You have permission to propagate a work of Target Code formed by
+combining the Runtime Library with Independent Modules, even if such
+propagation would otherwise violate the terms of GPLv3, provided that
+all Target Code was generated by Eligible Compilation Processes. You
+may then convey such a combination under terms of your choice,
+consistent with the licensing of the Independent Modules.
+
+2. No Weakening of GCC Copyleft.
+
+The availability of this Exception does not imply any general
+presumption that third-party software is unaffected by the copyleft
+requirements of the license of GCC.
+
+----
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/tools/wheels/LICENSE_osx.txt b/tools/wheels/LICENSE_osx.txt
new file mode 100644
index 000000000..9a687c3b6
--- /dev/null
+++ b/tools/wheels/LICENSE_osx.txt
@@ -0,0 +1,789 @@
+
+----
+
+This binary distribution of NumPy also bundles the following software:
+
+
+Name: GCC runtime library
+Files: .dylibs/*
+Description: dynamically linked to files compiled with gcc
+Availability: https://gcc.gnu.org/viewcvs/gcc/
+License: GPLv3 + runtime exception
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+
+ Libgfortran is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgfortran is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>.
+
+----
+
+Full text of license texts referred to above follows (that they are
+listed below does not necessarily imply the conditions apply to the
+present binary release):
+
+----
+
+GCC RUNTIME LIBRARY EXCEPTION
+
+Version 3.1, 31 March 2009
+
+Copyright (C) 2009 Free Software Foundation, Inc. <http://fsf.org/>
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+This GCC Runtime Library Exception ("Exception") is an additional
+permission under section 7 of the GNU General Public License, version
+3 ("GPLv3"). It applies to a given file (the "Runtime Library") that
+bears a notice placed by the copyright holder of the file stating that
+the file is governed by GPLv3 along with this Exception.
+
+When you use GCC to compile a program, GCC may combine portions of
+certain GCC header files and runtime libraries with the compiled
+program. The purpose of this Exception is to allow compilation of
+non-GPL (including proprietary) programs to use, in this way, the
+header files and runtime libraries covered by this Exception.
+
+0. Definitions.
+
+A file is an "Independent Module" if it either requires the Runtime
+Library for execution after a Compilation Process, or makes use of an
+interface provided by the Runtime Library, but is not otherwise based
+on the Runtime Library.
+
+"GCC" means a version of the GNU Compiler Collection, with or without
+modifications, governed by version 3 (or a specified later version) of
+the GNU General Public License (GPL) with the option of using any
+subsequent versions published by the FSF.
+
+"GPL-compatible Software" is software whose conditions of propagation,
+modification and use would permit combination with GCC in accord with
+the license of GCC.
+
+"Target Code" refers to output from any compiler for a real or virtual
+target processor architecture, in executable form or suitable for
+input to an assembler, loader, linker and/or execution
+phase. Notwithstanding that, Target Code does not include data in any
+format that is used as a compiler intermediate representation, or used
+for producing a compiler intermediate representation.
+
+The "Compilation Process" transforms code entirely represented in
+non-intermediate languages designed for human-written code, and/or in
+Java Virtual Machine byte code, into Target Code. Thus, for example,
+use of source code generators and preprocessors need not be considered
+part of the Compilation Process, since the Compilation Process can be
+understood as starting with the output of the generators or
+preprocessors.
+
+A Compilation Process is "Eligible" if it is done using GCC, alone or
+with other GPL-compatible software, or if it is done without using any
+work based on GCC. For example, using non-GPL-compatible Software to
+optimize any GCC intermediate representations would not qualify as an
+Eligible Compilation Process.
+
+1. Grant of Additional Permission.
+
+You have permission to propagate a work of Target Code formed by
+combining the Runtime Library with Independent Modules, even if such
+propagation would otherwise violate the terms of GPLv3, provided that
+all Target Code was generated by Eligible Compilation Processes. You
+may then convey such a combination under terms of your choice,
+consistent with the licensing of the Independent Modules.
+
+2. No Weakening of GCC Copyleft.
+
+The availability of this Exception does not imply any general
+presumption that third-party software is unaffected by the copyleft
+requirements of the license of GCC.
+
+----
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/tools/wheels/LICENSE_win32.txt b/tools/wheels/LICENSE_win32.txt
new file mode 100644
index 000000000..1014d77cd
--- /dev/null
+++ b/tools/wheels/LICENSE_win32.txt
@@ -0,0 +1,938 @@
+
+----
+
+This binary distribution of NumPy also bundles the following software:
+
+
+Name: OpenBLAS
+Files: extra-dll\libopenb*.dll
+Description: bundled as a dynamically linked library
+Availability: https://github.com/xianyi/OpenBLAS/
+License: 3-clause BSD
+ Copyright (c) 2011-2014, The OpenBLAS Project
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ 3. Neither the name of the OpenBLAS project nor the names of
+ its contributors may be used to endorse or promote products
+ derived from this software without specific prior written
+ permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+Name: LAPACK
+Files: extra-dll\libopenb*.dll
+Description: bundled in OpenBLAS
+Availability: https://github.com/xianyi/OpenBLAS/
+License 3-clause BSD
+ Copyright (c) 1992-2013 The University of Tennessee and The University
+ of Tennessee Research Foundation. All rights
+ reserved.
+ Copyright (c) 2000-2013 The University of California Berkeley. All
+ rights reserved.
+ Copyright (c) 2006-2013 The University of Colorado Denver. All rights
+ reserved.
+
+ $COPYRIGHT$
+
+ Additional copyrights may follow
+
+ $HEADER$
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer listed
+ in this license in the documentation and/or other materials
+ provided with the distribution.
+
+ - Neither the name of the copyright holders nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ The copyright holders provide no reassurances that the source code
+ provided does not infringe any patent, copyright, or any other
+ intellectual property rights of third parties. The copyright holders
+ disclaim any liability to any recipient for claims brought against
+ recipient by any third party for infringement of that parties
+ intellectual property rights.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+Name: GCC runtime library
+Files: extra-dll\*.dll
+Description: statically linked, in DLL files compiled with gfortran only
+Availability: https://gcc.gnu.org/viewcvs/gcc/
+License: GPLv3 + runtime exception
+ Copyright (C) 2002-2017 Free Software Foundation, Inc.
+
+ Libgfortran is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ Libgfortran is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>.
+
+
+Name: Microsoft Visual C++ Runtime Files
+Files: extra-dll\msvcp140.dll
+License: MSVC
+ https://www.visualstudio.com/license-terms/distributable-code-microsoft-visual-studio-2015-rc-microsoft-visual-studio-2015-sdk-rc-includes-utilities-buildserver-files/#visual-c-runtime
+
+ Subject to the License Terms for the software, you may copy and
+ distribute with your program any of the files within the followng
+ folder and its subfolders except as noted below. You may not modify
+ these files.
+
+ C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist
+
+ You may not distribute the contents of the following folders:
+
+ C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist\debug_nonredist
+ C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist\onecore\debug_nonredist
+
+ Subject to the License Terms for the software, you may copy and
+ distribute the following files with your program in your program’s
+ application local folder or by deploying them into the Global
+ Assembly Cache (GAC):
+
+ VC\atlmfc\lib\mfcmifc80.dll
+ VC\atlmfc\lib\amd64\mfcmifc80.dll
+
+
+Name: Microsoft Visual C++ Runtime Files
+Files: extra-dll\msvc*90.dll, extra-dll\Microsoft.VC90.CRT.manifest
+License: MSVC
+ For your convenience, we have provided the following folders for
+ use when redistributing VC++ runtime files. Subject to the license
+ terms for the software, you may redistribute the folder
+ (unmodified) in the application local folder as a sub-folder with
+ no change to the folder name. You may also redistribute all the
+ files (*.dll and *.manifest) within a folder, listed below the
+ folder for your convenience, as an entire set.
+
+ \VC\redist\x86\Microsoft.VC90.ATL\
+ atl90.dll
+ Microsoft.VC90.ATL.manifest
+ \VC\redist\ia64\Microsoft.VC90.ATL\
+ atl90.dll
+ Microsoft.VC90.ATL.manifest
+ \VC\redist\amd64\Microsoft.VC90.ATL\
+ atl90.dll
+ Microsoft.VC90.ATL.manifest
+ \VC\redist\x86\Microsoft.VC90.CRT\
+ msvcm90.dll
+ msvcp90.dll
+ msvcr90.dll
+ Microsoft.VC90.CRT.manifest
+ \VC\redist\ia64\Microsoft.VC90.CRT\
+ msvcm90.dll
+ msvcp90.dll
+ msvcr90.dll
+ Microsoft.VC90.CRT.manifest
+
+----
+
+Full text of license texts referred to above follows (that they are
+listed below does not necessarily imply the conditions apply to the
+present binary release):
+
+----
+
+GCC RUNTIME LIBRARY EXCEPTION
+
+Version 3.1, 31 March 2009
+
+Copyright (C) 2009 Free Software Foundation, Inc. <http://fsf.org/>
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+This GCC Runtime Library Exception ("Exception") is an additional
+permission under section 7 of the GNU General Public License, version
+3 ("GPLv3"). It applies to a given file (the "Runtime Library") that
+bears a notice placed by the copyright holder of the file stating that
+the file is governed by GPLv3 along with this Exception.
+
+When you use GCC to compile a program, GCC may combine portions of
+certain GCC header files and runtime libraries with the compiled
+program. The purpose of this Exception is to allow compilation of
+non-GPL (including proprietary) programs to use, in this way, the
+header files and runtime libraries covered by this Exception.
+
+0. Definitions.
+
+A file is an "Independent Module" if it either requires the Runtime
+Library for execution after a Compilation Process, or makes use of an
+interface provided by the Runtime Library, but is not otherwise based
+on the Runtime Library.
+
+"GCC" means a version of the GNU Compiler Collection, with or without
+modifications, governed by version 3 (or a specified later version) of
+the GNU General Public License (GPL) with the option of using any
+subsequent versions published by the FSF.
+
+"GPL-compatible Software" is software whose conditions of propagation,
+modification and use would permit combination with GCC in accord with
+the license of GCC.
+
+"Target Code" refers to output from any compiler for a real or virtual
+target processor architecture, in executable form or suitable for
+input to an assembler, loader, linker and/or execution
+phase. Notwithstanding that, Target Code does not include data in any
+format that is used as a compiler intermediate representation, or used
+for producing a compiler intermediate representation.
+
+The "Compilation Process" transforms code entirely represented in
+non-intermediate languages designed for human-written code, and/or in
+Java Virtual Machine byte code, into Target Code. Thus, for example,
+use of source code generators and preprocessors need not be considered
+part of the Compilation Process, since the Compilation Process can be
+understood as starting with the output of the generators or
+preprocessors.
+
+A Compilation Process is "Eligible" if it is done using GCC, alone or
+with other GPL-compatible software, or if it is done without using any
+work based on GCC. For example, using non-GPL-compatible Software to
+optimize any GCC intermediate representations would not qualify as an
+Eligible Compilation Process.
+
+1. Grant of Additional Permission.
+
+You have permission to propagate a work of Target Code formed by
+combining the Runtime Library with Independent Modules, even if such
+propagation would otherwise violate the terms of GPLv3, provided that
+all Target Code was generated by Eligible Compilation Processes. You
+may then convey such a combination under terms of your choice,
+consistent with the licensing of the Independent Modules.
+
+2. No Weakening of GCC Copyleft.
+
+The availability of this Exception does not imply any general
+presumption that third-party software is unaffected by the copyleft
+requirements of the license of GCC.
+
+----
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>. \ No newline at end of file
diff --git a/tools/wheels/check_license.py b/tools/wheels/check_license.py
new file mode 100644
index 000000000..0fe7356c0
--- /dev/null
+++ b/tools/wheels/check_license.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+"""
+check_license.py [MODULE]
+
+Check the presence of a LICENSE.txt in the installed module directory,
+and that it appears to contain text prevalent for a NumPy binary
+distribution.
+
+"""
+import os
+import sys
+import io
+import re
+import argparse
+
+
+def check_text(text):
+ ok = "Copyright (c)" in text and re.search(
+ r"This binary distribution of \w+ also bundles the following software",
+ text,
+ )
+ return ok
+
+
+def main():
+ p = argparse.ArgumentParser(usage=__doc__.rstrip())
+ p.add_argument("module", nargs="?", default="numpy")
+ args = p.parse_args()
+
+ # Drop '' from sys.path
+ sys.path.pop(0)
+
+ # Find module path
+ __import__(args.module)
+ mod = sys.modules[args.module]
+
+ # Check license text
+ license_txt = os.path.join(os.path.dirname(mod.__file__), "LICENSE.txt")
+ with io.open(license_txt, "r", encoding="utf-8") as f:
+ text = f.read()
+
+ ok = check_text(text)
+ if not ok:
+ print(
+ "ERROR: License text {} does not contain expected "
+ "text fragments\n".format(license_txt)
+ )
+ print(text)
+ sys.exit(1)
+
+ sys.exit(0)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tools/wheels/cibw_before_build.sh b/tools/wheels/cibw_before_build.sh
new file mode 100644
index 000000000..5cf7d8088
--- /dev/null
+++ b/tools/wheels/cibw_before_build.sh
@@ -0,0 +1,58 @@
+set -xe
+
+PROJECT_DIR="$1"
+PLATFORM=$(PYTHONPATH=tools python -c "import openblas_support; print(openblas_support.get_plat())")
+
+# Update license
+if [[ $RUNNER_OS == "Linux" ]] ; then
+ cat $PROJECT_DIR/tools/wheels/LICENSE_linux.txt >> $PROJECT_DIR/LICENSE.txt
+elif [[ $RUNNER_OS == "macOS" ]]; then
+ cat $PROJECT_DIR/tools/wheels/LICENSE_osx.txt >> $PROJECT_DIR/LICENSE.txt
+elif [[ $RUNNER_OS == "Windows" ]]; then
+ cat $PROJECT_DIR/tools/wheels/LICENSE_win32.txt >> $PROJECT_DIR/LICENSE.txt
+fi
+
+# Install Openblas
+if [[ $RUNNER_OS == "Linux" || $RUNNER_OS == "macOS" ]] ; then
+ basedir=$(python tools/openblas_support.py)
+ cp -r $basedir/lib/* /usr/local/lib
+ cp $basedir/include/* /usr/local/include
+ if [[ $RUNNER_OS == "macOS" && $PLATFORM == "macosx-arm64" ]]; then
+ sudo mkdir -p /opt/arm64-builds/lib /opt/arm64-builds/include
+ sudo chown -R $USER /opt/arm64-builds
+ cp -r $basedir/lib/* /opt/arm64-builds/lib
+ cp $basedir/include/* /opt/arm64-builds/include
+ fi
+elif [[ $RUNNER_OS == "Windows" ]]; then
+ PYTHONPATH=tools python -c "import openblas_support; openblas_support.make_init('numpy')"
+ target=$(python tools/openblas_support.py)
+ mkdir -p openblas
+ cp $target openblas
+fi
+
+# Install GFortran
+if [[ $RUNNER_OS == "macOS" ]]; then
+ # same version of gfortran as the openblas-libs and numpy-wheel builds
+ curl -L https://github.com/MacPython/gfortran-install/raw/master/archives/gfortran-4.9.0-Mavericks.dmg -o gfortran.dmg
+ GFORTRAN_SHA256=$(shasum -a 256 gfortran.dmg)
+ KNOWN_SHA256="d2d5ca5ba8332d63bbe23a07201c4a0a5d7e09ee56f0298a96775f928c3c4b30 gfortran.dmg"
+ if [ "$GFORTRAN_SHA256" != "$KNOWN_SHA256" ]; then
+ echo sha256 mismatch
+ exit 1
+ fi
+
+ hdiutil attach -mountpoint /Volumes/gfortran gfortran.dmg
+ sudo installer -pkg /Volumes/gfortran/gfortran.pkg -target /
+ otool -L /usr/local/gfortran/lib/libgfortran.3.dylib
+
+ # arm64 stuff from gfortran_utils
+ if [[ $PLATFORM == "macosx-arm64" ]]; then
+ source $PROJECT_DIR/tools/wheels/gfortran_utils.sh
+ install_arm64_cross_gfortran
+ fi
+
+ # Manually symlink gfortran-4.9 to plain gfortran for f2py.
+ # No longer needed after Feb 13 2020 as gfortran is already present
+ # and the attempted link errors. Keep this for future reference.
+ # ln -s /usr/local/bin/gfortran-4.9 /usr/local/bin/gfortran
+fi
diff --git a/tools/wheels/cibw_test_command.sh b/tools/wheels/cibw_test_command.sh
new file mode 100644
index 000000000..b296993fc
--- /dev/null
+++ b/tools/wheels/cibw_test_command.sh
@@ -0,0 +1,19 @@
+# This script is used by .github/workflows/wheels.yml to build wheels with
+# cibuildwheel. It runs the full test suite, checks for lincense inclusion
+# and that the openblas version is correct.
+set -xe
+
+PROJECT_DIR="$1"
+
+python -c "import numpy; numpy.show_config()"
+if [[ $RUNNER_OS == "Windows" ]]; then
+ # GH 20391
+ PY_DIR=$(python -c "import sys; print(sys.prefix)")
+ mkdir $PY_DIR/libs
+fi
+python -c "import sys; import numpy; sys.exit(not numpy.test('full', extra_argv=['-vvv']))"
+
+python $PROJECT_DIR/tools/wheels/check_license.py
+if [[ $UNAME == "Linux" || $UNAME == "Darwin" ]] ; then
+ python $PROJECT_DIR/tools/openblas_support.py --check_version
+fi
diff --git a/tools/wheels/gfortran_utils.sh b/tools/wheels/gfortran_utils.sh
new file mode 100644
index 000000000..e0c7054a5
--- /dev/null
+++ b/tools/wheels/gfortran_utils.sh
@@ -0,0 +1,168 @@
+# This file is vendored from github.com/MacPython/gfortran-install It is
+# licensed under BSD-2 which is copied as a comment below
+
+# Copyright 2016-2021 Matthew Brett, Isuru Fernando, Matti Picus
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+
+# Redistributions in binary form must reproduce the above copyright notice, this
+# list of conditions and the following disclaimer in the documentation and/or
+# other materials provided with the distribution.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Bash utilities for use with gfortran
+
+GF_LIB_URL="https://3f23b170c54c2533c070-1c8a9b3114517dc5fe17b7c3f8c63a43.ssl.cf2.rackcdn.com"
+ARCHIVE_SDIR="${ARCHIVE_SDIR:-archives}"
+
+GF_UTIL_DIR=$(dirname "${BASH_SOURCE[0]}")
+
+function get_distutils_platform {
+ # Report platform as in form of distutils get_platform.
+ # This is like the platform tag that pip will use.
+ # Modify fat architecture tags on macOS to reflect compiled architecture
+
+ # Deprecate this function once get_distutils_platform_ex is used in all
+ # downstream projects
+ local plat=$1
+ case $plat in
+ i686|x86_64|arm64|universal2|intel|aarch64|s390x|ppc64le) ;;
+ *) echo Did not recognize plat $plat; return 1 ;;
+ esac
+ local uname=${2:-$(uname)}
+ if [ "$uname" != "Darwin" ]; then
+ if [ "$plat" == "intel" ]; then
+ echo plat=intel not allowed for Manylinux
+ return 1
+ fi
+ echo "manylinux1_$plat"
+ return
+ fi
+ # macOS 32-bit arch is i386
+ [ "$plat" == "i686" ] && plat="i386"
+ local target=$(echo $MACOSX_DEPLOYMENT_TARGET | tr .- _)
+ echo "macosx_${target}_${plat}"
+}
+
+function get_distutils_platform_ex {
+ # Report platform as in form of distutils get_platform.
+ # This is like the platform tag that pip will use.
+ # Modify fat architecture tags on macOS to reflect compiled architecture
+ # For non-darwin, report manylinux version
+ local plat=$1
+ local mb_ml_ver=${MB_ML_VER:-1}
+ case $plat in
+ i686|x86_64|arm64|universal2|intel|aarch64|s390x|ppc64le) ;;
+ *) echo Did not recognize plat $plat; return 1 ;;
+ esac
+ local uname=${2:-$(uname)}
+ if [ "$uname" != "Darwin" ]; then
+ if [ "$plat" == "intel" ]; then
+ echo plat=intel not allowed for Manylinux
+ return 1
+ fi
+ echo "manylinux${mb_ml_ver}_${plat}"
+ return
+ fi
+ # macOS 32-bit arch is i386
+ [ "$plat" == "i686" ] && plat="i386"
+ local target=$(echo $MACOSX_DEPLOYMENT_TARGET | tr .- _)
+ echo "macosx_${target}_${plat}"
+}
+
+function get_macosx_target {
+ # Report MACOSX_DEPLOYMENT_TARGET as given by distutils get_platform.
+ python -c "import sysconfig as s; print(s.get_config_vars()['MACOSX_DEPLOYMENT_TARGET'])"
+}
+
+function check_gfortran {
+ # Check that gfortran exists on the path
+ if [ -z "$(which gfortran)" ]; then
+ echo Missing gfortran
+ exit 1
+ fi
+}
+
+function get_gf_lib_for_suf {
+ local suffix=$1
+ local prefix=$2
+ local plat=${3:-$PLAT}
+ local uname=${4:-$(uname)}
+ if [ -z "$prefix" ]; then echo Prefix not defined; exit 1; fi
+ local plat_tag=$(get_distutils_platform_ex $plat $uname)
+ if [ -n "$suffix" ]; then suffix="-$suffix"; fi
+ local fname="$prefix-${plat_tag}${suffix}.tar.gz"
+ local out_fname="${ARCHIVE_SDIR}/$fname"
+ if [ ! -e "$out_fname" ]; then
+ curl -L "${GF_LIB_URL}/$fname" > $out_fname || (echo "Fetch of $out_fname failed"; exit 1)
+ fi
+ [ -s $out_fname ] || (echo "$out_fname is empty"; exit 24)
+ echo "$out_fname"
+}
+
+if [ "$(uname)" == "Darwin" ]; then
+ mac_target=${MACOSX_DEPLOYMENT_TARGET:-$(get_macosx_target)}
+ export MACOSX_DEPLOYMENT_TARGET=$mac_target
+ GFORTRAN_DMG="${GF_UTIL_DIR}/archives/gfortran-4.9.0-Mavericks.dmg"
+ export GFORTRAN_SHA="$(shasum $GFORTRAN_DMG)"
+
+ function install_arm64_cross_gfortran {
+ curl -L -O https://github.com/isuruf/gcc/releases/download/gcc-10-arm-20210228/gfortran-darwin-arm64.tar.gz
+ export GFORTRAN_SHA=f26990f6f08e19b2ec150b9da9d59bd0558261dd
+ if [[ "$(shasum gfortran-darwin-arm64.tar.gz)" != "${GFORTRAN_SHA} gfortran-darwin-arm64.tar.gz" ]]; then
+ echo "shasum mismatch for gfortran-darwin-arm64"
+ exit 1
+ fi
+ sudo mkdir -p /opt/
+ sudo cp "gfortran-darwin-arm64.tar.gz" /opt/gfortran-darwin-arm64.tar.gz
+ pushd /opt
+ sudo tar -xvf gfortran-darwin-arm64.tar.gz
+ sudo rm gfortran-darwin-arm64.tar.gz
+ popd
+ export FC_ARM64="$(find /opt/gfortran-darwin-arm64/bin -name "*-gfortran")"
+ local libgfortran="$(find /opt/gfortran-darwin-arm64/lib -name libgfortran.dylib)"
+ local libdir=$(dirname $libgfortran)
+
+ export FC_ARM64_LDFLAGS="-L$libdir -Wl,-rpath,$libdir"
+ if [[ "${PLAT:-}" == "arm64" ]]; then
+ export FC=$FC_ARM64
+ fi
+ }
+ function install_gfortran {
+ hdiutil attach -mountpoint /Volumes/gfortran $GFORTRAN_DMG
+ sudo installer -pkg /Volumes/gfortran/gfortran.pkg -target /
+ check_gfortran
+ if [[ "${PLAT:-}" == "universal2" || "${PLAT:-}" == "arm64" ]]; then
+ install_arm64_cross_gfortran
+ fi
+ }
+
+ function get_gf_lib {
+ # Get lib with gfortran suffix
+ get_gf_lib_for_suf "gf_${GFORTRAN_SHA:0:7}" $@
+ }
+else
+ function install_gfortran {
+ # No-op - already installed on manylinux image
+ check_gfortran
+ }
+
+ function get_gf_lib {
+ # Get library with no suffix
+ get_gf_lib_for_suf "" $@
+ }
+fi
diff --git a/tools/wheels/upload_wheels.sh b/tools/wheels/upload_wheels.sh
new file mode 100644
index 000000000..46532a5f0
--- /dev/null
+++ b/tools/wheels/upload_wheels.sh
@@ -0,0 +1,58 @@
+set_travis_vars() {
+ # Set env vars
+ echo "TRAVIS_EVENT_TYPE is $TRAVIS_EVENT_TYPE"
+ echo "TRAVIS_TAG is $TRAVIS_TAG"
+ if [[ "$TRAVIS_EVENT_TYPE" == "push" && "$TRAVIS_TAG" == v* ]]; then
+ IS_PUSH="true"
+ else
+ IS_PUSH="false"
+ fi
+ if [[ "$TRAVIS_EVENT_TYPE" == "cron" ]]; then
+ IS_SCHEDULE_DISPATCH="true"
+ elif [[ "$TRAVIS_EVENT_TYPE" == "api" ]]; then
+ # Manual CI run, so upload
+ IS_SCHEDULE_DISPATCH="true"
+ else
+ IS_SCHEDULE_DISPATCH="false"
+ fi
+}
+set_upload_vars() {
+ echo "IS_PUSH is $IS_PUSH"
+ echo "IS_SCHEDULE_DISPATCH is $IS_SCHEDULE_DISPATCH"
+ if [[ "$IS_PUSH" == "true" ]]; then
+ echo push and tag event
+ export ANACONDA_ORG="multibuild-wheels-staging"
+ export TOKEN="$NUMPY_STAGING_UPLOAD_TOKEN"
+ export ANACONDA_UPLOAD="true"
+ elif [[ "$IS_SCHEDULE_DISPATCH" == "true" ]]; then
+ echo scheduled or dispatched event
+ export ANACONDA_ORG="scipy-wheels-nightly"
+ export TOKEN="$NUMPY_NIGHTLY_UPLOAD_TOKEN"
+ export ANACONDA_UPLOAD="true"
+ else
+ echo non-dispatch event
+ export ANACONDA_UPLOAD="false"
+ fi
+}
+upload_wheels() {
+ echo ${PWD}
+ if [[ ${ANACONDA_UPLOAD} == true ]]; then
+ if [ -z ${TOKEN} ]; then
+ echo no token set, not uploading
+ else
+ python -m pip install git+https://github.com/Anaconda-Server/anaconda-client
+ # sdists are located under dist folder when built through setup.py
+ if compgen -G "./dist/*.gz"; then
+ echo "Found sdist"
+ anaconda -t ${TOKEN} upload --skip -u ${ANACONDA_ORG} ./dist/*.gz
+ elif compgen -G "./wheelhouse/*.whl"; then
+ echo "Found wheel"
+ anaconda -t ${TOKEN} upload --skip -u ${ANACONDA_ORG} ./wheelhouse/*.whl
+ else
+ echo "Files do not exist"
+ return 1
+ fi
+ echo "PyPI-style index: https://pypi.anaconda.org/$ANACONDA_ORG/simple"
+ fi
+ fi
+}