Import PIL consistently and with exception handling, list as optional dependency in INSTALL
|Reported by:||Jeff Kowalczyk||Owned by:||nobody|
|Severity:||Keywords:||PIL imaging easy_install|
|Has patch:||no||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
Some projects import PIL, some Imaging intending to reach the same code depending on how PIL was installed. Django appears to use the second form in at least one spot.
Some imports handle ImportError exceptions, some don't.
PIL is not mentioned in the INSTALL document.
$ ack -B 4 -A 4 'PIL|Imaging' django/forms/fields.py 472- 473- def clean(self, data, initial=None): 474- """ 475- Checks that the file-upload field data contains a valid image (GIF, JPG, 476: PNG, possibly others -- whatever the Python Imaging Library supports). 477- """ 478- f = super(ImageField, self).clean(data, initial) 479- if f is None: 480- return None 481- elif not data and initial: 482- return initial 483: from PIL import Image 484- 485: # We need to get a file object for PIL. We might have a path or we might 486- # have to read the data into memory. 487- if hasattr(data, 'temporary_file_path'): 488- file = data.temporary_file_path() 489- else: -- 507- # but it must be called immediately after the constructor 508- trial_image = Image.open(file) 509- trial_image.verify() 510- except ImportError: 511: # Under PyPy, it is possible to import PIL. However, the underlying 512- # _imaging C module isn't available, so an ImportError will be 513- # raised. Catch and re-raise. 514- raise 515: except Exception: # Python Imaging Library doesn't recognize it as an image 516- raise ValidationError(self.error_messages['invalid_image']) 517- if hasattr(f, 'seek') and callable(f.seek): 518- f.seek(0) 519- return f django/core/files/images.py 1-""" 2-Utility functions for handling images. 3- 4:Requires PIL, as you might imagine. 5-""" 6- 7-from django.core.files import File 8- -- 25- return self._dimensions_cache 26- 27-def get_image_dimensions(file_or_path): 28- """Returns the (width, height) of an image, given an open file or a path.""" 29: from PIL import ImageFile as PILImageFile 30: p = PILImageFile.Parser() 31- if hasattr(file_or_path, 'read'): 32- file = file_or_path 33- else: 34- file = open(file_or_path, 'rb') django/core/validators.py 167- 168-def isValidImage(field_data, all_data): 169- """ 170- Checks that the file-upload field data contains a valid image (GIF, JPG, 171: PNG, possibly others -- whatever the Python Imaging Library supports). 172- """ 173: from PIL import Image 174- from cStringIO import StringIO 175- try: 176- content = field_data.read() 177- except TypeError: -- 184- # verify() is the only method that can spot a corrupt PNG, 185- # but it must be called immediately after the constructor 186- trial_image = Image.open(StringIO(content)) 187- trial_image.verify() 188: except Exception: # Python Imaging Library doesn't recognize it as an image 189- raise ValidationError, _("Upload a valid image. The file you uploaded was either not an image or a corrupted image.") 190- 191-def isValidImageURL(field_data, all_data): 192- uc = URLMimeTypeCheck(('image/jpeg', 'image/gif', 'image/png')) django/core/management/validation.py 47- if isinstance(f, models.FileField) and not f.upload_to: 48- e.add(opts, '"%s": FileFields require an "upload_to" attribute.' % f.name) 49- if isinstance(f, models.ImageField): 50- try: 51: from PIL import Image 52- except ImportError: 53: 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) 54- if f.choices: 55- if isinstance(f.choices, basestring) or not is_iterable(f.choices): 56- e.add(opts, '"%s": "choices" should be iterable (e.g., a tuple or list).' % f.name) 57- else: tests/regressiontests/file_storage/models.py 6- 7-temp_storage = FileSystemStorage(tempfile.gettempdir()) 8- 9-# Test for correct behavior of width_field/height_field. 10:# Of course, we can't run this without PIL. 11- 12-try: 13- # Checking for the existence of Image is enough for CPython, but 14- # for PyPy, you need to check for the underlying modules 15- import Image, _imaging 16-except ImportError: 17- Image = None 18- 19:# If we have PIL, do these tests 20-if Image: 21- class Person(models.Model): 22- name = models.CharField(max_length=50) 23- mugshot = models.ImageField(storage=temp_storage, upload_to='tests', tests/regressiontests/serializers_regress/models.py 1-""" 2-A test spanning all the capabilities of all the serializers. 3- 4-This class sets up a model for each model field type 5:(except for image types, because of the PIL dependency). 6-""" 7- 8-from django.db import models 9-from django.contrib.contenttypes import generic tests/modeltests/model_forms/models.py 70- 71-class ImageFile(models.Model): 72- description = models.CharField(max_length=20) 73- try: 74: # If PIL is available, try testing PIL. 75- # Checking for the existence of Image is enough for CPython, but 76- # for PyPy, you need to check for the underlying modules 77: # If PIL is not available, this test is equivalent to TextFile above. 78- import Image, _imaging 79- image = models.ImageField(storage=temp_storage, upload_to='tests') 80- except ImportError: 81- image = models.FileField(storage=temp_storage, upload_to='tests')
Change History (4)
comment:2 Changed 8 years ago by
|Patch needs improvement:||unset|
|Status:||closed → reopened|