158 lines
5.1 KiB
Python
158 lines
5.1 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
To provide a shim layer over Pillow/PIL situation until the PIL support is
|
|
removed. See #19934.
|
|
|
|
|
|
Combinations To Account For
|
|
===========================
|
|
|
|
* Pillow:
|
|
|
|
* never has ``_imaging`` under any Python
|
|
* has the ``Image.alpha_composite``, which may aid in detection
|
|
|
|
* PIL
|
|
|
|
* CPython 2.x may have _imaging (& work)
|
|
* CPython 2.x may *NOT* have _imaging (broken & needs a error message)
|
|
* CPython 3.x doesn't work
|
|
* PyPy will *NOT* have _imaging (but works?)
|
|
* On some platforms (Homebrew and RHEL6 reported) _imaging isn't available,
|
|
the needed import is from PIL import _imaging (refs #21355)
|
|
|
|
Restated, that looks like:
|
|
|
|
* If we're on Python 2.x, it could be either Pillow or PIL:
|
|
|
|
* If ``import _imaging`` results in ``ImportError``, either they have a
|
|
working Pillow installation or a broken PIL installation, so we need to
|
|
detect further:
|
|
|
|
* To detect, we first ``import Image``.
|
|
* If ``Image`` has a ``alpha_composite`` attribute present, only Pillow
|
|
has this, so we assume it's working.
|
|
* If ``Image`` DOES NOT have a ``alpha_composite``attribute, it must be
|
|
PIL & is a broken (likely C compiler-less) install, which we need to
|
|
warn the user about.
|
|
|
|
* If ``import _imaging`` works, it must be PIL & is a working install.
|
|
|
|
* Python 3.x
|
|
|
|
* If ``import Image`` works, it must be Pillow, since PIL isn't Python 3.x
|
|
compatible.
|
|
|
|
* PyPy
|
|
|
|
* If ``import _imaging`` results in ``ImportError``, it could be either
|
|
Pillow or PIL, both of which work without it on PyPy, so we're fine.
|
|
|
|
|
|
Approach
|
|
========
|
|
|
|
* Attempt to import ``Image``
|
|
|
|
* ``ImportError`` - nothing is installed, toss an exception
|
|
* Either Pillow or the PIL is installed, so continue detecting
|
|
|
|
* Attempt to ``hasattr(Image, 'alpha_composite')``
|
|
|
|
* If it works, it's Pillow & working
|
|
* If it fails, we've got a PIL install, continue detecting
|
|
|
|
* The only option here is that we're on Python 2.x or PyPy, of which
|
|
we only care about if we're on CPython.
|
|
* If we're on CPython, attempt to ``from PIL import _imaging`` and
|
|
``import _imaging``
|
|
|
|
* ``ImportError`` - Bad install, toss an exception
|
|
|
|
"""
|
|
from __future__ import unicode_literals
|
|
|
|
import warnings
|
|
|
|
from django.core.exceptions import ImproperlyConfigured
|
|
from django.utils.deprecation import RemovedInDjango18Warning
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
|
|
Image = None
|
|
_imaging = None
|
|
ImageFile = None
|
|
|
|
|
|
def _detect_image_library():
|
|
global Image
|
|
global _imaging
|
|
global ImageFile
|
|
|
|
# Skip re-attempting to import if we've already run detection.
|
|
if Image is not None:
|
|
return Image, _imaging, ImageFile
|
|
|
|
# Assume it's not there.
|
|
PIL_imaging = False
|
|
|
|
try:
|
|
# Try from the Pillow (or one variant of PIL) install location first.
|
|
from PIL import Image as PILImage
|
|
except ImportError as err:
|
|
try:
|
|
# If that failed, try the alternate import syntax for PIL.
|
|
import Image as PILImage
|
|
except ImportError as err:
|
|
# Neither worked, so it's likely not installed.
|
|
raise ImproperlyConfigured(
|
|
_("Neither Pillow nor PIL could be imported: %s") % err
|
|
)
|
|
|
|
# ``Image.alpha_composite`` was added to Pillow in SHA: e414c6 & is not
|
|
# available in any version of the PIL.
|
|
if hasattr(PILImage, 'alpha_composite'):
|
|
PIL_imaging = False
|
|
else:
|
|
# We're dealing with the PIL. Determine if we're on CPython & if
|
|
# ``_imaging`` is available.
|
|
import platform
|
|
|
|
# This is the Alex Approved™ way.
|
|
# See http://mail.python.org/pipermail//pypy-dev/2011-November/008739.html
|
|
if platform.python_implementation().lower() == 'cpython':
|
|
# We're on CPython (likely 2.x). Since a C compiler is needed to
|
|
# produce a fully-working PIL & will create a ``_imaging`` module,
|
|
# we'll attempt to import it to verify their kit works.
|
|
try:
|
|
from PIL import _imaging as PIL_imaging
|
|
except ImportError:
|
|
try:
|
|
import _imaging as PIL_imaging
|
|
except ImportError as err:
|
|
raise ImproperlyConfigured(
|
|
_("The '_imaging' module for the PIL could not be "
|
|
"imported: %s") % err
|
|
)
|
|
|
|
# Try to import ImageFile as well.
|
|
try:
|
|
from PIL import ImageFile as PILImageFile
|
|
except ImportError:
|
|
# This import cannot fail unless Pillow/PIL install is completely
|
|
# broken (e.g. missing Python modules).
|
|
import ImageFile as PILImageFile
|
|
|
|
# Finally, warn about deprecation...
|
|
if PIL_imaging is not False:
|
|
warnings.warn(
|
|
"Support for the PIL will be removed in Django 1.8. Please " +
|
|
"uninstall it & install Pillow instead.",
|
|
RemovedInDjango18Warning
|
|
)
|
|
|
|
return PILImage, PIL_imaging, PILImageFile
|
|
|
|
|
|
Image, _imaging, ImageFile = _detect_image_library()
|