Author: Michal Vyskocil <michal.vysko...@gmail.com> Branch: Changeset: r3201:93d6970fc206 Date: 2019-01-10 13:28 +0100 http://bitbucket.org/cffi/cffi/changeset/93d6970fc206/
Log: Define and raise specific hierarchy of exceptions * PkgConfigNotFound - not installed * PkgConfigError - base pkg-config errors * PkgConfigModuleNotFound - pc file for module was not found * PkgConfigModuleVersionNotFound - requested version was not found Boilerplate now looks ``` from cffi.error import PkgConfigNotFound, PkgConfigError ... try: # try pkg-config way ffibuilder.set_source(..., pkgconfig=["libczmq >= 4.0.0"]) except PkgConfigNotFound as e: # if pkg-config is not installed, try backup ffibuilder.set_source(..., libraries=["czmq", "zmq", "uuid", "pgm"]) except PkgConfigError as e: # here we catch both PkgConfigModuleNotFound and PkgConfigModuleVersionNotFound # and raise it again - simply to show they are raised raise e from None ``` diff --git a/cffi/error.py b/cffi/error.py --- a/cffi/error.py +++ b/cffi/error.py @@ -21,3 +21,15 @@ """ An error raised when incomplete structures are passed into cdef, but no verification has been done """ + +class PkgConfigNotFound(Exception): + """ An error raised when pkgconfig was not found""" + +class PkgConfigError(Exception): + """ Generic super class for pkg-config related errors""" + +class PkgConfigModuleNotFound(PkgConfigError): + """ Module or it's pkg-config file was not found on a system""" + +class PkgConfigModuleVersionNotFound(PkgConfigError): + """ Requested version of module was not found""" diff --git a/cffi/pkgconfig.py b/cffi/pkgconfig.py --- a/cffi/pkgconfig.py +++ b/cffi/pkgconfig.py @@ -1,7 +1,11 @@ # pkg-config, https://www.freedesktop.org/wiki/Software/pkg-config/ integration for cffi import subprocess import sys +import re +from .error import PkgConfigNotFound +from .error import PkgConfigModuleVersionNotFound +from .error import PkgConfigError def merge_flags(cfg1, cfg2): """Merge values from cffi config flags cfg2 to cf1 @@ -19,11 +23,29 @@ def call(libname, flag): - """Calls pkg-config and returing the output""" + """Calls pkg-config and returing the output if found + """ a = ["pkg-config", "--print-errors"] a.append(flag) a.append(libname) - return subprocess.check_output(a) + pc = None + try: + pc = subprocess.Popen(a, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + except FileNotFoundError: + pass + if pc is None: + raise PkgConfigNotFound("pkg-config was not found on this system") + + bout, berr = pc.communicate() + if berr is not None: + err = berr.decode(sys.getfilesystemencoding()) + if re.search("Package .* was not found in the pkg-config search path", err, re.MULTILINE) is not None: + raise PkgConfigNotFoundError(err) + elif re.search("Requested '.*' but version of ", err, re.MULTILINE): + raise PkgConfigModuleVersionNotFound(err) + else: + PkgConfigError(err) + return bout def flags(libs): @@ -38,8 +60,11 @@ extra_link_args are extended with an output of pkg-config for libfoo and libbar. - Raise `FileNotFoundError` if pkg-config is not installed or - `subprocess.CalledProcessError` if pkg-config fails. + Raises + * PkgConfigNotFound if pkg-config is not installed + * PkgConfigModuleNotFound if requested module not found + * PkgConfigModuleVersionNotFound if requested version does not match + * PkgConfigError for all other errors """ subprocess.check_output(["pkg-config", "--version"]) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit