|
| 1 | +# Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. |
| 2 | +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| 3 | +# |
| 4 | +# The Universal Permissive License (UPL), Version 1.0 |
| 5 | +# |
| 6 | +# Subject to the condition set forth below, permission is hereby granted to any |
| 7 | +# person obtaining a copy of this software, associated documentation and/or |
| 8 | +# data (collectively the "Software"), free of charge and under any and all |
| 9 | +# copyright rights in the Software, and any and all patent rights owned or |
| 10 | +# freely licensable by each licensor hereunder covering either (i) the |
| 11 | +# unmodified Software as contributed to or provided by such licensor, or (ii) |
| 12 | +# the Larger Works (as defined below), to deal in both |
| 13 | +# |
| 14 | +# (a) the Software, and |
| 15 | +# |
| 16 | +# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if |
| 17 | +# one is included with the Software each a "Larger Work" to which the Software |
| 18 | +# is contributed by such licensors), |
| 19 | +# |
| 20 | +# without restriction, including without limitation the rights to copy, create |
| 21 | +# derivative works of, display, perform, and distribute the Software and make, |
| 22 | +# use, sell, offer for sale, import, export, have made, and have sold the |
| 23 | +# Software and the Larger Work(s), and to sublicense the foregoing rights on |
| 24 | +# either these or other terms. |
| 25 | +# |
| 26 | +# This license is subject to the following condition: |
| 27 | +# |
| 28 | +# The above copyright notice and either this complete permission notice or at a |
| 29 | +# minimum a reference to the UPL must be included in all copies or substantial |
| 30 | +# portions of the Software. |
| 31 | +# |
| 32 | +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 33 | +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 34 | +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 35 | +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 36 | +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 37 | +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 38 | +# SOFTWARE. |
| 39 | + |
| 40 | +import argparse |
| 41 | +import json |
| 42 | +import os |
| 43 | +import subprocess |
| 44 | +import sys |
| 45 | +import tempfile |
| 46 | +import zipfile |
| 47 | + |
| 48 | + |
| 49 | +def system(cmd, msg=""): |
| 50 | + status = os.system(cmd) |
| 51 | + if status != 0: |
| 52 | + xit(msg, status=status) |
| 53 | + |
| 54 | + |
| 55 | +def known_packages(): |
| 56 | + def setuptools(): |
| 57 | + install_from_pypi("setuptools") |
| 58 | + |
| 59 | + def numpy(): |
| 60 | + url = "https://files.pythonhosted.org/packages/b0/2b/497c2bb7c660b2606d4a96e2035e92554429e139c6c71cdff67af66b58d2/numpy-1.14.3.zip" |
| 61 | + tempdir = tempfile.mkdtemp() |
| 62 | + system("curl -o %s/numpy-1.14.3.zip %s" % (tempdir, url)) |
| 63 | + system("unzip -u %s/numpy-1.14.3.zip -d %s" % (tempdir, tempdir)) |
| 64 | + |
| 65 | + patch = """ |
| 66 | +From 1842b6b02557d824692a32bb623b8e74eb7989d3 Mon Sep 17 00:00:00 2001 |
| 67 | +From: Tim Felgentreff <[email protected]> |
| 68 | +Date: Wed, 20 Jun 2018 18:01:30 +0200 |
| 69 | +Subject: PATCH |
| 70 | +
|
| 71 | +--- |
| 72 | + numpy/core/getlimits.py | 150 ++++++++++++++++++++++++------------------------ |
| 73 | + 1 file changed, 75 insertions(+), 75 deletions(-) |
| 74 | +
|
| 75 | +diff --git a/setup.py 2018-02-28 17:03:26.000000000 +0100 |
| 76 | +index e450a66..ed538b4 100644 |
| 77 | +--- a/setup.py |
| 78 | ++++ b/setup.py |
| 79 | +@@ -348,6 +348,8 @@ |
| 80 | + metadata = dict( |
| 81 | + name = 'numpy', |
| 82 | + maintainer = "NumPy Developers", |
| 83 | ++ zip_safe = False, # Truffle: make sure we're not zipped |
| 84 | ++ include_package_data = True, |
| 85 | + maintainer_email = "[email protected]", |
| 86 | + description = DOCLINES[0], |
| 87 | + long_description = "\n".join(DOCLINES[2:]), |
| 88 | +
|
| 89 | +
|
| 90 | +diff --git a/numpy/ctypeslib.py 2018-02-28 17:03:26.000000000 +0100 |
| 91 | +index e450a66..ed538b4 100644 |
| 92 | +--- a/numpy/ctypeslib.py |
| 93 | ++++ b/numpy/ctypeslib.py |
| 94 | +@@ -59,6 +59,6 @@ |
| 95 | + from numpy.core.multiarray import _flagdict, flagsobj |
| 96 | +
|
| 97 | + try: |
| 98 | +- import ctypes |
| 99 | ++ ctypes = None # Truffle: use the mock ctypes |
| 100 | + except ImportError: |
| 101 | + ctypes = None |
| 102 | +
|
| 103 | +
|
| 104 | +
|
| 105 | +diff --git a/numpy/core/include/numpy/ndarraytypes.h 2018-02-28 17:03:26.000000000 +0100 |
| 106 | +index e450a66..ed538b4 100644 |
| 107 | +--- a/numpy/core/include/numpy/ndarraytypes.h |
| 108 | ++++ b/numpy/core/include/numpy/ndarraytypes.h |
| 109 | +@@ -407,6 +407,6 @@ |
| 110 | + typedef int (PyArray_FromStrFunc)(char *s, void *dptr, char **endptr, |
| 111 | + struct _PyArray_Descr *); |
| 112 | +
|
| 113 | +-typedef int (PyArray_FillFunc)(void *, npy_intp, void *); |
| 114 | ++typedef void (PyArray_FillFunc)(void *, npy_intp, void *); |
| 115 | +
|
| 116 | + typedef int (PyArray_SortFunc)(void *, npy_intp, void *); |
| 117 | + typedef int (PyArray_ArgSortFunc)(void *, npy_intp *, npy_intp, void *); |
| 118 | +
|
| 119 | +
|
| 120 | +diff --git a/numpy/linalg/setup.py 2018-02-28 17:03:26.000000000 +0100 |
| 121 | +index e450a66..ed538b4 100644 |
| 122 | +--- a/numpy/linalg/setup.py |
| 123 | ++++ b/numpy/linalg/setup.py |
| 124 | +@@ -29,6 +29,7 @@ |
| 125 | + lapack_info = get_info('lapack_opt', 0) # and {} |
| 126 | +
|
| 127 | + def get_lapack_lite_sources(ext, build_dir): |
| 128 | ++ return all_sources |
| 129 | + if not lapack_info: |
| 130 | + print("### Warning: Using unoptimized lapack ###") |
| 131 | + return all_sources |
| 132 | +
|
| 133 | +
|
| 134 | +diff --git a/numpy/core/getlimits.py b/numpy/core/getlimits.py |
| 135 | +index e450a66..ed538b4 100644 |
| 136 | +--- a/numpy/core/getlimits.py |
| 137 | ++++ b/numpy/core/getlimits.py |
| 138 | +@@ -160,70 +160,70 @@ _float64_ma = MachArLike(_f64, |
| 139 | + huge=(1.0 - _epsneg_f64) / _tiny_f64 * _f64(4), |
| 140 | + tiny=_tiny_f64) |
| 141 | +
|
| 142 | +-# Known parameters for IEEE 754 128-bit binary float |
| 143 | +-_ld = ntypes.longdouble |
| 144 | +-_epsneg_f128 = exp2(_ld(-113)) |
| 145 | +-_tiny_f128 = exp2(_ld(-16382)) |
| 146 | +-# Ignore runtime error when this is not f128 |
| 147 | +-with numeric.errstate(all='ignore'): |
| 148 | +- _huge_f128 = (_ld(1) - _epsneg_f128) / _tiny_f128 * _ld(4) |
| 149 | +-_float128_ma = MachArLike(_ld, |
| 150 | +- machep=-112, |
| 151 | +- negep=-113, |
| 152 | +- minexp=-16382, |
| 153 | +- maxexp=16384, |
| 154 | +- it=112, |
| 155 | +- iexp=15, |
| 156 | +- ibeta=2, |
| 157 | +- irnd=5, |
| 158 | +- ngrd=0, |
| 159 | +- eps=exp2(_ld(-112)), |
| 160 | +- epsneg=_epsneg_f128, |
| 161 | +- huge=_huge_f128, |
| 162 | +- tiny=_tiny_f128) |
| 163 | +- |
| 164 | +-# Known parameters for float80 (Intel 80-bit extended precision) |
| 165 | +-_epsneg_f80 = exp2(_ld(-64)) |
| 166 | +-_tiny_f80 = exp2(_ld(-16382)) |
| 167 | +-# Ignore runtime error when this is not f80 |
| 168 | +-with numeric.errstate(all='ignore'): |
| 169 | +- _huge_f80 = (_ld(1) - _epsneg_f80) / _tiny_f80 * _ld(4) |
| 170 | +-_float80_ma = MachArLike(_ld, |
| 171 | +- machep=-63, |
| 172 | +- negep=-64, |
| 173 | +- minexp=-16382, |
| 174 | +- maxexp=16384, |
| 175 | +- it=63, |
| 176 | +- iexp=15, |
| 177 | +- ibeta=2, |
| 178 | +- irnd=5, |
| 179 | +- ngrd=0, |
| 180 | +- eps=exp2(_ld(-63)), |
| 181 | +- epsneg=_epsneg_f80, |
| 182 | +- huge=_huge_f80, |
| 183 | +- tiny=_tiny_f80) |
| 184 | +- |
| 185 | +-# Guessed / known parameters for double double; see: |
| 186 | +-# https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format#Double-double_arithmetic |
| 187 | +-# These numbers have the same exponent range as float64, but extended number of |
| 188 | +-# digits in the significand. |
| 189 | +-_huge_dd = (umath.nextafter(_ld(inf), _ld(0)) |
| 190 | +- if hasattr(umath, 'nextafter') # Missing on some platforms? |
| 191 | +- else _float64_ma.huge) |
| 192 | +-_float_dd_ma = MachArLike(_ld, |
| 193 | +- machep=-105, |
| 194 | +- negep=-106, |
| 195 | +- minexp=-1022, |
| 196 | +- maxexp=1024, |
| 197 | +- it=105, |
| 198 | +- iexp=11, |
| 199 | +- ibeta=2, |
| 200 | +- irnd=5, |
| 201 | +- ngrd=0, |
| 202 | +- eps=exp2(_ld(-105)), |
| 203 | +- epsneg= exp2(_ld(-106)), |
| 204 | +- huge=_huge_dd, |
| 205 | +- tiny=exp2(_ld(-1022))) |
| 206 | ++# # Known parameters for IEEE 754 128-bit binary float |
| 207 | ++# _ld = ntypes.longdouble |
| 208 | ++# _epsneg_f128 = exp2(_ld(-113)) |
| 209 | ++# _tiny_f128 = exp2(_ld(-16382)) |
| 210 | ++# # Ignore runtime error when this is not f128 |
| 211 | ++# with numeric.errstate(all='ignore'): |
| 212 | ++# _huge_f128 = (_ld(1) - _epsneg_f128) / _tiny_f128 * _ld(4) |
| 213 | ++# _float128_ma = MachArLike(_ld, |
| 214 | ++# machep=-112, |
| 215 | ++# negep=-113, |
| 216 | ++# minexp=-16382, |
| 217 | ++# maxexp=16384, |
| 218 | ++# it=112, |
| 219 | ++# iexp=15, |
| 220 | ++# ibeta=2, |
| 221 | ++# irnd=5, |
| 222 | ++# ngrd=0, |
| 223 | ++# eps=exp2(_ld(-112)), |
| 224 | ++# epsneg=_epsneg_f128, |
| 225 | ++# huge=_huge_f128, |
| 226 | ++# tiny=_tiny_f128) |
| 227 | ++ |
| 228 | ++# # Known parameters for float80 (Intel 80-bit extended precision) |
| 229 | ++# _epsneg_f80 = exp2(_ld(-64)) |
| 230 | ++# _tiny_f80 = exp2(_ld(-16382)) |
| 231 | ++# # Ignore runtime error when this is not f80 |
| 232 | ++# with numeric.errstate(all='ignore'): |
| 233 | ++# _huge_f80 = (_ld(1) - _epsneg_f80) / _tiny_f80 * _ld(4) |
| 234 | ++# _float80_ma = MachArLike(_ld, |
| 235 | ++# machep=-63, |
| 236 | ++# negep=-64, |
| 237 | ++# minexp=-16382, |
| 238 | ++# maxexp=16384, |
| 239 | ++# it=63, |
| 240 | ++# iexp=15, |
| 241 | ++# ibeta=2, |
| 242 | ++# irnd=5, |
| 243 | ++# ngrd=0, |
| 244 | ++# eps=exp2(_ld(-63)), |
| 245 | ++# epsneg=_epsneg_f80, |
| 246 | ++# huge=_huge_f80, |
| 247 | ++# tiny=_tiny_f80) |
| 248 | ++ |
| 249 | ++# # Guessed / known parameters for double double; see: |
| 250 | ++# # https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format#Double-double_arithmetic |
| 251 | ++# # These numbers have the same exponent range as float64, but extended number of |
| 252 | ++# # digits in the significand. |
| 253 | ++# _huge_dd = (umath.nextafter(_ld(inf), _ld(0)) |
| 254 | ++# if hasattr(umath, 'nextafter') # Missing on some platforms? |
| 255 | ++# else _float64_ma.huge) |
| 256 | ++# _float_dd_ma = MachArLike(_ld, |
| 257 | ++# machep=-105, |
| 258 | ++# negep=-106, |
| 259 | ++# minexp=-1022, |
| 260 | ++# maxexp=1024, |
| 261 | ++# it=105, |
| 262 | ++# iexp=11, |
| 263 | ++# ibeta=2, |
| 264 | ++# irnd=5, |
| 265 | ++# ngrd=0, |
| 266 | ++# eps=exp2(_ld(-105)), |
| 267 | ++# epsneg= exp2(_ld(-106)), |
| 268 | ++# huge=_huge_dd, |
| 269 | ++# tiny=exp2(_ld(-1022))) |
| 270 | +
|
| 271 | +
|
| 272 | + # Key to identify the floating point type. Key is result of |
| 273 | +@@ -234,17 +234,17 @@ _KNOWN_TYPES = { |
| 274 | + b'\\x9a\\x99\\x99\\x99\\x99\\x99\\xb9\\xbf' : _float64_ma, |
| 275 | + b'\\xcd\\xcc\\xcc\\xbd' : _float32_ma, |
| 276 | + b'f\\xae' : _float16_ma, |
| 277 | +- # float80, first 10 bytes containing actual storage |
| 278 | +- b'\\xcd\\xcc\\xcc\\xcc\\xcc\\xcc\\xcc\\xcc\\xfb\\xbf' : _float80_ma, |
| 279 | +- # double double; low, high order (e.g. PPC 64) |
| 280 | +- b'\\x9a\\x99\\x99\\x99\\x99\\x99Y<\\x9a\\x99\\x99\\x99\\x99\\x99\\xb9\\xbf' : |
| 281 | +- _float_dd_ma, |
| 282 | +- # double double; high, low order (e.g. PPC 64 le) |
| 283 | +- b'\\x9a\\x99\\x99\\x99\\x99\\x99\\xb9\\xbf\\x9a\\x99\\x99\\x99\\x99\\x99Y<' : |
| 284 | +- _float_dd_ma, |
| 285 | +- # IEEE 754 128-bit binary float |
| 286 | +- b'\\x9a\\x99\\x99\\x99\\x99\\x99\\x99\\x99\\x99\\x99\\x99\\x99\\x99\\x99\\xfb\\xbf' : |
| 287 | +- _float128_ma, |
| 288 | ++ # # float80, first 10 bytes containing actual storage |
| 289 | ++ # b'\\xcd\\xcc\\xcc\\xcc\\xcc\\xcc\\xcc\\xcc\\xfb\\xbf' : _float80_ma, |
| 290 | ++ # # double double; low, high order (e.g. PPC 64) |
| 291 | ++ # b'\\x9a\\x99\\x99\\x99\\x99\\x99Y<\\x9a\\x99\\x99\\x99\\x99\\x99\\xb9\\xbf' : |
| 292 | ++ # _float_dd_ma, |
| 293 | ++ # # double double; high, low order (e.g. PPC 64 le) |
| 294 | ++ # b'\\x9a\\x99\\x99\\x99\\x99\\x99\\xb9\\xbf\\x9a\\x99\\x99\\x99\\x99\\x99Y<' : |
| 295 | ++ # _float_dd_ma, |
| 296 | ++ # # IEEE 754 128-bit binary float |
| 297 | ++ # b'\\x9a\\x99\\x99\\x99\\x99\\x99\\x99\\x99\\x99\\x99\\x99\\x99\\x99\\x99\\xfb\\xbf' : |
| 298 | ++ # _float128_ma, |
| 299 | + } |
| 300 | +
|
| 301 | +
|
| 302 | +-- |
| 303 | +2.14.1 |
| 304 | +
|
| 305 | +""" |
| 306 | + with open("%s/numpy.patch" % tempdir, "w") as f: |
| 307 | + f.write(patch) |
| 308 | + system("patch -d %s/numpy-1.14.3/ -p1 < %s/numpy.patch" % (tempdir, tempdir)) |
| 309 | + system("cd %s/numpy-1.14.3; %s setup.py install --user" % (tempdir, sys.executable)) |
| 310 | + |
| 311 | + |
| 312 | + return locals() |
| 313 | + |
| 314 | + |
| 315 | +KNOWN_PACKAGES = known_packages() |
| 316 | + |
| 317 | + |
| 318 | +def xit(str, status=-1): |
| 319 | + print(msg) |
| 320 | + exit(-1) |
| 321 | + |
| 322 | + |
| 323 | +def install_from_pypi(package): |
| 324 | + url = None |
| 325 | + r = subprocess.check_output("curl https://pypi.org/pypi/%s/json" % package, shell=True).decode("utf8") |
| 326 | + try: |
| 327 | + urls = json.loads(r)["urls"] |
| 328 | + except: |
| 329 | + pass |
| 330 | + else: |
| 331 | + for url_info in urls: |
| 332 | + if url_info["python_version"] == "source": |
| 333 | + url = url_info["url"] |
| 334 | + break |
| 335 | + |
| 336 | + if url: |
| 337 | + tempdir = tempfile.mkdtemp() |
| 338 | + filename = url.rpartition("/")[2] |
| 339 | + status = os.system("curl -L -o %s/%s %s" % (tempdir, filename, url)) |
| 340 | + if status != 0: |
| 341 | + xit("Download error", status=status) |
| 342 | + dirname = None |
| 343 | + if filename.endswith(".zip"): |
| 344 | + with zipfile.ZipFile("%s/%s" % (tempdir, filename), 'r') as zf: |
| 345 | + zf.extractall(tempdir) |
| 346 | + dirname = filename[:-4] |
| 347 | + elif filename.endswith(".tar.gz"): |
| 348 | + status = os.system("tar -C %s -xzf %s/%s" % (tempdir, tempdir, filename)) |
| 349 | + if status != 0: |
| 350 | + xit("Error during extraction", status=status) |
| 351 | + dirname = filename[:-7] |
| 352 | + elif filename.endswith(".tar.bz2"): |
| 353 | + status = os.system("tar -C %s -xjf %s/%s" % (tempdir, tempdir, filename)) |
| 354 | + if status != 0: |
| 355 | + xit("Error during extraction", status=status) |
| 356 | + dirname = filename[:-7] |
| 357 | + else: |
| 358 | + xit("Unknown file type: %s" % filename) |
| 359 | + |
| 360 | + status = os.system("cd %s/%s; %s setup.py install --user" % (tempdir, dirname, sys.executable)) |
| 361 | + if status != 0: |
| 362 | + xit("An error occurred trying to run `setup.py install --user'") |
| 363 | + else: |
| 364 | + xit("Package not found: '%s'" % package) |
| 365 | + |
| 366 | + |
| 367 | +def main(argv): |
| 368 | + parser = argparse.ArgumentParser() |
| 369 | + parser.add_argument("--list", action="store_true", help="list known packages with potential workarounds available for installation") |
| 370 | + parser.add_argument("--install", help="install a known package") |
| 371 | + parser.add_argument("--pypi", help="attempt to install a package from PyPI (untested, likely won't work, it'll only try the latest version, and it won't install dependencies for you)") |
| 372 | + args, _ = parser.parse_known_args(argv) |
| 373 | + if args.list: |
| 374 | + print(list(KNOWN_PACKAGES.keys())) |
| 375 | + elif args.install: |
| 376 | + if args.install not in KNOWN_PACKAGES: |
| 377 | + xit("Unknown package: '%s'" % args.install) |
| 378 | + else: |
| 379 | + KNOWN_PACKAGES[args.install]() |
| 380 | + elif args.pypi: |
| 381 | + install_from_pypi(args.pypi) |
| 382 | + |
| 383 | + |
| 384 | + |
| 385 | +if __name__ == "__main__": |
| 386 | + main(sys.argv) |
0 commit comments