From c5eae9d75281fcb276e6079755cf60deaca0b3dc Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Sun, 6 Dec 2020 00:25:09 +0100 Subject: [PATCH] drop support for Python 3.6 and 3.7 We require Python 3.8 for sans-io (#1775), so we need to drop support for older versions. --- .github/workflows/main.yml | 4 ---- CHANGELOG.rst | 2 ++ dev.ps1 | 4 ++-- mitmproxy/master.py | 2 +- mitmproxy/net/http/url.py | 2 +- mitmproxy/net/tcp.py | 2 +- mitmproxy/tools/_main.py | 3 +-- mitmproxy/tools/main.py | 6 +++--- mitmproxy/utils/debug.py | 2 -- setup.py | 10 +++------- test/mitmproxy/addons/test_readfile.py | 4 ---- test/mitmproxy/net/http/test_url.py | 2 -- test/mitmproxy/utils/test_asyncio_utils.py | 7 +++---- test/mitmproxy/utils/test_debug.py | 3 +-- tox.ini | 4 ++-- 15 files changed, 20 insertions(+), 37 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0c48824b7..1e4fb7ce3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -51,10 +51,6 @@ jobs: py: 3.9 - os: ubuntu-latest py: 3.8 - - os: ubuntu-latest - py: 3.7 - - os: ubuntu-latest - py: 3.6 runs-on: ${{ matrix.os }} steps: - run: printenv diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 370634896..f6b9d0c0d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,12 +4,14 @@ Release History Unreleased: mitmproxy next ========================== +* Mitmproxy now requires Python 3.8 or above. * Fix query parameters in asgiapp addon (@jpstotz) * Fix command history failing on file IO errors (@Kriechi) * Deprecation of pathod and pathoc tools and modules. Future releases might not contain them! (@Kriechi) * Addon to suppress unwanted error messages sent by mitmproxy. (@anneborcherding) * Updated imports and styles for web scanner helper addons. (@anneborcherding) * Inform when underscore-formatted options are used in client arg. (@jrblixt) +* Binaries are now built with Python 3.9 (@mhils) * --- TODO: add new PRs above this line --- diff --git a/dev.ps1 b/dev.ps1 index 6193c5f67..d5de05265 100644 --- a/dev.ps1 +++ b/dev.ps1 @@ -1,8 +1,8 @@ $ErrorActionPreference = "Stop" $pyver = python --version -if($pyver -notmatch "3\.[6-9]") { - Write-Warning "Unexpected Python version, expected Python 3.6 or above: $pyver" +if($pyver -notmatch "3\.(8|9|\d{2,})") { + Write-Warning "Unexpected Python version, expected Python 3.8 or above: $pyver" } python -m venv .\venv --copies diff --git a/mitmproxy/master.py b/mitmproxy/master.py index e3867033a..e88c79a93 100644 --- a/mitmproxy/master.py +++ b/mitmproxy/master.py @@ -90,7 +90,7 @@ class Master: if not self.should_exit.is_set(): # pragma: no cover self.shutdown() loop = asyncio.get_event_loop() - tasks = asyncio.all_tasks(loop) if sys.version_info >= (3, 7) else asyncio.Task.all_tasks(loop) + tasks = asyncio.all_tasks(loop) for p in tasks: p.cancel() loop.close() diff --git a/mitmproxy/net/http/url.py b/mitmproxy/net/http/url.py index 902e6157e..14898c31e 100644 --- a/mitmproxy/net/http/url.py +++ b/mitmproxy/net/http/url.py @@ -56,7 +56,7 @@ def parse(url): if isinstance(parsed, urllib.parse.ParseResult): parsed = parsed.encode("ascii") - port = parsed.port # Returns None if port number invalid in Py3.5. Will throw ValueError in Py3.6 + port = parsed.port if not port: port = 443 if parsed.scheme == b"https" else 80 diff --git a/mitmproxy/net/tcp.py b/mitmproxy/net/tcp.py index f27db6ad1..d4cd0c018 100644 --- a/mitmproxy/net/tcp.py +++ b/mitmproxy/net/tcp.py @@ -20,7 +20,7 @@ from mitmproxy.coretypes import basethread socket_fileobject = socket.SocketIO # workaround for https://bugs.python.org/issue29515 -# Python 3.6 for Windows is missing a constant +# Python 3.8 for Windows is missing a constant, fixed in 3.9 IPPROTO_IPV6 = getattr(socket, "IPPROTO_IPV6", 41) diff --git a/mitmproxy/tools/_main.py b/mitmproxy/tools/_main.py index 7e9f91b38..b4c1f5acd 100644 --- a/mitmproxy/tools/_main.py +++ b/mitmproxy/tools/_main.py @@ -1,6 +1,5 @@ """ -This file contains python3.6+ syntax! -Feel free to import and use whatever new package you deem necessary. +This file now contains python3.8+ syntax! """ import os diff --git a/mitmproxy/tools/main.py b/mitmproxy/tools/main.py index 60c3e2e86..84dfee1f3 100644 --- a/mitmproxy/tools/main.py +++ b/mitmproxy/tools/main.py @@ -1,17 +1,17 @@ """ This file must be kept in a python2.7 and python3.5 compatible syntax! -DO NOT use type annotations or other python3.6-only features that makes this file unparsable by older interpreters! +DO NOT use type annotations or other modern features that makes this file unparsable by older interpreters! """ from __future__ import print_function # this is here for the version check to work on Python 2. import sys -if sys.version_info < (3, 6): +if sys.version_info < (3, 8): # This must be before any mitmproxy imports, as they already break! # Keep all other imports below with the 'noqa' magic comment. print("#" * 76, file=sys.stderr) - print("# mitmproxy requires Python 3.6 or higher! #", file=sys.stderr) + print("# mitmproxy requires Python 3.8 or higher! #", file=sys.stderr) print("#" + " " * 74 + "#", file=sys.stderr) print("# Please upgrade your Python interpreter or use our mitmproxy binaries from #", file=sys.stderr) print("# https://mitmproxy.org. If your operating system does not include the #", file=sys.stderr) diff --git a/mitmproxy/utils/debug.py b/mitmproxy/utils/debug.py index 17d594208..986372efa 100644 --- a/mitmproxy/utils/debug.py +++ b/mitmproxy/utils/debug.py @@ -83,8 +83,6 @@ def dump_info(signal=None, frame=None, file=sys.stdout, testing=False): # pragm print(i[1], i[0]) try: - if sys.version_info < (3, 8): - raise RuntimeError asyncio.get_running_loop() except RuntimeError: pass diff --git a/setup.py b/setup.py index ff009188a..e4d96b9dc 100644 --- a/setup.py +++ b/setup.py @@ -34,8 +34,6 @@ setup( "Operating System :: POSIX", "Operating System :: Microsoft :: Windows", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: Implementation :: CPython", @@ -65,6 +63,7 @@ setup( "pathoc = pathod.pathoc_cmdline:go_pathoc" ] }, + python_requires='>=3.8', # https://packaging.python.org/en/latest/requirements/#install-requires # It is not considered best practice to use install_requires to pin dependencies to specific versions. install_requires=[ @@ -75,8 +74,8 @@ setup( "click>=7.0,<8", "cryptography>=3.2,<3.3", "flask>=1.1.1,<1.2", - "h2>=4.0,<5; python_version>='3.6.0'", # python_version only needed to make "py36+ required" message work - "hyperframe>=6.0,<7; python_version>='3.6.0'", # python_version only needed to make "py36+ required" message work + "h2>=4.0,<5", + "hyperframe>=6.0,<7", "kaitaistruct>=0.7,<0.10", "ldap3>=2.8,<2.9", "msgpack>=1.0.0, <1.1.0", @@ -98,9 +97,6 @@ setup( ':sys_platform == "win32"': [ "pydivert>=2.0.3,<2.2", ], - ':python_version == "3.6"': [ - "dataclasses>=0.7", - ], 'dev': [ "hypothesis>=5.8,<6", "parver>=0.1,<2.0", diff --git a/test/mitmproxy/addons/test_readfile.py b/test/mitmproxy/addons/test_readfile.py index 71efb5696..0383beb23 100644 --- a/test/mitmproxy/addons/test_readfile.py +++ b/test/mitmproxy/addons/test_readfile.py @@ -1,6 +1,5 @@ import asyncio import io -import sys import pytest from unittest import mock @@ -47,7 +46,6 @@ class TestReadFile: with pytest.raises(Exception, match="Invalid readfile filter"): tctx.configure(rf, readfile_filter="~~") - @pytest.mark.skipif(sys.version_info < (3, 8), reason='requires Python 3.8 or higher') @pytest.mark.asyncio async def test_read(self, tmpdir, data, corrupt_data): rf = readfile.ReadFile() @@ -95,7 +93,6 @@ class TestReadFile: class TestReadFileStdin: - @pytest.mark.skipif(sys.version_info < (3, 8), reason='requires Python 3.8 or higher') @mock.patch('sys.stdin') @pytest.mark.asyncio async def test_stdin(self, stdin, data, corrupt_data): @@ -111,7 +108,6 @@ class TestReadFileStdin: with pytest.raises(exceptions.FlowReadException): await rf.load_flows(stdin.buffer) - @pytest.mark.skipif(sys.version_info < (3, 8), reason='requires Python 3.8 or higher') @pytest.mark.asyncio async def test_normal(self, tmpdir, data): rf = readfile.ReadFileStdin() diff --git a/test/mitmproxy/net/http/test_url.py b/test/mitmproxy/net/http/test_url.py index a4c586dc3..51435cb0c 100644 --- a/test/mitmproxy/net/http/test_url.py +++ b/test/mitmproxy/net/http/test_url.py @@ -1,7 +1,6 @@ from typing import AnyStr import pytest -import sys from mitmproxy.net.http import url from mitmproxy.net.http.url import parse_authority @@ -62,7 +61,6 @@ def test_ascii_check(): b'%BD%E7%8C%AB%E6%B0%93%E7%8C%AB%E6%B0%93' -@pytest.mark.skipif(sys.version_info < (3, 6), reason='requires Python 3.6 or higher') def test_parse_port_range(): # Port out of range with pytest.raises(ValueError): diff --git a/test/mitmproxy/utils/test_asyncio_utils.py b/test/mitmproxy/utils/test_asyncio_utils.py index ed40e0a34..5446027ae 100644 --- a/test/mitmproxy/utils/test_asyncio_utils.py +++ b/test/mitmproxy/utils/test_asyncio_utils.py @@ -1,5 +1,4 @@ import asyncio -import sys import pytest @@ -15,7 +14,6 @@ async def ttask(): @pytest.mark.asyncio -@pytest.mark.skipif(sys.version_info < (3, 8), reason="requires Python 3.8") async def test_simple(): task = asyncio_utils.create_task( ttask(), @@ -30,7 +28,6 @@ async def test_simple(): assert task.cancelled() -@pytest.mark.skipif(sys.version_info < (3, 8), reason="requires Python 3.8") def test_closed_loop(): # Crude test for line coverage. # This should eventually go, see the description in asyncio_utils.create_task for details. @@ -38,9 +35,11 @@ def test_closed_loop(): ttask(), name="ttask", ) + t = ttask() with pytest.raises(RuntimeError): asyncio_utils.create_task( - ttask(), + t, name="ttask", ignore_closed_loop=False, ) + t.close() # suppress "not awaited" warning \ No newline at end of file diff --git a/test/mitmproxy/utils/test_debug.py b/test/mitmproxy/utils/test_debug.py index 065574293..88a338093 100644 --- a/test/mitmproxy/utils/test_debug.py +++ b/test/mitmproxy/utils/test_debug.py @@ -24,8 +24,7 @@ def test_dump_info(): async def test_dump_info_async(): cs = io.StringIO() debug.dump_info(None, None, file=cs, testing=True) - if sys.version_info >= (3, 8): - assert "Tasks" in cs.getvalue() + assert "Tasks" in cs.getvalue() def test_dump_stacks(): diff --git a/tox.ini b/tox.ini index 374ad818d..355042215 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py35, py36, py37, py38, py39, flake8, filename_matching, mypy, individual_coverage, docs +envlist = py35, py38, py39, flake8, filename_matching, mypy, individual_coverage, docs skipsdist = True toxworkdir={env:TOX_WORK_DIR:.tox} @@ -20,7 +20,7 @@ whitelist_externals = deps = -rrequirements.txt commands = - bash -c "mitmdump --version 2>&1 | grep 'mitmproxy requires Python 3.6'" + bash -c "mitmdump --version 2>&1 | grep 'mitmproxy requires Python 3.8'" [testenv:flake8] deps = flake8==3.8.4