Loading django/core/files/images.py +2 −6 Original line number Diff line number Diff line """ Utility functions for handling images. Requires PIL, as you might imagine. Requires Pillow (or PIL), as you might imagine. """ import zlib Loading Loading @@ -35,11 +35,7 @@ def get_image_dimensions(file_or_path, close=False): 'close' to True to close the file at the end if it is initially in an open state. """ # Try to import PIL in either of the two ways it can end up installed. try: from PIL import ImageFile as PILImageFile except ImportError: import ImageFile as PILImageFile from django.utils.image import ImageFile as PILImageFile p = PILImageFile.Parser() if hasattr(file_or_path, 'read'): Loading django/core/management/validation.py +2 −6 Original line number Diff line number Diff line Loading @@ -105,14 +105,10 @@ def get_validation_errors(outfile, app=None): if isinstance(f, models.FileField) and not f.upload_to: e.add(opts, '"%s": FileFields require an "upload_to" attribute.' % f.name) if isinstance(f, models.ImageField): # Try to import PIL in either of the two ways it can end up installed. try: from PIL import Image from django.utils.image import Image except ImportError: try: import Image except ImportError: e.add(opts, '"%s": To use ImageFields, you need to install the Python Imaging Library. Get it at http://www.pythonware.com/products/pil/ .' % f.name) e.add(opts, '"%s": To use ImageFields, you need to install Pillow. Get it at https://pypi.python.org/pypi/Pillow.' % f.name) if isinstance(f, models.BooleanField) and getattr(f, 'null', False): e.add(opts, '"%s": BooleanFields do not accept null values. Use a NullBooleanField instead.' % f.name) if isinstance(f, models.FilePathField) and not (f.allow_files or f.allow_folders): Loading django/forms/fields.py +4 −12 Original line number Diff line number Diff line Loading @@ -602,13 +602,9 @@ class ImageField(FileField): if f is None: return None # Try to import PIL in either of the two ways it can end up installed. try: from PIL import Image except ImportError: import Image from django.utils.image import Image # We need to get a file object for PIL. We might have a path or we might # We need to get a file object for Pillow. We might have a path or we might # have to read the data into memory. if hasattr(data, 'temporary_file_path'): file = data.temporary_file_path() Loading @@ -623,12 +619,8 @@ class ImageField(FileField): # image in memory, which is a DoS vector. See #3848 and #18520. # verify() must be called immediately after the constructor. Image.open(file).verify() except ImportError: # Under PyPy, it is possible to import PIL. However, the underlying # _imaging C module isn't available, so an ImportError will be # raised. Catch and re-raise. raise except Exception: # Python Imaging Library doesn't recognize it as an image except Exception: # Pillow (or PIL) doesn't recognize it as an image. six.reraise(ValidationError, ValidationError(self.error_messages['invalid_image']), sys.exc_info()[2]) if hasattr(f, 'seek') and callable(f.seek): f.seek(0) Loading django/utils/image.py 0 → 100644 +146 −0 Original line number Diff line number Diff line # -*- coding: utf-8 -*- """ To provide a shim layer over Pillow/PIL situation until the PIL support is removed. 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?) 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 ``import _imaging`` * ``ImportError`` - Bad install, toss an exception """ import warnings from django.core.exceptions import ImproperlyConfigured 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( _(u"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, u'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() == u'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: import _imaging as PIL_imaging except ImportError as err: raise ImproperlyConfigured( _(u"The '_imaging' module for the PIL could not be " + u"imported: %s" % err) ) # Try to import ImageFile as well. try: from PIL import ImageFile as PILImageFile except ImportError: 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.", PendingDeprecationWarning ) return PILImage, PIL_imaging, PILImageFile Image, _imaging, ImageFile = _detect_image_library() docs/faq/contributing.txt +1 −1 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ to make it dead easy, even for someone who may not be intimately familiar with that area of the code, to understand the problem and verify the fix: * Are there clear instructions on how to reproduce the bug? If this touches a dependency (such as PIL), a contrib module, or a specific touches a dependency (such as Pillow/PIL), a contrib module, or a specific database, are those instructions clear enough even for someone not familiar with it? Loading Loading
django/core/files/images.py +2 −6 Original line number Diff line number Diff line """ Utility functions for handling images. Requires PIL, as you might imagine. Requires Pillow (or PIL), as you might imagine. """ import zlib Loading Loading @@ -35,11 +35,7 @@ def get_image_dimensions(file_or_path, close=False): 'close' to True to close the file at the end if it is initially in an open state. """ # Try to import PIL in either of the two ways it can end up installed. try: from PIL import ImageFile as PILImageFile except ImportError: import ImageFile as PILImageFile from django.utils.image import ImageFile as PILImageFile p = PILImageFile.Parser() if hasattr(file_or_path, 'read'): Loading
django/core/management/validation.py +2 −6 Original line number Diff line number Diff line Loading @@ -105,14 +105,10 @@ def get_validation_errors(outfile, app=None): if isinstance(f, models.FileField) and not f.upload_to: e.add(opts, '"%s": FileFields require an "upload_to" attribute.' % f.name) if isinstance(f, models.ImageField): # Try to import PIL in either of the two ways it can end up installed. try: from PIL import Image from django.utils.image import Image except ImportError: try: import Image except ImportError: e.add(opts, '"%s": To use ImageFields, you need to install the Python Imaging Library. Get it at http://www.pythonware.com/products/pil/ .' % f.name) e.add(opts, '"%s": To use ImageFields, you need to install Pillow. Get it at https://pypi.python.org/pypi/Pillow.' % f.name) if isinstance(f, models.BooleanField) and getattr(f, 'null', False): e.add(opts, '"%s": BooleanFields do not accept null values. Use a NullBooleanField instead.' % f.name) if isinstance(f, models.FilePathField) and not (f.allow_files or f.allow_folders): Loading
django/forms/fields.py +4 −12 Original line number Diff line number Diff line Loading @@ -602,13 +602,9 @@ class ImageField(FileField): if f is None: return None # Try to import PIL in either of the two ways it can end up installed. try: from PIL import Image except ImportError: import Image from django.utils.image import Image # We need to get a file object for PIL. We might have a path or we might # We need to get a file object for Pillow. We might have a path or we might # have to read the data into memory. if hasattr(data, 'temporary_file_path'): file = data.temporary_file_path() Loading @@ -623,12 +619,8 @@ class ImageField(FileField): # image in memory, which is a DoS vector. See #3848 and #18520. # verify() must be called immediately after the constructor. Image.open(file).verify() except ImportError: # Under PyPy, it is possible to import PIL. However, the underlying # _imaging C module isn't available, so an ImportError will be # raised. Catch and re-raise. raise except Exception: # Python Imaging Library doesn't recognize it as an image except Exception: # Pillow (or PIL) doesn't recognize it as an image. six.reraise(ValidationError, ValidationError(self.error_messages['invalid_image']), sys.exc_info()[2]) if hasattr(f, 'seek') and callable(f.seek): f.seek(0) Loading
django/utils/image.py 0 → 100644 +146 −0 Original line number Diff line number Diff line # -*- coding: utf-8 -*- """ To provide a shim layer over Pillow/PIL situation until the PIL support is removed. 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?) 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 ``import _imaging`` * ``ImportError`` - Bad install, toss an exception """ import warnings from django.core.exceptions import ImproperlyConfigured 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( _(u"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, u'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() == u'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: import _imaging as PIL_imaging except ImportError as err: raise ImproperlyConfigured( _(u"The '_imaging' module for the PIL could not be " + u"imported: %s" % err) ) # Try to import ImageFile as well. try: from PIL import ImageFile as PILImageFile except ImportError: 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.", PendingDeprecationWarning ) return PILImage, PIL_imaging, PILImageFile Image, _imaging, ImageFile = _detect_image_library()
docs/faq/contributing.txt +1 −1 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ to make it dead easy, even for someone who may not be intimately familiar with that area of the code, to understand the problem and verify the fix: * Are there clear instructions on how to reproduce the bug? If this touches a dependency (such as PIL), a contrib module, or a specific touches a dependency (such as Pillow/PIL), a contrib module, or a specific database, are those instructions clear enough even for someone not familiar with it? Loading