diff --git a/.files b/.files index 6b140a1..80dc44b 100644 Binary files a/.files and b/.files differ diff --git a/.rev b/.rev index 939c122..21bb194 100644 --- a/.rev +++ b/.rev @@ -118,4 +118,12 @@ * Some general performance improvements 930172 + + 1bb8139d0baf8129eb4d2adc418e81bc + 0.38.2 + + dimstar_suse + + 1091246 + diff --git a/python-scour-no-python2.patch b/python-scour-no-python2.patch new file mode 100644 index 0000000..2273a7d --- /dev/null +++ b/python-scour-no-python2.patch @@ -0,0 +1,624 @@ +Index: scour-0.38.2/README.md +=================================================================== +--- scour-0.38.2.orig/README.md ++++ scour-0.38.2/README.md +@@ -20,7 +20,7 @@ The project moved to GitLab in 2013 an i + + ## Installation + +-Scour requires [Python](https://www.python.org) 2.7 or 3.4+. Further, for installation, [pip](https://pip.pypa.io) should be used. ++Scour requires [Python](https://www.python.org) 3.4+. Further, for installation, [pip](https://pip.pypa.io) should be used. + + To install the [latest release](https://pypi.python.org/pypi/scour) of Scour from PyPI: + +Index: scour-0.38.2/scour/__init__.py +=================================================================== +--- scour-0.38.2.orig/scour/__init__.py ++++ scour-0.38.2/scour/__init__.py +@@ -16,4 +16,4 @@ + # + ############################################################################### + +-__version__ = u'0.38.2' ++__version__ = '0.38.2' +Index: scour-0.38.2/scour/scour.py +=================================================================== +--- scour-0.38.2.orig/scour/scour.py ++++ scour-0.38.2/scour/scour.py +@@ -44,23 +44,19 @@ + # - if a has only one element in it, collapse the (ensure transform, etc are carried down) + + +-from __future__ import division # use "true" division instead of integer division in Python 2 (see PEP 238) +-from __future__ import print_function # use print() as a function in Python 2 (see PEP 3105) +-from __future__ import absolute_import # use absolute imports by default in Python 2 (see PEP 328) +- + import math + import optparse + import os + import re + import sys + import time ++import urllib.parse ++import urllib.request + import xml.dom.minidom + from xml.dom import Node, NotFoundErr + from collections import namedtuple, defaultdict + from decimal import Context, Decimal, InvalidOperation, getcontext + +-import six +-from six.moves import range, urllib + + from scour.svg_regex import svg_parser + from scour.svg_transform import svg_transform_parser +@@ -68,9 +64,9 @@ from scour.yocto_css import parseCssStri + from scour import __version__ + + +-APP = u'scour' ++APP = 'scour' + VER = __version__ +-COPYRIGHT = u'Copyright Jeff Schiller, Louis Simard, 2010' ++COPYRIGHT = 'Copyright Jeff Schiller, Louis Simard, 2010' + + + XML_ENTS_NO_QUOTES = {'<': '<', '>': '>', '&': '&'} +@@ -423,7 +419,7 @@ sciExponent = re.compile(r"[eE]([-+]?\d+ + unit = re.compile("(em|ex|px|pt|pc|cm|mm|in|%){1,1}$") + + +-class Unit(object): ++class Unit: + # Integer constants for units. + INVALID = -1 + NONE = 0 +@@ -485,7 +481,7 @@ class Unit(object): + str = staticmethod(str) + + +-class SVGLength(object): ++class SVGLength: + + def __init__(self, str): + try: # simple unitless and no scientific notation +@@ -927,7 +923,7 @@ def protected_ids(seenIDs, options): + + + def unprotected_ids(doc, options): +- u"""Returns a list of unprotected IDs within the document doc.""" ++ """Returns a list of unprotected IDs within the document doc.""" + identifiedElements = findElementsWithId(doc.documentElement) + protectedIDs = protected_ids(identifiedElements, options) + if protectedIDs: +@@ -1445,7 +1441,7 @@ def collapseSinglyReferencedGradients(do + identifiedElements = findElementsWithId(doc.documentElement) + + # make sure to reset the ref'ed ids for when we are running this in testscour +- for rid, nodes in six.iteritems(findReferencedElements(doc.documentElement)): ++ for rid, nodes in findReferencedElements(doc.documentElement).items(): + # Make sure that there's actually a defining element for the current ID name. + # (Cyn: I've seen documents with #id references but no element with that ID!) + if len(nodes) == 1 and rid in identifiedElements: +@@ -1551,7 +1547,7 @@ def detect_duplicate_gradients(*grad_lis + key = computeGradientBucketKey(grad) + grad_buckets[key].append(grad) + +- for bucket in six.itervalues(grad_buckets): ++ for bucket in grad_buckets.values(): + if len(bucket) < 2: + # The gradient must be unique if it is the only one in + # this bucket. +@@ -1656,7 +1652,7 @@ def removeDuplicateGradients(doc): + + + def _getStyle(node): +- u"""Returns the style attribute of a node as a dictionary.""" ++ """Returns the style attribute of a node as a dictionary.""" + if node.nodeType != Node.ELEMENT_NODE: + return {} + style_attribute = node.getAttribute('style') +@@ -1673,7 +1669,7 @@ def _getStyle(node): + + + def _setStyle(node, styleMap): +- u"""Sets the style attribute of a node to the dictionary ``styleMap``.""" ++ """Sets the style attribute of a node to the dictionary ``styleMap``.""" + fixedStyle = ';'.join(prop + ':' + styleMap[prop] for prop in styleMap) + if fixedStyle != '': + node.setAttribute('style', fixedStyle) +@@ -2101,12 +2097,12 @@ for default_attribute in default_attribu + + + def taint(taintedSet, taintedAttribute): +- u"""Adds an attribute to a set of attributes. ++ """Adds an attribute to a set of attributes. + + Related attributes are also included.""" + taintedSet.add(taintedAttribute) + if taintedAttribute == 'marker': +- taintedSet |= set(['marker-start', 'marker-mid', 'marker-end']) ++ taintedSet |= {'marker-start', 'marker-mid', 'marker-end'} + if taintedAttribute in ['marker-start', 'marker-mid', 'marker-end']: + taintedSet.add('marker') + return taintedSet +@@ -2142,7 +2138,7 @@ def removeDefaultAttributeValue(node, at + + + def removeDefaultAttributeValues(node, options, tainted=set()): +- u"""'tainted' keeps a set of attributes defined in parent nodes. ++ """'tainted' keeps a set of attributes defined in parent nodes. + + For such attributes, we don't delete attributes with default values.""" + num = 0 +@@ -2207,14 +2203,14 @@ def convertColor(value): + r = int(float(rgbpMatch.group(1)) * 255.0 / 100.0) + g = int(float(rgbpMatch.group(2)) * 255.0 / 100.0) + b = int(float(rgbpMatch.group(3)) * 255.0 / 100.0) +- s = '#%02x%02x%02x' % (r, g, b) ++ s = '#{:02x}{:02x}{:02x}'.format(r, g, b) + else: + rgbMatch = rgb.match(s) + if rgbMatch is not None: + r = int(rgbMatch.group(1)) + g = int(rgbMatch.group(2)) + b = int(rgbMatch.group(3)) +- s = '#%02x%02x%02x' % (r, g, b) ++ s = '#{:02x}{:02x}{:02x}'.format(r, g, b) + + if s[0] == '#': + s = s.lower() +@@ -2997,8 +2993,8 @@ def scourUnitlessLength(length, renderer + # Gather the non-scientific notation version of the coordinate. + # Re-quantize from the initial value to prevent unnecessary loss of precision + # (e.g. 123.4 should become 123, not 120 or even 100) +- nonsci = '{0:f}'.format(length) +- nonsci = '{0:f}'.format(initial_length.quantize(Decimal(nonsci))) ++ nonsci = '{:f}'.format(length) ++ nonsci = '{:f}'.format(initial_length.quantize(Decimal(nonsci))) + if not renderer_workaround: + if len(nonsci) > 2 and nonsci[:2] == '0.': + nonsci = nonsci[1:] # remove the 0, leave the dot +@@ -3014,7 +3010,7 @@ def scourUnitlessLength(length, renderer + exponent = length.adjusted() # how far do we have to shift the dot? + length = length.scaleb(-exponent).normalize() # shift the dot and remove potential trailing zeroes + +- sci = six.text_type(length) + 'e' + six.text_type(exponent) ++ sci = str(length) + 'e' + str(exponent) + + if len(sci) < len(nonsci): + return_value = sci +@@ -3419,7 +3415,7 @@ def properlySizeDoc(docElement, options) + pass + + # at this point it's safe to set the viewBox and remove width/height +- docElement.setAttribute('viewBox', '0 0 %s %s' % (w.value, h.value)) ++ docElement.setAttribute('viewBox', '0 0 {} {}'.format(w.value, h.value)) + docElement.removeAttribute('width') + docElement.removeAttribute('height') + +@@ -3939,8 +3935,8 @@ class HeaderedFormatter(optparse.Indente + """ + + def format_usage(self, usage): +- return "%s %s\n%s\n%s" % (APP, VER, COPYRIGHT, +- optparse.IndentedHelpFormatter.format_usage(self, usage)) ++ return "{} {}\n{}\n{}".format(APP, VER, COPYRIGHT, ++ optparse.IndentedHelpFormatter.format_usage(self, usage)) + + + # GZ: would prefer this to be in a function or class scope, but tests etc need +@@ -4112,7 +4108,7 @@ def generateDefaultOptions(): + + # sanitizes options by updating attributes in a set of defaults options while discarding unknown attributes + def sanitizeOptions(options=None): +- optionsDict = dict((key, getattr(options, key)) for key in dir(options) if not key.startswith('__')) ++ optionsDict = {key: getattr(options, key) for key in dir(options) if not key.startswith('__')} + + sanitizedOptions = _options_parser.get_default_values() + sanitizedOptions._update_careful(optionsDict) +Index: scour-0.38.2/scour/svg_regex.py +=================================================================== +--- scour-0.38.2.orig/scour/svg_regex.py ++++ scour-0.38.2/scour/svg_regex.py +@@ -41,7 +41,6 @@ Out[4]: [('M', [(0.60509999999999997, 0. + In [5]: svg_parser.parse('M 100-200') # Another edge case + Out[5]: [('M', [(100.0, -200.0)])] + """ +-from __future__ import absolute_import + + import re + from decimal import Decimal, getcontext +@@ -51,7 +50,7 @@ from functools import partial + # Sentinel. + + +-class _EOF(object): ++class _EOF: + + def __repr__(self): + return 'EOF' +@@ -66,7 +65,7 @@ lexicon = [ + ] + + +-class Lexer(object): ++class Lexer: + """ Break SVG path data into tokens. + + The SVG spec requires that tokens are greedy. This lexer relies on Python's +@@ -81,7 +80,7 @@ class Lexer(object): + self.lexicon = lexicon + parts = [] + for name, regex in lexicon: +- parts.append('(?P<%s>%s)' % (name, regex)) ++ parts.append('(?P<{}>{})'.format(name, regex)) + self.regex_string = '|'.join(parts) + self.regex = re.compile(self.regex_string) + +@@ -103,7 +102,7 @@ class Lexer(object): + svg_lexer = Lexer(lexicon) + + +-class SVGPathParser(object): ++class SVGPathParser: + """ Parse SVG data into a list of commands. + + Each distinct command will take the form of a tuple (command, data). The +@@ -163,7 +162,7 @@ class SVGPathParser(object): + commands = [] + while token[0] is not EOF: + if token[0] != 'command': +- raise SyntaxError("expecting a command; got %r" % (token,)) ++ raise SyntaxError("expecting a command; got {!r}".format(token)) + rule = self.command_dispatch[token[1]] + command_group, token = rule(next_val_fn, token) + commands.append(command_group) +@@ -232,23 +231,23 @@ class SVGPathParser(object): + while token[0] in self.number_tokens: + rx = Decimal(token[1]) * 1 + if rx < Decimal("0.0"): +- raise SyntaxError("expecting a nonnegative number; got %r" % (token,)) ++ raise SyntaxError("expecting a nonnegative number; got {!r}".format(token)) + + token = next_val_fn() + if token[0] not in self.number_tokens: +- raise SyntaxError("expecting a number; got %r" % (token,)) ++ raise SyntaxError("expecting a number; got {!r}".format(token)) + ry = Decimal(token[1]) * 1 + if ry < Decimal("0.0"): +- raise SyntaxError("expecting a nonnegative number; got %r" % (token,)) ++ raise SyntaxError("expecting a nonnegative number; got {!r}".format(token)) + + token = next_val_fn() + if token[0] not in self.number_tokens: +- raise SyntaxError("expecting a number; got %r" % (token,)) ++ raise SyntaxError("expecting a number; got {!r}".format(token)) + axis_rotation = Decimal(token[1]) * 1 + + token = next_val_fn() + if token[1][0] not in ('0', '1'): +- raise SyntaxError("expecting a boolean flag; got %r" % (token,)) ++ raise SyntaxError("expecting a boolean flag; got {!r}".format(token)) + large_arc_flag = Decimal(token[1][0]) * 1 + + if len(token[1]) > 1: +@@ -257,7 +256,7 @@ class SVGPathParser(object): + else: + token = next_val_fn() + if token[1][0] not in ('0', '1'): +- raise SyntaxError("expecting a boolean flag; got %r" % (token,)) ++ raise SyntaxError("expecting a boolean flag; got {!r}".format(token)) + sweep_flag = Decimal(token[1][0]) * 1 + + if len(token[1]) > 1: +@@ -266,12 +265,12 @@ class SVGPathParser(object): + else: + token = next_val_fn() + if token[0] not in self.number_tokens: +- raise SyntaxError("expecting a number; got %r" % (token,)) ++ raise SyntaxError("expecting a number; got {!r}".format(token)) + x = Decimal(token[1]) * 1 + + token = next_val_fn() + if token[0] not in self.number_tokens: +- raise SyntaxError("expecting a number; got %r" % (token,)) ++ raise SyntaxError("expecting a number; got {!r}".format(token)) + y = Decimal(token[1]) * 1 + + token = next_val_fn() +@@ -281,7 +280,7 @@ class SVGPathParser(object): + + def rule_coordinate(self, next_val_fn, token): + if token[0] not in self.number_tokens: +- raise SyntaxError("expecting a number; got %r" % (token,)) ++ raise SyntaxError("expecting a number; got {!r}".format(token)) + x = getcontext().create_decimal(token[1]) + token = next_val_fn() + return x, token +@@ -289,11 +288,11 @@ class SVGPathParser(object): + def rule_coordinate_pair(self, next_val_fn, token): + # Inline these since this rule is so common. + if token[0] not in self.number_tokens: +- raise SyntaxError("expecting a number; got %r" % (token,)) ++ raise SyntaxError("expecting a number; got {!r}".format(token)) + x = getcontext().create_decimal(token[1]) + token = next_val_fn() + if token[0] not in self.number_tokens: +- raise SyntaxError("expecting a number; got %r" % (token,)) ++ raise SyntaxError("expecting a number; got {!r}".format(token)) + y = getcontext().create_decimal(token[1]) + token = next_val_fn() + return [x, y], token +Index: scour-0.38.2/scour/svg_transform.py +=================================================================== +--- scour-0.38.2.orig/scour/svg_transform.py ++++ scour-0.38.2/scour/svg_transform.py +@@ -55,17 +55,14 @@ Multiple transformations are supported: + In [12]: svg_transform_parser.parse('translate(30 -30) rotate(36)') + Out[12]: [('translate', [30.0, -30.0]), ('rotate', [36.0])] + """ +-from __future__ import absolute_import + + import re + from decimal import Decimal + from functools import partial + +-from six.moves import range +- + + # Sentinel. +-class _EOF(object): ++class _EOF: + + def __repr__(self): + return 'EOF' +@@ -82,7 +79,7 @@ lexicon = [ + ] + + +-class Lexer(object): ++class Lexer: + """ Break SVG path data into tokens. + + The SVG spec requires that tokens are greedy. This lexer relies on Python's +@@ -97,7 +94,7 @@ class Lexer(object): + self.lexicon = lexicon + parts = [] + for name, regex in lexicon: +- parts.append('(?P<%s>%s)' % (name, regex)) ++ parts.append('(?P<{}>{})'.format(name, regex)) + self.regex_string = '|'.join(parts) + self.regex = re.compile(self.regex_string) + +@@ -119,7 +116,7 @@ class Lexer(object): + svg_lexer = Lexer(lexicon) + + +-class SVGTransformationParser(object): ++class SVGTransformationParser: + """ Parse SVG transform="" data into a list of commands. + + Each distinct command will take the form of a tuple (type, data). The +@@ -165,15 +162,15 @@ class SVGTransformationParser(object): + + def rule_svg_transform(self, next_val_fn, token): + if token[0] != 'command': +- raise SyntaxError("expecting a transformation type; got %r" % (token,)) ++ raise SyntaxError("expecting a transformation type; got {!r}".format(token)) + command = token[1] + rule = self.command_dispatch[command] + token = next_val_fn() + if token[0] != 'coordstart': +- raise SyntaxError("expecting '('; got %r" % (token,)) ++ raise SyntaxError("expecting '('; got {!r}".format(token)) + numbers, token = rule(next_val_fn, token) + if token[0] != 'coordend': +- raise SyntaxError("expecting ')'; got %r" % (token,)) ++ raise SyntaxError("expecting ')'; got {!r}".format(token)) + token = next_val_fn() + return (command, numbers), token + +@@ -226,7 +223,7 @@ class SVGTransformationParser(object): + + def rule_number(self, next_val_fn, token): + if token[0] not in self.number_tokens: +- raise SyntaxError("expecting a number; got %r" % (token,)) ++ raise SyntaxError("expecting a number; got {!r}".format(token)) + x = Decimal(token[1]) * 1 + token = next_val_fn() + return x, token +Index: scour-0.38.2/setup.py +=================================================================== +--- scour-0.38.2.orig/setup.py ++++ scour-0.38.2/setup.py +@@ -44,13 +44,13 @@ Authors: + """ + + VERSIONFILE = os.path.join(os.path.dirname(os.path.realpath(__file__)), "scour", "__init__.py") +-verstrline = open(VERSIONFILE, "rt").read() +-VSRE = r"^__version__ = u['\"]([^'\"]*)['\"]" ++verstrline = open(VERSIONFILE).read() ++VSRE = r"^__version__ = ['\"]([^'\"]*)['\"]" + mo = re.search(VSRE, verstrline, re.M) + if mo: + verstr = mo.group(1) + else: +- raise RuntimeError("Unable to find version string in %s." % (VERSIONFILE,)) ++ raise RuntimeError("Unable to find version string in {}.".format(VERSIONFILE)) + + + setup( +@@ -64,7 +64,7 @@ setup( + author_email='codedread@gmail.com', + url='https://github.com/scour-project/scour', + platforms=('Any'), +- install_requires=['six>=1.9.0'], ++ install_requires=[], + packages=find_packages(), + zip_safe=True, + entry_points={ +Index: scour-0.38.2/test_css.py +=================================================================== +--- scour-0.38.2.orig/test_css.py ++++ scour-0.38.2/test_css.py +@@ -1,5 +1,4 @@ + #!/usr/bin/env python +-# -*- coding: utf-8 -*- + + # Test Harness for Scour + # +@@ -19,7 +18,6 @@ + # See the License for the specific language governing permissions and + # limitations under the License. + +-from __future__ import absolute_import + + import unittest + +Index: scour-0.38.2/test_scour.py +=================================================================== +--- scour-0.38.2.orig/test_scour.py ++++ scour-0.38.2/test_scour.py +@@ -20,16 +20,12 @@ + # See the License for the specific language governing permissions and + # limitations under the License. + +-from __future__ import print_function # use print() as a function in Python 2 (see PEP 3105) +-from __future__ import absolute_import # use absolute imports by default in Python 2 (see PEP 328) + ++import io + import os + import sys + import unittest + +-import six +-from six.moves import map, range +- + from scour.scour import (make_well_formed, parse_args, scourString, scourXmlFile, start, run, + XML_ENTS_ESCAPE_APOS, XML_ENTS_ESCAPE_QUOT) + from scour.svg_regex import svg_parser +@@ -1149,30 +1145,30 @@ class HandleEncodingUTF8(unittest.TestCa + + def runTest(self): + doc = scourXmlFile('unittests/encoding-utf8.svg') +- text = u'Hello in many languages:\n' \ +- u'ar: أهلا\n' \ +- u'bn: হ্যালো\n' \ +- u'el: Χαίρετε\n' \ +- u'en: Hello\n' \ +- u'hi: नमस्ते\n' \ +- u'iw: שלום\n' \ +- u'ja: こんにちは\n' \ +- u'km: ជំរាបសួរ\n' \ +- u'ml: ഹലോ\n' \ +- u'ru: Здравствуйте\n' \ +- u'ur: ہیلو\n' \ +- u'zh: 您好' +- desc = six.text_type(doc.getElementsByTagNameNS(SVGNS, 'desc')[0].firstChild.wholeText).strip() ++ text = 'Hello in many languages:\n' \ ++ 'ar: أهلا\n' \ ++ 'bn: হ্যালো\n' \ ++ 'el: Χαίρετε\n' \ ++ 'en: Hello\n' \ ++ 'hi: नमस्ते\n' \ ++ 'iw: שלום\n' \ ++ 'ja: こんにちは\n' \ ++ 'km: ជំរាបសួរ\n' \ ++ 'ml: ഹലോ\n' \ ++ 'ru: Здравствуйте\n' \ ++ 'ur: ہیلو\n' \ ++ 'zh: 您好' ++ desc = str(doc.getElementsByTagNameNS(SVGNS, 'desc')[0].firstChild.wholeText).strip() + self.assertEqual(desc, text, + 'Did not handle international UTF8 characters') +- desc = six.text_type(doc.getElementsByTagNameNS(SVGNS, 'desc')[1].firstChild.wholeText).strip() +- self.assertEqual(desc, u'“”‘’–—…‐‒°©®™•½¼¾⅓⅔†‡µ¢£€«»♠♣♥♦¿�', ++ desc = str(doc.getElementsByTagNameNS(SVGNS, 'desc')[1].firstChild.wholeText).strip() ++ self.assertEqual(desc, '“”‘’–—…‐‒°©®™•½¼¾⅓⅔†‡µ¢£€«»♠♣♥♦¿�', + 'Did not handle common UTF8 characters') +- desc = six.text_type(doc.getElementsByTagNameNS(SVGNS, 'desc')[2].firstChild.wholeText).strip() +- self.assertEqual(desc, u':-×÷±∞π∅≤≥≠≈∧∨∩∪∈∀∃∄∑∏←↑→↓↔↕↖↗↘↙↺↻⇒⇔', ++ desc = str(doc.getElementsByTagNameNS(SVGNS, 'desc')[2].firstChild.wholeText).strip() ++ self.assertEqual(desc, ':-×÷±∞π∅≤≥≠≈∧∨∩∪∈∀∃∄∑∏←↑→↓↔↕↖↗↘↙↺↻⇒⇔', + 'Did not handle mathematical UTF8 characters') +- desc = six.text_type(doc.getElementsByTagNameNS(SVGNS, 'desc')[3].firstChild.wholeText).strip() +- self.assertEqual(desc, u'⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁽⁾ⁿⁱ₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎', ++ desc = str(doc.getElementsByTagNameNS(SVGNS, 'desc')[3].firstChild.wholeText).strip() ++ self.assertEqual(desc, '⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁽⁾ⁿⁱ₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎', + 'Did not handle superscript/subscript UTF8 characters') + + +@@ -1180,8 +1176,8 @@ class HandleEncodingISO_8859_15(unittest + + def runTest(self): + doc = scourXmlFile('unittests/encoding-iso-8859-15.svg') +- desc = six.text_type(doc.getElementsByTagNameNS(SVGNS, 'desc')[0].firstChild.wholeText).strip() +- self.assertEqual(desc, u'áèîäöü߀ŠšŽžŒœŸ', 'Did not handle ISO 8859-15 encoded characters') ++ desc = str(doc.getElementsByTagNameNS(SVGNS, 'desc')[0].firstChild.wholeText).strip() ++ self.assertEqual(desc, 'áèîäöü߀ŠšŽžŒœŸ', 'Did not handle ISO 8859-15 encoded characters') + + + class HandleSciNoInPathData(unittest.TestCase): +@@ -2231,7 +2227,7 @@ class PathCommandRewrites(unittest.TestC + expected_path, message = expected_paths[i] + self.assertEqual(actual_path, + expected_path, +- '%s: "%s" != "%s"' % (message, actual_path, expected_path)) ++ '{}: "{}" != "{}"'.format(message, actual_path, expected_path)) + + + class DefaultsRemovalToplevel(unittest.TestCase): +@@ -2553,7 +2549,7 @@ class CommandLineUsage(unittest.TestCase + # stdout: a string representing the combined output to 'stdout' + # stderr: a string representing the combined output to 'stderr' + def _run_scour(self): +- class Result(object): ++ class Result: + pass + + result = Result() +@@ -2581,12 +2577,12 @@ class CommandLineUsage(unittest.TestCase + # TODO: can we create file objects that behave *exactly* like the original? + # this is a mess since we have to ensure compatibility across Python 2 and 3 and it seems impossible + # to replicate all the details of 'stdin', 'stdout' and 'stderr' +- class InOutBuffer(six.StringIO, object): ++ class InOutBuffer(io.StringIO): + def write(self, string): + try: +- return super(InOutBuffer, self).write(string) ++ return super().write(string) + except TypeError: +- return super(InOutBuffer, self).write(string.decode()) ++ return super().write(string.decode()) + + sys.stdin = self.temp_stdin = InOutBuffer() + sys.stdout = self.temp_stdout = InOutBuffer() +@@ -2740,7 +2736,7 @@ class EmbedRasters(unittest.TestCase): + "Raster image from local path '" + href + "' not embedded.") + + def test_raster_paths_local_absolute(self): +- with open('unittests/raster-formats.svg', 'r') as f: ++ with open('unittests/raster-formats.svg') as f: + svg = f.read() + + # create a reference string by scouring the original file with relative links +Index: scour-0.38.2/tox.ini +=================================================================== +--- scour-0.38.2.orig/tox.ini ++++ scour-0.38.2/tox.ini +@@ -1,7 +1,6 @@ + [tox] + envlist = + pypy +- py27 + py34 + py35 + py36 +@@ -15,7 +14,6 @@ envlist = + + [testenv] + deps = +- six + coverage + + commands = diff --git a/python-scour.changes b/python-scour.changes index 5cf4537..72942b6 100644 --- a/python-scour.changes +++ b/python-scour.changes @@ -1,4 +1,12 @@ ------------------------------------------------------------------- +Tue Jun 6 12:07:19 UTC 2023 - pgajdos@suse.com + +- drop python 2 support, do not require six +- added patches + https://github.com/scour-project/scour/pull/306 + + python-scour-no-python2.patch + +------------------------------------------------------------------- Mon Nov 8 12:34:10 UTC 2021 - Dirk Müller - add dependency to xml library diff --git a/python-scour.spec b/python-scour.spec index 3f2c0c8..6e4adfc 100644 --- a/python-scour.spec +++ b/python-scour.spec @@ -1,7 +1,7 @@ # # spec file for package python-scour # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,6 @@ %define oldpython python -%{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-scour Version: 0.38.2 Release: 0 @@ -26,14 +25,14 @@ License: Apache-2.0 Group: Productivity/Graphics/Other URL: https://github.com/oberstet/scour Source: https://github.com/scour-project/scour/archive/v%{version}/scour-%{version}.tar.gz +# https://github.com/scour-project/scour/pull/306 +Patch0: python-scour-no-python2.patch BuildRequires: %{python_module setuptools} -BuildRequires: %{python_module six} BuildRequires: %{python_module xml} BuildRequires: fdupes BuildRequires: python-rpm-macros BuildRequires: unzip Requires: python-setuptools -Requires: python-six >= 1.9.0 %ifpython2 Requires: python-xml %endif @@ -51,7 +50,7 @@ documents. The goal of scour is to provide an identically rendered image. %prep -%setup -q -n scour-%{version} +%autosetup -p1 -n scour-%{version} # remove unwanted shebang sed -i '/^#!/ d' scour/{scour.py,yocto_css.py,svg_transform.py}