Browse Source

Drop python 2 support.

FREEZE-blogpost-2021-01-19
Jelmer Vernooij 12 months ago
parent
commit
dd76aa0cf1
No known key found for this signature in database GPG Key ID: 579C160D4C9E23E8
  1. 26
      isso/compat.py
  2. 10
      isso/config.py
  3. 7
      isso/core.py
  4. 4
      isso/db/__init__.py
  5. 5
      isso/db/comments.py
  6. 11
      isso/ext/notifications.py
  7. 3
      isso/migrate.py
  8. 9
      isso/tests/test_comments.py
  9. 8
      isso/tests/test_db.py
  10. 4
      isso/tests/test_utils_hash.py
  11. 5
      isso/utils/__init__.py
  12. 3
      isso/utils/hash.py
  13. 11
      isso/utils/parse.py
  14. 1
      isso/views/__init__.py
  15. 17
      isso/views/comments.py
  16. 17
      isso/wsgi.py
  17. 5
      tox.ini

26
isso/compat.py

@ -1,26 +0,0 @@
# -*- encoding: utf-8 -*-
try:
text_type = unicode # Python 2
string_types = (str, unicode)
PY2K = True
except NameError: # Python 3
PY2K = False
text_type = str
string_types = (str, )
if not PY2K:
buffer = memoryview
filter, map, zip = filter, map, zip
def iteritems(dikt):
return iter(dikt.items()) # noqa: E731
from functools import reduce
else:
buffer = buffer
from itertools import ifilter, imap, izip
filter, map, zip = ifilter, imap, izip
def iteritems(dikt):
return dikt.iteritems() # noqa: E731
reduce = reduce

10
isso/config.py

@ -7,9 +7,7 @@ import logging
import datetime
from email.utils import parseaddr, formataddr
from configparser import ConfigParser
from isso.compat import text_type as str
from configparser import ConfigParser, NoOptionError, NoSectionError
logger = logging.getLogger("isso")
@ -142,7 +140,11 @@ def load(default, user=None):
logger.info("Your `session-key` has been stored in the "
"database itself, this option is now unused")
if not parseaddr(parser.get("smtp", "from"))[0]:
try:
fromaddr = parser.get("smtp", "from")
except (NoOptionError, NoSectionError):
fromaddr = ''
if not parseaddr(fromaddr)[0]:
parser.set("smtp", "from",
formataddr(("Ich schrei sonst!", parser.get("smtp", "from"))))

7
isso/core.py

@ -12,12 +12,7 @@ try:
except ImportError:
uwsgi = None
from isso.compat import PY2K
if PY2K:
import thread
else:
import _thread as thread
import _thread as thread
from flask_caching.backends.nullcache import NullCache
from flask_caching.backends.simplecache import SimpleCache

4
isso/db/__init__.py

@ -9,8 +9,6 @@ from collections import defaultdict
logger = logging.getLogger("isso")
from isso.compat import buffer
from isso.db.comments import Comments
from isso.db.threads import Threads
from isso.db.spam import Guard
@ -77,7 +75,7 @@ class SQLite3:
if self.version == 0:
from isso.utils import Bloomfilter
bf = buffer(Bloomfilter(iterable=["127.0.0.0"]).array)
bf = memoryview(Bloomfilter(iterable=["127.0.0.0"]).array)
with sqlite3.connect(self.path) as con:
con.execute('UPDATE comments SET voters=?', (bf, ))

5
isso/db/comments.py

@ -4,7 +4,6 @@ import logging
import time
from isso.utils import Bloomfilter
from isso.compat import buffer
logger = logging.getLogger("isso")
@ -70,7 +69,7 @@ class Comments:
'FROM threads WHERE threads.uri = ?;'], (
c.get('parent'),
c.get('created') or time.time(), None, c["mode"], c['remote_addr'],
c['text'], c.get('author'), c.get('email'), c.get('website'), buffer(
c['text'], c.get('author'), c.get('email'), c.get('website'), memoryview(
Bloomfilter(iterable=[c['remote_addr']]).array), c.get('notification'),
uri)
)
@ -305,7 +304,7 @@ class Comments:
'UPDATE comments SET',
' likes = likes + 1,' if upvote else 'dislikes = dislikes + 1,',
' voters = ?'
'WHERE id=?;'], (buffer(bf.array), id))
'WHERE id=?;'], (memoryview(bf.array), id))
if upvote:
return {'likes': likes + 1, 'dislikes': dislikes}

11
isso/ext/notifications.py

@ -14,10 +14,7 @@ from email.utils import formatdate
from email.header import Header
from email.mime.text import MIMEText
try:
from urllib.parse import quote
except ImportError:
from urllib import quote
from urllib.parse import quote
import logging
logger = logging.getLogger("isso")
@ -27,13 +24,9 @@ try:
except ImportError:
uwsgi = None
from isso.compat import PY2K
from isso import local
if PY2K:
from thread import start_new_thread
else:
from _thread import start_new_thread
from _thread import start_new_thread
class SMTPConnection(object):

3
isso/migrate.py

@ -15,7 +15,6 @@ from time import mktime, strptime, time
from collections import defaultdict
from isso.utils import anonymize
from isso.compat import string_types
try:
input = raw_input
@ -33,7 +32,7 @@ logger = logging.getLogger("isso")
def strip(val):
if isinstance(val, string_types):
if isinstance(val, (str, )):
return val.strip()
return val

9
isso/tests/test_comments.py

@ -8,10 +8,7 @@ import re
import tempfile
import unittest
try:
from urllib.parse import urlencode
except ImportError:
from urllib import urlencode
from urllib.parse import urlencode
from werkzeug.wrappers import Response
@ -19,8 +16,6 @@ from isso import Isso, core, config, dist
from isso.utils import http
from isso.views import comments
from isso.compat import iteritems
from fixtures import curl, loads, FakeIP, JSONClient
http.curl = curl
@ -402,7 +397,7 @@ class TestComments(unittest.TestCase):
expected = {'a': 1, 'b': 2, 'c': 0}
for uri, count in iteritems(expected):
for uri, count in expected.items():
for _ in range(count):
self.post('/new?uri=%s' %
uri, data=json.dumps({"text": "..."}))

8
isso/tests/test_db.py

@ -8,8 +8,6 @@ import tempfile
from isso import config
from isso.db import SQLite3
from isso.compat import iteritems
class TestDBMigration(unittest.TestCase):
@ -93,7 +91,7 @@ class TestDBMigration(unittest.TestCase):
con.execute(
"INSERT INTO threads (uri, title) VALUES (?, ?)", ("/", "Test"))
for (id, parent) in iteritems(tree):
for (id, parent) in tree.items():
con.execute("INSERT INTO comments ("
" id, parent, created)"
"VALUEs (?, ?, ?)", (id, parent, id))
@ -106,7 +104,7 @@ class TestDBMigration(unittest.TestCase):
})
SQLite3(self.path, conf)
flattened = list(iteritems({
flattened = list({
1: None,
2: None,
3: 2,
@ -114,7 +112,7 @@ class TestDBMigration(unittest.TestCase):
5: 2,
6: None,
7: 2
}))
}.items())
with sqlite3.connect(self.path) as con:
rv = con.execute(

4
isso/tests/test_utils_hash.py

@ -6,7 +6,6 @@ import unittest
from isso import config
from isso.compat import PY2K, string_types
from isso.utils.hash import Hash, PBKDF2, new
@ -22,9 +21,8 @@ class TestHasher(unittest.TestCase):
self.assertRaises(TypeError, h.hash, "...")
self.assertEqual(h.hash(b"..."), b"...")
self.assertIsInstance(h.uhash(u"..."), string_types)
self.assertIsInstance(h.uhash(u"..."), (str, ))
@unittest.skipIf(PY2K, "byte/str quirks")
def test_uhash(self):
h = Hash(b"", func=None)
self.assertRaises(TypeError, h.uhash, b"...")

5
isso/utils/__init__.py

@ -14,7 +14,6 @@ from jinja2 import Environment, FileSystemLoader
from werkzeug.wrappers import Response
from werkzeug.exceptions import BadRequest
from isso.compat import text_type
from isso.wsgi import Request
try:
@ -29,7 +28,7 @@ def anonymize(remote_addr):
and /48 (zero'd).
"""
if not isinstance(remote_addr, text_type) and isinstance(remote_addr, str):
if not isinstance(remote_addr, str) and isinstance(remote_addr, str):
remote_addr = remote_addr.decode('ascii', 'ignore')
try:
ipv4 = ipaddress.IPv4Address(remote_addr)
@ -38,7 +37,7 @@ def anonymize(remote_addr):
try:
ipv6 = ipaddress.IPv6Address(remote_addr)
if ipv6.ipv4_mapped is not None:
return anonymize(text_type(ipv6.ipv4_mapped))
return anonymize(str(ipv6.ipv4_mapped))
return u'' + ipv6.exploded.rsplit(':', 5)[0] + ':' + ':'.join(['0000'] * 5)
except ipaddress.AddressValueError:
return u'0.0.0.0'

3
isso/utils/hash.py

@ -5,7 +5,6 @@ from __future__ import unicode_literals
import codecs
import hashlib
from isso.compat import string_types, text_type as str
try:
from werkzeug.security import pbkdf2_bin as pbkdf2
@ -57,7 +56,7 @@ class Hash(object):
def uhash(self, val):
"""Calculate hash from unicode value and return hex value as unicode"""
if not isinstance(val, string_types):
if not isinstance(val, (str, )):
raise _TypeError("val", "str", val)
return codecs.encode(self.hash(val.encode("utf-8")), "hex_codec").decode("utf-8")

11
isso/utils/parse.py

@ -4,19 +4,10 @@ from __future__ import print_function, unicode_literals
from itertools import chain
try:
from urllib import unquote
except ImportError:
from urllib.parse import unquote
from urllib.parse import unquote
import html5lib
from isso.compat import map, filter, PY2K
if PY2K: # http://bugs.python.org/issue12984
from xml.dom.minidom import NamedNodeMap
NamedNodeMap.__contains__ = lambda self, key: self.has_key(key) # noqa
def thread(data, default=u"Untitled.", id=None):
"""

1
isso/views/__init__.py

@ -12,7 +12,6 @@ from werkzeug.routing import Rule
from werkzeug.exceptions import BadRequest
from isso import local
from isso.compat import text_type as str
class requires:

17
isso/views/comments.py

@ -20,8 +20,6 @@ from werkzeug.routing import Rule
from werkzeug.wrappers import Response
from werkzeug.exceptions import BadRequest, Forbidden, NotFound
from isso.compat import text_type as str
from isso import utils, local
from isso.utils import (http, parse,
JSONResponse as JSON, XMLResponse as XML,
@ -34,18 +32,9 @@ try:
from cgi import escape
except ImportError:
from html import escape
try:
from urlparse import urlparse
except ImportError:
from urllib.parse import urlparse
try:
from urllib import unquote
except ImportError:
from urllib.parse import unquote
try:
from StringIO import StringIO
except ImportError:
from io import BytesIO as StringIO
from urllib.parse import urlparse
from urllib.parse import unquote
from io import BytesIO as StringIO
# from Django appearently, looks good to me *duck*

17
isso/wsgi.py

@ -5,24 +5,15 @@ from __future__ import unicode_literals
import sys
import socket
try:
from urllib.parse import quote, urlparse
from urllib.parse import quote, urlparse
from socketserver import ThreadingMixIn
from http.server import HTTPServer
except ImportError:
from urllib import quote
from urlparse import urlparse
from SocketServer import ThreadingMixIn
from BaseHTTPServer import HTTPServer
from socketserver import ThreadingMixIn
from http.server import HTTPServer
from werkzeug.serving import WSGIRequestHandler
from werkzeug.wrappers import Request as _Request
from werkzeug.datastructures import Headers
from isso.compat import string_types
def host(environ): # pragma: no cover
"""
@ -52,7 +43,7 @@ def urlsplit(name):
Parse :param:`name` into (netloc, port, ssl)
"""
if not (isinstance(name, string_types)):
if not isinstance(name, (str, )):
name = str(name)
if not name.startswith(('http://', 'https://')):

5
tox.ini

@ -8,11 +8,6 @@ deps =
commands =
python setup.py nosetests
[testenv:py27]
deps =
configparser
{[testenv]deps}
[testenv:debian]
deps=
bleach

Loading…
Cancel
Save