introduce a virtual imaplib2

The virtual imaplib2 first try to import imaplib2 when provided by the system.
If not provided or if the version is not supported, fallback on the bundled
imaplib2 version.

Distribution maintainers can now easily remove the bundled imaplib2 version if
they want to get it packaged outside of offlineimap.

We still want to provide imaplib2 by default because:
- this library is neither in Python core nor packaged by a lot of distributions;
- users expect to be able to run offlineimap by just downloading the tarball or
  after a git clone.

In order to avoid unexpected (too old) versions of imaplib2, we restrict the
supported versions of this librabry.

Reviewed-by: Łukasz Żarnowiecki <dolohow@outlook.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
Nicolas Sebrecht 2016-06-04 00:49:57 +02:00
parent 922bed05a7
commit acc9c3cf49
5 changed files with 59 additions and 10 deletions

View File

@ -1,5 +1,5 @@
# IMAP folder support
# Copyright (C) 2002-2012 John Goerzen & contributors
# Copyright (C) 2002-2016 John Goerzen & contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -20,14 +20,13 @@ import binascii
import re
import os
import time
import six
from sys import exc_info
from .Base import BaseFolder
from offlineimap import imaputil, imaplibutil, emailutil, OfflineImapError
from offlineimap import globals
from offlineimap.imaplib2 import MonthNames
import six
from offlineimap.virtual_imaplib2 import MonthNames
# Globals

View File

@ -1,5 +1,5 @@
# imaplib utilities
# Copyright (C) 2002-2015 John Goerzen & contributors
# Copyright (C) 2002-2016 John Goerzen & contributors
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
@ -23,12 +23,12 @@ import threading
from hashlib import sha1
import socket
import errno
import zlib
import six
from offlineimap.ui import getglobalui
from offlineimap import OfflineImapError
from offlineimap.imaplib2 import IMAP4, IMAP4_SSL, zlib, InternalDate, Mon2num
import six
from offlineimap.virtual_imaplib2 import IMAP4, IMAP4_SSL, InternalDate, Mon2num
class UsefulIMAPMixIn(object):

View File

@ -1,5 +1,5 @@
# OfflineIMAP initialization code
# Copyright (C) 2002-2015 John Goerzen & contributors
# Copyright (C) 2002-2016 John Goerzen & contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -18,7 +18,7 @@
import os
import sys
import threading
import offlineimap.imaplib2 as imaplib
import offlineimap.virtual_imaplib2 as imaplib
import signal
import socket
import logging

View File

@ -0,0 +1,50 @@
# Copyright (C) 2016-2016 Nicolas Sebrecht & contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
The virtual imaplib2 takes care to import the correct imaplib2 library. Any
internal use of imaplib2 everywhere else in offlineimap must be done through
this virtual_imaplib2 or we might go into troubles.
"""
_SUPPORTED_RELEASE = 2
_SUPPORTED_REVISION = 53
try:
# Try any imaplib2 in PYTHONPATH first. This allows both maintainers of
# distributions and developers to not work with the bundled imaplib2.
from imaplib2 import *
import imaplib2 as imaplib
if (int(imaplib.__release__) < _SUPPORTED_RELEASE or
int(imaplib.__revision__) < _SUPPORTED_REVISION):
raise ImportError("The provided imaplib2 version '%s' is not supported"%
imaplib.__version__)
except (ImportError, NameError) as e:
try:
from offlineimap.bundled_imaplib2 import *
import offlineimap.bundled_imaplib2 as imaplib
except:
print("Error while trying to import system imaplib2: %s"% e)
raise
# We should really get those literals exposed by upstream. Same goes for
# __version__, __release__ and __revision__.
InternalDate = imaplib.InternalDate
Mon2num = imaplib.Mon2num
MonthNames = imaplib.MonthNames