From 27bb4cef92874f4d3a1cfd195f4fbcc2b2d81640 Mon Sep 17 00:00:00 2001 From: Nikita Karamov Date: Mon, 23 Jan 2023 06:44:41 +0100 Subject: [PATCH 01/14] Do not use u-strings --- scour/__init__.py | 2 +- scour/scour.py | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/scour/__init__.py b/scour/__init__.py index 591803a..92970c2 100644 --- a/scour/__init__.py +++ b/scour/__init__.py @@ -16,4 +16,4 @@ # ############################################################################### -__version__ = u'0.38.2' +__version__ = '0.38.2' diff --git a/scour/scour.py b/scour/scour.py index 9d19906..ca0c8ea 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -70,9 +70,9 @@ from scour.yocto_css import parseCssString 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 = {'<': '<', '>': '>', '&': '&'} @@ -928,7 +928,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: @@ -1649,7 +1649,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') @@ -1666,7 +1666,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) @@ -2094,7 +2094,7 @@ for default_attribute in default_attributes: 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) @@ -2135,7 +2135,7 @@ def removeDefaultAttributeValue(node, attribute): def removeDefaultAttributeValues(node, options, tainted=None): - 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 From a284dec2f9302dfad5c9051e95e33901db686b58 Mon Sep 17 00:00:00 2001 From: Nikita Karamov Date: Mon, 23 Jan 2023 06:44:56 +0100 Subject: [PATCH 02/14] Remove "coding" pragma --- scour/scour.py | 1 - scour/svg_transform.py | 1 - scour/yocto_css.py | 1 - test_css.py | 1 - test_scour.py | 1 - 5 files changed, 5 deletions(-) diff --git a/scour/scour.py b/scour/scour.py index ca0c8ea..387f1ed 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # Scour # diff --git a/scour/svg_transform.py b/scour/svg_transform.py index 83454b3..fc3b5ff 100644 --- a/scour/svg_transform.py +++ b/scour/svg_transform.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # SVG transformation list parser # diff --git a/scour/yocto_css.py b/scour/yocto_css.py index 0aaac5a..4975dbd 100644 --- a/scour/yocto_css.py +++ b/scour/yocto_css.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # yocto-css, an extremely bare minimum CSS parser # diff --git a/test_css.py b/test_css.py index d7fd3e2..7b136ce 100755 --- a/test_css.py +++ b/test_css.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # Test Harness for Scour # diff --git a/test_scour.py b/test_scour.py index 549333f..8e0ad73 100755 --- a/test_scour.py +++ b/test_scour.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- # Test Harness for Scour # From 1ceeaf11e69b143cb171e37f77248689da946a13 Mon Sep 17 00:00:00 2001 From: Nikita Karamov Date: Mon, 23 Jan 2023 06:45:18 +0100 Subject: [PATCH 03/14] Remove __future__ imports --- scour/scour.py | 3 --- scour/svg_regex.py | 1 - scour/svg_transform.py | 1 - test_css.py | 1 - test_scour.py | 2 -- 5 files changed, 8 deletions(-) diff --git a/scour/scour.py b/scour/scour.py index 387f1ed..5bb4ee1 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -44,9 +44,6 @@ # - 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 diff --git a/scour/svg_regex.py b/scour/svg_regex.py index c62ba2a..f91063c 100644 --- a/scour/svg_regex.py +++ b/scour/svg_regex.py @@ -41,7 +41,6 @@ Out[4]: [('M', [(0.60509999999999997, 0.5)])] 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 diff --git a/scour/svg_transform.py b/scour/svg_transform.py index fc3b5ff..769c48c 100644 --- a/scour/svg_transform.py +++ b/scour/svg_transform.py @@ -55,7 +55,6 @@ 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 diff --git a/test_css.py b/test_css.py index 7b136ce..5525ba4 100755 --- a/test_css.py +++ b/test_css.py @@ -18,7 +18,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -from __future__ import absolute_import import unittest diff --git a/test_scour.py b/test_scour.py index 8e0ad73..f4f3bda 100755 --- a/test_scour.py +++ b/test_scour.py @@ -19,8 +19,6 @@ # 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 os import sys From d1fd32fd5be004a81225a0496382e03d2a19eef6 Mon Sep 17 00:00:00 2001 From: Nikita Karamov Date: Mon, 23 Jan 2023 06:45:59 +0100 Subject: [PATCH 04/14] Do not explicitly extend object --- scour/scour.py | 4 ++-- scour/stats.py | 2 +- scour/svg_regex.py | 6 +++--- scour/svg_transform.py | 6 +++--- test_scour.py | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/scour/scour.py b/scour/scour.py index 5bb4ee1..479f6c8 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -421,7 +421,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 @@ -483,7 +483,7 @@ class Unit(object): str = staticmethod(str) -class SVGLength(object): +class SVGLength: def __init__(self, str): try: # simple unitless and no scientific notation diff --git a/scour/stats.py b/scour/stats.py index 2762b92..5a1e59e 100644 --- a/scour/stats.py +++ b/scour/stats.py @@ -1,4 +1,4 @@ -class ScourStats(object): +class ScourStats: __slots__ = ( 'num_elements_removed', diff --git a/scour/svg_regex.py b/scour/svg_regex.py index f91063c..abba621 100644 --- a/scour/svg_regex.py +++ b/scour/svg_regex.py @@ -50,7 +50,7 @@ from functools import partial # Sentinel. -class _EOF(object): +class _EOF: def __repr__(self): return 'EOF' @@ -65,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 @@ -102,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 diff --git a/scour/svg_transform.py b/scour/svg_transform.py index 769c48c..25aaec4 100644 --- a/scour/svg_transform.py +++ b/scour/svg_transform.py @@ -64,7 +64,7 @@ from six.moves import range # Sentinel. -class _EOF(object): +class _EOF: def __repr__(self): return 'EOF' @@ -81,7 +81,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 @@ -118,7 +118,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 diff --git a/test_scour.py b/test_scour.py index f4f3bda..ba28815 100755 --- a/test_scour.py +++ b/test_scour.py @@ -2550,7 +2550,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() @@ -2578,7 +2578,7 @@ 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(six.StringIO): def write(self, string): try: return super(InOutBuffer, self).write(string) From 1cc86cc3c80015a76eebc6da6e876d945c7cf37c Mon Sep 17 00:00:00 2001 From: Nikita Karamov Date: Mon, 23 Jan 2023 06:47:09 +0100 Subject: [PATCH 05/14] Use str.format() --- scour/scour.py | 12 ++++++------ scour/svg_regex.py | 26 +++++++++++++------------- scour/svg_transform.py | 10 +++++----- setup.py | 2 +- test_scour.py | 2 +- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/scour/scour.py b/scour/scour.py index 479f6c8..49f13d1 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -2199,14 +2199,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() @@ -2988,8 +2988,8 @@ def scourUnitlessLength(length, renderer_workaround=False, is_control_point=Fals # 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 @@ -3406,7 +3406,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') @@ -3899,7 +3899,7 @@ class HeaderedFormatter(optparse.IndentedHelpFormatter): """ def format_usage(self, usage): - return "%s %s\n%s\n%s" % (APP, VER, COPYRIGHT, + return "{} {}\n{}\n{}".format(APP, VER, COPYRIGHT, optparse.IndentedHelpFormatter.format_usage(self, usage)) diff --git a/scour/svg_regex.py b/scour/svg_regex.py index abba621..fe65abc 100644 --- a/scour/svg_regex.py +++ b/scour/svg_regex.py @@ -80,7 +80,7 @@ class Lexer: 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) @@ -162,7 +162,7 @@ class SVGPathParser: 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) @@ -231,23 +231,23 @@ class SVGPathParser: 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: @@ -256,7 +256,7 @@ class SVGPathParser: 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: @@ -265,12 +265,12 @@ class SVGPathParser: 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() @@ -280,7 +280,7 @@ class SVGPathParser: 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 @@ -288,11 +288,11 @@ class SVGPathParser: 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 diff --git a/scour/svg_transform.py b/scour/svg_transform.py index 25aaec4..87137e5 100644 --- a/scour/svg_transform.py +++ b/scour/svg_transform.py @@ -96,7 +96,7 @@ class Lexer: 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) @@ -164,15 +164,15 @@ class SVGTransformationParser: 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 @@ -225,7 +225,7 @@ class SVGTransformationParser: 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 diff --git a/setup.py b/setup.py index 990b596..5336a3c 100644 --- a/setup.py +++ b/setup.py @@ -50,7 +50,7 @@ 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( diff --git a/test_scour.py b/test_scour.py index ba28815..d0f98a9 100755 --- a/test_scour.py +++ b/test_scour.py @@ -2228,7 +2228,7 @@ class PathCommandRewrites(unittest.TestCase): 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): From c3b305cc5d2f596f7fdd738e8bf66f4e977d19d4 Mon Sep 17 00:00:00 2001 From: Nikita Karamov Date: Mon, 23 Jan 2023 06:47:48 +0100 Subject: [PATCH 06/14] Remove unneeded six stuff --- scour/scour.py | 8 ++++---- scour/svg_transform.py | 1 - test_scour.py | 45 +++++++++++++++++++++--------------------- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/scour/scour.py b/scour/scour.py index 49f13d1..5580fc5 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -57,7 +57,7 @@ from collections import namedtuple, defaultdict from decimal import Context, Decimal, InvalidOperation, getcontext import six -from six.moves import range, urllib +from six.moves import urllib from scour.stats import ScourStats from scour.svg_regex import svg_parser @@ -1433,7 +1433,7 @@ def collapse_singly_referenced_gradients(doc, stats): 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: @@ -1540,7 +1540,7 @@ def detect_duplicate_gradients(*grad_lists): 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. @@ -3005,7 +3005,7 @@ def scourUnitlessLength(length, renderer_workaround=False, is_control_point=Fals 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 diff --git a/scour/svg_transform.py b/scour/svg_transform.py index 87137e5..1639ae5 100644 --- a/scour/svg_transform.py +++ b/scour/svg_transform.py @@ -60,7 +60,6 @@ import re from decimal import Decimal from functools import partial -from six.moves import range # Sentinel. diff --git a/test_scour.py b/test_scour.py index d0f98a9..44db11f 100755 --- a/test_scour.py +++ b/test_scour.py @@ -25,7 +25,6 @@ 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) @@ -1146,30 +1145,30 @@ class HandleEncodingUTF8(unittest.TestCase): 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') @@ -1177,8 +1176,8 @@ class HandleEncodingISO_8859_15(unittest.TestCase): 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): From 91414835277b2814d1a1c02714c51c21c1491466 Mon Sep 17 00:00:00 2001 From: Nikita Karamov Date: Mon, 23 Jan 2023 06:48:05 +0100 Subject: [PATCH 07/14] Use dict literals --- scour/scour.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scour/scour.py b/scour/scour.py index 5580fc5..9449f3c 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -2095,7 +2095,7 @@ def taint(taintedSet, taintedAttribute): 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 @@ -4072,7 +4072,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) From de3d930421db30470f4c5e8f18a49ed0fe5dd0ee Mon Sep 17 00:00:00 2001 From: Nikita Karamov Date: Mon, 23 Jan 2023 06:51:43 +0100 Subject: [PATCH 08/14] Remove redundant open() flags --- setup.py | 2 +- test_scour.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 5336a3c..419fb42 100644 --- a/setup.py +++ b/setup.py @@ -44,7 +44,7 @@ Authors: """ VERSIONFILE = os.path.join(os.path.dirname(os.path.realpath(__file__)), "scour", "__init__.py") -verstrline = open(VERSIONFILE, "rt").read() +verstrline = open(VERSIONFILE).read() VSRE = r"^__version__ = u['\"]([^'\"]*)['\"]" mo = re.search(VSRE, verstrline, re.M) if mo: diff --git a/test_scour.py b/test_scour.py index 44db11f..f5217b1 100755 --- a/test_scour.py +++ b/test_scour.py @@ -2736,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 From 783632fb2480231b34e442fdda1fdab645a7271b Mon Sep 17 00:00:00 2001 From: Nikita Karamov Date: Mon, 23 Jan 2023 06:51:50 +0100 Subject: [PATCH 09/14] Use simpler super() --- test_scour.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_scour.py b/test_scour.py index f5217b1..ebc9911 100755 --- a/test_scour.py +++ b/test_scour.py @@ -2580,9 +2580,9 @@ class CommandLineUsage(unittest.TestCase): class InOutBuffer(six.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() From 24c297cfe7faeb58aafd11afca242e2292d118d1 Mon Sep 17 00:00:00 2001 From: Nikita Karamov Date: Mon, 23 Jan 2023 06:58:54 +0100 Subject: [PATCH 10/14] Remove six dependency --- scour/scour.py | 5 ++--- scour/svg_transform.py | 1 - setup.py | 2 +- test_scour.py | 5 ++--- tox.ini | 1 - 5 files changed, 5 insertions(+), 9 deletions(-) diff --git a/scour/scour.py b/scour/scour.py index 9449f3c..c64d0d2 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -44,20 +44,19 @@ # - if a has only one element in it, collapse the (ensure transform, etc are carried down) - 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 urllib from scour.stats import ScourStats from scour.svg_regex import svg_parser diff --git a/scour/svg_transform.py b/scour/svg_transform.py index 1639ae5..7314c44 100644 --- a/scour/svg_transform.py +++ b/scour/svg_transform.py @@ -61,7 +61,6 @@ from decimal import Decimal from functools import partial - # Sentinel. class _EOF: diff --git a/setup.py b/setup.py index 419fb42..252a2fc 100644 --- a/setup.py +++ b/setup.py @@ -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={ diff --git a/test_scour.py b/test_scour.py index ebc9911..6a10665 100755 --- a/test_scour.py +++ b/test_scour.py @@ -20,12 +20,11 @@ # limitations under the License. +import io import os import sys import unittest -import six - 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 @@ -2577,7 +2576,7 @@ 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): + class InOutBuffer(io.StringIO): def write(self, string): try: return super().write(string) diff --git a/tox.ini b/tox.ini index 82420b6..6716ba6 100644 --- a/tox.ini +++ b/tox.ini @@ -15,7 +15,6 @@ envlist = [testenv] deps = - six coverage commands = From 56910e6e9c99889febce6b4be9ad345f31e83ae8 Mon Sep 17 00:00:00 2001 From: Nikita Karamov Date: Mon, 23 Jan 2023 06:59:14 +0100 Subject: [PATCH 11/14] Fix formatting --- scour/scour.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scour/scour.py b/scour/scour.py index c64d0d2..e203a75 100644 --- a/scour/scour.py +++ b/scour/scour.py @@ -3899,7 +3899,7 @@ class HeaderedFormatter(optparse.IndentedHelpFormatter): def format_usage(self, usage): return "{} {}\n{}\n{}".format(APP, VER, COPYRIGHT, - optparse.IndentedHelpFormatter.format_usage(self, usage)) + optparse.IndentedHelpFormatter.format_usage(self, usage)) # GZ: would prefer this to be in a function or class scope, but tests etc need From 507020449fbb72b11ccc67b832cf2e3b64342ba8 Mon Sep 17 00:00:00 2001 From: Nikita Karamov Date: Mon, 23 Jan 2023 07:02:11 +0100 Subject: [PATCH 12/14] Fix setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 252a2fc..dcc300f 100644 --- a/setup.py +++ b/setup.py @@ -45,7 +45,7 @@ Authors: VERSIONFILE = os.path.join(os.path.dirname(os.path.realpath(__file__)), "scour", "__init__.py") verstrline = open(VERSIONFILE).read() -VSRE = r"^__version__ = u['\"]([^'\"]*)['\"]" +VSRE = r"^__version__ = ['\"]([^'\"]*)['\"]" mo = re.search(VSRE, verstrline, re.M) if mo: verstr = mo.group(1) From 51484bf21b87d020581fc101a739b233c89bc2df Mon Sep 17 00:00:00 2001 From: Nikita Karamov Date: Mon, 23 Jan 2023 07:03:40 +0100 Subject: [PATCH 13/14] Remove py27 tox venv --- tox.ini | 1 - 1 file changed, 1 deletion(-) diff --git a/tox.ini b/tox.ini index 6716ba6..a46c697 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,6 @@ [tox] envlist = pypy - py27 py34 py35 py36 From 565686a6d5dc642a8fc18135af986ee509bbdbad Mon Sep 17 00:00:00 2001 From: Nikita Karamov Date: Mon, 23 Jan 2023 07:27:59 +0100 Subject: [PATCH 14/14] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ace6711..b4eb018 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ The project moved to GitLab in 2013 an is now maintained by Tobias "oberstet" Ob ## 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: