Пример #1
0
def gfortran_legacy_flag_hook(cmd, ext):
    """
    Pre-build hook to add dd gfortran legacy flag -fallow-argument-mismatch
    """
    from .compiler_helper import try_add_flag
    from scipy._lib import _pep440

    if isinstance(ext, dict):
        # build_clib
        compilers = ((cmd._f_compiler, ext.setdefault('extra_f77_compile_args', [])),
                      (cmd._f_compiler, ext.setdefault('extra_f90_compile_args', [])))
    else:
        # build_ext
        compilers = ((cmd._f77_compiler, ext.extra_f77_compile_args),
                     (cmd._f90_compiler, ext.extra_f90_compile_args))

    for compiler, args in compilers:
        if compiler is None:
            continue

        if (compiler.compiler_type == "gnu95" and
        _pep440.parse(str(compiler.version)) >= _pep440.Version("10")):
            try_add_flag(args, compiler, "-fallow-argument-mismatch")
Пример #2
0
                if isinstance(value, (list, tuple)):
                    if isinstance(old_value, (list, tuple)):
                        new_dict[key] = list(old_value) + list(value)
                        continue
                elif value == old_value:
                    continue

                raise ValueError("Conflicting configuration dicts: {!r} {!r}"
                                 "".format(new_dict, d))
            else:
                new_dict[key] = value

    return new_dict


if _pep440.parse(np.__version__) >= _pep440.Version("1.15.0.dev"):
    # For new enough numpy.distutils, the ACCELERATE=None environment
    # variable in the top-level setup.py is enough, so no need to
    # customize BLAS detection.
    print("We are in the modern numpy, get_info = old_get_info")
    get_info = old_get_info
else:
    # For NumPy < 1.15.0, we need overrides.

    def get_info(name, notfound_action=0):
        print("old numpy: ", np.__version__)
        # Special case our custom *_opt_info.
        cls = {'lapack_opt': lapack_opt_info,
               'blas_opt': blas_opt_info}.get(name.lower())
        if cls is None:
            return old_get_info(name, notfound_action)
Пример #3
0
        msg = """Error importing SciPy: you cannot import SciPy while
        being in scipy source directory; please exit the SciPy source
        tree first and relaunch your Python interpreter."""
        raise ImportError(msg) from e

    from scipy.version import version as __version__

    # Allow distributors to run custom init code
    from . import _distributor_init

    from scipy._lib import _pep440
    # In maintenance branch, change to np_maxversion N+3 if numpy is at N
    # See setup.py for more details
    np_minversion = '1.18.5'
    np_maxversion = '9.9.99'
    if (_pep440.parse(__numpy_version__) < _pep440.Version(np_minversion)
            or _pep440.parse(__numpy_version__) >=
            _pep440.Version(np_maxversion)):
        import warnings
        warnings.warn(
            f"A NumPy version >={np_minversion} and <{np_maxversion}"
            f" is required for this version of SciPy (detected "
            f"version {__numpy_version__}", UserWarning)

    del _pep440

    from scipy._lib._ccallback import LowLevelCallable

    from scipy._lib._testutils import PytestTester
    test = PytestTester(__name__)
    del PytestTester
Пример #4
0
else:
    try:
        from scipy.__config__ import show as show_config
    except ImportError as e:
        msg = """Error importing SciPy: you cannot import SciPy while
        being in scipy source directory; please exit the SciPy source
        tree first and relaunch your Python interpreter."""
        raise ImportError(msg) from e

    from scipy.version import version as __version__

    # Allow distributors to run custom init code
    from . import _distributor_init

    from scipy._lib import _pep440
    if _pep440.parse(__numpy_version__) < _pep440.Version('1.16.5'):
        import warnings
        warnings.warn("NumPy 1.16.5 or above is required for this version of "
                      "SciPy (detected version %s)" % __numpy_version__,
                      UserWarning)

    del _pep440

    from scipy._lib._ccallback import LowLevelCallable

    from scipy._lib._testutils import PytestTester
    test = PytestTester(__name__)
    del PytestTester

    # This makes "from scipy import fft" return scipy.fft, not np.fft
    del fft
class TestInterop(object):
    #
    # Test that FITPACK-based spl* functions can deal with BSpline objects
    #
    def setup_method(self):
        xx = np.linspace(0, 4. * np.pi, 41)
        yy = np.cos(xx)
        b = make_interp_spline(xx, yy)
        self.tck = (b.t, b.c, b.k)
        self.xx, self.yy, self.b = xx, yy, b

        self.xnew = np.linspace(0, 4. * np.pi, 21)

        c2 = np.c_[b.c, b.c, b.c]
        self.c2 = np.dstack((c2, c2))
        self.b2 = BSpline(b.t, self.c2, b.k)

    def test_splev(self):
        xnew, b, b2 = self.xnew, self.b, self.b2

        # check that splev works with 1-D array of coefficients
        # for array and scalar `x`
        assert_allclose(splev(xnew, b), b(xnew), atol=1e-15, rtol=1e-15)
        assert_allclose(splev(xnew, b.tck), b(xnew), atol=1e-15, rtol=1e-15)
        assert_allclose([splev(x, b) for x in xnew],
                        b(xnew),
                        atol=1e-15,
                        rtol=1e-15)

        # With N-D coefficients, there's a quirck:
        # splev(x, BSpline) is equivalent to BSpline(x)
        with suppress_warnings() as sup:
            sup.filter(
                DeprecationWarning,
                "Calling splev.. with BSpline objects with c.ndim > 1 is not recommended."
            )
            assert_allclose(splev(xnew, b2), b2(xnew), atol=1e-15, rtol=1e-15)

        # However, splev(x, BSpline.tck) needs some transposes. This is because
        # BSpline interpolates along the first axis, while the legacy FITPACK
        # wrapper does list(map(...)) which effectively interpolates along the
        # last axis. Like so:
        sh = tuple(range(1, b2.c.ndim)) + (0, )  # sh = (1, 2, 0)
        cc = b2.c.transpose(sh)
        tck = (b2.t, cc, b2.k)
        assert_allclose(splev(xnew, tck),
                        b2(xnew).transpose(sh),
                        atol=1e-15,
                        rtol=1e-15)

    def test_splrep(self):
        x, y = self.xx, self.yy
        # test that "new" splrep is equivalent to _impl.splrep
        tck = splrep(x, y)
        t, c, k = _impl.splrep(x, y)
        assert_allclose(tck[0], t, atol=1e-15)
        assert_allclose(tck[1], c, atol=1e-15)
        assert_equal(tck[2], k)

        # also cover the `full_output=True` branch
        tck_f, _, _, _ = splrep(x, y, full_output=True)
        assert_allclose(tck_f[0], t, atol=1e-15)
        assert_allclose(tck_f[1], c, atol=1e-15)
        assert_equal(tck_f[2], k)

        # test that the result of splrep roundtrips with splev:
        # evaluate the spline on the original `x` points
        yy = splev(x, tck)
        assert_allclose(y, yy, atol=1e-15)

        # ... and also it roundtrips if wrapped in a BSpline
        b = BSpline(*tck)
        assert_allclose(y, b(x), atol=1e-15)

    @pytest.mark.xfail(
        _pep440.parse(np.__version__) < _pep440.Version('1.14.0'),
        reason='requires NumPy >= 1.14.0')
    def test_splrep_errors(self):
        # test that both "old" and "new" splrep raise for an N-D ``y`` array
        # with n > 1
        x, y = self.xx, self.yy
        y2 = np.c_[y, y]
        with assert_raises(ValueError):
            splrep(x, y2)
        with assert_raises(ValueError):
            _impl.splrep(x, y2)

        # input below minimum size
        with assert_raises(TypeError, match="m > k must hold"):
            splrep(x[:3], y[:3])
        with assert_raises(TypeError, match="m > k must hold"):
            _impl.splrep(x[:3], y[:3])

    def test_splprep(self):
        x = np.arange(15).reshape((3, 5))
        b, u = splprep(x)
        tck, u1 = _impl.splprep(x)

        # test the roundtrip with splev for both "old" and "new" output
        assert_allclose(u, u1, atol=1e-15)
        assert_allclose(splev(u, b), x, atol=1e-15)
        assert_allclose(splev(u, tck), x, atol=1e-15)

        # cover the ``full_output=True`` branch
        (b_f, u_f), _, _, _ = splprep(x, s=0, full_output=True)
        assert_allclose(u, u_f, atol=1e-15)
        assert_allclose(splev(u_f, b_f), x, atol=1e-15)

    def test_splprep_errors(self):
        # test that both "old" and "new" code paths raise for x.ndim > 2
        x = np.arange(3 * 4 * 5).reshape((3, 4, 5))
        with assert_raises(ValueError, match="too many values to unpack"):
            splprep(x)
        with assert_raises(ValueError, match="too many values to unpack"):
            _impl.splprep(x)

        # input below minimum size
        x = np.linspace(0, 40, num=3)
        with assert_raises(TypeError, match="m > k must hold"):
            splprep([x])
        with assert_raises(TypeError, match="m > k must hold"):
            _impl.splprep([x])

        # automatically calculated parameters are non-increasing
        # see gh-7589
        x = [-50.49072266, -50.49072266, -54.49072266, -54.49072266]
        with assert_raises(ValueError, match="Invalid inputs"):
            splprep([x])
        with assert_raises(ValueError, match="Invalid inputs"):
            _impl.splprep([x])

        # given non-increasing parameter values u
        x = [1, 3, 2, 4]
        u = [0, 0.3, 0.2, 1]
        with assert_raises(ValueError, match="Invalid inputs"):
            splprep(*[[x], None, u])

    def test_sproot(self):
        b, b2 = self.b, self.b2
        roots = np.array([0.5, 1.5, 2.5, 3.5]) * np.pi
        # sproot accepts a BSpline obj w/ 1-D coef array
        assert_allclose(sproot(b), roots, atol=1e-7, rtol=1e-7)
        assert_allclose(sproot((b.t, b.c, b.k)), roots, atol=1e-7, rtol=1e-7)

        # ... and deals with trailing dimensions if coef array is N-D
        with suppress_warnings() as sup:
            sup.filter(
                DeprecationWarning,
                "Calling sproot.. with BSpline objects with c.ndim > 1 is not recommended."
            )
            r = sproot(b2, mest=50)
        r = np.asarray(r)

        assert_equal(r.shape, (3, 2, 4))
        assert_allclose(r - roots, 0, atol=1e-12)

        # and legacy behavior is preserved for a tck tuple w/ N-D coef
        c2r = b2.c.transpose(1, 2, 0)
        rr = np.asarray(sproot((b2.t, c2r, b2.k), mest=50))
        assert_equal(rr.shape, (3, 2, 4))
        assert_allclose(rr - roots, 0, atol=1e-12)

    def test_splint(self):
        # test that splint accepts BSpline objects
        b, b2 = self.b, self.b2
        assert_allclose(splint(0, 1, b), splint(0, 1, b.tck), atol=1e-14)
        assert_allclose(splint(0, 1, b), b.integrate(0, 1), atol=1e-14)

        # ... and deals with N-D arrays of coefficients
        with suppress_warnings() as sup:
            sup.filter(
                DeprecationWarning,
                "Calling splint.. with BSpline objects with c.ndim > 1 is not recommended."
            )
            assert_allclose(splint(0, 1, b2), b2.integrate(0, 1), atol=1e-14)

        # and the legacy behavior is preserved for a tck tuple w/ N-D coef
        c2r = b2.c.transpose(1, 2, 0)
        integr = np.asarray(splint(0, 1, (b2.t, c2r, b2.k)))
        assert_equal(integr.shape, (3, 2))
        assert_allclose(integr, splint(0, 1, b), atol=1e-14)

    def test_splder(self):
        for b in [self.b, self.b2]:
            # pad the c array (FITPACK convention)
            ct = len(b.t) - len(b.c)
            if ct > 0:
                b.c = np.r_[b.c, np.zeros((ct, ) + b.c.shape[1:])]

            for n in [1, 2, 3]:
                bd = splder(b)
                tck_d = _impl.splder((b.t, b.c, b.k))
                assert_allclose(bd.t, tck_d[0], atol=1e-15)
                assert_allclose(bd.c, tck_d[1], atol=1e-15)
                assert_equal(bd.k, tck_d[2])
                assert_(isinstance(bd, BSpline))
                assert_(isinstance(tck_d,
                                   tuple))  # back-compat: tck in and out

    def test_splantider(self):
        for b in [self.b, self.b2]:
            # pad the c array (FITPACK convention)
            ct = len(b.t) - len(b.c)
            if ct > 0:
                b.c = np.r_[b.c, np.zeros((ct, ) + b.c.shape[1:])]

            for n in [1, 2, 3]:
                bd = splantider(b)
                tck_d = _impl.splantider((b.t, b.c, b.k))
                assert_allclose(bd.t, tck_d[0], atol=1e-15)
                assert_allclose(bd.c, tck_d[1], atol=1e-15)
                assert_equal(bd.k, tck_d[2])
                assert_(isinstance(bd, BSpline))
                assert_(isinstance(tck_d,
                                   tuple))  # back-compat: tck in and out

    def test_insert(self):
        b, b2, xx = self.b, self.b2, self.xx

        j = b.t.size // 2
        tn = 0.5 * (b.t[j] + b.t[j + 1])

        bn, tck_n = insert(tn, b), insert(tn, (b.t, b.c, b.k))
        assert_allclose(splev(xx, bn), splev(xx, tck_n), atol=1e-15)
        assert_(isinstance(bn, BSpline))
        assert_(isinstance(tck_n, tuple))  # back-compat: tck in, tck out

        # for N-D array of coefficients, BSpline.c needs to be transposed
        # after that, the results are equivalent.
        sh = tuple(range(b2.c.ndim))
        c_ = b2.c.transpose(sh[1:] + (0, ))
        tck_n2 = insert(tn, (b2.t, c_, b2.k))

        bn2 = insert(tn, b2)

        # need a transpose for comparing the results, cf test_splev
        assert_allclose(np.asarray(splev(xx, tck_n2)).transpose(2, 0, 1),
                        bn2(xx),
                        atol=1e-15)
        assert_(isinstance(bn2, BSpline))
        assert_(isinstance(tck_n2, tuple))  # back-compat: tck in, tck out
Пример #6
0
def check_version(module, min_ver):
    if type(module) == MissingModule:
        return pytest.mark.skip(reason="{} is not installed".format(module.name))
    return pytest.mark.skipif(_pep440.parse(module.__version__) < _pep440.Version(min_ver),
                              reason="{} version >= {} required".format(module.__name__, min_ver))
Пример #7
0
def test_legacy_version():
    # Non-PEP-440 version identifiers always compare less. For NumPy this only
    # occurs on dev builds prior to 1.10.0 which are unsupported anyway.
    assert parse('invalid') < Version('0.0.0')
    assert parse('1.9.0-f16acvda') < Version('1.0.0')
Пример #8
0
def _get_mark(item, name):
    if _pep440.parse(pytest.__version__) >= _pep440.Version("3.6.0"):
        mark = item.get_closest_marker(name)
    else:
        mark = item.get_marker(name)
    return mark
Пример #9
0
def process_pyx(fromfile, tofile, cwd):
    try:
        from Cython.Compiler.Version import version as cython_version
        from scipy._lib import _pep440

        # Try to find pyproject.toml
        pyproject_toml = join(dirname(__file__), '..', 'pyproject.toml')
        if not os.path.exists(pyproject_toml):
            raise ImportError()

        # Try to find the minimum version from pyproject.toml
        with open(pyproject_toml) as pt:
            for line in pt:
                if "cython" not in line.lower():
                    continue
                line = ''.join(line.split('=')[1:])  # get rid of "Cython>="
                if ',<' in line:
                    # There's an upper bound as well
                    split_on = ',<'
                    if ',<=' in line:
                        split_on = ',<='
                    min_required_version, max_required_version = line.split(split_on)
                    max_required_version, _ = max_required_version.split('"')
                else:
                    min_required_version, _ = line.split('"')

                break
            else:
                raise ImportError()

        # Note: we only check lower bound, for upper bound we rely on pip
        # respecting pyproject.toml. Reason: we want to be able to build/test
        # with more recent Cython locally or on main, upper bound is for
        # sdist in a release.
        if _pep440.parse(cython_version) < _pep440.Version(min_required_version):
            raise Exception('Building SciPy requires Cython >= {}, found '
                            '{}'.format(min_required_version, cython_version))

    except ImportError:
        pass

    flags = ['--fast-fail', '-3']
    if tofile.endswith('.cxx'):
        flags += ['--cplus']

    try:
        try:
            r = subprocess.call(['cython'] + flags + ["-o", tofile, fromfile], cwd=cwd)
            if r != 0:
                raise Exception('Cython failed')
        except OSError as e:
            # There are ways of installing Cython that don't result in a cython
            # executable on the path, see gh-2397.
            r = subprocess.call([sys.executable, '-c',
                                 'import sys; from Cython.Compiler.Main import '
                                 'setuptools_main as main; sys.exit(main())'] + flags +
                                 ["-o", tofile, fromfile],
                                cwd=cwd)
            if r != 0:
                raise Exception("Cython either isn't installed or it failed.") from e
    except OSError as e:
        raise OSError('Cython needs to be installed') from e