Drop support for Python 3.3 and <=2.7.9 by removing HTTP

This commit is contained in:
hugovk 2017-09-17 10:49:46 +03:00
parent 47531969b6
commit 3a403c943f
3 changed files with 22 additions and 114 deletions

View file

@ -20,6 +20,7 @@ Install via pip:
pip install pylast pip install pylast
pyLast >= 2.0.0 supports Python 2.7.9+ and 3.4+.
Features Features
-------- --------

View file

@ -10,7 +10,7 @@
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
# You may obtain a copy of the License at # You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # https://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, # distributed under the License is distributed on an "AS IS" BASIS,
@ -22,15 +22,16 @@
import hashlib import hashlib
from xml.dom import minidom, Node from xml.dom import minidom, Node
import xml.dom
import time
import shelve
import tempfile
import sys
import collections import collections
import warnings
import re import re
import shelve
import six import six
import ssl
import sys
import tempfile
import time
import warnings
import xml.dom
__version__ = '1.9.0' __version__ = '1.9.0'
__author__ = 'Amr Hassan, hugovk' __author__ = 'Amr Hassan, hugovk'
@ -43,35 +44,17 @@ def _deprecation_warning(message):
warnings.warn(message, DeprecationWarning) warnings.warn(message, DeprecationWarning)
def _can_use_ssl_securely():
# Python 3.3 doesn't support create_default_context() but can be made to
# work sanely.
# <2.7.9 and <3.2 never did any SSL verification so don't do SSL there.
# >3.4 and >2.7.9 has sane defaults so use SSL there.
v = sys.version_info
return v > (3, 3) or ((2, 7, 9) < v < (3, 0))
if _can_use_ssl_securely():
import ssl
if sys.version_info[0] == 3: if sys.version_info[0] == 3:
if _can_use_ssl_securely():
from http.client import HTTPSConnection
else:
from http.client import HTTPConnection
import html.entities as htmlentitydefs import html.entities as htmlentitydefs
from http.client import HTTPSConnection
from urllib.parse import splithost as url_split_host from urllib.parse import splithost as url_split_host
from urllib.parse import quote_plus as url_quote_plus from urllib.parse import quote_plus as url_quote_plus
unichr = chr unichr = chr
elif sys.version_info[0] == 2: elif sys.version_info[0] == 2:
if _can_use_ssl_securely():
from httplib import HTTPSConnection
else:
from httplib import HTTPConnection
import htmlentitydefs import htmlentitydefs
from httplib import HTTPSConnection
from urllib import splithost as url_split_host from urllib import splithost as url_split_host
from urllib import quote_plus as url_quote_plus from urllib import quote_plus as url_quote_plus
@ -150,57 +133,7 @@ RE_XML_ILLEGAL = (u'([\u0000-\u0008\u000b-\u000c\u000e-\u001f\ufffe-\uffff])' +
XML_ILLEGAL = re.compile(RE_XML_ILLEGAL) XML_ILLEGAL = re.compile(RE_XML_ILLEGAL)
# Python <=3.3 doesn't support create_default_context()
# <2.7.9 and <3.2 never did any SSL verification
# FIXME This can be removed after 2017-09 when 3.3 is no longer supported and
# pypy3 uses 3.4 or later, see
# https://en.wikipedia.org/wiki/CPython#Version_history
if sys.version_info[0] == 3 and sys.version_info[1] == 3:
import certifi
SSL_CONTEXT = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
SSL_CONTEXT.verify_mode = ssl.CERT_REQUIRED
SSL_CONTEXT.options |= ssl.OP_NO_COMPRESSION
# Intermediate from https://wiki.mozilla.org/Security/Server_Side_TLS
# Create the cipher string
cipher_string = """
ECDHE-ECDSA-CHACHA20-POLY1305
ECDHE-RSA-CHACHA20-POLY1305
ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-RSA-AES256-GCM-SHA384
DHE-RSA-AES128-GCM-SHA256
DHE-RSA-AES256-GCM-SHA384
ECDHE-ECDSA-AES128-SHA256
ECDHE-RSA-AES128-SHA256
ECDHE-ECDSA-AES128-SHA
ECDHE-RSA-AES256-SHA384
ECDHE-RSA-AES128-SHA
ECDHE-ECDSA-AES256-SHA384
ECDHE-ECDSA-AES256-SHA
ECDHE-RSA-AES256-SHA
DHE-RSA-AES128-SHA256
DHE-RSA-AES128-SHA
DHE-RSA-AES256-SHA256
DHE-RSA-AES256-SHA
ECDHE-ECDSA-DES-CBC3-SHA
ECDHE-RSA-DES-CBC3-SHA
EDH-RSA-DES-CBC3-SHA
AES128-GCM-SHA256
AES256-GCM-SHA384
AES128-SHA256
AES256-SHA256
AES128-SHA
AES256-SHA
DES-CBC3-SHA
!DSS
"""
cipher_string = ' '.join(cipher_string.split())
SSL_CONTEXT.set_ciphers(cipher_string)
SSL_CONTEXT.load_verify_locations(certifi.where())
# Python >3.4 and >2.7.9 has sane defaults # Python >3.4 and >2.7.9 has sane defaults
elif sys.version_info > (3, 4) or ((2, 7, 9) < sys.version_info < (3, 0)):
SSL_CONTEXT = ssl.create_default_context() SSL_CONTEXT = ssl.create_default_context()
@ -1180,15 +1113,10 @@ class _Request(object):
(HOST_NAME, HOST_SUBDIR) = self.network.ws_server (HOST_NAME, HOST_SUBDIR) = self.network.ws_server
if self.network.is_proxy_enabled(): if self.network.is_proxy_enabled():
if _can_use_ssl_securely():
conn = HTTPSConnection( conn = HTTPSConnection(
context=SSL_CONTEXT, context=SSL_CONTEXT,
host=self.network._get_proxy()[0], host=self.network._get_proxy()[0],
port=self.network._get_proxy()[1]) port=self.network._get_proxy()[1])
else:
conn = HTTPConnection(
host=self.network._get_proxy()[0],
port=self.network._get_proxy()[1])
try: try:
conn.request( conn.request(
@ -1198,15 +1126,7 @@ class _Request(object):
raise NetworkError(self.network, e) raise NetworkError(self.network, e)
else: else:
if _can_use_ssl_securely(): conn = HTTPSConnection(context=SSL_CONTEXT, host=HOST_NAME)
conn = HTTPSConnection(
context=SSL_CONTEXT,
host=HOST_NAME
)
else:
conn = HTTPConnection(
host=HOST_NAME
)
try: try:
conn.request( conn.request(
@ -4387,15 +4307,7 @@ class _ScrobblerRequest(object):
def execute(self): def execute(self):
"""Returns a string response of this request.""" """Returns a string response of this request."""
if _can_use_ssl_securely(): connection = HTTPSConnection(context=SSL_CONTEXT, host=self.hostname)
connection = HTTPSConnection(
context=SSL_CONTEXT,
host=self.hostname
)
else:
connection = HTTPConnection(
host=self.hostname
)
data = [] data = []
for name in self.params.keys(): for name in self.params.keys():

View file

@ -7,12 +7,6 @@ setup(
version="1.9.0", version="1.9.0",
author="Amr Hassan <amr.hassan@gmail.com>", author="Amr Hassan <amr.hassan@gmail.com>",
install_requires=['six'], install_requires=['six'],
# FIXME This can be removed after 2017-09 when 3.3 is no longer supported
# and pypy3 uses 3.4 or later, see
# https://en.wikipedia.org/wiki/CPython#Version_history
extras_require={
':python_version=="3.3"': ["certifi"],
},
tests_require=['mock', 'pytest', 'coverage', 'pep8', 'pyyaml', 'pyflakes'], tests_require=['mock', 'pytest', 'coverage', 'pep8', 'pyyaml', 'pyflakes'],
description=("A Python interface to Last.fm and Libre.fm"), description=("A Python interface to Last.fm and Libre.fm"),
author_email="amr.hassan@gmail.com", author_email="amr.hassan@gmail.com",
@ -26,10 +20,11 @@ setup(
"Programming Language :: Python :: 2", "Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7", "Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.6",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
], ],
keywords=["Last.fm", "music", "scrobble", "scrobbling"], keywords=["Last.fm", "music", "scrobble", "scrobbling"],
packages=find_packages(exclude=('tests*',)), packages=find_packages(exclude=('tests*',)),