[pypy-commit] pypy default: update to cffi/59b8d697b9b9

arigo pypy.commits at gmail.com
Thu Jan 31 16:43:13 EST 2019


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r95763:4c96a83024a4
Date: 2019-01-31 22:42 +0100
http://bitbucket.org/pypy/pypy/changeset/4c96a83024a4/

Log:	update to cffi/59b8d697b9b9

diff --git a/extra_tests/cffi_tests/cffi1/test_pkgconfig.py b/extra_tests/cffi_tests/cffi1/test_pkgconfig.py
new file mode 100644
--- /dev/null
+++ b/extra_tests/cffi_tests/cffi1/test_pkgconfig.py
@@ -0,0 +1,95 @@
+# Generated by pypy/tool/import_cffi.py
+import sys
+import subprocess
+import py
+import cffi.pkgconfig as pkgconfig
+from cffi import PkgConfigError
+
+
+def mock_call(libname, flag):
+    assert libname=="foobarbaz"
+    flags = {
+        "--cflags": "-I/usr/include/python3.6m -DABCD -DCFFI_TEST=1 -O42\n",
+        "--libs": "-L/usr/lib64 -lpython3.6 -shared\n",
+    }
+    return flags[flag]
+
+
+def test_merge_flags():
+    d1 = {"ham": [1, 2, 3], "spam" : ["a", "b", "c"], "foo" : []}
+    d2 = {"spam" : ["spam", "spam", "spam"], "bar" : ["b", "a", "z"]}
+
+    pkgconfig.merge_flags(d1, d2)
+    assert d1 == {
+        "ham": [1, 2, 3],
+        "spam" : ["a", "b", "c", "spam", "spam", "spam"],
+        "bar" : ["b", "a", "z"],
+        "foo" : []}
+
+
+def test_pkgconfig():
+    assert pkgconfig.flags_from_pkgconfig([]) == {}
+
+    saved = pkgconfig.call
+    try:
+        pkgconfig.call = mock_call
+        flags = pkgconfig.flags_from_pkgconfig(["foobarbaz"])
+    finally:
+        pkgconfig.call = saved
+    assert flags == {
+        'include_dirs': ['/usr/include/python3.6m'],
+        'library_dirs': ['/usr/lib64'],
+        'libraries': ['python3.6'],
+        'define_macros': [('ABCD', None), ('CFFI_TEST', '1')],
+        'extra_compile_args': ['-O42'],
+        'extra_link_args': ['-shared']
+    }
+
+class mock_subprocess:
+    PIPE = Ellipsis
+    class Popen:
+        def __init__(self, cmd, stdout, stderr):
+            if mock_subprocess.RESULT is None:
+                raise OSError("oops can't run")
+            assert cmd == ['pkg-config', '--print-errors', '--cflags', 'libfoo']
+        def communicate(self):
+            bout, berr, rc = mock_subprocess.RESULT
+            self.returncode = rc
+            return bout, berr
+
+def test_call():
+    saved = pkgconfig.subprocess
+    try:
+        pkgconfig.subprocess = mock_subprocess
+
+        mock_subprocess.RESULT = None
+        e = py.test.raises(PkgConfigError, pkgconfig.call, "libfoo", "--cflags")
+        assert str(e.value) == "cannot run pkg-config: oops can't run"
+
+        mock_subprocess.RESULT = b"", "Foo error!\n", 1
+        e = py.test.raises(PkgConfigError, pkgconfig.call, "libfoo", "--cflags")
+        assert str(e.value) == "Foo error!"
+
+        mock_subprocess.RESULT = b"abc\\def\n", "", 0
+        e = py.test.raises(PkgConfigError, pkgconfig.call, "libfoo", "--cflags")
+        assert str(e.value).startswith("pkg-config --cflags libfoo returned an "
+                                       "unsupported backslash-escaped output:")
+
+        mock_subprocess.RESULT = b"abc def\n", "", 0
+        result = pkgconfig.call("libfoo", "--cflags")
+        assert result == "abc def\n"
+
+        mock_subprocess.RESULT = b"abc def\n", "", 0
+        result = pkgconfig.call("libfoo", "--cflags")
+        assert result == "abc def\n"
+
+        if sys.version_info >= (3,):
+            mock_subprocess.RESULT = b"\xff\n", "", 0
+            e = py.test.raises(PkgConfigError, pkgconfig.call,
+                               "libfoo", "--cflags", encoding="utf-8")
+            assert str(e.value) == (
+                "pkg-config --cflags libfoo returned bytes that cannot be "
+                "decoded with encoding 'utf-8':\nb'\\xff\\n'")
+
+    finally:
+        pkgconfig.subprocess = saved
diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py
--- a/lib_pypy/cffi/__init__.py
+++ b/lib_pypy/cffi/__init__.py
@@ -3,6 +3,7 @@
 
 from .api import FFI
 from .error import CDefError, FFIError, VerificationError, VerificationMissing
+from .error import PkgConfigError
 
 __version__ = "1.12.0"
 __version_info__ = (1, 12, 0)
diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py
--- a/lib_pypy/cffi/api.py
+++ b/lib_pypy/cffi/api.py
@@ -643,6 +643,16 @@
         self._assigned_source = (str(module_name), source,
                                  source_extension, kwds)
 
+    def set_source_pkgconfig(self, module_name, pkgconfig_libs, source,
+                             source_extension='.c', **kwds):
+        from . import pkgconfig
+        if not isinstance(pkgconfig_libs, list):
+            raise TypeError("the pkgconfig_libs argument must be a list "
+                            "of package names")
+        kwds2 = pkgconfig.flags_from_pkgconfig(pkgconfig_libs)
+        pkgconfig.merge_flags(kwds, kwds2)
+        self.set_source(module_name, source, source_extension, **kwds)
+
     def distutils_extension(self, tmpdir='build', verbose=True):
         from distutils.dir_util import mkpath
         from .recompiler import recompile
diff --git a/lib_pypy/cffi/error.py b/lib_pypy/cffi/error.py
--- a/lib_pypy/cffi/error.py
+++ b/lib_pypy/cffi/error.py
@@ -1,8 +1,9 @@
 
 class FFIError(Exception):
-    pass
+    __module__ = 'cffi'
 
 class CDefError(Exception):
+    __module__ = 'cffi'
     def __str__(self):
         try:
             current_decl = self.args[1]
@@ -16,8 +17,15 @@
 class VerificationError(Exception):
     """ An error raised when verification fails
     """
+    __module__ = 'cffi'
 
 class VerificationMissing(Exception):
     """ An error raised when incomplete structures are passed into
     cdef, but no verification has been done
     """
+    __module__ = 'cffi'
+
+class PkgConfigError(Exception):
+    """ An error raised for missing modules in pkg-config
+    """
+    __module__ = 'cffi'


More information about the pypy-commit mailing list