-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Use pybind11 for C/C++ extensions #23787
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
8381ef9
f2f597f
cdfaf20
b15fd9c
293dffc
7da3539
f8226d8
2f8cfec
846f4c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1167,43 +1167,43 @@ def test_internal_cpp_api(): | |
# C++ Triangulation. | ||
with pytest.raises( | ||
TypeError, | ||
match=r'function takes exactly 7 arguments \(0 given\)'): | ||
match=r'__init__\(\): incompatible constructor arguments.'): | ||
mpl._tri.Triangulation() | ||
|
||
with pytest.raises( | ||
ValueError, match=r'x and y must be 1D arrays of the same length'): | ||
mpl._tri.Triangulation([], [1], [[]], None, None, None, False) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if None is not accepted anymore this warrants a changelog entry There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the internal C++ Triangulation API ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Python Triangulation class still accepts |
||
mpl._tri.Triangulation([], [1], [[]], (), (), (), False) | ||
|
||
x = [0, 1, 1] | ||
y = [0, 0, 1] | ||
with pytest.raises( | ||
ValueError, | ||
match=r'triangles must be a 2D array of shape \(\?,3\)'): | ||
mpl._tri.Triangulation(x, y, [[0, 1]], None, None, None, False) | ||
mpl._tri.Triangulation(x, y, [[0, 1]], (), (), (), False) | ||
|
||
tris = [[0, 1, 2]] | ||
with pytest.raises( | ||
ValueError, | ||
match=r'mask must be a 1D array with the same length as the ' | ||
r'triangles array'): | ||
mpl._tri.Triangulation(x, y, tris, [0, 1], None, None, False) | ||
mpl._tri.Triangulation(x, y, tris, [0, 1], (), (), False) | ||
|
||
with pytest.raises( | ||
ValueError, match=r'edges must be a 2D array with shape \(\?,2\)'): | ||
mpl._tri.Triangulation(x, y, tris, None, [[1]], None, False) | ||
mpl._tri.Triangulation(x, y, tris, (), [[1]], (), False) | ||
|
||
with pytest.raises( | ||
ValueError, | ||
match=r'neighbors must be a 2D array with the same shape as the ' | ||
r'triangles array'): | ||
mpl._tri.Triangulation(x, y, tris, None, None, [[-1]], False) | ||
mpl._tri.Triangulation(x, y, tris, (), (), [[-1]], False) | ||
|
||
triang = mpl._tri.Triangulation(x, y, tris, None, None, None, False) | ||
triang = mpl._tri.Triangulation(x, y, tris, (), (), (), False) | ||
|
||
with pytest.raises( | ||
ValueError, | ||
match=r'z array must have same length as triangulation x and y ' | ||
r'array'): | ||
match=r'z must be a 1D array with the same length as the ' | ||
r'triangulation x and y arrays'): | ||
triang.calculate_plane_coefficients([]) | ||
|
||
with pytest.raises( | ||
|
@@ -1215,7 +1215,7 @@ def test_internal_cpp_api(): | |
# C++ TriContourGenerator. | ||
with pytest.raises( | ||
TypeError, | ||
match=r'function takes exactly 2 arguments \(0 given\)'): | ||
match=r'__init__\(\): incompatible constructor arguments.'): | ||
mpl._tri.TriContourGenerator() | ||
|
||
with pytest.raises( | ||
|
@@ -1233,7 +1233,8 @@ def test_internal_cpp_api(): | |
|
||
# C++ TrapezoidMapTriFinder. | ||
with pytest.raises( | ||
TypeError, match=r'function takes exactly 1 argument \(0 given\)'): | ||
TypeError, | ||
match=r'__init__\(\): incompatible constructor arguments.'): | ||
mpl._tri.TrapezoidMapTriFinder() | ||
|
||
trifinder = mpl._tri.TrapezoidMapTriFinder(triang) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -66,6 +66,15 @@ def has_flag(self, flagname): | |
return True | ||
|
||
|
||
# Wrapper for distutils.ccompiler.CCompiler._compile to remove C++-specific | ||
# flags when compiling C files. | ||
def compile_wrapper(compiler, obj, src, ext, cc_args, extra_postargs, pp_opts): | ||
if src.lower().endswith(".c"): | ||
extra_postargs = list(filter(lambda x: x[1:4] != "std", | ||
extra_postargs)) | ||
compiler._compile_old(obj, src, ext, cc_args, extra_postargs, pp_opts) | ||
|
||
|
||
class BuildExtraLibraries(setuptools.command.build_ext.build_ext): | ||
def finalize_options(self): | ||
self.distribution.ext_modules[:] = [ | ||
|
@@ -184,9 +193,20 @@ def build_extension(self, ext): | |
orig_build_temp = self.build_temp | ||
self.build_temp = os.path.join(self.build_temp, ext.name) | ||
try: | ||
if ext.name == "matplotlib._qhull": | ||
# For qhull extension some C++ flags must be removed before | ||
# compiling C files. | ||
from distutils.ccompiler import CCompiler | ||
self.compiler._compile_old = self.compiler._compile | ||
self.compiler._compile = compile_wrapper.__get__( | ||
self.compiler, CCompiler) | ||
super().build_extension(ext) | ||
finally: | ||
self.build_temp = orig_build_temp | ||
if ext.name == "matplotlib._qhull" and hasattr( | ||
self.compiler, "_compile_old"): | ||
self.compiler._compile = self.compiler._compile_old | ||
delattr(self.compiler, "_compile_old") | ||
|
||
|
||
def update_matplotlibrc(path): | ||
|
@@ -302,6 +322,8 @@ def make_release_tree(self, base_dir, files): | |
setup_requires=[ | ||
"certifi>=2020.06.20", | ||
"numpy>=1.19", | ||
"pybind11>=2.6", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a new build dependency, but is not a runtime dependency. |
||
"setuptools>=42", | ||
"setuptools_scm>=7", | ||
], | ||
install_requires=[ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ | |
import textwrap | ||
import urllib.request | ||
|
||
from pybind11.setup_helpers import Pybind11Extension | ||
from setuptools import Distribution, Extension | ||
|
||
_log = logging.getLogger(__name__) | ||
|
@@ -432,10 +433,10 @@ def get_extensions(self): | |
add_libagg_flags_and_sources(ext) | ||
yield ext | ||
# qhull | ||
ext = Extension( | ||
ext = Pybind11Extension( | ||
"matplotlib._qhull", ["src/_qhull_wrapper.cpp"], | ||
cxx_std=11, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can specify the C++ standard to follow, so here we are explicitly restricting to C++11. This would probably be a configuration param at the top of the file to make it clear what C++ standard the project is currently working to. |
||
define_macros=[("MPL_DEVNULL", os.devnull)]) | ||
add_numpy_flags(ext) | ||
Qhull.add_flags(ext) | ||
yield ext | ||
# tkagg | ||
|
@@ -452,12 +453,12 @@ def get_extensions(self): | |
add_libagg_flags(ext) | ||
yield ext | ||
# tri | ||
ext = Extension( | ||
ext = Pybind11Extension( | ||
"matplotlib._tri", [ | ||
"src/tri/_tri.cpp", | ||
"src/tri/_tri_wrapper.cpp", | ||
]) | ||
add_numpy_flags(ext) | ||
], | ||
cxx_std=11) | ||
yield ext | ||
# ttconv | ||
ext = Extension( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why the pin?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't recall the precise reason, presumably I was experimenting when the build didn't work. But it doesn't matter now, since merging of #24102 we don't need to preinstall
pybind11
for editable installs so changes like this can be reverted.