Remove Python 2 support

This commit is contained in:
Guillaume Ayoub 2016-03-31 19:57:40 +02:00
parent fa4eaef08e
commit 434cb533e9
34 changed files with 71 additions and 187 deletions

View File

@ -1,10 +1,9 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2008 Nicolas Kandel
# Copyright © 2008 Pascal Halter
# Copyright © 2008-2013 Guillaume Ayoub
# Copyright © 2008-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,8 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2011-2013 Guillaume Ayoub
# Copyright © 2011-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,10 +1,9 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2008 Nicolas Kandel
# Copyright © 2008 Pascal Halter
# Copyright © 2008-2013 Guillaume Ayoub
# Copyright © 2008-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,8 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2011-2013 Guillaume Ayoub
# Copyright © 2011-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,9 +1,7 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2008 Nicolas Kandel
# Copyright © 2008 Pascal Halter
# Copyright © 2008-2015 Guillaume Ayoub
# Copyright © 2008-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -29,28 +27,20 @@ should have been included in this package.
"""
import os
import sys
import pprint
import base64
import socket
import ssl
import wsgiref.simple_server
import re
# Manage Python2/3 different modules
# pylint: disable=F0401,E0611
try:
from http import client
from urllib.parse import unquote, urlparse
except ImportError:
import httplib as client
from urllib import unquote
from urlparse import urlparse
# pylint: enable=F0401,E0611
from http import client
from urllib.parse import unquote, urlparse
from . import auth, config, ical, log, pathutils, rights, storage, xmlutils
VERSION = "1.1.1"
VERSION = "2.0.0-pre"
# Standard "not allowed" response that is returned when an authenticated user
# tries to access information they don't have rights to
@ -69,7 +59,7 @@ class HTTPServer(wsgiref.simple_server.WSGIServer, object):
self.address_family = socket.AF_INET6
# Do not bind and activate, as we might change socket options
super(HTTPServer, self).__init__(address, handler, False)
super().__init__(address, handler, False)
if ipv6:
# Only allow IPv6 connections to the IPv6 socket
@ -84,7 +74,7 @@ class HTTPSServer(HTTPServer):
"""HTTPS server."""
def __init__(self, address, handler):
"""Create server by wrapping HTTP socket in an SSL socket."""
super(HTTPSServer, self).__init__(address, handler, False)
super().__init__(address, handler, False)
# Test if the SSL files can be read
for name in ("certificate", "key"):
@ -102,9 +92,8 @@ class HTTPSServer(HTTPServer):
keyfile=config.get("server", "key"),
ssl_version=getattr(
ssl, config.get("server", "protocol"), ssl.PROTOCOL_SSLv23))
# add ciphers argument only if supported (Python 2.7+)
if sys.version_info >= (2, 7):
ssl_kwargs["ciphers"] = config.get("server", "ciphers") or None
ssl_kwargs["ciphers"] = config.get("server", "ciphers") or None
self.socket = ssl.wrap_socket(self.socket, **ssl_kwargs)
@ -120,8 +109,8 @@ class RequestHandler(wsgiref.simple_server.WSGIRequestHandler):
def address_string(self):
"""Client address, formatted for logging."""
if config.getboolean("server", "dns_lookup"):
return \
wsgiref.simple_server.WSGIRequestHandler.address_string(self)
return (
wsgiref.simple_server.WSGIRequestHandler.address_string(self))
else:
return self.client_address[0]
@ -130,7 +119,7 @@ class Application(object):
"""WSGI application managing collections."""
def __init__(self):
"""Initialize application."""
super(Application, self).__init__()
super().__init__()
auth.load()
storage.load()
rights.load()
@ -295,8 +284,6 @@ class Application(object):
else:
status = client.SEE_OTHER
log.LOGGER.info("/.well-known/ redirection to: %s" % redirect)
if sys.version_info < (3, 0):
redirect = redirect.encode(self.encoding)
headers = {"Location": redirect}
status = "%i %s" % (
status, client.responses.get(status, "Unknown"))

View File

@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2011-2013 Guillaume Ayoub
# Copyright © 2011-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -162,14 +160,14 @@ def run():
# Create a socket pair to notify the select syscall of program shutdown
# This is not available in python < 3.5 on Windows
if hasattr(socket, "socketpair"):
shutdown_program_socket_in, shutdown_program_socket_out = \
socket.socketpair()
shutdown_program_socket_in, shutdown_program_socket_out = (
socket.socketpair())
else:
shutdown_program_socket_in, shutdown_program_socket_out = None, None
# SIGTERM and SIGINT (aka KeyboardInterrupt) should just mark this for
# shutdown
def shutdown(*_):
def shutdown(*args):
if shutdown_program[0]:
# Ignore following signals
return
@ -192,11 +190,11 @@ def run():
log.LOGGER.debug("Radicale server ready")
while not shutdown_program[0]:
try:
rlist, _, xlist = select.select(sockets, [], sockets,
select_timeout)
rlist, _, xlist = select.select(
sockets, [], sockets, select_timeout)
except (KeyboardInterrupt, select.error):
# SIGINT ist handled by signal handler above
rlist, _, xlist = [], [], []
# SIGINT is handled by signal handler above
rlist, xlist = [], []
if xlist:
raise RuntimeError("Unhandled socket error")
if rlist:

View File

@ -1,9 +1,7 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2012 Daniel Aleksandersen
# Copyright © 2013 Nikita Koshikov
# Copyright © 2013 Guillaume Ayoub
# Copyright © 2013-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -28,8 +26,6 @@ port 143. Legacy SSL (often on legacy port 993) is deprecated and thus
unsupported. STARTTLS is enforced except if host is ``localhost`` as
passwords are sent in PLAIN.
Python 3.2 or newer is required for TLS.
"""
import imaplib

View File

@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2011 Corentin Le Bail
# Copyright © 2011-2013 Guillaume Ayoub
# Copyright © 2011-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2011 Henry-Nicolas Tourneur
# Copyright © 2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -24,9 +23,10 @@ Authentication based on the ``pam-python`` module.
"""
import grp
import pam
import pwd
import pam
from .. import config, log

View File

@ -1,9 +1,7 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2008 Nicolas Kandel
# Copyright © 2008 Pascal Halter
# Copyright © 2008-2013 Guillaume Ayoub
# Copyright © 2008-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2011 Henry-Nicolas Tourneur
#

View File

@ -1,9 +1,7 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2008 Nicolas Kandel
# Copyright © 2008 Pascal Halter
# Copyright © 2008-2013 Guillaume Ayoub
# Copyright © 2008-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -104,7 +102,7 @@ def _bcrypt(hash_value, password):
def _md5apr1(hash_value, password):
return _passlib_md5apr1.verify(password, hash_value)
return _passlib_md5apr1.verify(password, hash_value)
# Prepare mapping between encryption names and verification functions.

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2012 Ehsanul Hoque
# Copyright © 2013 Guillaume Ayoub

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2012 Ehsanul Hoque
# Copyright © 2013 Guillaume Ayoub

View File

@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2008-2015 Guillaume Ayoub
# Copyright © 2008-2016 Guillaume Ayoub
# Copyright © 2008 Nicolas Kandel
# Copyright © 2008 Pascal Halter
#
@ -27,13 +25,8 @@ Give a configparser-like interface to read and write configuration.
import os
import sys
# Manage Python2/3 different modules
# pylint: disable=F0401
try:
from configparser import RawConfigParser as ConfigParser
except ImportError:
from ConfigParser import RawConfigParser as ConfigParser
# pylint: enable=F0401
from configparser import RawConfigParser as ConfigParser
# Default configuration

View File

@ -1,9 +1,7 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2008 Nicolas Kandel
# Copyright © 2008 Pascal Halter
# Copyright © 2008-2015 Guillaume Ayoub
# Copyright © 2008-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2011-2013 Guillaume Ayoub
# Copyright © 2011-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
#
# This library is free software: you can redistribute it and/or modify
@ -81,7 +79,7 @@ def is_safe_filesystem_path_component(path):
def path_to_filesystem(path, base_folder):
"""Convert path to a local filesystem path relative to base_folder.
Conversion is done in a secure manner, or raises ValueError.
Conversion is done in a secure manner, or raises ``ValueError``.
"""
sane_path = sanitize_path(path).strip("/")

View File

@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2012-2013 Guillaume Ayoub
# Copyright © 2012-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,9 +1,7 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2008 Nicolas Kandel
# Copyright © 2008 Pascal Halter
# Copyright © 2008-2013 Guillaume Ayoub
# Copyright © 2008-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2012-2013 Guillaume Ayoub
# Copyright © 2012-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -23,7 +21,9 @@ This module loads the storage backend, according to the storage
configuration.
"""
import sys
from .. import config, ical

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2013 Guillaume Ayoub
#
@ -24,6 +22,7 @@ SQLAlchemy storage backend.
import time
from datetime import datetime
from contextlib import contextmanager
from sqlalchemy import create_engine, Column, Unicode, Integer, ForeignKey
from sqlalchemy import func
from sqlalchemy.orm import sessionmaker, relationship
@ -104,7 +103,7 @@ class Collection(ical.Collection):
"""Collection stored in a database."""
def __init__(self, path, principal=False):
self.session = Session()
super(Collection, self).__init__(path, principal)
super().__init__(path, principal)
def __del__(self):
self.session.commit()

View File

@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2012-2015 Guillaume Ayoub
# Copyright © 2012-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2014 Jean-Marc Martins
# Copyright © 2014-2015 Guillaume Ayoub
# Copyright © 2014-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -27,8 +25,8 @@ import json
import shutil
import time
import sys
from contextlib import contextmanager
from . import filesystem
from .. import ical
from .. import log
@ -52,9 +50,7 @@ class Collection(filesystem.Collection):
for component in self.components:
text = ical.serialize(
self.tag, self.headers, [component] + self.timezones)
name = (
component.name if sys.version_info[0] >= 3 else
component.name.encode(filesystem.FILESYSTEM_ENCODING))
name = component.name
if not pathutils.is_safe_filesystem_path_component(name):
log.LOGGER.debug(
"Can't tranlate name safely to filesystem, "

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2008 Nicolas Kandel
# Copyright © 2008 Pascal Halter
@ -27,23 +25,10 @@ in them for XML requests (all but PUT).
"""
try:
from collections import OrderedDict
except ImportError:
# Python 2.6 has no OrderedDict, use a dict instead
OrderedDict = dict # pylint: disable=C0103
# Manage Python2/3 different modules
# pylint: disable=F0401,E0611
try:
from urllib.parse import unquote, urlparse
except ImportError:
from urllib import unquote
from urlparse import urlparse
# pylint: enable=F0401,E0611
import re
import xml.etree.ElementTree as ET
from collections import OrderedDict
from urllib.parse import unquote, urlparse
from . import client, config, ical, rights
@ -62,12 +47,7 @@ NAMESPACES_REV = {}
for short, url in NAMESPACES.items():
NAMESPACES_REV[url] = short
if hasattr(ET, "register_namespace"):
# Register namespaces cleanly with Python 2.7+ and 3.2+ ...
ET.register_namespace("" if short == "D" else short, url)
else:
# ... and badly with Python 2.6 and 3.1
ET._namespace_map[url] = short # pylint: disable=W0212
ET.register_namespace("" if short == "D" else short, url)
CLARK_TAG_REGEX = re.compile(r"""

View File

@ -1,8 +1,7 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2009-2013 Guillaume Ayoub
# Copyright © 2009-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -67,11 +66,7 @@ setup(
"Intended Audience :: Information Technology",
"License :: OSI Approved :: GNU General Public License (GPL)",
"Operating System :: OS Independent",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.6",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.2",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",

View File

@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2012-2013 Guillaume Ayoub
# Copyright © 2012-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -30,8 +28,6 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
os.environ["RADICALE_CONFIG"] = os.path.join(os.path.dirname(
os.path.dirname(__file__)), "config")
from .helpers import get_file_content
class BaseTest(object):
"""Base class for tests."""
@ -46,8 +42,7 @@ class BaseTest(object):
args["REQUEST_METHOD"] = method.upper()
args["PATH_INFO"] = path
if data:
if sys.version_info[0] >= 3:
data = data.encode("utf-8")
data = data.encode("utf-8")
args["wsgi.input"] = BytesIO(data)
args["CONTENT_LENGTH"] = str(len(data))
self.application._answer = self.application(args, self.start_response)

View File

@ -1 +0,0 @@
# coding=utf-8

View File

@ -1,9 +1,7 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2008 Nicolas Kandel
# Copyright © 2008 Pascal Halter
# Copyright © 2008-2013 Guillaume Ayoub
# Copyright © 2008-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2012-2013 Guillaume Ayoub
# Copyright © 2012-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,9 +1,7 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2008 Nicolas Kandel
# Copyright © 2008 Pascal Halter
# Copyright © 2008-2013 Guillaume Ayoub
# Copyright © 2008-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2012-2013 Guillaume Ayoub
# Copyright © 2012-2013 Jean-Marc Martins
# Copyright © 2012-2016 Jean-Marc Martins
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -27,9 +25,11 @@ import hashlib
import os
import radicale
import tempfile
from radicale import config
from radicale.auth import htpasswd
from tests import BaseTest
from . import BaseTest
class TestBaseAuthRequests(BaseTest):

View File

@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
#
# This file is part of Radicale Server - Calendar Server
# Copyright © 2012-2013 Guillaume Ayoub
# Copyright © 2012-2016 Guillaume Ayoub
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -120,7 +118,7 @@ class TestDataBaseSystem(BaseRequests, BaseTest):
storage_type = "database"
def setup(self):
super(TestDataBaseSystem, self).setup()
super().setup()
radicale.config.set("storage", "database_url", "sqlite://")
from radicale.storage import database
database.Session = sessionmaker()
@ -134,7 +132,7 @@ class TestDataBaseSystem(BaseRequests, BaseTest):
class TestGitFileSystem(TestFileSystem):
"""Base class for filesystem tests using Git"""
def setup(self):
super(TestGitFileSystem, self).setup()
super().setup()
Repo.init(self.colpath)
from radicale.storage import filesystem
filesystem.GIT_REPOSITORY = Repo(self.colpath)
@ -150,7 +148,7 @@ class TestCustomStorageSystem(BaseRequests, BaseTest):
def setup(self):
"""Setup function for each test."""
super(TestCustomStorageSystem, self).setup()
super().setup()
self.colpath = tempfile.mkdtemp()
radicale.config.set(
"storage", "custom_handler", "tests.custom.storage")

28
tox.ini
View File

@ -1,5 +1,5 @@
[tox]
envlist = py26, py27, py32, py33, py34#, pypy
envlist = py33, py34, py35
[base]
deps =
@ -11,23 +11,6 @@ deps =
[testenv]
commands = nosetests []
[testenv:py26]
deps =
python-ldap
dulwich<=0.9.5
{[base]deps}
[testenv:py27]
deps =
python-ldap
dulwich
{[base]deps}
[testenv:py32]
deps =
git+https://github.com/eberle1080/dulwich-py3k.git
{[base]deps}
[testenv:py33]
deps =
git+https://github.com/eberle1080/dulwich-py3k.git
@ -38,8 +21,7 @@ deps =
git+https://github.com/eberle1080/dulwich-py3k.git
{[base]deps}
# Pypy support seems to be broken, at least with sqlalchemy
#[testenv:pypy]
#deps =
# dulwich
# {[base]deps}
[testenv:py35]
deps =
git+https://github.com/eberle1080/dulwich-py3k.git
{[base]deps}