Skip to content

Commit

Permalink
Merge pull request #510 from cherrypy/debt/py36
Browse files Browse the repository at this point in the history
Drop support for Python 3.5 and 2.7
  • Loading branch information
jaraco authored Nov 19, 2022
2 parents f0f9764 + 06f2107 commit ca63e92
Show file tree
Hide file tree
Showing 33 changed files with 241 additions and 853 deletions.
35 changes: 6 additions & 29 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -638,14 +638,11 @@ jobs:
- 3.11
- >-
3.10
- pypy2.7-v7.3.9
- 3.9
- 3.8
- pypy-3.7
- 3.7
- 3.6
- 3.5
- 2.7
- pypy-3.6
os:
- ubuntu-20.04
Expand All @@ -658,10 +655,6 @@ jobs:
# NOTE: Windows PyPy jobs are excluded to address the tox bug
# NOTE: https://github.com/tox-dev/tox/issues/1704.
# NOTE: They should be re-added once it's fixed.
- os: windows-2022
python-version: pypy2.7-v7.3.9
- os: windows-2019
python-version: pypy2.7-v7.3.9
- os: windows-2022
python-version: pypy-3.6
- os: windows-2019
Expand All @@ -676,23 +669,14 @@ jobs:
# NOTE: macOS PyPy jobs are excluded because installing cryptography
# NOTE: needs openssl headers that aren't present at the moment.
# TODO: Remove the exclusions once this is addressed.
- os: macos-11.0
python-version: pypy2.7-v7.3.9
- os: macos-latest
python-version: pypy2.7-v7.3.9
- os: macos-11.0
- os: macOS-11.0
python-version: pypy-3.6
- os: macos-latest
python-version: pypy-3.6
- os: macos-11.0
python-version: pypy-3.7
- os: macos-latest
python-version: pypy-3.7
include:
# NOTE: The only GNU/Linux CPython 3.4 available is built for Ubuntu 18
# https://github.com/actions/python-versions/blob/c483657/versions-manifest.json#L1228
- os: ubuntu-18.04
python-version: 3.4

continue-on-error: >-
${{
Expand All @@ -704,22 +688,15 @@ jobs:
(
startsWith(matrix.python-version, '~')
) ||
(
matrix.python-version == '2.7' &&
startsWith(matrix.os, 'windows-')
)
contains(matrix.python-version, 'alpha')
) && true || false
}}
env:
PYTEST_ADDOPTS: >-
${{
(
matrix.python-version == 'pypy2.7-v7.3.9' &&
startsWith(matrix.os, 'ubuntu-')
) &&
'-p no:warnings' || ''
}}
PIP_DISABLE_PIP_VERSION_CHECK: 1
PIP_NO_PYTHON_VERSION_WARNING: 1
PIP_NO_WARN_SCRIPT_LOCATION: 1
PY_COLORS: 1
TOXENV: python

steps:
Expand Down
8 changes: 8 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
.. scm-version-title:: v9.0.0

- :issue:`252` via :pr:`339`: Cheroot now requires Python
3.6 or later. Python 3.5 and Python 2.7 are still supported
by the :gh:`maint/8.x branch
<cherrypy/cheroot/tree/maint/8.x>` and stabilizing
bugfixes will be accepted to that branch.

.. scm-version-title:: v8.6.0

Significant improvements:
Expand Down
3 changes: 0 additions & 3 deletions cheroot/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
"""High-performance, pure-Python HTTP server used by CherryPy."""

from __future__ import absolute_import, division, print_function
__metaclass__ = type

try:
from importlib import metadata
except ImportError:
Expand Down
101 changes: 18 additions & 83 deletions cheroot/_compat.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
# pylint: disable=unused-import
"""Compatibility code for using Cheroot with various versions of Python."""

from __future__ import absolute_import, division, print_function
__metaclass__ = type

import os
import platform
import re

import six

try:
import selectors # lgtm [py/unused-import]
except ImportError:
import selectors2 as selectors # noqa: F401 # lgtm [py/unused-import]

try:
import ssl
Expand All @@ -22,20 +12,6 @@
except ImportError:
IS_ABOVE_OPENSSL10 = None

# contextlib.suppress was added in Python 3.4
try:
from contextlib import suppress
except ImportError:
from contextlib import contextmanager

@contextmanager
def suppress(*exceptions):
"""Return a context manager that suppresses the `exceptions`."""
try:
yield
except exceptions:
pass


IS_CI = bool(os.getenv('CI'))
IS_GITHUB_ACTIONS_WORKFLOW = bool(os.getenv('GITHUB_WORKFLOW'))
Expand All @@ -53,53 +29,23 @@ def suppress(*exceptions):
IS_PPC = PLATFORM_ARCH.startswith('ppc')


if not six.PY2:
def ntob(n, encoding='ISO-8859-1'):
"""Return the native string as bytes in the given encoding."""
assert_native(n)
# In Python 3, the native string type is unicode
return n.encode(encoding)

def ntou(n, encoding='ISO-8859-1'):
"""Return the native string as Unicode with the given encoding."""
assert_native(n)
# In Python 3, the native string type is unicode
return n

def bton(b, encoding='ISO-8859-1'):
"""Return the byte string as native string in the given encoding."""
return b.decode(encoding)
else:
# Python 2
def ntob(n, encoding='ISO-8859-1'):
"""Return the native string as bytes in the given encoding."""
assert_native(n)
# In Python 2, the native string type is bytes. Assume it's already
# in the given encoding, which for ISO-8859-1 is almost always what
# was intended.
return n

def ntou(n, encoding='ISO-8859-1'):
"""Return the native string as Unicode with the given encoding."""
assert_native(n)
# In Python 2, the native string type is bytes.
# First, check for the special encoding 'escape'. The test suite uses
# this to signal that it wants to pass a string with embedded \uXXXX
# escapes, but without having to prefix it with u'' for Python 2,
# but no prefix for Python 3.
if encoding == 'escape':
return re.sub(
r'\\u([0-9a-zA-Z]{4})',
lambda m: six.unichr(int(m.group(1), 16)),
n.decode('ISO-8859-1'),
)
# Assume it's already in the given encoding, which for ISO-8859-1
# is almost always what was intended.
return n.decode(encoding)

def bton(b, encoding='ISO-8859-1'):
"""Return the byte string as native string in the given encoding."""
return b
def ntob(n, encoding='ISO-8859-1'):
"""Return the native string as bytes in the given encoding."""
assert_native(n)
# In Python 3, the native string type is unicode
return n.encode(encoding)


def ntou(n, encoding='ISO-8859-1'):
"""Return the native string as Unicode with the given encoding."""
assert_native(n)
# In Python 3, the native string type is unicode
return n


def bton(b, encoding='ISO-8859-1'):
"""Return the byte string as native string in the given encoding."""
return b.decode(encoding)


def assert_native(n):
Expand All @@ -113,17 +59,6 @@ def assert_native(n):
raise TypeError('n must be a native str (got %s)' % type(n).__name__)


if not six.PY2:
"""Python 3 has :py:class:`memoryview` builtin."""
# Python 2.7 has it backported, but socket.write() does
# str(memoryview(b'0' * 100)) -> <memory at 0x7fb6913a5588>
# instead of accessing it correctly.
memoryview = memoryview
else:
"""Link :py:class:`memoryview` to buffer under Python 2."""
memoryview = buffer # noqa: F821


def extract_bytes(mv):
r"""Retrieve bytes out of the given input buffer.
Expand All @@ -138,7 +73,7 @@ def extract_bytes(mv):
or :py:class:`bytes`
"""
if isinstance(mv, memoryview):
return bytes(mv) if six.PY2 else mv.tobytes()
return mv.tobytes()

if isinstance(mv, bytes):
return mv
Expand Down
4 changes: 0 additions & 4 deletions cheroot/_compat.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ from typing import Any, ContextManager, Optional, Type, Union

def suppress(*exceptions: Type[BaseException]) -> ContextManager[None]: ...

selectors: Any

IS_ABOVE_OPENSSL10: Optional[bool]
IS_CI: bool
IS_GITHUB_ACTIONS_WORKFLOW: bool
Expand All @@ -20,6 +18,4 @@ def ntou(n: str, encoding: str = ...) -> str: ...
def bton(b: bytes, encoding: str = ...) -> str: ...
def assert_native(n: str) -> None: ...

memoryview: Any

def extract_bytes(mv: Union[memoryview, bytes]) -> bytes: ...
12 changes: 4 additions & 8 deletions cheroot/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,14 @@
"""

import argparse
from importlib import import_module
import os
import sys

import six
import urllib.parse # noqa: WPS301
from importlib import import_module
from contextlib import suppress

from . import server
from . import wsgi
from ._compat import suppress


__metaclass__ = type


class BindLocation:
Expand Down Expand Up @@ -143,7 +139,7 @@ def parse_wsgi_bind_location(bind_addr_string):
return AbstractSocket(bind_addr_string[1:])

# try and match for an IP/hostname and port
match = six.moves.urllib.parse.urlparse(
match = urllib.parse.urlparse(
'//{addr}'.format(addr=bind_addr_string),
)
try:
Expand Down
17 changes: 4 additions & 13 deletions cheroot/connections.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
"""Utilities to manage open connections."""

from __future__ import absolute_import, division, print_function
__metaclass__ = type

import io
import os
import socket
import threading
import time
import selectors
from contextlib import suppress

from . import errors
from ._compat import selectors
from ._compat import suppress
from ._compat import IS_WINDOWS
from .makefile import MakeFile

import six

try:
import fcntl
except ImportError:
Expand Down Expand Up @@ -310,8 +305,7 @@ def _from_server_socket(self, server_socket): # noqa: C901 # FIXME
msg,
]

sock_to_make = s if not six.PY2 else s._sock
wfile = mf(sock_to_make, 'wb', io.DEFAULT_BUFFER_SIZE)
wfile = mf(s, 'wb', io.DEFAULT_BUFFER_SIZE)
try:
wfile.write(''.join(buf).encode('ISO-8859-1'))
except socket.error as ex:
Expand All @@ -327,10 +321,7 @@ def _from_server_socket(self, server_socket): # noqa: C901 # FIXME

conn = self.server.ConnectionClass(self.server, s, mf)

if not isinstance(
self.server.bind_addr,
(six.text_type, six.binary_type),
):
if not isinstance(self.server.bind_addr, (str, bytes)):
# optional values
# Until we do DNS lookups, omit REMOTE_HOST
if addr is None: # sometimes this can happen
Expand Down
3 changes: 0 additions & 3 deletions cheroot/errors.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
# -*- coding: utf-8 -*-
"""Collection of exceptions raised and/or processed by Cheroot."""

from __future__ import absolute_import, division, print_function
__metaclass__ = type

import errno
import sys

Expand Down
Loading

0 comments on commit ca63e92

Please sign in to comment.