commit 4fb881a2a4ee07670b18ac3fd8f414bdf5cf90ca14d2a21505bb45feb845062b Author: Markéta Machová Date: Tue Sep 17 12:36:12 2024 +0000 needed for python-fpdf2 OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-ghostscript?expand=0&rev=1 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b03811 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57affb6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.osc diff --git a/_service b/_service new file mode 100644 index 0000000..74dec7a --- /dev/null +++ b/_service @@ -0,0 +1,7 @@ + + + http + gitlab.com + pdftools/python-ghostscript/-/raw/develop/test/testimage.bmp + + \ No newline at end of file diff --git a/_service:download_url:testimage.bmp b/_service:download_url:testimage.bmp new file mode 100644 index 0000000..5bcc397 Binary files /dev/null and b/_service:download_url:testimage.bmp differ diff --git a/ghostscript-0.7.tar.gz b/ghostscript-0.7.tar.gz new file mode 100644 index 0000000..6cdcca0 --- /dev/null +++ b/ghostscript-0.7.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7875a87098740eb0be3de2d9662d15db727305ca9a6d4b7534a3cc33a4b965a +size 46557 diff --git a/python-ghostscript-update-tests.patch b/python-ghostscript-update-tests.patch new file mode 100644 index 0000000..544bf11 --- /dev/null +++ b/python-ghostscript-update-tests.patch @@ -0,0 +1,379 @@ +diff -Nru ghostscript-0.7/MANIFEST.in ghostscript-0.7-update-tests/MANIFEST.in +--- ghostscript-0.7/MANIFEST.in 2021-03-06 12:54:56.000000000 -0300 ++++ ghostscript-0.7-update-tests/MANIFEST.in 2024-09-16 09:39:36.434531108 -0300 +@@ -1,5 +1,5 @@ + include COPYING + include README.txt + exclude .gitgnore +-recursive-include test *.xml *.py *.bmp ++recursive-include test *.xml *.py *.bmp *.ps + #recursive-include doc *.html *.1 +Binary files ghostscript-0.7/test/hello_world.bmp and ghostscript-0.7-update-tests/test/hello_world.bmp differ +diff -Nru ghostscript-0.7/test/test_highlevel.py ghostscript-0.7-update-tests/test/test_highlevel.py +--- ghostscript-0.7/test/test_highlevel.py 2021-03-06 12:54:56.000000000 -0300 ++++ ghostscript-0.7-update-tests/test/test_highlevel.py 2024-09-16 10:10:16.046587248 -0300 +@@ -1,7 +1,7 @@ + # -*- coding: utf-8 -*- + # + # This file is part of python-ghostscript. +-# Copyright 2010-2021 by Hartmut Goebel ++# Copyright 2010-2023 by Hartmut Goebel + # + # This program is free software: you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by +@@ -14,39 +14,33 @@ + # General Public License for more details. + # + # You should have received a copy of the GNU General Public License +-# along with this program. If not, see . ++# along with this program. If not, see . + # + + __author__ = "Hartmut Goebel " +-__copyright__ = "Copyright 2010-2021 by Hartmut Goebel " ++__copyright__ = "Copyright 2010-2023 by Hartmut Goebel " + __licence__ = "GNU General Public License version 3 (GPL v3)" + + import io +-import sys, os +-import locale # required to encode file paths + import binascii ++import pathlib + import warnings + +-import py, pytest ++import pytest + + import ghostscript as gslib + + +-postscript_img = b""" +- /Helvetica findfont 12 scalefont setfont +- 0 0 moveto +- (Hello World) show +- showpage +- """ +- + HELLO_WORLD = ''.join(('%x' % ord(c) for c in 'Hello World')) + postscript_doc = ('<%s> = flush' % HELLO_WORLD).encode('ascii') + + STDARGS = ['test.py', '-dNOPAUSE', '-dBATCH', '-dSAFER', '-q', +- '-sDEVICE=bmp16', '-g80x12'] ++ '-sDEVICE=bmp16', '-g80x20'] + +-TEST_PIC_FILENAME = os.path.join(os.path.dirname(__file__), 'hello_world.bmp') +-TEST_PIC_DATA = py.path.local(TEST_PIC_FILENAME).read('rb') ++POSTSCRIPT_FILE = pathlib.Path(__file__).with_name('testimage.ps') ++POSTSCRIPT_DATA = POSTSCRIPT_FILE.read_bytes() ++TEST_PIC = POSTSCRIPT_FILE.with_suffix('.bmp') ++TEST_PIC_DATA = TEST_PIC.read_bytes() + + + # Ensure the instanse is removed after all high-level tests have been +@@ -71,7 +65,7 @@ + + + def test_revision_instance(instance): +- with gslib.Ghostscript('-dBATCH', '-q') as gs: ++ with gslib.Ghostscript('test.py', '-dBATCH', '-q') as gs: + rev1 = gs.revision() + rev2 = gslib.revision() + assert rev1 == rev2 +@@ -80,7 +74,7 @@ + def test_simple(instance, tmpdir): + """Let ghostscript read from a file and write to a file""" + infile = tmpdir.join('in.ps') +- infile.write(postscript_img) ++ infile.write(POSTSCRIPT_DATA) + outfile = tmpdir.join('out.bmp') + + # Using a context with an empty body looks not like good code, So +@@ -95,7 +89,7 @@ + def test_unicode_arguments(instance, tmpdir): + """Let ghostscript read from a file and write to a file""" + infile = tmpdir.join('in-äöü.ps') +- infile.write(postscript_img) ++ infile.write(POSTSCRIPT_DATA) + outfile = tmpdir.join('outäöü.bmp') + + gs = gslib.Ghostscript(*STDARGS, '-sOutputFile=%s' % outfile, str(infile)) +@@ -108,7 +102,7 @@ + def test_run_string_empty(instance, tmpdir): + """Let ghostscript read from a file and write to a file""" + infile = tmpdir.join('in.ps') +- infile.write(postscript_img) ++ infile.write(POSTSCRIPT_DATA) + outfile = tmpdir.join('out.bmp') + + with gslib.Ghostscript(*STDARGS, '-sOutputFile=%s' % outfile) as gs: +@@ -128,7 +122,7 @@ + outfile = tmpdir.join('out.bmp') + + with gslib.Ghostscript(*STDARGS, '-sOutputFile=%s' % outfile) as gs: +- gs.run_string(postscript_img) ++ gs.run_string(POSTSCRIPT_DATA) + + data = outfile.read('rb') + assert data == TEST_PIC_DATA +@@ -138,7 +132,7 @@ + """Let ghostscript read from stdin and write to a file""" + outfile = tmpdir.join('out.bmp') + gs = gslib.Ghostscript(*STDARGS, '-sOutputFile=%s' % outfile, '-', +- stdin=io.BytesIO(postscript_img)) ++ stdin=io.BytesIO(POSTSCRIPT_DATA)) + gs.exit() + + data = outfile.read('rb') +@@ -176,15 +170,13 @@ + keep stdout on the console. + """ + stderr = io.BytesIO() # buffer for collecting stderr +- try: ++ with pytest.raises(gslib.GhostscriptError): ++ # this call is expected to fail due to the intended error in ++ # the postscript code + with gslib.Ghostscript(*STDARGS, '-', + stdin=io.BytesIO(b'foobar'), + stderr=stderr): +- # this call is expected to fail due to the intended error in +- # the postscript code + pass +- except gslib.GhostscriptError: +- pass + + data = stderr.getvalue() + assert b'Unrecoverable error' in data +@@ -197,15 +189,13 @@ + """ + stdout = io.BytesIO() # buffer for collecting the output + stderr = io.BytesIO() # buffer for collecting stderr +- try: ++ with pytest.raises(gslib.GhostscriptError): ++ # this call is expected to fail due to the intended error in ++ # the postscript code + with gslib.Ghostscript(*STDARGS, '-', + stdin=io.BytesIO(b'foobar'), + stdout=stdout, stderr=stderr): +- # this call is expected to fail due to the intended error in +- # the postscript code + pass +- except gslib.GhostscriptError: +- pass + + data = stdout.getvalue() + assert b'Error: /undefined in foobar' in data +@@ -219,8 +209,9 @@ + # Cause all warnings to always be triggered + warnings.simplefilter("always") + # Trigger the warning +- with gslib.Ghostscript(b'-dBATCH', b'-q') as gs: ++ with gslib.Ghostscript(b'test.py', b'-dBATCH', b'-q') as gs: + pass + assert len(w) == 1 + assert issubclass(w[-1].category, DeprecationWarning) + assert "deprecated" in str(w[-1].message) ++ +Binary files ghostscript-0.7/test/testimage.bmp and ghostscript-0.7-update-tests/test/testimage.bmp differ +diff -Nru ghostscript-0.7/test/testimage.ps ghostscript-0.7-update-tests/test/testimage.ps +--- ghostscript-0.7/test/testimage.ps 1969-12-31 21:00:00.000000000 -0300 ++++ ghostscript-0.7-update-tests/test/testimage.ps 2024-09-16 09:42:20.618536118 -0300 +@@ -0,0 +1,22 @@ ++%!PS-Adobe-3.0 ++%%BoundingBox: 0 0 80 50 ++newpath ++0 0 moveto ++0 20 rlineto ++40 0 rlineto ++closepath ++gsave ++0.5 setgray ++fill ++grestore ++newpath ++40 0 moveto ++0 20 rlineto ++40 0 rlineto ++closepath ++gsave ++0.7 setgray ++fill ++grestore ++showpage ++ +diff -Nru ghostscript-0.7/test/test_lowlevel.py ghostscript-0.7-update-tests/test/test_lowlevel.py +--- ghostscript-0.7/test/test_lowlevel.py 2021-03-06 12:54:56.000000000 -0300 ++++ ghostscript-0.7-update-tests/test/test_lowlevel.py 2024-09-16 10:08:18.602583664 -0300 +@@ -1,7 +1,7 @@ + # -*- coding: utf-8 -*- + # + # This file is part of python-ghostscript. +-# Copyright 2010-2021 by Hartmut Goebel ++# Copyright 2010-2023 by Hartmut Goebel + # + # This program is free software: you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by +@@ -14,41 +14,41 @@ + # General Public License for more details. + # + # You should have received a copy of the GNU General Public License +-# along with this program. If not, see . ++# along with this program. If not, see . + # + + __author__ = "Hartmut Goebel " +-__copyright__ = "Copyright 2010-2021 by Hartmut Goebel " ++__copyright__ = "Copyright 2010-2023 by Hartmut Goebel " + __licence__ = "GNU General Public License version 3 (GPL v3)" + + import io +-import sys, os +-import locale # required to encode file paths ++import locale # required to encode arguments + import binascii ++import pathlib + +-import py ++import pytest + + import ghostscript._gsprint as gs + +-postscript_img = b""" +- /Helvetica findfont 12 scalefont setfont +- 0 0 moveto +- (Hello World) show +- showpage +- """ + + HELLO_WORLD = ''.join(('%x' % ord(c) for c in 'Hello World')) + #HELLO_WORLD = binascii.hexlify('Hello World') + postscript_doc = ('<%s> = flush' % HELLO_WORLD).encode('ascii') + ++# For the low-level interface arguments have to be bytes. Encode them ++# using local encoding to save calling set_arg_encoding(). + STDARGS = [b'test.py', b'-dNOPAUSE', b'-dBATCH', b'-dSAFER', b'-q', +- b'-sDEVICE=bmp16', b'-g80x12'] ++ b'-sDEVICE=bmp16', b'-g80x20'] + +-TEST_PIC_FILENAME = os.path.join(os.path.dirname(__file__), 'hello_world.bmp') +-TEST_PIC_DATA = py.path.local(TEST_PIC_FILENAME).read('rb') ++POSTSCRIPT_FILE = pathlib.Path(__file__).with_name('testimage.ps') ++POSTSCRIPT_DATA = POSTSCRIPT_FILE.read_bytes() ++TEST_PIC = POSTSCRIPT_FILE.with_suffix('.bmp') ++TEST_PIC_DATA = TEST_PIC.read_bytes() + + + def _encode(*args): ++ # For the low-level interface arguments have to be bytes. Encode ++ # them using local encoding to save calling set_arg_encoding(). + encoding = locale.getpreferredencoding() + return [a.encode(encoding) for a in args] + +@@ -70,8 +70,8 @@ + instance = gs.new_instance() + + try: +- gs.init_with_args(instance, args) +- gs.run_string(instance, postscript_img) ++ assert gs.init_with_args(instance, args) == 0 ++ assert gs.run_string(instance, POSTSCRIPT_DATA) == 0 + finally: + gs.exit(instance) + gs.delete_instance(instance) +@@ -80,17 +80,33 @@ + assert data == TEST_PIC_DATA + + ++def test_run_bugyy_string(tmpdir): ++ """ ++ Test whether the program flow (try/finally, gs.exit, ++ gs.delete_instance) is correct if executing fails. ++ """ ++ args = STDARGS ++ instance = gs.new_instance() ++ try: ++ assert gs.init_with_args(instance, args) == 0 ++ with pytest.raises(gs.GhostscriptError): ++ gs.run_string(instance, b"invalid postscript code") ++ finally: ++ gs.exit(instance) ++ gs.delete_instance(instance) ++ ++ + def test_simple(tmpdir): + """Let ghostscript read from a file and write to a file""" + infile = tmpdir.join('in.ps') +- infile.write(postscript_img) ++ infile.write(POSTSCRIPT_DATA) + outfile = tmpdir.join('out.bmp') + + args = STDARGS + _encode('-sOutputFile=%s' % outfile, str(infile)) + + instance = gs.new_instance() + try: +- gs.init_with_args(instance, args) ++ assert gs.init_with_args(instance, args) == 0 + finally: + gs.exit(instance) + gs.delete_instance(instance) +@@ -103,7 +119,7 @@ + instance = gs.new_instance() + + # wrappers like in +- # http://ghostscript.com/doc/8.54/API.htm#Example_usage ++ # https://ghostscript.readthedocs.io/en/gs10.0.0/API.html#Example_usage + if stdin is not None: stdin = gs._wrap_stdin(stdin) + if stdout is not None: stdout = gs._wrap_stdout(stdout) + if stderr is not None: stderr = gs._wrap_stderr(stderr) +@@ -122,7 +138,7 @@ + + args = STDARGS + _encode('-sOutputFile=%s' % outfile, '-') + +- _gs_stdio(args, stdin=io.BytesIO(postscript_img)) ++ _gs_stdio(args, stdin=io.BytesIO(POSTSCRIPT_DATA)) + + data = outfile.read('rb') + assert data == TEST_PIC_DATA +@@ -164,12 +180,10 @@ + + stderr = io.BytesIO() # buffer for collecting stderr + +- try: ++ with pytest.raises(gs.GhostscriptError): + # this call is expected to fail due to the intended error in + # the postscript code + _gs_stdio(args, stdin=io.BytesIO(b'foobar'), stderr=stderr) +- except gs.GhostscriptError: +- pass + + data = stderr.getvalue() + assert b'Unrecoverable error' in data +@@ -185,13 +199,11 @@ + stdout = io.BytesIO() # buffer for collecting the output + stderr = io.BytesIO() # buffer for collecting stderr + +- try: ++ with pytest.raises(gs.GhostscriptError): + # this call is expected to fail due to the intended error in + # the postscript code + _gs_stdio(args, + stdin=io.BytesIO(b'foobar'), stdout=stdout, stderr=stderr) +- except gs.GhostscriptError: +- pass + + data = stdout.getvalue() + assert b'Error: /undefined in foobar' in data +@@ -206,10 +218,11 @@ + Use command line ghostscript to generate the image used in testing + """ + import subprocess +- outfile = TEST_PIC_FILENAME ++ args = ['gs'] + STDARGS[1:] + _encode('-sOutputFile=%s' % TEST_PIC, ++ str(POSTSCRIPT_FILE)) ++ subprocess.Popen(args).wait() + +- args = ['gs'] + STDARGS[1:] + _encode('-sOutputFile=%s' % outfile, '-') +- subprocess.Popen(args).communicate(postscript_doc) + + if __name__ == '__main__': + generate_test_picture() ++ diff --git a/python-ghostscript.changes b/python-ghostscript.changes new file mode 100644 index 0000000..41be4fb --- /dev/null +++ b/python-ghostscript.changes @@ -0,0 +1,21 @@ +------------------------------------------------------------------- +Mon Sep 16 13:34:01 UTC 2024 - Aline Werner + +- Add patch to change the tests to not use fonts, as they generated +different results depending on ghostscript version and platform: +https://gitlab.com/pdftools/python-ghostscript/-/commit/f2eaf4c9ae0907042b9a47e1e093f0414f50bdc2 + +------------------------------------------------------------------- +Fri Aug 23 20:17:22 UTC 2024 - Aline Werner + +- Enable tests. + +------------------------------------------------------------------- +Fri Aug 23 19:40:14 UTC 2024 - Aline Werner + +- Update to v0.7. + +------------------------------------------------------------------- +Sun Jun 28 02:12:37 AM UTC 2020 - John Vandenberg + +- Initial spec for v0.6 diff --git a/python-ghostscript.spec b/python-ghostscript.spec new file mode 100644 index 0000000..f6e453f --- /dev/null +++ b/python-ghostscript.spec @@ -0,0 +1,70 @@ +# +# spec file for package python-ghostscript +# +# Copyright (c) 2024 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via http://bugs.opensuse.org/ + + +%{?sle15_python_module_pythons} +Name: python-ghostscript +Version: 0.7 +Release: 0 +License: GPL-3.0-or-later +Summary: Python interface to the Ghostscript C-API +Group: Development/Languages/Python +Url: https://gitlab.com/pdftools/python-ghostscript +Source: https://files.pythonhosted.org/packages/source/g/ghostscript/ghostscript-%{version}.tar.gz +# Previous tests were dependent on fonts and generated different results +# depending on ghostscript version and platform +Patch1: python-ghostscript-update-tests.patch +BuildRequires: python-rpm-macros +BuildRequires: %{python_module pip} +BuildRequires: %{python_module devel} +BuildRequires: %{python_module setuptools} +BuildRequires: ghostscript >= 9.0.8 +# SECTION test requirements +BuildRequires: %{python_module pytest} +# /SECTION +BuildRequires: fdupes +Requires: ghostscript >= 9.0.8 +Requires: python-setuptools +BuildArch: noarch + +%python_subpackages + +%description +Python interface to the Ghostscript C-API, both high and low-level, based on ctypes. + +%prep +%autosetup -p1 -n ghostscript-%{version} +mv %{_sourcedir}/testimage.bmp test + +%build +%pyproject_wheel + +%install +%pyproject_install +%python_expand %fdupes %{buildroot}%{$python_sitelib} + +%check +%pytest -v + + +%files %{python_files} +%doc CHANGES.txt README.rst +%license COPYING +%{python_sitelib}/ghostscript +%{python_sitelib}/ghostscript-%{version}*-info + + +%changelog