Merge pull request #208 from pylast/rm-python-3.3
Drop support for Python 3.3 and 2.7.9
This commit is contained in:
commit
3e5393cde7
|
@ -23,8 +23,6 @@ matrix:
|
||||||
env: TOXENV=py35
|
env: TOXENV=py35
|
||||||
- python: 3.4
|
- python: 3.4
|
||||||
env: TOXENV=py34
|
env: TOXENV=py34
|
||||||
- python: 3.3
|
|
||||||
env: TOXENV=py33
|
|
||||||
- python: pypy3
|
- python: pypy3
|
||||||
env: TOXENV=pypy3
|
env: TOXENV=pypy3
|
||||||
- python: pypy
|
- python: pypy
|
||||||
|
|
|
@ -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
|
||||||
--------
|
--------
|
||||||
|
|
|
@ -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,58 +133,8 @@ 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()
|
|
||||||
|
|
||||||
|
|
||||||
class _Network(object):
|
class _Network(object):
|
||||||
|
@ -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():
|
||||||
|
|
9
setup.py
9
setup.py
|
@ -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*',)),
|
||||||
|
|
Loading…
Reference in a new issue