From 90b669dfd980fb70eb18a9cfd6170358a92c5585 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 11 Jan 2022 16:02:39 +0200 Subject: [PATCH 1/2] Drop support for EOL Python 3.6 --- .github/workflows/test.yml | 2 +- scripts/run_tests.sh | 4 ++-- setup.cfg | 3 --- setup.py | 4 ++-- tox.ini | 10 ++-------- 5 files changed, 7 insertions(+), 16 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 44eef5aa..82fdd259 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,7 +9,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "pypy3"] + python-version: ["3.7", "3.8", "3.9", "3.10", "pypy-3.8"] os: [ubuntu-latest, macos-latest, windows-latest] steps: diff --git a/scripts/run_tests.sh b/scripts/run_tests.sh index 5bdf49bd..f56241ef 100755 --- a/scripts/run_tests.sh +++ b/scripts/run_tests.sh @@ -23,10 +23,10 @@ case "${MODE}" in tox -e docs ;; format) - black --target-version=py36 bleach/*.py tests/ tests_website/ + black --target-version=py37 bleach/*.py tests/ tests_website/ ;; format-check) - black --target-version=py36 --check --diff bleach/*.py tests/ tests_website/ + black --target-version=py37 --check --diff bleach/*.py tests/ tests_website/ ;; check-reqs) mv requirements-dev.txt requirements-dev.txt.orig diff --git a/setup.cfg b/setup.cfg index 7875aeb5..d7bdc09e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -14,6 +14,3 @@ max-line-length = 100 [tool:pytest] addopts = -W error:html5lib:DeprecationWarning - -[wheel] -universal=1 diff --git a/setup.py b/setup.py index 4d0638cd..b139d4dc 100755 --- a/setup.py +++ b/setup.py @@ -45,7 +45,7 @@ def get_version(): include_package_data=True, package_data={'': ['README.rst']}, zip_safe=False, - python_requires='>=3.6', + python_requires='>=3.7', install_requires=install_requires, classifiers=[ 'Development Status :: 5 - Production/Stable', @@ -55,7 +55,7 @@ def get_version(): 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', diff --git a/tox.ini b/tox.ini index f53aee2c..98b6dfac 100644 --- a/tox.ini +++ b/tox.ini @@ -2,8 +2,8 @@ [tox] envlist = - py{36,37,38,39,310,py3} - py{36,37,38,39,310}-build-no-lang + py{37,38,39,310,py3} + py{37,38,39,310}-build-no-lang docs format-check lint @@ -16,12 +16,6 @@ commands = pytest {posargs:-v} python setup.py build -[testenv:py36-build-no-lang] -setenv = - LANG= -commands = - python setup.py build - [testenv:py37-build-no-lang] setenv = LANG= From a5e64a3c93644c97d93cf5e6d8b4bf94f6ec027f Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 11 Jan 2022 16:04:29 +0200 Subject: [PATCH 2/2] Upgrade Python syntax with pyupgrade --py37-plus --- bleach/__init__.py | 2 -- bleach/html5lib_shim.py | 19 ++++++++----------- bleach/linkifier.py | 16 ++++++---------- bleach/sanitizer.py | 9 ++++----- docs/conf.py | 17 ++++++++--------- setup.py | 6 +++--- tests/test_linkify.py | 2 +- tests/test_unicode.py | 1 - tests_website/data_to_json.py | 2 +- tests_website/open_test_page.py | 2 +- tests_website/server.py | 2 +- 11 files changed, 33 insertions(+), 45 deletions(-) diff --git a/bleach/__init__.py b/bleach/__init__.py index d619fb2c..e847de2a 100644 --- a/bleach/__init__.py +++ b/bleach/__init__.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - import packaging.version from bleach.linkifier import ( diff --git a/bleach/html5lib_shim.py b/bleach/html5lib_shim.py index 3c9c3306..d97d5c49 100644 --- a/bleach/html5lib_shim.py +++ b/bleach/html5lib_shim.py @@ -257,7 +257,7 @@ class BleachHTMLTokenizer(HTMLTokenizer): """Tokenizer that doesn't consume character entities""" def __init__(self, consume_entities=False, **kwargs): - super(BleachHTMLTokenizer, self).__init__(**kwargs) + super().__init__(**kwargs) self.consume_entities = consume_entities @@ -267,7 +267,7 @@ def __init__(self, consume_entities=False, **kwargs): def __iter__(self): last_error_token = None - for token in super(BleachHTMLTokenizer, self).__iter__(): + for token in super().__iter__(): if last_error_token is not None: if ( last_error_token["data"] == "invalid-character-in-attribute-name" @@ -342,9 +342,7 @@ def consumeEntity(self, allowedChar=None, fromAttribute=False): # If this tokenizer is set to consume entities, then we can let the # superclass do its thing. if self.consume_entities: - return super(BleachHTMLTokenizer, self).consumeEntity( - allowedChar, fromAttribute - ) + return super().consumeEntity(allowedChar, fromAttribute) # If this tokenizer is set to not consume entities, then we don't want # to consume and convert them, so this overrides the html5lib tokenizer's @@ -364,7 +362,7 @@ def tagOpenState(self): # we've collected so far and we do that by calling start_tag() on # the input stream wrapper. self.stream.start_tag() - return super(BleachHTMLTokenizer, self).tagOpenState() + return super().tagOpenState() def emitCurrentToken(self): token = self.currentToken @@ -397,7 +395,7 @@ def emitCurrentToken(self): self.state = self.dataState return - super(BleachHTMLTokenizer, self).emitCurrentToken() + super().emitCurrentToken() class BleachHTMLParser(HTMLParser): @@ -416,7 +414,7 @@ def __init__(self, tags, strip, consume_entities, **kwargs): self.tags = [tag.lower() for tag in tags] if tags is not None else None self.strip = strip self.consume_entities = consume_entities - super(BleachHTMLParser, self).__init__(**kwargs) + super().__init__(**kwargs) def _parse( self, stream, innerHTML=False, container="div", scripting=True, **kwargs @@ -642,15 +640,14 @@ def serialize(self, treewalker, encoding=None): in_tag = False after_equals = False - for stoken in super(BleachHTMLSerializer, self).serialize(treewalker, encoding): + for stoken in super().serialize(treewalker, encoding): if in_tag: if stoken == ">": in_tag = False elif after_equals: if stoken != '"': - for part in self.escape_base_amp(stoken): - yield part + yield from self.escape_base_amp(stoken) after_equals = False continue diff --git a/bleach/linkifier.py b/bleach/linkifier.py index 759882e9..9a991dd2 100644 --- a/bleach/linkifier.py +++ b/bleach/linkifier.py @@ -228,7 +228,7 @@ def __init__( :arg re email_re: email matching regex """ - super(LinkifyFilter, self).__init__(source) + super().__init__(source) self.callbacks = callbacks or [] self.skip_tags = skip_tags or [] @@ -332,8 +332,7 @@ def handle_email_addresses(self, src_iter): if end < len(text): new_tokens.append({"type": "Characters", "data": text[end:]}) - for new_token in new_tokens: - yield new_token + yield from new_tokens continue @@ -460,8 +459,7 @@ def handle_links(self, src_iter): if end < len(text): new_tokens.append({"type": "Characters", "data": text[end:]}) - for new_token in new_tokens: - yield new_token + yield from new_tokens continue @@ -499,8 +497,7 @@ def handle_a_tag(self, token_buffer): # The callbacks didn't change the text, so we yield the new "a" # token, then whatever else was there, then the end "a" token yield a_token - for mem in token_buffer[1:]: - yield mem + yield from token_buffer[1:] else: # If the callbacks changed the text, then we're going to drop @@ -516,7 +513,7 @@ def __iter__(self): token_buffer = [] - for token in super(LinkifyFilter, self).__iter__(): + for token in super().__iter__(): if in_a: # Handle the case where we're in an "a" tag--we want to buffer tokens # until we hit an end "a" tag. @@ -524,8 +521,7 @@ def __iter__(self): # Add the end tag to the token buffer and then handle them # and yield anything returned token_buffer.append(token) - for new_token in self.handle_a_tag(token_buffer): - yield new_token + yield from self.handle_a_tag(token_buffer) # Clear "a" related state and continue since we've yielded all # the tokens we're going to yield diff --git a/bleach/sanitizer.py b/bleach/sanitizer.py index 89aff1f4..0e981996 100644 --- a/bleach/sanitizer.py +++ b/bleach/sanitizer.py @@ -280,7 +280,7 @@ def __init__( category=DeprecationWarning, module="bleach._vendor.html5lib", ) - return super(BleachSanitizerFilter, self).__init__(source, **kwargs) + return super().__init__(source, **kwargs) def sanitize_stream(self, token_iterator): for token in token_iterator: @@ -290,8 +290,7 @@ def sanitize_stream(self, token_iterator): continue if isinstance(ret, list): - for subtoken in ret: - yield subtoken + yield from ret else: yield ret @@ -575,7 +574,7 @@ def disallowed_token(self, token): if ns is None or ns not in html5lib_shim.prefixes: namespaced_name = name else: - namespaced_name = "%s:%s" % (html5lib_shim.prefixes[ns], name) + namespaced_name = "{}:{}".format(html5lib_shim.prefixes[ns], name) attrs.append( ' %s="%s"' @@ -587,7 +586,7 @@ def disallowed_token(self, token): v, ) ) - token["data"] = "<%s%s>" % (token["name"], "".join(attrs)) + token["data"] = "<{}{}>".format(token["name"], "".join(attrs)) else: token["data"] = "<%s>" % token["name"] diff --git a/docs/conf.py b/docs/conf.py index 6a490050..7ec15153 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # # Bleach documentation build configuration file, created by # sphinx-quickstart on Fri May 11 21:11:39 2012. @@ -40,8 +39,8 @@ master_doc = 'index' # General information about the project. -project = u'Bleach' -copyright = u'2012-2015, James Socol; 2015-2017, Mozilla Foundation' +project = 'Bleach' +copyright = '2012-2015, James Socol; 2015-2017, Mozilla Foundation' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -196,8 +195,8 @@ # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'Bleach.tex', u'Bleach Documentation', - u'Will Kahn-Greene', 'manual'), + ('index', 'Bleach.tex', 'Bleach Documentation', + 'Will Kahn-Greene', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -226,8 +225,8 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'bleach', u'Bleach Documentation', - [u'Will Kahn-Greene'], 1) + ('index', 'bleach', 'Bleach Documentation', + ['Will Kahn-Greene'], 1) ] # If true, show URL addresses after external links. @@ -240,8 +239,8 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'Bleach', u'Bleach Documentation', - u'Will Kahn-Greene', 'Bleach', 'One line description of project.', + ('index', 'Bleach', 'Bleach Documentation', + 'Will Kahn-Greene', 'Bleach', 'One line description of project.', 'Miscellaneous'), ] diff --git a/setup.py b/setup.py index b139d4dc..4aa92289 100755 --- a/setup.py +++ b/setup.py @@ -16,10 +16,10 @@ def get_long_desc(): - with io.open('README.rst', encoding='utf-8') as fp: + with open('README.rst', encoding='utf-8') as fp: desc = fp.read() desc += '\n\n' - with io.open('CHANGES', encoding='utf-8') as fp: + with open('CHANGES', encoding='utf-8') as fp: desc += fp.read() return desc @@ -27,7 +27,7 @@ def get_long_desc(): def get_version(): fn = os.path.join('bleach', '__init__.py') vsre = r"""^__version__ = ['"]([^'"]*)['"]""" - with io.open(fn, encoding='utf-8') as fp: + with open(fn, encoding='utf-8') as fp: version_file = fp.read() return re.search(vsre, version_file, re.M).group(1) diff --git a/tests/test_linkify.py b/tests/test_linkify.py index a215da51..2880dc75 100644 --- a/tests/test_linkify.py +++ b/tests/test_linkify.py @@ -48,7 +48,7 @@ def test_mangle_link(): def filter_url(attrs, new=False): if not attrs.get((None, "href"), "").startswith("http://bouncer"): quoted = quote_plus(attrs[(None, "href")]) - attrs[(None, "href")] = "http://bouncer/?u={0!s}".format(quoted) + attrs[(None, "href")] = "http://bouncer/?u={!s}".format(quoted) return attrs assert ( diff --git a/tests/test_unicode.py b/tests/test_unicode.py index db3545e1..8261675f 100644 --- a/tests/test_unicode.py +++ b/tests/test_unicode.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest from bleach import clean, linkify diff --git a/tests_website/data_to_json.py b/tests_website/data_to_json.py index 5f888b8c..3043bae8 100755 --- a/tests_website/data_to_json.py +++ b/tests_website/data_to_json.py @@ -39,7 +39,7 @@ def main(): for infn in ins: case_name = infn.rsplit(".test", 1)[0] - with open(infn, "r") as fin: + with open(infn) as fin: data, expected = fin.read().split("\n--\n") data = data.strip() expected = expected.strip() diff --git a/tests_website/open_test_page.py b/tests_website/open_test_page.py index 23e15277..b1bfb65f 100755 --- a/tests_website/open_test_page.py +++ b/tests_website/open_test_page.py @@ -36,4 +36,4 @@ browser = webbrowser.get(browser_name) browser.open_new_tab("http://localhost:8080") except Exception as error: - print("error getting test browser %s: %s" % (browser_name, error)) + print("error getting test browser {}: {}".format(browser_name, error)) diff --git a/tests_website/server.py b/tests_website/server.py index 2d25ea25..0f0ed740 100755 --- a/tests_website/server.py +++ b/tests_website/server.py @@ -27,7 +27,7 @@ class BleachCleanHandler(http.server.SimpleHTTPRequestHandler): def do_POST(self): content_len = int(self.headers.get("content-length", 0)) body = self.rfile.read(content_len) - print("read %s bytes: %s" % (content_len, body)) + print("read {} bytes: {}".format(content_len, body)) body = body.decode("utf-8") print("input: %r" % body)