From f5f18a38ab990910ca43448212c70938992c9787 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 21 Nov 2010 17:51:41 +0000 Subject: [PATCH] Fixed #14749 -- added support for using Django's file object as context managers. Thanks to Florian Apolloner for the patch. git-svn-id: http://code.djangoproject.com/svn/django/trunk@14671 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/core/files/base.py | 6 ++++++ tests/modeltests/files/tests.py | 4 +++- tests/modeltests/files/tests_25.py | 17 +++++++++++++++++ tests/regressiontests/file_storage/tests.py | 18 ++++++++++++------ tests/regressiontests/test_utils/tests.py | 2 +- .../test_utils/{python_25.py => tests_25.py} | 0 6 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 tests/modeltests/files/tests_25.py rename tests/regressiontests/test_utils/{python_25.py => tests_25.py} (100%) diff --git a/django/core/files/base.py b/django/core/files/base.py index f9e3f1039a..6204d71040 100644 --- a/django/core/files/base.py +++ b/django/core/files/base.py @@ -101,6 +101,12 @@ class File(FileProxyMixin): if buffer_ is not None: yield buffer_ + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, tb): + self.close() + def open(self, mode=None): if not self.closed: self.seek(0) diff --git a/tests/modeltests/files/tests.py b/tests/modeltests/files/tests.py index 025fcc574a..26808f7d9a 100644 --- a/tests/modeltests/files/tests.py +++ b/tests/modeltests/files/tests.py @@ -1,4 +1,5 @@ import shutil +import sys from django.core.cache import cache from django.core.files.base import ContentFile @@ -6,6 +7,8 @@ from django.core.files.uploadedfile import SimpleUploadedFile from django.test import TestCase from models import Storage, temp_storage, temp_storage_location +if sys.version_info >= (2, 5): + from tests_25 import FileObjTests class FileTests(TestCase): @@ -97,4 +100,3 @@ class FileTests(TestCase): obj2.normal.delete() obj3.default.delete() obj4.random.delete() - diff --git a/tests/modeltests/files/tests_25.py b/tests/modeltests/files/tests_25.py new file mode 100644 index 0000000000..48eb6e26f7 --- /dev/null +++ b/tests/modeltests/files/tests_25.py @@ -0,0 +1,17 @@ +from __future__ import with_statement + +import tempfile + +from django.core.files import File +from django.utils.unittest import TestCase + + +class FileObjTests(TestCase): + def test_context_manager(self): + orig_file = tempfile.TemporaryFile() + base_file = File(orig_file) + with base_file as f: + self.assertIs(base_file, f) + self.assertFalse(f.closed) + self.assertTrue(f.closed) + self.assertTrue(orig_file.closed) diff --git a/tests/regressiontests/file_storage/tests.py b/tests/regressiontests/file_storage/tests.py index b90bf0e49b..e73b61fc21 100644 --- a/tests/regressiontests/file_storage/tests.py +++ b/tests/regressiontests/file_storage/tests.py @@ -4,8 +4,17 @@ import shutil import sys import tempfile import time -from cStringIO import StringIO from datetime import datetime, timedelta +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + +try: + import threading +except ImportError: + import dummy_threading as threading + from django.conf import settings from django.core.exceptions import SuspiciousOperation from django.core.files.base import ContentFile, File @@ -15,11 +24,6 @@ from django.core.files.uploadedfile import UploadedFile from django.core.exceptions import ImproperlyConfigured from django.utils import unittest -try: - import threading -except ImportError: - import dummy_threading as threading - # Try to import PIL in either of the two ways it can end up installed. # Checking for the existence of Image is enough for CPython, but # for PyPy, you need to check for the underlying modules @@ -31,6 +35,7 @@ except ImportError: except ImportError: Image = None + class GetStorageClassTests(unittest.TestCase): def assertRaisesErrorWithMessage(self, error, message, callable, *args, **kwargs): @@ -430,6 +435,7 @@ class InconsistentGetImageDimensionsBug(unittest.TestCase): Multiple calls of get_image_dimensions() should return the same size. """ from django.core.files.images import ImageFile + img_path = os.path.join(os.path.dirname(__file__), "test.png") image = ImageFile(open(img_path, 'rb')) image_pil = Image.open(img_path) diff --git a/tests/regressiontests/test_utils/tests.py b/tests/regressiontests/test_utils/tests.py index 2e55ba7718..2a9c826451 100644 --- a/tests/regressiontests/test_utils/tests.py +++ b/tests/regressiontests/test_utils/tests.py @@ -4,7 +4,7 @@ from django.test import TestCase, skipUnlessDBFeature, skipIfDBFeature if sys.version_info >= (2, 5): - from python_25 import AssertNumQueriesTests + from tests_25 import AssertNumQueriesTests class SkippingTestCase(TestCase): diff --git a/tests/regressiontests/test_utils/python_25.py b/tests/regressiontests/test_utils/tests_25.py similarity index 100% rename from tests/regressiontests/test_utils/python_25.py rename to tests/regressiontests/test_utils/tests_25.py