mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #11753 - Q objects with callables no longer explode on Python 2.4. Thanks, Jeremy Dunck.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@11901 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
		| @@ -2,7 +2,7 @@ | |||||||
| Form Widget classes specific to the Django admin site. | Form Widget classes specific to the Django admin site. | ||||||
| """ | """ | ||||||
|  |  | ||||||
| import copy | import django.utils.copycompat as copy | ||||||
|  |  | ||||||
| from django import forms | from django import forms | ||||||
| from django.forms.widgets import RadioFieldRenderer | from django.forms.widgets import RadioFieldRenderer | ||||||
|   | |||||||
| @@ -821,7 +821,7 @@ class GEOSTest(unittest.TestCase): | |||||||
|  |  | ||||||
|     def test22_copy(self): |     def test22_copy(self): | ||||||
|         "Testing use with the Python `copy` module." |         "Testing use with the Python `copy` module." | ||||||
|         import copy |         import django.utils.copycompat as copy | ||||||
|         poly = GEOSGeometry('POLYGON((0 0, 0 23, 23 23, 23 0, 0 0), (5 5, 5 10, 10 10, 10 5, 5 5))') |         poly = GEOSGeometry('POLYGON((0 0, 0 23, 23 23, 23 0, 0 0), (5 5, 5 10, 10 10, 10 5, 5 5))') | ||||||
|         cpy1 = copy.copy(poly) |         cpy1 = copy.copy(poly) | ||||||
|         cpy2 = copy.deepcopy(poly) |         cpy2 = copy.deepcopy(poly) | ||||||
|   | |||||||
| @@ -2,9 +2,11 @@ | |||||||
| # Modified from original contribution by Aryeh Leib Taurog, which was | # Modified from original contribution by Aryeh Leib Taurog, which was | ||||||
| # released under the New BSD license. | # released under the New BSD license. | ||||||
| import unittest | import unittest | ||||||
|  |  | ||||||
|  | import django.utils.copycompat as copy | ||||||
|  |  | ||||||
| from django.contrib.gis.geos import * | from django.contrib.gis.geos import * | ||||||
| from django.contrib.gis.geos.error import GEOSIndexError | from django.contrib.gis.geos.error import GEOSIndexError | ||||||
| import copy |  | ||||||
|  |  | ||||||
| def getItem(o,i): return o[i] | def getItem(o,i): return o[i] | ||||||
| def delItem(o,i): del o[i] | def delItem(o,i): del o[i] | ||||||
|   | |||||||
| @@ -1,10 +1,10 @@ | |||||||
| import os, unittest | import os, unittest | ||||||
| from copy import copy |  | ||||||
| from decimal import Decimal | from decimal import Decimal | ||||||
| from models import City, County, CountyFeat, Interstate, ICity1, ICity2, State, city_mapping, co_mapping, cofeat_mapping, inter_mapping | from models import City, County, CountyFeat, Interstate, ICity1, ICity2, State, city_mapping, co_mapping, cofeat_mapping, inter_mapping | ||||||
| from django.contrib.gis.db.backend import SpatialBackend | from django.contrib.gis.db.backend import SpatialBackend | ||||||
| from django.contrib.gis.utils.layermapping import LayerMapping, LayerMapError, InvalidDecimal, MissingForeignKey | from django.contrib.gis.utils.layermapping import LayerMapping, LayerMapError, InvalidDecimal, MissingForeignKey | ||||||
| from django.contrib.gis.gdal import DataSource | from django.contrib.gis.gdal import DataSource | ||||||
|  | from django.utils.copycompat import copy | ||||||
|  |  | ||||||
| shp_path = os.path.dirname(__file__) | shp_path = os.path.dirname(__file__) | ||||||
| city_shp = os.path.join(shp_path, '../data/cities/cities.shp') | city_shp = os.path.join(shp_path, '../data/cities/cities.shp') | ||||||
|   | |||||||
| @@ -1,4 +1,3 @@ | |||||||
| import copy |  | ||||||
| import types | import types | ||||||
| import sys | import sys | ||||||
| import os | import os | ||||||
| @@ -13,6 +12,7 @@ from django.db.models.options import Options | |||||||
| from django.db import connection, transaction, DatabaseError | from django.db import connection, transaction, DatabaseError | ||||||
| from django.db.models import signals | from django.db.models import signals | ||||||
| from django.db.models.loading import register_models, get_model | from django.db.models.loading import register_models, get_model | ||||||
|  | import django.utils.copycompat as copy | ||||||
| from django.utils.functional import curry | from django.utils.functional import curry | ||||||
| from django.utils.encoding import smart_str, force_unicode, smart_unicode | from django.utils.encoding import smart_str, force_unicode, smart_unicode | ||||||
| from django.conf import settings | from django.conf import settings | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| from copy import deepcopy |  | ||||||
| from datetime import datetime | from datetime import datetime | ||||||
|  |  | ||||||
| from django.utils import tree | from django.utils import tree | ||||||
|  | from django.utils.copycompat import deepcopy | ||||||
|  |  | ||||||
| class ExpressionNode(tree.Node): | class ExpressionNode(tree.Node): | ||||||
|     """ |     """ | ||||||
|   | |||||||
| @@ -1,12 +1,10 @@ | |||||||
| import copy |  | ||||||
| import datetime | import datetime | ||||||
|  | import decimal | ||||||
| import os | import os | ||||||
| import re | import re | ||||||
| import time | import time | ||||||
| try: |  | ||||||
|     import decimal | import django.utils.copycompat as copy | ||||||
| except ImportError: |  | ||||||
|     from django.utils import _decimal as decimal    # for Python 2.3 |  | ||||||
|  |  | ||||||
| from django.db import connection | from django.db import connection | ||||||
| from django.db.models import signals | from django.db.models import signals | ||||||
|   | |||||||
| @@ -1,7 +1,8 @@ | |||||||
| import copy |  | ||||||
| import datetime | import datetime | ||||||
| import os | import os | ||||||
|  |  | ||||||
|  | import django.utils.copycompat as copy | ||||||
|  |  | ||||||
| from django.conf import settings | from django.conf import settings | ||||||
| from django.db.models.fields import Field | from django.db.models.fields import Field | ||||||
| from django.core.files.base import File, ContentFile | from django.core.files.base import File, ContentFile | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import copy | import django.utils.copycompat as copy | ||||||
| from django.db.models.query import QuerySet, EmptyQuerySet, insert_query | from django.db.models.query import QuerySet, EmptyQuerySet, insert_query | ||||||
| from django.db.models import signals | from django.db.models import signals | ||||||
| from django.db.models.fields import FieldDoesNotExist | from django.db.models.fields import FieldDoesNotExist | ||||||
|   | |||||||
| @@ -2,12 +2,12 @@ | |||||||
| The main QuerySet implementation. This provides the public API for the ORM. | The main QuerySet implementation. This provides the public API for the ORM. | ||||||
| """ | """ | ||||||
|  |  | ||||||
| from copy import deepcopy |  | ||||||
| from django.db import connection, transaction, IntegrityError | from django.db import connection, transaction, IntegrityError | ||||||
| from django.db.models.aggregates import Aggregate | from django.db.models.aggregates import Aggregate | ||||||
| from django.db.models.fields import DateField | from django.db.models.fields import DateField | ||||||
| from django.db.models.query_utils import Q, select_related_descend, CollectedObjects, CyclicDependency, deferred_class_factory | from django.db.models.query_utils import Q, select_related_descend, CollectedObjects, CyclicDependency, deferred_class_factory | ||||||
| from django.db.models import signals, sql | from django.db.models import signals, sql | ||||||
|  | from django.utils.copycompat import deepcopy | ||||||
|  |  | ||||||
| # Used to control how many objects are worked with at once in some cases (e.g. | # Used to control how many objects are worked with at once in some cases (e.g. | ||||||
| # when deleting objects). | # when deleting objects). | ||||||
|   | |||||||
| @@ -7,16 +7,11 @@ circular import difficulties. | |||||||
| """ | """ | ||||||
|  |  | ||||||
| import weakref | import weakref | ||||||
| from copy import deepcopy | from django.utils.copycompat import deepcopy | ||||||
|  |  | ||||||
| from django.utils import tree | from django.utils import tree | ||||||
| from django.utils.datastructures import SortedDict | from django.utils.datastructures import SortedDict | ||||||
|  |  | ||||||
| try: |  | ||||||
|     sorted |  | ||||||
| except NameError: |  | ||||||
|     from django.utils.itercompat import sorted  # For Python 2.3. |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class CyclicDependency(Exception): | class CyclicDependency(Exception): | ||||||
|     """ |     """ | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ databases). The abstraction barrier only works one way: this module has to know | |||||||
| all about the internals of models in order to get the information it needs. | all about the internals of models in order to get the information it needs. | ||||||
| """ | """ | ||||||
|  |  | ||||||
| from copy import deepcopy | from django.utils.copycompat import deepcopy | ||||||
| from django.utils.tree import Node | from django.utils.tree import Node | ||||||
| from django.utils.datastructures import SortedDict | from django.utils.datastructures import SortedDict | ||||||
| from django.utils.encoding import force_unicode | from django.utils.encoding import force_unicode | ||||||
|   | |||||||
| @@ -2,28 +2,19 @@ | |||||||
| Field classes. | Field classes. | ||||||
| """ | """ | ||||||
|  |  | ||||||
| import copy |  | ||||||
| import datetime | import datetime | ||||||
| import os | import os | ||||||
| import re | import re | ||||||
| import time | import time | ||||||
| import urlparse | import urlparse | ||||||
|  | from decimal import Decimal, DecimalException | ||||||
| try: | try: | ||||||
|     from cStringIO import StringIO |     from cStringIO import StringIO | ||||||
| except ImportError: | except ImportError: | ||||||
|     from StringIO import StringIO |     from StringIO import StringIO | ||||||
|  |  | ||||||
| # Python 2.3 fallbacks |  | ||||||
| try: |  | ||||||
|     from decimal import Decimal, DecimalException |  | ||||||
| except ImportError: |  | ||||||
|     from django.utils._decimal import Decimal, DecimalException |  | ||||||
| try: |  | ||||||
|     set |  | ||||||
| except NameError: |  | ||||||
|     from sets import Set as set |  | ||||||
|  |  | ||||||
| import django.core.exceptions | import django.core.exceptions | ||||||
|  | import django.utils.copycompat as copy | ||||||
| from django.utils.translation import ugettext_lazy as _ | from django.utils.translation import ugettext_lazy as _ | ||||||
| from django.utils.encoding import smart_unicode, smart_str | from django.utils.encoding import smart_unicode, smart_str | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,8 +2,7 @@ | |||||||
| Form classes | Form classes | ||||||
| """ | """ | ||||||
|  |  | ||||||
| from copy import deepcopy | from django.utils.copycompat import deepcopy | ||||||
|  |  | ||||||
| from django.utils.datastructures import SortedDict | from django.utils.datastructures import SortedDict | ||||||
| from django.utils.html import conditional_escape | from django.utils.html import conditional_escape | ||||||
| from django.utils.encoding import StrAndUnicode, smart_unicode, force_unicode | from django.utils.encoding import StrAndUnicode, smart_unicode, force_unicode | ||||||
|   | |||||||
| @@ -2,12 +2,7 @@ | |||||||
| HTML Widget classes | HTML Widget classes | ||||||
| """ | """ | ||||||
|  |  | ||||||
| try: | import django.utils.copycompat as copy | ||||||
|     set |  | ||||||
| except NameError: |  | ||||||
|     from sets import Set as set   # Python 2.3 fallback |  | ||||||
|  |  | ||||||
| import copy |  | ||||||
| from itertools import chain | from itertools import chain | ||||||
| from django.conf import settings | from django.conf import settings | ||||||
| from django.utils.datastructures import MultiValueDict, MergeDict | from django.utils.datastructures import MultiValueDict, MergeDict | ||||||
|   | |||||||
| @@ -183,7 +183,7 @@ class QueryDict(MultiValueDict): | |||||||
|         return result |         return result | ||||||
|  |  | ||||||
|     def __deepcopy__(self, memo): |     def __deepcopy__(self, memo): | ||||||
|         import copy |         import django.utils.copycompat as copy | ||||||
|         result = self.__class__('', mutable=True) |         result = self.__class__('', mutable=True) | ||||||
|         memo[id(self)] = result |         memo[id(self)] = result | ||||||
|         for key, value in dict.items(self): |         for key, value in dict.items(self): | ||||||
|   | |||||||
| @@ -134,7 +134,7 @@ __all__ = [ | |||||||
|     'setcontext', 'getcontext' |     'setcontext', 'getcontext' | ||||||
| ] | ] | ||||||
|  |  | ||||||
| import copy as _copy | import django.utils.copycompat as _copy | ||||||
|  |  | ||||||
| #Rounding | #Rounding | ||||||
| ROUND_DOWN = 'ROUND_DOWN' | ROUND_DOWN = 'ROUND_DOWN' | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								django/utils/copycompat.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								django/utils/copycompat.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | """ | ||||||
|  | Fixes Python 2.4's failure to deepcopy unbound functions. | ||||||
|  | """ | ||||||
|  |  | ||||||
|  | import copy | ||||||
|  | import types | ||||||
|  |  | ||||||
|  | # Monkeypatch copy's deepcopy registry to handle functions correctly. | ||||||
|  | if (hasattr(copy, '_deepcopy_dispatch') and types.FunctionType not in copy._deepcopy_dispatch): | ||||||
|  |     copy._deepcopy_dispatch[types.FunctionType] = copy._deepcopy_atomic | ||||||
|  |  | ||||||
|  | # Pose as the copy module now. | ||||||
|  | del copy, types | ||||||
|  | from copy import * | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| from copy import deepcopy | from django.utils.copycompat import deepcopy | ||||||
|  |  | ||||||
|  |  | ||||||
| class MergeDict(object): | class MergeDict(object): | ||||||
| @@ -214,7 +214,7 @@ class MultiValueDict(dict): | |||||||
|         return self.__class__(super(MultiValueDict, self).items()) |         return self.__class__(super(MultiValueDict, self).items()) | ||||||
|  |  | ||||||
|     def __deepcopy__(self, memo=None): |     def __deepcopy__(self, memo=None): | ||||||
|         import copy |         import django.utils.copycompat as copy | ||||||
|         if memo is None: |         if memo is None: | ||||||
|             memo = {} |             memo = {} | ||||||
|         result = self.__class__() |         result = self.__class__() | ||||||
|   | |||||||
| @@ -335,8 +335,10 @@ class SimpleLazyObject(LazyObject): | |||||||
|             memo[id(self)] = result |             memo[id(self)] = result | ||||||
|             return result |             return result | ||||||
|         else: |         else: | ||||||
|             import copy |             # Changed to use deepcopy from copycompat, instead of copy | ||||||
|             return copy.deepcopy(self._wrapped, memo) |             # For Python 2.4. | ||||||
|  |             from django.utils.copycompat import deepcopy | ||||||
|  |             return deepcopy(self._wrapped, memo) | ||||||
|  |  | ||||||
|     # Need to pretend to be the wrapped class, for the sake of objects that care |     # Need to pretend to be the wrapped class, for the sake of objects that care | ||||||
|     # about this (especially in equality tests) |     # about this (especially in equality tests) | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ A class for storing a tree graph. Primarily used for filter constructs in the | |||||||
| ORM. | ORM. | ||||||
| """ | """ | ||||||
|  |  | ||||||
| from copy import deepcopy | from django.utils.copycompat import deepcopy | ||||||
|  |  | ||||||
| class Node(object): | class Node(object): | ||||||
|     """ |     """ | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| from django.dispatch import Signal | from django.dispatch import Signal | ||||||
| import unittest | import unittest | ||||||
| import copy |  | ||||||
| import sys | import sys | ||||||
| import gc | import gc | ||||||
|  | import django.utils.copycompat as copy | ||||||
|  |  | ||||||
| if sys.platform.startswith('java'): | if sys.platform.startswith('java'): | ||||||
|     def garbage_collect(): |     def garbage_collect(): | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| import copy |  | ||||||
| import datetime | import datetime | ||||||
|  |  | ||||||
|  | import django.utils.copycompat as copy | ||||||
|  |  | ||||||
| from django.contrib.auth.models import User | from django.contrib.auth.models import User | ||||||
| from django.db import models | from django.db import models | ||||||
| from django.db.models.query import Q | from django.db.models.query import Q | ||||||
|   | |||||||
| @@ -220,7 +220,7 @@ class TestUtilsSimpleLazyObject(TestCase): | |||||||
|         self.assertEqual(_ComplexObject, SimpleLazyObject(complex_object).__class__) |         self.assertEqual(_ComplexObject, SimpleLazyObject(complex_object).__class__) | ||||||
|  |  | ||||||
|     def test_deepcopy(self): |     def test_deepcopy(self): | ||||||
|         import copy |         import django.utils.copycompat as copy | ||||||
|         # Check that we *can* do deep copy, and that it returns the right |         # Check that we *can* do deep copy, and that it returns the right | ||||||
|         # objects. |         # objects. | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user