From 16c2c6b66da22bcb9ee8bf1150c7c2b6e29b4162 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Sat, 9 Mar 2019 15:20:48 +0100 Subject: [PATCH 1/4] python3Packages.qasm2image: require Python 3.5 at least According to `setup.py` in 0.8 older Python wouldn't work. --- pkgs/development/python-modules/qasm2image/default.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkgs/development/python-modules/qasm2image/default.nix b/pkgs/development/python-modules/qasm2image/default.nix index 39c7b2055c1..8a49e8418fd 100644 --- a/pkgs/development/python-modules/qasm2image/default.nix +++ b/pkgs/development/python-modules/qasm2image/default.nix @@ -8,6 +8,7 @@ , svgwrite , colorama , python +, pythonOlder }: buildPythonPackage rec { @@ -21,6 +22,8 @@ buildPythonPackage rec { sha256 = "1bnkzv7wrdvrq71dmsqanb3v2hcsxh5zaglfcxm2d9zzpmvb4a2n"; }; + disabled = pythonOlder "3.5"; + propagatedBuildInputs = [ cairocffi cairosvg From 8dac8644700a364a45cd4537211df90ad509f5e4 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Mon, 11 Mar 2019 23:15:40 +0100 Subject: [PATCH 2/4] pythonPackages.thumbor: 6.6.0 -> 6.7.0 This patch ensures that the currently broken `thumbor`[1] package builds and works again. The following problems were fixed: * Rather than placing required packages (like `gifsicle` or `exiftool`) into the build input list, we reference them explicitly where needed to ensure that the package works after the build without further installs. * Skip the `test_redeye_applied` test case which is broken for a while now. [1] https://hydra.nixos.org/build/90290998 --- ...implementation-to-find-required-exec.patch | 277 ++++++++++++++++++ .../python-modules/thumbor/default.nix | 25 +- 2 files changed, 293 insertions(+), 9 deletions(-) create mode 100644 pkgs/development/python-modules/thumbor/0001-Don-t-use-which-implementation-to-find-required-exec.patch diff --git a/pkgs/development/python-modules/thumbor/0001-Don-t-use-which-implementation-to-find-required-exec.patch b/pkgs/development/python-modules/thumbor/0001-Don-t-use-which-implementation-to-find-required-exec.patch new file mode 100644 index 00000000000..4a2d9df0618 --- /dev/null +++ b/pkgs/development/python-modules/thumbor/0001-Don-t-use-which-implementation-to-find-required-exec.patch @@ -0,0 +1,277 @@ +From bd5a5b58b438ff34d27781e28cd7fab93bfc9f3f Mon Sep 17 00:00:00 2001 +From: Maximilian Bosch +Date: Sat, 9 Mar 2019 23:26:30 +0100 +Subject: [PATCH] Don't use `which` implementation to find required executables + +Nix specific patch. + +Rather than relying on a global state, we set an absolute store path for +all external dependencies to ensure their functionality. +--- + integration_tests/__init__.py | 4 ++-- + tests/engines/test_gif.py | 2 +- + tests/handlers/test_base_handler.py | 30 ++++++++++++++--------------- + tests/optimizers/test_gifv.py | 2 +- + tests/test_server.py | 4 ++++ + tests/test_utils.py | 3 +++ + thumbor/server.py | 7 +------ + 7 files changed, 26 insertions(+), 26 deletions(-) + +diff --git a/integration_tests/__init__.py b/integration_tests/__init__.py +index 9bdd0a3..7d9de8f 100644 +--- a/integration_tests/__init__.py ++++ b/integration_tests/__init__.py +@@ -15,7 +15,7 @@ class EngineCase(AsyncHTTPTestCase): + def get_app(self): + cfg = Config(SECURITY_KEY='ACME-SEC') + server_params = ServerParameters(None, None, None, None, None, None) +- server_params.gifsicle_path = which('gifsicle') ++ server_params.gifsicle_path = '@gifsicle@' + + cfg.DETECTORS = [ + 'thumbor.detectors.face_detector', +@@ -28,7 +28,7 @@ class EngineCase(AsyncHTTPTestCase): + cfg.FILE_LOADER_ROOT_PATH = os.path.join(os.path.dirname(__file__), 'imgs') + cfg.ENGINE = getattr(self, 'engine', None) + cfg.USE_GIFSICLE_ENGINE = True +- cfg.FFMPEG_PATH = which('ffmpeg') ++ cfg.FFMPEG_PATH = '@ffmpeg@' + cfg.ENGINE_THREADPOOL_SIZE = 10 + cfg.OPTIMIZERS = [ + 'thumbor.optimizers.gifv', +diff --git a/tests/engines/test_gif.py b/tests/engines/test_gif.py +index c0c8430..ce0cc51 100644 +--- a/tests/engines/test_gif.py ++++ b/tests/engines/test_gif.py +@@ -44,7 +44,7 @@ class GitEngineTestCase(TestCase): + def get_server(self): + server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None) + server.security_key = 'ACME-SEC' +- server.gifsicle_path = which('gifsicle') ++ server.gifsicle_path = '@gifsicle@' + return server + + def get_context(self, *args, **kwargs): +diff --git a/tests/handlers/test_base_handler.py b/tests/handlers/test_base_handler.py +index 69dc110..4493abe 100644 +--- a/tests/handlers/test_base_handler.py ++++ b/tests/handlers/test_base_handler.py +@@ -557,7 +557,7 @@ class ImageOperationsWithAutoWebPTestCase(BaseImagingTestCase): + server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None) + server.security_key = 'ACME-SEC' + ctx = Context(server, cfg, importer) +- ctx.server.gifsicle_path = which('gifsicle') ++ ctx.server.gifsicle_path = '@gifsicle@' + return ctx + + def get_as_webp(self, url): +@@ -657,7 +657,7 @@ class ImageOperationsWithAutoWebPWithResultStorageTestCase(BaseImagingTestCase): + server.security_key = 'ACME-SEC' + ctx = Context(server, cfg, importer) + ctx.request = self.get_request() +- ctx.server.gifsicle_path = which('gifsicle') ++ ctx.server.gifsicle_path = '@gifsicle@' + return ctx + + @property +@@ -783,7 +783,7 @@ class ImageOperationsWithGifVTestCase(BaseImagingTestCase): + cfg = Config(SECURITY_KEY='ACME-SEC') + cfg.LOADER = "thumbor.loaders.file_loader" + cfg.FILE_LOADER_ROOT_PATH = self.loader_path +- cfg.FFMPEG_PATH = which('ffmpeg') ++ cfg.FFMPEG_PATH = '@ffmpeg@' + cfg.OPTIMIZERS = [ + 'thumbor.optimizers.gifv', + ] +@@ -793,7 +793,7 @@ class ImageOperationsWithGifVTestCase(BaseImagingTestCase): + server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None) + server.security_key = 'ACME-SEC' + ctx = Context(server, cfg, importer) +- ctx.server.gifsicle_path = which('gifsicle') ++ ctx.server.gifsicle_path = '@gifsicle@' + return ctx + + def test_should_convert_animated_gif_to_mp4_when_filter_without_params(self): +@@ -828,7 +828,7 @@ class ImageOperationsImageCoverTestCase(BaseImagingTestCase): + server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None) + server.security_key = 'ACME-SEC' + ctx = Context(server, cfg, importer) +- ctx.server.gifsicle_path = which('gifsicle') ++ ctx.server.gifsicle_path = '@gifsicle@' + return ctx + + def test_can_get_image_cover(self): +@@ -849,7 +849,7 @@ class ImageOperationsWithResultStorageTestCase(BaseImagingTestCase): + cfg.RESULT_STORAGE_FILE_STORAGE_ROOT_PATH = self.root_path + + cfg.USE_GIFSICLE_ENGINE = True +- cfg.FFMPEG_PATH = which('ffmpeg') ++ cfg.FFMPEG_PATH = '@ffmpeg@' + cfg.AUTO_WEBP = True + cfg.OPTIMIZERS = [ + 'thumbor.optimizers.gifv', +@@ -860,7 +860,7 @@ class ImageOperationsWithResultStorageTestCase(BaseImagingTestCase): + server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None) + server.security_key = 'ACME-SEC' + ctx = Context(server, cfg, importer) +- ctx.server.gifsicle_path = which('gifsicle') ++ ctx.server.gifsicle_path = '@gifsicle@' + + return ctx + +@@ -891,7 +891,7 @@ class ImageOperationsResultStorageOnlyTestCase(BaseImagingTestCase): + cfg.RESULT_STORAGE = 'thumbor.result_storages.file_storage' + cfg.RESULT_STORAGE_EXPIRATION_SECONDS = 60 + cfg.RESULT_STORAGE_FILE_STORAGE_ROOT_PATH = self.root_path +- cfg.FFMPEG_PATH = which('ffmpeg') ++ cfg.FFMPEG_PATH = '@ffmpeg@' + + cfg.USE_GIFSICLE_ENGINE = True + cfg.AUTO_WEBP = True +@@ -904,7 +904,7 @@ class ImageOperationsResultStorageOnlyTestCase(BaseImagingTestCase): + server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None) + server.security_key = 'ACME-SEC' + ctx = Context(server, cfg, importer) +- ctx.server.gifsicle_path = which('gifsicle') ++ ctx.server.gifsicle_path = '@gifsicle@' + + return ctx + +@@ -1040,7 +1040,7 @@ class ImageOperationsWithMaxPixels(BaseImagingTestCase): + server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None) + server.security_key = 'ACME-SEC' + ctx = Context(server, cfg, importer) +- ctx.server.gifsicle_path = which('gifsicle') ++ ctx.server.gifsicle_path = '@gifsicle@' + return ctx + + def test_should_error(self): +@@ -1061,7 +1061,7 @@ class ImageOperationsWithRespectOrientation(BaseImagingTestCase): + server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None) + server.security_key = 'ACME-SEC' + self.context = Context(server, cfg, importer) +- self.context.server.gifsicle_path = which('gifsicle') ++ self.context.server.gifsicle_path = '@gifsicle@' + return self.context + + def test_should_be_ok_when_orientation_exif(self): +@@ -1153,7 +1153,7 @@ class ImageOperationsWithJpegtranTestCase(BaseImagingTestCase): + cfg = Config(SECURITY_KEY='ACME-SEC') + cfg.LOADER = "thumbor.loaders.file_loader" + cfg.FILE_LOADER_ROOT_PATH = self.loader_path +- cfg.JPEGTRAN_PATH = which('jpegtran') ++ cfg.JPEGTRAN_PATH = '@jpegtran@' + cfg.PROGRESSIVE_JPEG = True, + cfg.RESULT_STORAGE_STORES_UNSAFE = True, + cfg.OPTIMIZERS = [ +@@ -1175,9 +1175,7 @@ class ImageOperationsWithJpegtranTestCase(BaseImagingTestCase): + f.write(response.body) + f.close() + +- exiftool = which('exiftool') +- if not exiftool: +- raise AssertionError('exiftool was not found. Please install it to run thumbor\'s tests.') ++ exiftool = '@exiftool@' + + command = [ + exiftool, +@@ -1221,7 +1219,7 @@ class ImageOperationsWithoutStorage(BaseImagingTestCase): + server = ServerParameters(8889, 'localhost', 'thumbor.conf', None, 'info', None) + server.security_key = 'ACME-SEC' + ctx = Context(server, cfg, importer) +- ctx.server.gifsicle_path = which('gifsicle') ++ ctx.server.gifsicle_path = '@gifsicle@' + return ctx + + def test_meta(self): +diff --git a/tests/optimizers/test_gifv.py b/tests/optimizers/test_gifv.py +index 229e9cd..066f2d5 100644 +--- a/tests/optimizers/test_gifv.py ++++ b/tests/optimizers/test_gifv.py +@@ -31,7 +31,7 @@ class GifvOptimizerTest(TestCase): + def get_context(self): + conf = Config() + conf.STATSD_HOST = '' +- conf.FFMPEG_PATH = which('ffmpeg') ++ conf.FFMPEG_PATH = '@ffmpeg@' + ctx = Context(config=conf) + ctx.request = RequestParameters() + ctx.request.filters.append('gifv') +diff --git a/tests/test_server.py b/tests/test_server.py +index 5b31750..c2a65dc 100644 +--- a/tests/test_server.py ++++ b/tests/test_server.py +@@ -11,6 +11,8 @@ + from unittest import TestCase + import mock + ++from nose.tools import nottest ++ + from preggy import expect + + from thumbor.app import ThumborServiceApp +@@ -118,6 +120,7 @@ class ServerTestCase(TestCase): + expect(server_parameters.security_key).to_equal('something') + + @mock.patch.object(thumbor.server, 'which') ++ @nottest + def test_validate_gifsicle_path(self, which_mock): + server_parameters = mock.Mock(security_key=None) + conf = Config(SECURITY_KEY='test', USE_GIFSICLE_ENGINE=True) +@@ -128,6 +131,7 @@ class ServerTestCase(TestCase): + expect(server_parameters.gifsicle_path).to_equal('/usr/bin/gifsicle') + + @mock.patch.object(thumbor.server, 'which') ++ @nottest + def test_validate_null_gifsicle_path(self, which_mock): + server_parameters = mock.Mock(security_key=None) + conf = Config(SECURITY_KEY='test', USE_GIFSICLE_ENGINE=True) +diff --git a/tests/test_utils.py b/tests/test_utils.py +index 38cd51b..7dd0b3e 100644 +--- a/tests/test_utils.py ++++ b/tests/test_utils.py +@@ -10,6 +10,7 @@ + + from mock import Mock, patch + from unittest import TestCase ++from nose.tools import nottest + import logging + + from preggy import expect +@@ -112,6 +113,7 @@ class UtilsTestCase(TestCase): + test_func() + mock_warn.assert_called_once_with('Deprecated function test_func: func2') + ++ @nottest + def test_can_which_by_path(self): + result = which('/bin/ls') + expect(result).to_equal('/bin/ls') +@@ -119,6 +121,7 @@ class UtilsTestCase(TestCase): + result = which('/tmp') + expect(result).to_be_null() + ++ @nottest + def test_can_which_by_env(self): + result = which('ls') + expect(result).to_equal('/bin/ls') +diff --git a/thumbor/server.py b/thumbor/server.py +index c75a769..821163b 100644 +--- a/thumbor/server.py ++++ b/thumbor/server.py +@@ -89,12 +89,7 @@ def validate_config(config, server_parameters): + warnings.simplefilter('error', Image.DecompressionBombWarning) + + if config.USE_GIFSICLE_ENGINE: +- server_parameters.gifsicle_path = which('gifsicle') +- if server_parameters.gifsicle_path is None: +- raise RuntimeError( +- 'If using USE_GIFSICLE_ENGINE configuration to True, the `gifsicle` binary must be in the PATH ' +- 'and must be an executable.' +- ) ++ server_parameters.gifsicle_path = '@gifsicle@' + + + def get_context(server_parameters, config, importer): +-- +2.18.1 + diff --git a/pkgs/development/python-modules/thumbor/default.nix b/pkgs/development/python-modules/thumbor/default.nix index 0f10692685b..fcba0a96861 100644 --- a/pkgs/development/python-modules/thumbor/default.nix +++ b/pkgs/development/python-modules/thumbor/default.nix @@ -2,12 +2,12 @@ , pillow, derpconf, python_magic, libthumbor, webcolors , piexif, futures, statsd, thumborPexif, fetchFromGitHub, isPy3k, lib , mock, raven, nose, yanc, remotecv, pyssim, cairosvg1, preggy, opencv3 -, pkgs, coreutils +, pkgs, coreutils, substituteAll }: buildPythonPackage rec { pname = "thumbor"; - version = "6.6.0"; + version = "6.7.0"; disabled = isPy3k; # see https://github.com/thumbor/thumbor/issues/1004 @@ -16,9 +16,19 @@ buildPythonPackage rec { owner = pname; repo = pname; rev = version; - sha256 = "0m4q40fcha1aydyr1khjhnb08cdfma67yxgyhsvwar5a6sl0906i"; + sha256 = "1qv02jz7ivn38dsywp7nxrlflly86x9pm2pk3yqi8m8myhc7lipg"; }; + patches = [ + (substituteAll { + src = ./0001-Don-t-use-which-implementation-to-find-required-exec.patch; + gifsicle = "${pkgs.gifsicle}/bin/gifsicle"; + exiftool = "${pkgs.exiftool}/bin/exiftool"; + jpegtran = "${pkgs.libjpeg}/bin/jpegtran"; + ffmpeg = "${pkgs.ffmpeg}/bin/ffmpeg"; + }) + ]; + postPatch = '' substituteInPlace "setup.py" \ --replace '"argparse",' "" ${lib.optionalString isPy3k ''--replace '"futures",' ""''} @@ -39,10 +49,10 @@ buildPythonPackage rec { mock yanc remotecv - cairosvg1 raven pkgs.redis pkgs.glibcLocales + pkgs.gifsicle ]; propagatedBuildInputs = [ @@ -58,10 +68,7 @@ buildPythonPackage rec { webcolors piexif statsd - pkgs.exiftool - pkgs.libjpeg - pkgs.ffmpeg - pkgs.gifsicle + cairosvg1 ] ++ lib.optionals (!isPy3k) [ futures thumborPexif ]; # Remove the source tree before running nosetests because otherwise nosetests @@ -71,7 +78,7 @@ buildPythonPackage rec { redis-server --port 6668 --requirepass hey_you & rm -r thumbor export LC_ALL="en_US.UTF-8" - nosetests -v --with-yanc -s tests/ + nosetests -v --with-yanc -s tests/ -e test_redeye_applied ''; meta = with lib; { From e878fd6f5f38a1daeee25fdfb205fe5d96fce15c Mon Sep 17 00:00:00 2001 From: "Alexander V. Nikolaev" Date: Sat, 2 Mar 2019 19:56:39 +0200 Subject: [PATCH 3/4] pythonPackages.cairocffi: support 1.0 and 0.9 This patch ensures that Python2 can be used if cairocffi is used. Version 1.0 dropped Python 2 support. --- .../python-modules/cairocffi/default.nix | 90 +++++++++++-------- .../cairocffi/dlopen-paths-0.9.patch | 47 ++++++++++ .../cairocffi/dlopen-paths.patch | 21 +++-- pkgs/top-level/python-packages.nix | 5 +- 4 files changed, 115 insertions(+), 48 deletions(-) create mode 100644 pkgs/development/python-modules/cairocffi/dlopen-paths-0.9.patch diff --git a/pkgs/development/python-modules/cairocffi/default.nix b/pkgs/development/python-modules/cairocffi/default.nix index 80b23e43380..863e181f991 100644 --- a/pkgs/development/python-modules/cairocffi/default.nix +++ b/pkgs/development/python-modules/cairocffi/default.nix @@ -1,12 +1,14 @@ # FIXME: make gdk_pixbuf dependency optional { stdenv , buildPythonPackage +, pythonOlder , fetchPypi , lib , substituteAll , makeFontsConf , freefont_ttf , pytest +, pytestrunner , glibcLocales , cairo , cffi @@ -15,46 +17,62 @@ , glib , gdk_pixbuf }: -buildPythonPackage rec { - pname = "cairocffi"; - version = "1.0.2"; +let + generic = { version, sha256, dlopen_patch, disabled ? false }: + buildPythonPackage rec { + pname = "cairocffi"; + inherit version disabled; - src = fetchPypi { - inherit pname version; - sha256 = "01ac51ae12c4324ca5809ce270f9dd1b67f5166fe63bd3e497e9ea3ca91946ff"; - }; + src = fetchPypi { + inherit pname version sha256; + }; - LC_ALL = "en_US.UTF-8"; + LC_ALL = "en_US.UTF-8"; - # checkPhase require at least one 'normal' font and one 'monospace', - # otherwise glyph tests fails - FONTCONFIG_FILE = makeFontsConf { - fontDirectories = [ freefont_ttf ]; - }; + # checkPhase require at least one 'normal' font and one 'monospace', + # otherwise glyph tests fails + FONTCONFIG_FILE = makeFontsConf { + fontDirectories = [ freefont_ttf ]; + }; - checkInputs = [ pytest glibcLocales ]; - propagatedBuildInputs = [ cairo cffi ] ++ lib.optional withXcffib xcffib; + checkInputs = [ pytest pytestrunner glibcLocales ]; + propagatedBuildInputs = [ cairo cffi ] ++ lib.optional withXcffib xcffib; - checkPhase = '' - py.test $out/${python.sitePackages} - ''; + checkPhase = '' + py.test $out/${python.sitePackages} + ''; - patches = [ - # OSError: dlopen() failed to load a library: gdk_pixbuf-2.0 / gdk_pixbuf-2.0-0 - (substituteAll { - src = ./dlopen-paths.patch; - ext = stdenv.hostPlatform.extensions.sharedLibrary; - cairo = cairo.out; - glib = glib.out; - gdk_pixbuf = gdk_pixbuf.out; - }) - ./fix_test_scaled_font.patch - ]; + patches = [ + # OSError: dlopen() failed to load a library: gdk_pixbuf-2.0 / gdk_pixbuf-2.0-0 + (substituteAll { + src = dlopen_patch; + ext = stdenv.hostPlatform.extensions.sharedLibrary; + cairo = cairo.out; + glib = glib.out; + gdk_pixbuf = gdk_pixbuf.out; + }) + ./fix_test_scaled_font.patch + ]; - meta = with lib; { - homepage = https://github.com/SimonSapin/cairocffi; - license = licenses.bsd3; - maintainers = with maintainers; []; - description = "cffi-based cairo bindings for Python"; - }; -} + meta = with lib; { + homepage = https://github.com/SimonSapin/cairocffi; + license = licenses.bsd3; + maintainers = with maintainers; []; + description = "cffi-based cairo bindings for Python"; + }; + }; +in + { + cairocffi_1_0 = generic { + version = "1.0.2"; + sha256 = "01ac51ae12c4324ca5809ce270f9dd1b67f5166fe63bd3e497e9ea3ca91946ff"; + dlopen_patch = ./dlopen-paths.patch; + disabled = pythonOlder "3.5"; + }; + + cairocffi_0_9 = generic { + version = "0.9.0"; + sha256 = "15386c3a9e08823d6826c4491eaccc7b7254b1dc587a3b9ce60c350c3f990337"; + dlopen_patch = ./dlopen-paths-0.9.patch; + }; + } diff --git a/pkgs/development/python-modules/cairocffi/dlopen-paths-0.9.patch b/pkgs/development/python-modules/cairocffi/dlopen-paths-0.9.patch new file mode 100644 index 00000000000..862f7bd4bf7 --- /dev/null +++ b/pkgs/development/python-modules/cairocffi/dlopen-paths-0.9.patch @@ -0,0 +1,47 @@ +commit 705dc9a55bd160625d9996e63fc7dc532d0ad0ab +Author: Alexander V. Nikolaev +Date: Sat Feb 6 08:09:06 2016 +0200 + + Patch dlopen() to allow direct paths to all required libs + + This patch is NixOS specific + +diff --git a/cairocffi/__init__.py b/cairocffi/__init__.py +index 718aa7f..1a1dcff 100644 +--- a/cairocffi/__init__.py ++++ b/cairocffi/__init__.py +@@ -27,20 +27,22 @@ VERSION = '0.7.2' + version = '1.10.0' + version_info = (1, 10, 0) + ++# Use hardcoded soname, because ctypes.util use gcc/objdump which shouldn't be required for runtime ++_LIBS = { ++ 'cairo': '@cairo@/lib/libcairo@ext@', ++ 'glib-2.0': '@glib@/lib/libglib-2.0@ext@', ++ 'gobject-2.0': '@glib@/lib/libgobject-2.0@ext@', ++ 'gdk_pixbuf-2.0': '@gdk_pixbuf@/lib/libgdk_pixbuf-2.0@ext@', ++} + +-def dlopen(ffi, *names): ++def dlopen(ffi, name, *names): + """Try various names for the same library, for different platforms.""" +- for name in names: +- for lib_name in [name, 'lib' + name]: +- try: +- path = ctypes.util.find_library(lib_name) +- if path: +- lib = ffi.dlopen(path) +- if lib: +- return lib +- except OSError: +- pass +- raise OSError("dlopen() failed to load a library: %s" % ' / '.join(names)) ++ path = _LIBS.get(name, None) ++ if path: ++ lib = ffi.dlopen(path) ++ if lib: ++ return lib ++ raise OSError("dlopen() failed to load a library: %s as %s" % (name, path)) + + + cairo = dlopen(ffi, 'cairo', 'cairo-2') diff --git a/pkgs/development/python-modules/cairocffi/dlopen-paths.patch b/pkgs/development/python-modules/cairocffi/dlopen-paths.patch index 862f7bd4bf7..d42b8bcce48 100644 --- a/pkgs/development/python-modules/cairocffi/dlopen-paths.patch +++ b/pkgs/development/python-modules/cairocffi/dlopen-paths.patch @@ -1,4 +1,4 @@ -commit 705dc9a55bd160625d9996e63fc7dc532d0ad0ab +commit 0435bc2577d4b18f54b78b2f5185abb2b2005982 Author: Alexander V. Nikolaev Date: Sat Feb 6 08:09:06 2016 +0200 @@ -7,12 +7,12 @@ Date: Sat Feb 6 08:09:06 2016 +0200 This patch is NixOS specific diff --git a/cairocffi/__init__.py b/cairocffi/__init__.py -index 718aa7f..1a1dcff 100644 +index 6061973..3538a58 100644 --- a/cairocffi/__init__.py +++ b/cairocffi/__init__.py -@@ -27,20 +27,22 @@ VERSION = '0.7.2' - version = '1.10.0' - version_info = (1, 10, 0) +@@ -21,19 +21,22 @@ VERSION = __version__ = (Path(__file__).parent / 'VERSION').read_text().strip() + version = '1.16.0' + version_info = (1, 16, 0) +# Use hardcoded soname, because ctypes.util use gcc/objdump which shouldn't be required for runtime +_LIBS = { @@ -26,13 +26,12 @@ index 718aa7f..1a1dcff 100644 +def dlopen(ffi, name, *names): """Try various names for the same library, for different platforms.""" - for name in names: -- for lib_name in [name, 'lib' + name]: +- for lib_name in (name, 'lib' + name): - try: - path = ctypes.util.find_library(lib_name) -- if path: -- lib = ffi.dlopen(path) -- if lib: -- return lib +- lib = ffi.dlopen(path or lib_name) +- if lib: +- return lib - except OSError: - pass - raise OSError("dlopen() failed to load a library: %s" % ' / '.join(names)) @@ -44,4 +43,4 @@ index 718aa7f..1a1dcff 100644 + raise OSError("dlopen() failed to load a library: %s as %s" % (name, path)) - cairo = dlopen(ffi, 'cairo', 'cairo-2') + cairo = dlopen(ffi, 'cairo', 'cairo-2', 'cairo-gobject-2', 'cairo.so.2') diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 5acc12fe4ba..ccef0e38c92 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -1311,7 +1311,10 @@ in { canmatrix = callPackage ../development/python-modules/canmatrix {}; - cairocffi = callPackage ../development/python-modules/cairocffi {}; + + cairocffi = let + inherit (callPackage ../development/python-modules/cairocffi {}) cairocffi_1_0 cairocffi_0_9; + in if isPy3k then cairocffi_1_0 else cairocffi_0_9; cairosvg1 = callPackage ../development/python-modules/cairosvg/1_x.nix {}; From 01cb9b01b8c69d0af451bc4c24df102bc0b92c99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=BCtz?= Date: Wed, 13 Mar 2019 23:27:46 +0100 Subject: [PATCH 4/4] python3.pkgs.cairosvg: 2.2.1 -> 2.3.0 --- .../python-modules/cairosvg/default.nix | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/pkgs/development/python-modules/cairosvg/default.nix b/pkgs/development/python-modules/cairosvg/default.nix index abaabb24b4d..17d442e4527 100644 --- a/pkgs/development/python-modules/cairosvg/default.nix +++ b/pkgs/development/python-modules/cairosvg/default.nix @@ -1,31 +1,21 @@ { stdenv, buildPythonPackage, fetchPypi, isPy3k, fetchpatch , cairocffi, cssselect2, defusedxml, pillow, tinycss2 -, pytestrunner, pytestcov, pytest-flake8, pytest-isort }: +, pytest, pytestrunner, pytestcov, pytest-flake8, pytest-isort }: buildPythonPackage rec { pname = "CairoSVG"; - version = "2.2.1"; + version = "2.3.0"; disabled = !isPy3k; src = fetchPypi { inherit pname version; - sha256 = "93c5b3204478c4e20c4baeb33807db5311b4420c21db2f21034a6deda998cb14"; + sha256 = "66f333ef5dc79fdfbd3bbe98adc791b1f854e0461067d202fa7b15de66d517ec"; }; - patches = [ - # Fix tests. Remove with the next release - (fetchpatch { - url = https://github.com/Kozea/CairoSVG/commit/1f403ad229f0e2782d6427a79f0fbeb6b76148b6.patch; - sha256 = "1dxpj5zh8wmx9f8pj11hrixd5jlaqq5xlcdnbl462bh29zj18l26"; - }) - ]; - - LC_ALL="en_US.UTF-8"; - propagatedBuildInputs = [ cairocffi cssselect2 defusedxml pillow tinycss2 ]; - checkInputs = [ pytestrunner pytestcov pytest-flake8 pytest-isort ]; + checkInputs = [ pytest pytestrunner pytestcov pytest-flake8 pytest-isort ]; meta = with stdenv.lib; { homepage = https://cairosvg.org;