aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Holth <dholth@fastmail.fm>2016-08-03 21:55:39 -0400
committerDaniel Holth <dholth@fastmail.fm>2016-08-03 21:55:39 -0400
commita2605b297c147a1ad54078181d32fe369fa4f37d (patch)
tree59786ea683feecb6ec208792d6a2086b12995842
parent6a4e5446c941291ec5e7c56cee1d5a872300c955 (diff)
downloadexternal_python_setuptools-a2605b297c147a1ad54078181d32fe369fa4f37d.tar.gz
external_python_setuptools-a2605b297c147a1ad54078181d32fe369fa4f37d.tar.bz2
external_python_setuptools-a2605b297c147a1ad54078181d32fe369fa4f37d.zip
use abi3 extension if Extension().is_abi3
-rw-r--r--setuptools/command/build_ext.py13
-rw-r--r--setuptools/extension.py4
-rw-r--r--setuptools/tests/test_build_ext.py20
3 files changed, 36 insertions, 1 deletions
diff --git a/setuptools/command/build_ext.py b/setuptools/command/build_ext.py
index e6db0764..dad28999 100644
--- a/setuptools/command/build_ext.py
+++ b/setuptools/command/build_ext.py
@@ -59,6 +59,14 @@ elif os.name != 'nt':
if_dl = lambda s: s if have_rtld else ''
+def get_abi3_suffix():
+ """Return the file extension for an abi3-compliant Extension()"""
+ import imp
+ for suffix, _, _ in (s for s in imp.get_suffixes() if s[2] == imp.C_EXTENSION):
+ if '.abi3' in suffix: # Unix
+ return suffix
+ elif suffix == '.pyd': # Windows
+ return suffix
class build_ext(_build_ext):
@@ -96,6 +104,11 @@ class build_ext(_build_ext):
filename = _build_ext.get_ext_filename(self, fullname)
if fullname in self.ext_map:
ext = self.ext_map[fullname]
+ if sys.version_info[0] != 2 and getattr(ext, 'is_abi3'):
+ from distutils.sysconfig import get_config_var
+ so_ext = get_config_var('SO')
+ filename = filename[:-len(so_ext)]
+ filename = filename + get_abi3_suffix()
if isinstance(ext, Library):
fn, ext = os.path.splitext(filename)
return self.shlib_compiler.library_filename(fn, libtype)
diff --git a/setuptools/extension.py b/setuptools/extension.py
index 5ea72c06..a6cc0915 100644
--- a/setuptools/extension.py
+++ b/setuptools/extension.py
@@ -36,6 +36,10 @@ have_pyrex = _have_cython
class Extension(_Extension):
"""Extension that uses '.c' files in place of '.pyx' files"""
+ def __init__(self, name, sources, is_abi3=False, **kw):
+ self.is_abi3 = is_abi3
+ _Extension.__init__(self, name, sources, **kw)
+
def _convert_pyx_sources_to_lang(self):
"""
Replace sources with .pyx extensions to sources with the target
diff --git a/setuptools/tests/test_build_ext.py b/setuptools/tests/test_build_ext.py
index 5168ebf0..e0f2e73b 100644
--- a/setuptools/tests/test_build_ext.py
+++ b/setuptools/tests/test_build_ext.py
@@ -1,8 +1,10 @@
+import sys
import distutils.command.build_ext as orig
+from distutils.sysconfig import get_config_var
from setuptools.command.build_ext import build_ext
from setuptools.dist import Distribution
-
+from setuptools.extension import Extension
class TestBuildExt:
@@ -18,3 +20,19 @@ class TestBuildExt:
res = cmd.get_ext_filename('foo')
wanted = orig.build_ext.get_ext_filename(cmd, 'foo')
assert res == wanted
+
+ def test_abi3_filename(self):
+ """
+ Filename needs to be loadable by several versions
+ of Python 3 if 'is_abi3' is truthy on Extension()
+ """
+ dist = Distribution(dict(ext_modules=[Extension('spam.eggs', [], is_abi3=True)]))
+ cmd = build_ext(dist)
+ res = cmd.get_ext_filename('spam.eggs')
+
+ if sys.version_info[0] == 2:
+ assert res.endswith(get_config_var('SO'))
+ elif sys.platform == 'win32':
+ assert res.endswith('eggs.pyd')
+ else:
+ assert 'abi3' in res \ No newline at end of file