--- a/web/lib/django/db/models/fields/subclassing.py Wed May 19 17:43:59 2010 +0200
+++ b/web/lib/django/db/models/fields/subclassing.py Tue May 25 02:43:45 2010 +0200
@@ -1,11 +1,77 @@
"""
-Convenience routines for creating non-trivial Field subclasses.
+Convenience routines for creating non-trivial Field subclasses, as well as
+backwards compatibility utilities.
Add SubfieldBase as the __metaclass__ for your Field subclass, implement
to_python() and the other necessary methods and everything will work seamlessly.
"""
-class SubfieldBase(type):
+from inspect import getargspec
+from warnings import warn
+
+def call_with_connection(func):
+ arg_names, varargs, varkwargs, defaults = getargspec(func)
+ updated = ('connection' in arg_names or varkwargs)
+ if not updated:
+ warn("A Field class whose %s method hasn't been updated to take a "
+ "`connection` argument." % func.__name__,
+ PendingDeprecationWarning, stacklevel=2)
+
+ def inner(*args, **kwargs):
+ if 'connection' not in kwargs:
+ from django.db import connection
+ kwargs['connection'] = connection
+ warn("%s has been called without providing a connection argument. " %
+ func.__name__, PendingDeprecationWarning,
+ stacklevel=1)
+ if updated:
+ return func(*args, **kwargs)
+ if 'connection' in kwargs:
+ del kwargs['connection']
+ return func(*args, **kwargs)
+ return inner
+
+def call_with_connection_and_prepared(func):
+ arg_names, varargs, varkwargs, defaults = getargspec(func)
+ updated = (
+ ('connection' in arg_names or varkwargs) and
+ ('prepared' in arg_names or varkwargs)
+ )
+ if not updated:
+ warn("A Field class whose %s method hasn't been updated to take "
+ "`connection` and `prepared` arguments." % func.__name__,
+ PendingDeprecationWarning, stacklevel=2)
+
+ def inner(*args, **kwargs):
+ if 'connection' not in kwargs:
+ from django.db import connection
+ kwargs['connection'] = connection
+ warn("%s has been called without providing a connection argument. " %
+ func.__name__, PendingDeprecationWarning,
+ stacklevel=1)
+ if updated:
+ return func(*args, **kwargs)
+ if 'connection' in kwargs:
+ del kwargs['connection']
+ if 'prepared' in kwargs:
+ del kwargs['prepared']
+ return func(*args, **kwargs)
+ return inner
+
+class LegacyConnection(type):
+ """
+ A metaclass to normalize arguments give to the get_db_prep_* and db_type
+ methods on fields.
+ """
+ def __new__(cls, names, bases, attrs):
+ new_cls = super(LegacyConnection, cls).__new__(cls, names, bases, attrs)
+ for attr in ('db_type', 'get_db_prep_save'):
+ setattr(new_cls, attr, call_with_connection(getattr(new_cls, attr)))
+ for attr in ('get_db_prep_lookup', 'get_db_prep_value'):
+ setattr(new_cls, attr, call_with_connection_and_prepared(getattr(new_cls, attr)))
+ return new_cls
+
+class SubfieldBase(LegacyConnection):
"""
A metaclass for custom Field subclasses. This ensures the model's attribute
has the descriptor protocol attached to it.
@@ -26,7 +92,7 @@
def __get__(self, obj, type=None):
if obj is None:
raise AttributeError('Can only be accessed via an instance.')
- return obj.__dict__[self.field.name]
+ return obj.__dict__[self.field.name]
def __set__(self, obj, value):
obj.__dict__[self.field.name] = self.field.to_python(value)