summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatti Picus <matti.picus@gmail.com>2023-02-01 15:50:53 +0200
committerGitHub <noreply@github.com>2023-02-01 15:50:53 +0200
commit340b3ff2ea6fdfebcb43a83aa8799dffd77ab325 (patch)
tree4303e5435608c7c7a42a172f141fbd670c02a0c6
parentd352270849b3cbff4fcf5511551a247065474f01 (diff)
parent20d397400d6325cff3decbba3d6195418e873237 (diff)
downloadnumpy-340b3ff2ea6fdfebcb43a83aa8799dffd77ab325.tar.gz
Merge pull request #23069 from andyfaff/wheel
BLD: musllinux wheel build
-rw-r--r--.github/workflows/wheels.yml5
-rw-r--r--numpy/core/getlimits.py17
-rw-r--r--numpy/core/tests/test_longdouble.py27
-rw-r--r--numpy/core/tests/test_print.py4
-rw-r--r--numpy/core/tests/test_scalar_methods.py4
-rw-r--r--numpy/core/tests/test_scalarprint.py6
-rw-r--r--numpy/core/tests/test_umath.py19
-rw-r--r--pyproject.toml3
8 files changed, 69 insertions, 16 deletions
diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml
index a9e9ea9d4..3ce70d7ba 100644
--- a/.github/workflows/wheels.yml
+++ b/.github/workflows/wheels.yml
@@ -75,6 +75,7 @@ jobs:
# https://github.com/github/feedback/discussions/7835#discussioncomment-1769026
buildplat:
- [ubuntu-20.04, manylinux_x86_64]
+ - [ubuntu-20.04, musllinux_x86_64]
- [macos-12, macosx_*]
- [windows-2019, win_amd64]
- [windows-2019, win32]
@@ -82,8 +83,8 @@ jobs:
exclude:
# Don't build PyPy 32-bit windows
- buildplat: [windows-2019, win32]
- python: "pp38"
- - buildplat: [windows-2019, win32]
+ python: "pp39"
+ - buildplat: [ ubuntu-20.04, musllinux_x86_64 ]
python: "pp39"
env:
IS_32_BIT: ${{ matrix.buildplat[1] == 'win32' }}
diff --git a/numpy/core/getlimits.py b/numpy/core/getlimits.py
index 8146c4644..f848af085 100644
--- a/numpy/core/getlimits.py
+++ b/numpy/core/getlimits.py
@@ -147,8 +147,12 @@ _MACHAR_PARAMS = {
# Key to identify the floating point type. Key is result of
# ftype('-0.1').newbyteorder('<').tobytes()
+#
+# 20230201 - use (ftype(-1.0) / ftype(10.0)).newbyteorder('<').tobytes()
+# instead because stold may have deficiencies on some platforms.
# See:
# https://perl5.git.perl.org/perl.git/blob/3118d7d684b56cbeb702af874f4326683c45f045:/Configure
+
_KNOWN_TYPES = {}
def _register_type(machar, bytepat):
_KNOWN_TYPES[bytepat] = machar
@@ -240,8 +244,6 @@ def _register_known_types():
# IEEE 754 128-bit binary float
_register_type(float128_ma,
b'\x9a\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\xfb\xbf')
- _register_type(float128_ma,
- b'\x9a\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\xfb\xbf')
_float_ma[128] = float128_ma
# Known parameters for float80 (Intel 80-bit extended precision)
@@ -329,7 +331,9 @@ def _get_machar(ftype):
if params is None:
raise ValueError(repr(ftype))
# Detect known / suspected types
- key = ftype('-0.1').newbyteorder('<').tobytes()
+ # ftype(-1.0) / ftype(10.0) is better than ftype('-0.1') because stold
+ # may be deficient
+ key = (ftype(-1.0) / ftype(10.)).newbyteorder('<').tobytes()
ma_like = None
if ftype == ntypes.longdouble:
# Could be 80 bit == 10 byte extended precision, where last bytes can
@@ -338,7 +342,14 @@ def _get_machar(ftype):
# random garbage.
ma_like = _KNOWN_TYPES.get(key[:10])
if ma_like is None:
+ # see if the full key is known.
ma_like = _KNOWN_TYPES.get(key)
+ if ma_like is None and len(key) == 16:
+ # machine limits could be f80 masquerading as np.float128,
+ # find all keys with length 16 and make new dict, but make the keys
+ # only 10 bytes long, the last bytes can be random garbage
+ _kt = {k[:10]: v for k, v in _KNOWN_TYPES.items() if len(k) == 16}
+ ma_like = _kt.get(key[:10])
if ma_like is not None:
return ma_like
# Fall back to parameter discovery
diff --git a/numpy/core/tests/test_longdouble.py b/numpy/core/tests/test_longdouble.py
index 1a54e62d8..abefa8529 100644
--- a/numpy/core/tests/test_longdouble.py
+++ b/numpy/core/tests/test_longdouble.py
@@ -1,10 +1,11 @@
import warnings
+import platform
import pytest
import numpy as np
from numpy.testing import (
assert_, assert_equal, assert_raises, assert_warns, assert_array_equal,
- temppath,
+ temppath, IS_MUSL
)
from numpy.core.tests._locales import CommaDecimalPointLocale
@@ -30,6 +31,10 @@ def test_scalar_extraction():
# 0.1 not exactly representable in base 2 floating point.
repr_precision = len(repr(np.longdouble(0.1)))
# +2 from macro block starting around line 842 in scalartypes.c.src.
+
+
+@pytest.mark.skipif(IS_MUSL,
+ reason="test flaky on musllinux")
@pytest.mark.skipif(LD_INFO.precision + 2 >= repr_precision,
reason="repr precision not enough to show eps")
def test_repr_roundtrip():
@@ -368,3 +373,23 @@ def test_longdouble_from_int(int_val):
True, False])
def test_longdouble_from_bool(bool_val):
assert np.longdouble(bool_val) == np.longdouble(int(bool_val))
+
+
+@pytest.mark.skipif(
+ not (IS_MUSL and platform.machine() == "x86_64"),
+ reason="only need to run on musllinux_x86_64"
+)
+def test_musllinux_x86_64_signature():
+ # this test may fail if you're emulating musllinux_x86_64 on a different
+ # architecture, but should pass natively.
+ known_sigs = [b'\xcd\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xfb\xbf']
+ sig = (np.longdouble(-1.0) / np.longdouble(10.0)
+ ).newbyteorder('<').tobytes()[:10]
+ assert sig in known_sigs
+
+
+def test_eps_positive():
+ # np.finfo('g').eps should be positive on all platforms. If this isn't true
+ # then something may have gone wrong with the MachArLike, e.g. if
+ # np.core.getlimits._discovered_machar didn't work properly
+ assert np.finfo(np.longdouble).eps > 0.
diff --git a/numpy/core/tests/test_print.py b/numpy/core/tests/test_print.py
index 89a8b48bf..162686ee0 100644
--- a/numpy/core/tests/test_print.py
+++ b/numpy/core/tests/test_print.py
@@ -3,7 +3,7 @@ import sys
import pytest
import numpy as np
-from numpy.testing import assert_, assert_equal
+from numpy.testing import assert_, assert_equal, IS_MUSL
from numpy.core.tests._locales import CommaDecimalPointLocale
@@ -196,5 +196,7 @@ class TestCommaDecimalPointLocale(CommaDecimalPointLocale):
def test_locale_double(self):
assert_equal(str(np.double(1.2)), str(float(1.2)))
+ @pytest.mark.skipif(IS_MUSL,
+ reason="test flaky on musllinux")
def test_locale_longdouble(self):
assert_equal(str(np.longdouble('1.2')), str(float(1.2)))
diff --git a/numpy/core/tests/test_scalar_methods.py b/numpy/core/tests/test_scalar_methods.py
index a53e47b19..4f57c94c0 100644
--- a/numpy/core/tests/test_scalar_methods.py
+++ b/numpy/core/tests/test_scalar_methods.py
@@ -10,7 +10,7 @@ from typing import Any, Type
import pytest
import numpy as np
-from numpy.testing import assert_equal, assert_raises
+from numpy.testing import assert_equal, assert_raises, IS_MUSL
class TestAsIntegerRatio:
@@ -99,6 +99,8 @@ class TestAsIntegerRatio:
try:
nf = np.longdouble(n)
df = np.longdouble(d)
+ if not np.isfinite(df):
+ raise OverflowError
except (OverflowError, RuntimeWarning):
# the values may not fit in any float type
pytest.skip("longdouble too small on this platform")
diff --git a/numpy/core/tests/test_scalarprint.py b/numpy/core/tests/test_scalarprint.py
index 4deb5a0a4..98d1f4aa1 100644
--- a/numpy/core/tests/test_scalarprint.py
+++ b/numpy/core/tests/test_scalarprint.py
@@ -8,7 +8,7 @@ import sys
from tempfile import TemporaryFile
import numpy as np
-from numpy.testing import assert_, assert_equal, assert_raises
+from numpy.testing import assert_, assert_equal, assert_raises, IS_MUSL
class TestRealScalars:
def test_str(self):
@@ -260,10 +260,10 @@ class TestRealScalars:
assert_equal(fpos64('324', unique=False, precision=5,
fractional=False), "324.00")
-
def test_dragon4_interface(self):
tps = [np.float16, np.float32, np.float64]
- if hasattr(np, 'float128'):
+ # test is flaky for musllinux on np.float128
+ if hasattr(np, 'float128') and not IS_MUSL:
tps.append(np.float128)
fpos = np.format_float_positional
diff --git a/numpy/core/tests/test_umath.py b/numpy/core/tests/test_umath.py
index 4028634ea..eb5cecbe4 100644
--- a/numpy/core/tests/test_umath.py
+++ b/numpy/core/tests/test_umath.py
@@ -1292,9 +1292,20 @@ class TestLog:
# test log() of max for dtype does not raise
for dt in ['f', 'd', 'g']:
- with np.errstate(all='raise'):
- x = np.finfo(dt).max
- np.log(x)
+ try:
+ with np.errstate(all='raise'):
+ x = np.finfo(dt).max
+ np.log(x)
+ except FloatingPointError as exc:
+ if dt == 'g' and IS_MUSL:
+ # FloatingPointError is known to occur on longdouble
+ # for musllinux_x86_64 x is very large
+ pytest.skip(
+ "Overflow has occurred for"
+ " np.log(np.finfo(np.longdouble).max)"
+ )
+ else:
+ raise exc
def test_log_strides(self):
np.random.seed(42)
@@ -4260,7 +4271,7 @@ def _test_spacing(t):
nan = t(np.nan)
inf = t(np.inf)
with np.errstate(invalid='ignore'):
- assert_(np.spacing(one) == eps)
+ assert_equal(np.spacing(one), eps)
assert_(np.isnan(np.spacing(nan)))
assert_(np.isnan(np.spacing(inf)))
assert_(np.isnan(np.spacing(-inf)))
diff --git a/pyproject.toml b/pyproject.toml
index 02953da03..4817aa101 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -143,7 +143,7 @@ requires = [
[tool.cibuildwheel]
-skip = "cp36-* cp37-* pp37-* *-manylinux_i686 *_ppc64le *_s390x *-musllinux*"
+skip = "cp36-* cp37-* pp37-* *-manylinux_i686 *_ppc64le *_s390x *-musllinux_aarch64"
build-verbosity = "3"
before-build = "bash {project}/tools/wheels/cibw_before_build.sh {project}"
before-test = "pip install -r {project}/test_requirements.txt"
@@ -152,6 +152,7 @@ test-command = "bash {project}/tools/wheels/cibw_test_command.sh {project}"
[tool.cibuildwheel.linux]
manylinux-x86_64-image = "manylinux2014"
manylinux-aarch64-image = "manylinux2014"
+musllinux-x86_64-image = "musllinux_1_1"
environment = { CFLAGS="-std=c99 -fno-strict-aliasing", LDFLAGS="-Wl,--strip-debug", OPENBLAS64_="/usr/local", NPY_USE_BLAS_ILP64="1", RUNNER_OS="Linux" }
[tool.cibuildwheel.macos]