Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate Python 3.6 support #1693

merged 2 commits into from Feb 8, 2022

Deprecate Python 3.6 support #1693

merged 2 commits into from Feb 8, 2022


Copy link

@twm twm commented Feb 7, 2022

Contributor Checklist:

  • The associated ticket in Trac is here:
  • I ran tox -e lint to format my patch to meet the Twisted Coding Standard
  • I have created a newsfragment in src/twisted/newsfragments/ (see: News files)
  • The title of the PR starts with the associated Trac ticket number (without the # character).
  • I have updated the automated tests and checked that all checks for the PR are green.
  • I have submitted the associated Trac ticket for review by adding the word review to the keywords field in Trac, and putting a link to this PR in the comment; it shows up in now.

@twm twm requested a review from Feb 7, 2022
Copy link

@adiroiban adiroiban commented Feb 7, 2022

Thanks for the update.

I think that py3.6 should also be removed from the CI


Also, I think that it would help to do a cpython and pypy 3.6 cleanup in this PR


diff --git a/src/twisted/cred/test/ b/src/twisted/cred/test/
index 08e7ed0a1e..d797894ecf 100644
--- a/src/twisted/cred/test/
+++ b/src/twisted/cred/test/
@@ -266,11 +266,6 @@ class HashedPasswordOnDiskDatabaseTests(unittest.TestCase):
     def hash(self, u: bytes, p: bytes, s: bytes) -> bytes:
         hashed_password = crypt(p.decode("ascii"), s.decode("ascii"))  # type: ignore[misc]
-        # workaround for pypy3 3.6.9 and above which returns bytes from crypt.crypt()
-        # This is fixed in pypy3 7.3.5.
-        # See L{}
-        if isinstance(hashed_password, bytes):
-            return hashed_password
         return hashed_password.encode("ascii")
     def testGoodCredentials(self):
diff --git a/src/twisted/internet/ b/src/twisted/internet/
index 802dad5ee0..2be87ed300 100644
--- a/src/twisted/internet/
+++ b/src/twisted/internet/
@@ -1681,11 +1681,7 @@ def _inlineCallbacks(
             appCodeTrace = traceback.tb_next
             assert appCodeTrace is not None
-            if version_info < (3, 7):
-                # The contextvars backport and our no-op shim add an extra frame.
-                appCodeTrace = appCodeTrace.tb_next
-                assert appCodeTrace is not None
-            elif _PYPY:
+            if _PYPY:
                 # PyPy as of 3.7 adds an extra frame.
                 appCodeTrace = appCodeTrace.tb_next
                 assert appCodeTrace is not None
diff --git a/src/twisted/internet/ b/src/twisted/internet/
index 9eca93fd56..b638a86e20 100644
--- a/src/twisted/internet/
+++ b/src/twisted/internet/
@@ -1086,8 +1086,8 @@ class IReactorProcess(Interface):
         L{bytes} using the encoding given by L{sys.getfilesystemencoding}, to be
         used with the "narrow" OS APIs.  On Python 3 on Windows, L{bytes}
         arguments will be decoded up to L{unicode} using the encoding given by
-        L{sys.getfilesystemencoding} (C{mbcs} before Python 3.6, C{utf8}
-        thereafter) and given to Windows's native "wide" APIs.
+        L{sys.getfilesystemencoding which is C{utf8}}
+        and given to Windows's native "wide" APIs.
         @param processProtocol: An object which will be notified of all events
             related to the created process.
diff --git a/src/twisted/mail/test/ b/src/twisted/mail/test/
index 6842df0806..9dc2ace4b1 100644
--- a/src/twisted/mail/test/
+++ b/src/twisted/mail/test/
@@ -630,10 +630,6 @@ class POP3ClientModuleStructureTests(TestCase):
         for pc in publicClasses:
-            if sys.version_info < (3, 7) and pc == "List":
-                # typing.List shows up in publicClasses on
-                # Python < 3.7, so skip it.
-                continue
             if not pc == "POP3Client":
                     hasattr(twisted.mail.pop3, pc),
diff --git a/src/twisted/test/ b/src/twisted/test/
index faae0ac3c3..b4257fc220 100644
--- a/src/twisted/test/
+++ b/src/twisted/test/
@@ -3342,12 +3342,8 @@ class SelectVerifyImplementationTests(SynchronousTestCase):
         importErrors = [
-            # Python 3.6.3
-            "'import of service_identity halted; None in sys.modules'",
             # Python 3
             "'import of 'service_identity' halted; None in sys.modules'",
-            # Python 2
-            "'No module named service_identity'",
         expectedMessages = []
diff --git a/src/twisted/web/test/ b/src/twisted/web/test/
index 7ffea4e0bc..4b3614e8de 100644
--- a/src/twisted/web/test/
+++ b/src/twisted/web/test/
@@ -2422,17 +2422,6 @@ ok
 class QueryArgumentsTests(unittest.TestCase):
-    # FIXME:
-    # Re-enable once the implementation is updated.
-    @skipIf(sys.version_info >= (3, 6, 13), "newer py3.6 parse_qs treat ; differently")
-    def testParseqs(self):
-        self.assertEqual(parse_qs(b"a=b&d=c;+=f"), http.parse_qs(b"a=b&d=c;+=f"))
-        self.assertRaises(ValueError, http.parse_qs, b"blah", strict_parsing=True)
-        self.assertEqual(
-            parse_qs(b"a=&b=c", keep_blank_values=1),
-            http.parse_qs(b"a=&b=c", keep_blank_values=1),
-        )
-        self.assertEqual(parse_qs(b"a=&b=c"), http.parse_qs(b"a=&b=c"))
     def test_urlparse(self):

Copy link

@adiroiban adiroiban commented Feb 7, 2022

and there is which I think that it can be closed , now that we no longer support 3.6

Copy link

@adiroiban adiroiban commented Feb 7, 2022

Also, I think that we can remove the contextvars dependency as it's provided by stdlib in 3.7 and newer

Copy link
Contributor Author

@twm twm commented Feb 8, 2022

Hi @adiroiban, this is just to deprecate support. Dropping support is and it can't be done until a year after the depreciation, as I understand the compatibility policy. So the CI updates and cleanup will have to wait until then.

@twm twm enabled auto-merge Feb 8, 2022
@twm twm merged commit a6849d4 into trunk Feb 8, 2022
15 checks passed
Copy link

@adiroiban adiroiban left a comment

I think the deprecation policy only applies to twisted API.

But yes, you are right.

Let's merge this to make the announcement and later we can look at the cleanup.

@twm twm deleted the 10303-deprecate-py36 branch Mar 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
None yet

Successfully merging this pull request may close these issues.

None yet

2 participants