From 464b5aa6fb93632fd3d3a831aee9f5611eb9b65e Mon Sep 17 00:00:00 2001 From: Frederik Rietdijk Date: Mon, 1 May 2017 11:20:13 +0200 Subject: [PATCH] pythonPackages.Wand: fix loading extensions --- .../python-modules/Wand/default.nix | 51 ++++++ .../python-modules/Wand/libraries.patch | 149 ++++++++++++++++++ pkgs/top-level/python-packages.nix | 22 +-- 3 files changed, 202 insertions(+), 20 deletions(-) create mode 100644 pkgs/development/python-modules/Wand/default.nix create mode 100644 pkgs/development/python-modules/Wand/libraries.patch diff --git a/pkgs/development/python-modules/Wand/default.nix b/pkgs/development/python-modules/Wand/default.nix new file mode 100644 index 000000000000..f7b6aeae6157 --- /dev/null +++ b/pkgs/development/python-modules/Wand/default.nix @@ -0,0 +1,51 @@ +{ stdenv +, lib +, buildPythonPackage +, fetchPypi +, imagemagick +, pytest +, psutil +, memory_profiler +, pytest_xdist +, sharedLibraryExtension +}: + +let + magick_wand_library = "${imagemagick}/lib/libMagickWand-6.Q16${sharedLibraryExtension}"; + imagemagick_library = "${imagemagick}/lib/libMagickCore-6.Q16${sharedLibraryExtension}"; +in buildPythonPackage rec { + pname = "Wand"; + version = "0.4.4"; + name = "${pname}-${version}"; + + src = fetchPypi { + inherit pname version; + sha256 = "28e0454c9d16d69c5d5034918d96320d8f9f1377b4fdaf4944eec2f938c74704"; + }; + + checkInputs = [ pytest pytest_xdist memory_profiler psutil ]; + + buildInputs = [ imagemagick ]; + + patches = [ + ./libraries.patch + ]; + + inherit magick_wand_library imagemagick_library; + + postPatch = '' + substituteAllInPlace wand/api.py + ''; + + # No tests + doCheck = false; + meta = { + description = "Ctypes-based simple MagickWand API binding for Python"; + homepage = http://wand-py.org/; + license = with lib.licenses; [ mit ]; + }; + + passthru = { + inherit imagemagick; + }; +} diff --git a/pkgs/development/python-modules/Wand/libraries.patch b/pkgs/development/python-modules/Wand/libraries.patch new file mode 100644 index 000000000000..15b19f5168bd --- /dev/null +++ b/pkgs/development/python-modules/Wand/libraries.patch @@ -0,0 +1,149 @@ +diff --git a/wand/api.py b/wand/api.py +index 2c18513..1a1b511 100644 +--- a/wand/api.py ++++ b/wand/api.py +@@ -43,98 +43,6 @@ class c_magick_char_p(ctypes.c_char_p): + """ + library.MagickRelinquishMemory(self) + +- +-def library_paths(): +- """Iterates for library paths to try loading. The result paths are not +- guaranteed that they exist. +- +- :returns: a pair of libwand and libmagick paths. they can be the same. +- path can be ``None`` as well +- :rtype: :class:`tuple` +- +- """ +- libwand = None +- libmagick = None +- versions = '', '-6', '-Q16', '-Q8', '-6.Q16' +- options = '', 'HDRI', 'HDRI-2' +- system = platform.system() +- magick_home = os.environ.get('MAGICK_HOME') +- +- if system == 'Windows': +- # ImageMagick installers normally install coder and filter DLLs in +- # subfolders, we need to add those folders to PATH, otherwise loading +- # the DLL later will fail. +- try: +- with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, +- r"SOFTWARE\ImageMagick\Current") as reg_key: +- libPath = winreg.QueryValueEx(reg_key, "LibPath") +- coderPath = winreg.QueryValueEx(reg_key, "CoderModulesPath") +- filterPath = winreg.QueryValueEx(reg_key, "FilterModulesPath") +- magick_home = libPath[0] +- os.environ['PATH'] += (';' + libPath[0] + ";" + +- coderPath[0] + ";" + filterPath[0]) +- except OSError: +- # otherwise use MAGICK_HOME, and we assume the coder and +- # filter DLLs are in the same directory +- pass +- +- def magick_path(path): +- return os.path.join(magick_home, *path) +- combinations = itertools.product(versions, options) +- for suffix in (version + option for version, option in combinations): +- # On Windows, the API is split between two libs. On other platforms, +- # it's all contained in one. +- if magick_home: +- if system == 'Windows': +- libwand = 'CORE_RL_wand_{0}.dll'.format(suffix), +- libmagick = 'CORE_RL_magick_{0}.dll'.format(suffix), +- yield magick_path(libwand), magick_path(libmagick) +- libwand = 'libMagickWand{0}.dll'.format(suffix), +- libmagick = 'libMagickCore{0}.dll'.format(suffix), +- yield magick_path(libwand), magick_path(libmagick) +- elif system == 'Darwin': +- libwand = 'lib', 'libMagickWand{0}.dylib'.format(suffix), +- yield magick_path(libwand), magick_path(libwand) +- else: +- libwand = 'lib', 'libMagickWand{0}.so'.format(suffix), +- yield magick_path(libwand), magick_path(libwand) +- if system == 'Windows': +- libwand = ctypes.util.find_library('CORE_RL_wand_' + suffix) +- libmagick = ctypes.util.find_library('CORE_RL_magick_' + suffix) +- yield libwand, libmagick +- libwand = ctypes.util.find_library('libMagickWand' + suffix) +- libmagick = ctypes.util.find_library('libMagickCore' + suffix) +- yield libwand, libmagick +- else: +- libwand = ctypes.util.find_library('MagickWand' + suffix) +- yield libwand, libwand +- +- +-def load_library(): +- """Loads the MagickWand library. +- +- :returns: the MagickWand library and the ImageMagick library +- :rtype: :class:`ctypes.CDLL` +- +- """ +- tried_paths = [] +- for libwand_path, libmagick_path in library_paths(): +- if libwand_path is None or libmagick_path is None: +- continue +- try: +- tried_paths.append(libwand_path) +- libwand = ctypes.CDLL(libwand_path) +- if libwand_path == libmagick_path: +- libmagick = libwand +- else: +- tried_paths.append(libmagick_path) +- libmagick = ctypes.CDLL(libmagick_path) +- except (IOError, OSError): +- continue +- return libwand, libmagick +- raise IOError('cannot find library; tried paths: ' + repr(tried_paths)) +- +- + if not hasattr(ctypes, 'c_ssize_t'): + if ctypes.sizeof(ctypes.c_uint) == ctypes.sizeof(ctypes.c_void_p): + ctypes.c_ssize_t = ctypes.c_int +@@ -176,43 +84,14 @@ class AffineMatrix(ctypes.Structure): + # Preserve the module itself even if it fails to import + sys.modules['wand._api'] = sys.modules['wand.api'] + +-try: +- libraries = load_library() +-except (OSError, IOError): +- msg = 'http://docs.wand-py.org/en/latest/guide/install.html' +- if sys.platform.startswith(('dragonfly', 'freebsd')): +- msg = 'pkg install' +- elif sys.platform == 'win32': +- msg += '#install-imagemagick-on-windows' +- elif sys.platform == 'darwin': +- mac_pkgmgrs = {'brew': 'brew install freetype imagemagick', +- 'port': 'port install imagemagick'} +- for pkgmgr in mac_pkgmgrs: +- with os.popen('which ' + pkgmgr) as f: +- if f.read().strip(): +- msg = mac_pkgmgrs[pkgmgr] +- break +- else: +- msg += '#install-imagemagick-on-mac' +- else: +- distname, _, __ = platform.linux_distribution() +- distname = (distname or '').lower() +- if distname in ('debian', 'ubuntu'): +- msg = 'apt-get install libmagickwand-dev' +- elif distname in ('fedora', 'centos', 'redhat'): +- msg = 'yum install ImageMagick-devel' +- raise ImportError('MagickWand shared library not found.\n' +- 'You probably had not installed ImageMagick library.\n' +- 'Try to install:\n ' + msg) +- + #: (:class:`ctypes.CDLL`) The MagickWand library. +-library = libraries[0] ++library = ctypes.CDLL("@magick_wand_library@") + + #: (:class:`ctypes.CDLL`) The ImageMagick library. It is the same with + #: :data:`library` on platforms other than Windows. + #: + #: .. versionadded:: 0.1.10 +-libmagick = libraries[1] ++libmagick = ctypes.CDLL("@imagemagick_library@") + + try: + library.MagickWandGenesis.argtypes = [] diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 3e89d46885fd..e8d667753578 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -26721,28 +26721,10 @@ EOF websockets = callPackage ../development/python-modules/websockets { }; - Wand = buildPythonPackage rec { - pname = "Wand"; - version = "0.4.4"; - name = "${pname}-${version}"; - - src = pkgs.fetchurl { - url = "mirror://pypi/${builtins.substring 0 1 pname}/${pname}/${name}.tar.gz"; - sha256 = "28e0454c9d16d69c5d5034918d96320d8f9f1377b4fdaf4944eec2f938c74704"; - }; - - buildInputs = with self; [ pkgs.imagemagick pytest psutil memory_profiler pytest_xdist ]; - - # No tests - doCheck = false; - meta = { - description = "Ctypes-based simple MagickWand API binding for Python"; - homepage = http://wand-py.org/; - platforms = platforms.all; - }; + Wand = callPackage ../development/python-modules/Wand { + imagemagick = pkgs.imagemagickBig; }; - wcwidth = buildPythonPackage rec { name = "wcwidth-${version}"; version = "0.1.6";