Skip to content

Commit

Permalink
Put back [8120] along with a small tweak. Fixed #6217.
Browse files Browse the repository at this point in the history
git-svn-id: http://code.djangoproject.com/svn/django/trunk@8127 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
malcolmt committed Jul 28, 2008
1 parent eca5aac commit 55ba38f
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 25 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Expand Up @@ -407,6 +407,7 @@ answer newbie questions, and generally made Django that much better:
charly.wilhelm@gmail.com charly.wilhelm@gmail.com
Rachel Willmer <http://www.willmer.com/kb/> Rachel Willmer <http://www.willmer.com/kb/>
Gary Wilson <gary.wilson@gmail.com> Gary Wilson <gary.wilson@gmail.com>
Jakub Wilk <ubanus@users.sf.net>
Jakub Wiśniowski <restless.being@gmail.com> Jakub Wiśniowski <restless.being@gmail.com>
Maciej Wiśniowski <pigletto@gmail.com> Maciej Wiśniowski <pigletto@gmail.com>
wojtek wojtek
Expand Down
3 changes: 2 additions & 1 deletion django/db/models/fields/__init__.py
Expand Up @@ -191,7 +191,8 @@ def validate(self, field_data, all_data):
def set_attributes_from_name(self, name): def set_attributes_from_name(self, name):
self.name = name self.name = name
self.attname, self.column = self.get_attname_column() self.attname, self.column = self.get_attname_column()
self.verbose_name = self.verbose_name or (name and name.replace('_', ' ')) if self.verbose_name is None and name:
self.verbose_name = name.replace('_', ' ')


def contribute_to_class(self, cls, name): def contribute_to_class(self, cls, name):
self.set_attributes_from_name(name) self.set_attributes_from_name(name)
Expand Down
60 changes: 36 additions & 24 deletions django/utils/functional.py
Expand Up @@ -148,42 +148,54 @@ def lazy(func, *resultclasses):
function is evaluated on every access. function is evaluated on every access.
""" """
class __proxy__(Promise): class __proxy__(Promise):
# This inner class encapsulates the code that should be evaluated """
# lazily. On calling of one of the magic methods it will force Encapsulate a function call and act as a proxy for methods that are
# the evaluation and store the result. Afterwards, the result called on the result of that function. The function is not evaluated
# is delivered directly. So the result is memoized. until one of the methods on the result is called.
"""
__dispatch = None

def __init__(self, args, kw): def __init__(self, args, kw):
self.__func = func self.__func = func
self.__args = args self.__args = args
self.__kw = kw self.__kw = kw
self.__dispatch = {} if self.__dispatch is None:
self.__prepare_class__()

def __prepare_class__(cls):
cls.__dispatch = {}
for resultclass in resultclasses: for resultclass in resultclasses:
self.__dispatch[resultclass] = {} cls.__dispatch[resultclass] = {}
for (k, v) in resultclass.__dict__.items(): for (k, v) in resultclass.__dict__.items():
setattr(self, k, self.__promise__(resultclass, k, v)) if hasattr(cls, k):
self._delegate_str = str in resultclasses continue
self._delegate_unicode = unicode in resultclasses setattr(cls, k, cls.__promise__(resultclass, k, v))
assert not (self._delegate_str and self._delegate_unicode), "Cannot call lazy() with both str and unicode return types." cls._delegate_str = str in resultclasses
if self._delegate_unicode: cls._delegate_unicode = unicode in resultclasses
# Each call to lazy() makes a new __proxy__ object, so this assert not (cls._delegate_str and cls._delegate_unicode), "Cannot call lazy() with both str and unicode return types."
# doesn't interfere with any other lazy() results. if cls._delegate_unicode:
__proxy__.__unicode__ = __proxy__.__unicode_cast cls.__unicode__ = cls.__unicode_cast
elif self._delegate_str: elif cls._delegate_str:
__proxy__.__str__ = __proxy__.__str_cast cls.__str__ = cls.__str_cast

__prepare_class__ = classmethod(__prepare_class__)
def __promise__(self, klass, funcname, func):
def __promise__(cls, klass, funcname, func):
# Builds a wrapper around some magic method and registers that magic # Builds a wrapper around some magic method and registers that magic
# method for the given type and method name. # method for the given type and method name.
def __wrapper__(*args, **kw): def __wrapper__(self, *args, **kw):
# Automatically triggers the evaluation of a lazy value and # Automatically triggers the evaluation of a lazy value and
# applies the given magic method of the result type. # applies the given magic method of the result type.
res = self.__func(*self.__args, **self.__kw) res = self.__func(*self.__args, **self.__kw)
return self.__dispatch[type(res)][funcname](res, *args, **kw) for t in type(res).mro():

if t in self.__dispatch:
if klass not in self.__dispatch: return self.__dispatch[t][funcname](res, *args, **kw)
self.__dispatch[klass] = {} raise TypeError("Lazy object returned unexpected type.")
self.__dispatch[klass][funcname] = func
if klass not in cls.__dispatch:
cls.__dispatch[klass] = {}
cls.__dispatch[klass][funcname] = func
return __wrapper__ return __wrapper__
__promise__ = classmethod(__promise__)


def __unicode_cast(self): def __unicode_cast(self):
return self.__func(*self.__args, **self.__kw) return self.__func(*self.__args, **self.__kw)
Expand Down

0 comments on commit 55ba38f

Please sign in to comment.