PyPy3 support (#2146)
* Error out eval_file
* Enable dynamic attribute support for Pypy >= 6
* Add a test for dynamic attribute support
* Skip test for eval_file on pypy
* Workaround for __qualname__ on PyPy3
* Add a PyPy3.6 7.3.0 build
* Only disable in PyPy3
* Fix travis testing
* No numpy and scipy for pypy
* Enable test on pypy2
* Fix logic in eval_file
* Skip a few tests due to bugs in PyPy
* scipy wheels are broken. make pypy2 a failrue
Co-authored-by: Andreas Kloeckner <inform@tiker.net>
diff --git a/.travis.yml b/.travis.yml
index f9a9065..0e50458 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -192,9 +192,8 @@
make pytest -j 2"
set +ex
allow_failures:
- - name: PyPy 7.3, Python 2.7, c++11, gcc 4.8
- - name: PyPy 7.3, Python 3.6, c++11, gcc 5
- name: Python 3.9 beta, c++17, gcc 7 (w/o numpy/scipy)
+ - name: PyPy 7.3, Python 2.7, c++11, gcc 4.8
cache:
directories:
- $HOME/.local/bin
@@ -278,15 +277,17 @@
fi
export NPY_NUM_BUILD_JOBS=2
- echo "Installing pytest, numpy, scipy..."
local PIP_CMD=""
if [ -n "$PYPY" ]; then
# For expediency, install only versions that are available on the extra index.
+ echo "Not installing numpy, scipy as working wheels are not available"
+ # travis_wait 30 $PY_CMD -m pip install --user --upgrade --extra-index-url https://antocuni.github.io/pypy-wheels/manylinux2010 \
+ # numpy scipy
+ echo "Installing pytest"
travis_wait 30 \
- $PY_CMD -m pip install --user --upgrade --extra-index-url https://antocuni.github.io/pypy-wheels/manylinux2010 \
- numpy scipy
$PY_CMD -m pip install --user --upgrade pytest
else
+ echo "Installing pytest, numpy, scipy..."
$PY_CMD -m pip install --user --upgrade pytest numpy scipy
fi
echo "done."
diff --git a/include/pybind11/detail/class.h b/include/pybind11/detail/class.h
index e5783d9..f6b89c2 100644
--- a/include/pybind11/detail/class.h
+++ b/include/pybind11/detail/class.h
@@ -15,7 +15,7 @@
NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
NAMESPACE_BEGIN(detail)
-#if PY_VERSION_HEX >= 0x03030000
+#if PY_VERSION_HEX >= 0x03030000 && !defined(PYPY_VERSION)
# define PYBIND11_BUILTIN_QUALNAME
# define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj)
#else
@@ -475,7 +475,7 @@
/// Give instances of this type a `__dict__` and opt into garbage collection.
inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) {
auto type = &heap_type->ht_type;
-#if defined(PYPY_VERSION)
+#if defined(PYPY_VERSION) && (PYPY_VERSION_NUM < 0x06000000)
pybind11_fail(std::string(type->tp_name) + ": dynamic attributes are "
"currently not supported in "
"conjunction with PyPy!");
diff --git a/include/pybind11/eval.h b/include/pybind11/eval.h
index ea85ba1..422e629 100644
--- a/include/pybind11/eval.h
+++ b/include/pybind11/eval.h
@@ -66,6 +66,20 @@
eval<eval_statements>(s, global, local);
}
+#if defined(PYPY_VERSION) && PY_VERSION_HEX >= 0x3000000
+template <eval_mode mode = eval_statements>
+object eval_file(str, object, object) {
+ pybind11_fail("eval_file not supported in PyPy3. Use eval");
+}
+template <eval_mode mode = eval_statements>
+object eval_file(str, object) {
+ pybind11_fail("eval_file not supported in PyPy3. Use eval");
+}
+template <eval_mode mode = eval_statements>
+object eval_file(str) {
+ pybind11_fail("eval_file not supported in PyPy3. Use eval");
+}
+#else
template <eval_mode mode = eval_statements>
object eval_file(str fname, object global = globals(), object local = object()) {
if (!local)
@@ -113,5 +127,6 @@
throw error_already_set();
return reinterpret_steal<object>(result);
}
+#endif
NAMESPACE_END(PYBIND11_NAMESPACE)
diff --git a/tests/conftest.py b/tests/conftest.py
index 57f681c..58ebeca 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -215,6 +215,11 @@
pytest.requires_eigen_and_scipy = skipif(
not have_eigen or not scipy, reason="eigen and/or scipy are not installed")
pytest.unsupported_on_pypy = skipif(pypy, reason="unsupported on PyPy")
+ pytest.bug_in_pypy = pytest.mark.xfail(pypy, reason="bug in PyPy")
+ pytest.unsupported_on_pypy3 = skipif(pypy and sys.version_info.major >= 3,
+ reason="unsupported on PyPy3")
+ pytest.unsupported_on_pypy_lt_6 = skipif(pypy and sys.pypy_version_info[0] < 6,
+ reason="unsupported on PyPy<6")
pytest.unsupported_on_py2 = skipif(sys.version_info.major < 3,
reason="unsupported on Python 2.x")
pytest.gc_collect = gc_collect
diff --git a/tests/test_eval.py b/tests/test_eval.py
index bda4ef6..94228e7 100644
--- a/tests/test_eval.py
+++ b/tests/test_eval.py
@@ -1,4 +1,5 @@
import os
+import pytest
from pybind11_tests import eval_ as m
@@ -10,8 +11,12 @@
assert m.test_eval()
assert m.test_eval_single_statement()
+ assert m.test_eval_failure()
+
+
+@pytest.unsupported_on_pypy3
+def test_eval_file():
filename = os.path.join(os.path.dirname(__file__), "test_eval_call.py")
assert m.test_eval_file(filename)
- assert m.test_eval_failure()
assert m.test_eval_file_failure()
diff --git a/tests/test_local_bindings.py b/tests/test_local_bindings.py
index b380376..be841a7 100644
--- a/tests/test_local_bindings.py
+++ b/tests/test_local_bindings.py
@@ -152,6 +152,7 @@
assert m.local_cpp_types_addr() != cm.local_cpp_types_addr()
+@pytest.bug_in_pypy
def test_stl_caster_vs_stl_bind(msg):
"""One module uses a generic vector caster from `<pybind11/stl.h>` while the other
exports `std::vector<int>` via `py:bind_vector` and `py::module_local`"""
diff --git a/tests/test_multiple_inheritance.cpp b/tests/test_multiple_inheritance.cpp
index ba1674f..70e3417 100644
--- a/tests/test_multiple_inheritance.cpp
+++ b/tests/test_multiple_inheritance.cpp
@@ -193,7 +193,7 @@
.def_readwrite_static("static_value", &VanillaStaticMix2::static_value);
-#if !defined(PYPY_VERSION)
+#if !(defined(PYPY_VERSION) && (PYPY_VERSION_NUM < 0x06000000))
struct WithDict { };
struct VanillaDictMix1 : Vanilla, WithDict { };
struct VanillaDictMix2 : WithDict, Vanilla { };
diff --git a/tests/test_multiple_inheritance.py b/tests/test_multiple_inheritance.py
index 475dd3b..7a6e4a0 100644
--- a/tests/test_multiple_inheritance.py
+++ b/tests/test_multiple_inheritance.py
@@ -10,6 +10,7 @@
assert mt.bar() == 4
+@pytest.bug_in_pypy
def test_multiple_inheritance_mix1():
class Base1:
def __init__(self, i):
@@ -49,6 +50,7 @@
assert mt.bar() == 4
+@pytest.bug_in_pypy
def test_multiple_inheritance_python():
class MI1(m.Base1, m.Base2):
@@ -253,7 +255,7 @@
assert d.static_value == 0
-@pytest.unsupported_on_pypy
+@pytest.unsupported_on_pypy_lt_6
def test_mi_dynamic_attributes():
"""Mixing bases with and without dynamic attribute support"""