Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ jobs:
run: pytest tests/extra_setuptools
if: "!(matrix.runs-on == 'windows-2022')"

# This tests ABI compatibility
- name: ABI test
run: pytest tests/extra_abi


deadsnakes:
strategy:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@ pybind11Targets.cmake
/docs/_build/*
.ipynb_checkpoints/
tests/main.cpp
tests/*/temp*
17 changes: 17 additions & 0 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,23 @@ def tests_packaging(session: nox.Session) -> None:
session.run("pytest", "tests/extra_python_package", *session.posargs)


@nox.session
def tests_abi(session: nox.Session) -> None:
"""
Run the abi checker.
"""

session.install("pybind11==2.8.0", "--no-build-isolation")
session.install(
"tests/extra_abi", "--no-build-isolation", env={"EXAMPLE_NAME": "pet"}
)
session.install(".", "--no-build-isolation")
session.install(
"tests/extra_abi", "--no-build-isolation", env={"EXAMPLE_NAME": "dog"}
)
session.run("python", "tests/extra_abi/check_installed.py")


@nox.session(reuse_venv=True)
def docs(session: nox.Session) -> None:
"""
Expand Down
26 changes: 15 additions & 11 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
import pytest

# Early diagnostic for failed imports
import pybind11_tests
try:
import pybind11_tests
except ModuleNotFoundError:
pybind11_tests = None

_long_marker = re.compile(r"([0-9])L")
_hexadecimal = re.compile(r"0x[0-9a-fA-F]+")
Expand Down Expand Up @@ -201,13 +204,14 @@ def pytest_configure():


def pytest_report_header(config):
del config # Unused.
assert (
pybind11_tests.compiler_info is not None
), "Please update pybind11_tests.cpp if this assert fails."
return (
"C++ Info:"
f" {pybind11_tests.compiler_info}"
f" {pybind11_tests.cpp_std}"
f" {pybind11_tests.PYBIND11_INTERNALS_ID}"
)
if pybind11_tests is not None:
del config # Unused.
assert (
pybind11_tests.compiler_info is not None
), "Please update pybind11_tests.cpp if this assert fails."
return (
"C++ Info:"
f" {pybind11_tests.compiler_info}"
f" {pybind11_tests.cpp_std}"
f" {pybind11_tests.PYBIND11_INTERNALS_ID}"
)
13 changes: 13 additions & 0 deletions tests/extra_abi/check_installed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
try:
import dog

raise RuntimeError("Broken! Dog must require Pet to be loaded")
except ImportError:
import pet # noqa: F401

import dog # noqa: F811

d = dog.Dog("Bluey")

d.bark()
assert d.name == "Bluey"
11 changes: 11 additions & 0 deletions tests/extra_abi/dog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <pybind11/pybind11.h>

#include "dog.hpp"

#include <string>

namespace py = pybind11;

PYBIND11_MODULE(dog, m) {
py::class_<Dog, Pet>(m, "Dog").def(py::init<const std::string &>()).def("bark", &Dog::bark);
}
10 changes: 10 additions & 0 deletions tests/extra_abi/dog.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include <pybind11/pybind11.h>

#include "pet.hpp"

#include <string>

struct PYBIND11_EXPORT Dog : Pet {
explicit Dog(const std::string &name) : Pet(name) {}
std::string bark() const { return "woof!"; }
};
12 changes: 12 additions & 0 deletions tests/extra_abi/pet.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <pybind11/pybind11.h>

#include "pet.hpp"

#include <string>

namespace py = pybind11;

PYBIND11_MODULE(pet, m) {
py::class_<Pet> pet(m, "Pet");
pet.def(py::init<const std::string &>()).def_readwrite("name", &Pet::name);
}
6 changes: 6 additions & 0 deletions tests/extra_abi/pet.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <string>

struct Pet {
explicit Pet(const std::string &name) : name(name) {}
std::string name;
};
20 changes: 20 additions & 0 deletions tests/extra_abi/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import os
import sys

from setuptools import setup

from pybind11.setup_helpers import Pybind11Extension

name = os.environ["EXAMPLE_NAME"]
assert name in {"pet", "dog"}


ext = Pybind11Extension(
name,
[f"{name}.cpp"],
include_dirs=["."],
cxx_std=11,
extra_compile_args=["/d2FH4-"] if sys.platform.startswith("win32") else [],
)

setup(name=name, version="0.0.0", ext_modules=[ext])
16 changes: 16 additions & 0 deletions tests/extra_abi/test_venv_abi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from pathlib import Path

DIR = Path(__file__).parent.resolve()


def test_build_import(virtualenv):
virtualenv.run('pip install "pybind11==2.8.0" --no-build-isolation')
virtualenv.env["EXAMPLE_NAME"] = "pet"
virtualenv.run(f"pip install {DIR} --no-build-isolation")

virtualenv.run(f"pip install {DIR.parent.parent} --no-build-isolation")
virtualenv.env["EXAMPLE_NAME"] = "dog"
virtualenv.run(f"pip install {DIR} --no-build-isolation")

script = DIR / "check_installed.py"
virtualenv.run(f"python {script}")
1 change: 1 addition & 0 deletions tests/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ numpy==1.21.5; platform_python_implementation!="PyPy" and python_version>="3.7"
numpy==1.22.2; platform_python_implementation!="PyPy" and python_version>="3.10" and python_version<"3.11"
pytest==7.0.0
pytest-timeout
pytest-virtualenv
scipy==1.5.4; platform_python_implementation!="PyPy" and python_version<"3.10"
scipy==1.8.0; platform_python_implementation!="PyPy" and python_version=="3.10"