[py3] Ported django.utils.functional.
This commit is contained in:
parent
7e01e532c0
commit
fe8484efda
|
@ -93,13 +93,19 @@ def lazy(func, *resultclasses):
|
||||||
if hasattr(cls, k):
|
if hasattr(cls, k):
|
||||||
continue
|
continue
|
||||||
setattr(cls, k, meth)
|
setattr(cls, k, meth)
|
||||||
cls._delegate_str = bytes in resultclasses
|
cls._delegate_bytes = bytes in resultclasses
|
||||||
cls._delegate_unicode = six.text_type in resultclasses
|
cls._delegate_text = six.text_type in resultclasses
|
||||||
assert not (cls._delegate_str and cls._delegate_unicode), "Cannot call lazy() with both str and unicode return types."
|
assert not (cls._delegate_bytes and cls._delegate_text), "Cannot call lazy() with both bytes and text return types."
|
||||||
if cls._delegate_unicode:
|
if cls._delegate_text:
|
||||||
cls.__unicode__ = cls.__unicode_cast
|
if six.PY3:
|
||||||
elif cls._delegate_str:
|
cls.__str__ = cls.__text_cast
|
||||||
cls.__str__ = cls.__str_cast
|
else:
|
||||||
|
cls.__unicode__ = cls.__text_cast
|
||||||
|
elif cls._delegate_bytes:
|
||||||
|
if six.PY3:
|
||||||
|
cls.__bytes__ = cls.__bytes_cast
|
||||||
|
else:
|
||||||
|
cls.__str__ = cls.__bytes_cast
|
||||||
__prepare_class__ = classmethod(__prepare_class__)
|
__prepare_class__ = classmethod(__prepare_class__)
|
||||||
|
|
||||||
def __promise__(cls, klass, funcname, method):
|
def __promise__(cls, klass, funcname, method):
|
||||||
|
@ -120,17 +126,17 @@ def lazy(func, *resultclasses):
|
||||||
return __wrapper__
|
return __wrapper__
|
||||||
__promise__ = classmethod(__promise__)
|
__promise__ = classmethod(__promise__)
|
||||||
|
|
||||||
def __unicode_cast(self):
|
def __text_cast(self):
|
||||||
return func(*self.__args, **self.__kw)
|
return func(*self.__args, **self.__kw)
|
||||||
|
|
||||||
def __str_cast(self):
|
def __bytes_cast(self):
|
||||||
return str(func(*self.__args, **self.__kw))
|
return bytes(func(*self.__args, **self.__kw))
|
||||||
|
|
||||||
def __cast(self):
|
def __cast(self):
|
||||||
if self._delegate_str:
|
if self._delegate_bytes:
|
||||||
return self.__str_cast()
|
return self.__bytes_cast()
|
||||||
elif self._delegate_unicode:
|
elif self._delegate_text:
|
||||||
return self.__unicode_cast()
|
return self.__text_cast()
|
||||||
else:
|
else:
|
||||||
return func(*self.__args, **self.__kw)
|
return func(*self.__args, **self.__kw)
|
||||||
|
|
||||||
|
@ -144,10 +150,12 @@ def lazy(func, *resultclasses):
|
||||||
other = other.__cast()
|
other = other.__cast()
|
||||||
return self.__cast() < other
|
return self.__cast() < other
|
||||||
|
|
||||||
|
__hash__ = object.__hash__
|
||||||
|
|
||||||
def __mod__(self, rhs):
|
def __mod__(self, rhs):
|
||||||
if self._delegate_str:
|
if self._delegate_bytes and not six.PY3:
|
||||||
return str(self) % rhs
|
return bytes(self) % rhs
|
||||||
elif self._delegate_unicode:
|
elif self._delegate_text:
|
||||||
return six.text_type(self) % rhs
|
return six.text_type(self) % rhs
|
||||||
else:
|
else:
|
||||||
raise AssertionError('__mod__ not supported for non-string types')
|
raise AssertionError('__mod__ not supported for non-string types')
|
||||||
|
@ -234,6 +242,9 @@ class LazyObject(object):
|
||||||
__dir__ = new_method_proxy(dir)
|
__dir__ = new_method_proxy(dir)
|
||||||
|
|
||||||
|
|
||||||
|
# Workaround for http://bugs.python.org/issue12370
|
||||||
|
_super = super
|
||||||
|
|
||||||
class SimpleLazyObject(LazyObject):
|
class SimpleLazyObject(LazyObject):
|
||||||
"""
|
"""
|
||||||
A lazy object initialised from any function.
|
A lazy object initialised from any function.
|
||||||
|
@ -251,13 +262,17 @@ class SimpleLazyObject(LazyObject):
|
||||||
value.
|
value.
|
||||||
"""
|
"""
|
||||||
self.__dict__['_setupfunc'] = func
|
self.__dict__['_setupfunc'] = func
|
||||||
super(SimpleLazyObject, self).__init__()
|
_super(SimpleLazyObject, self).__init__()
|
||||||
|
|
||||||
def _setup(self):
|
def _setup(self):
|
||||||
self._wrapped = self._setupfunc()
|
self._wrapped = self._setupfunc()
|
||||||
|
|
||||||
__str__ = new_method_proxy(bytes)
|
if six.PY3:
|
||||||
__unicode__ = new_method_proxy(six.text_type)
|
__bytes__ = new_method_proxy(bytes)
|
||||||
|
__str__ = new_method_proxy(str)
|
||||||
|
else:
|
||||||
|
__str__ = new_method_proxy(str)
|
||||||
|
__unicode__ = new_method_proxy(unicode)
|
||||||
|
|
||||||
def __deepcopy__(self, memo):
|
def __deepcopy__(self, memo):
|
||||||
if self._wrapped is empty:
|
if self._wrapped is empty:
|
||||||
|
@ -284,7 +299,8 @@ class SimpleLazyObject(LazyObject):
|
||||||
__class__ = property(new_method_proxy(operator.attrgetter("__class__")))
|
__class__ = property(new_method_proxy(operator.attrgetter("__class__")))
|
||||||
__eq__ = new_method_proxy(operator.eq)
|
__eq__ = new_method_proxy(operator.eq)
|
||||||
__hash__ = new_method_proxy(hash)
|
__hash__ = new_method_proxy(hash)
|
||||||
__nonzero__ = new_method_proxy(bool)
|
__bool__ = new_method_proxy(bool) # Python 3
|
||||||
|
__nonzero__ = __bool__ # Python 2
|
||||||
|
|
||||||
|
|
||||||
class lazy_property(property):
|
class lazy_property(property):
|
||||||
|
|
|
@ -96,7 +96,7 @@ def mark_safe(s):
|
||||||
"""
|
"""
|
||||||
if isinstance(s, SafeData):
|
if isinstance(s, SafeData):
|
||||||
return s
|
return s
|
||||||
if isinstance(s, bytes) or (isinstance(s, Promise) and s._delegate_str):
|
if isinstance(s, bytes) or (isinstance(s, Promise) and s._delegate_bytes):
|
||||||
return SafeString(s)
|
return SafeString(s)
|
||||||
if isinstance(s, (six.text_type, Promise)):
|
if isinstance(s, (six.text_type, Promise)):
|
||||||
return SafeUnicode(s)
|
return SafeUnicode(s)
|
||||||
|
@ -112,7 +112,7 @@ def mark_for_escaping(s):
|
||||||
"""
|
"""
|
||||||
if isinstance(s, (SafeData, EscapeData)):
|
if isinstance(s, (SafeData, EscapeData)):
|
||||||
return s
|
return s
|
||||||
if isinstance(s, bytes) or (isinstance(s, Promise) and s._delegate_str):
|
if isinstance(s, bytes) or (isinstance(s, Promise) and s._delegate_bytes):
|
||||||
return EscapeString(s)
|
return EscapeString(s)
|
||||||
if isinstance(s, (six.text_type, Promise)):
|
if isinstance(s, (six.text_type, Promise)):
|
||||||
return EscapeUnicode(s)
|
return EscapeUnicode(s)
|
||||||
|
|
|
@ -19,17 +19,27 @@ class _ComplexObject(object):
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash(self.name)
|
return hash(self.name)
|
||||||
|
|
||||||
|
if six.PY3:
|
||||||
|
def __bytes__(self):
|
||||||
|
return ("I am _ComplexObject(%r)" % self.name).encode("utf-8")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "I am _ComplexObject(%r)" % self.name
|
return self.name
|
||||||
|
|
||||||
|
else:
|
||||||
|
def __str__(self):
|
||||||
|
return b"I am _ComplexObject(%r)" % str(self.name)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return six.text_type(self.name)
|
return self.name
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "_ComplexObject(%r)" % self.name
|
return "_ComplexObject(%r)" % self.name
|
||||||
|
|
||||||
|
|
||||||
complex_object = lambda: _ComplexObject("joe")
|
complex_object = lambda: _ComplexObject("joe")
|
||||||
|
|
||||||
|
|
||||||
class TestUtilsSimpleLazyObject(TestCase):
|
class TestUtilsSimpleLazyObject(TestCase):
|
||||||
"""
|
"""
|
||||||
Tests for SimpleLazyObject
|
Tests for SimpleLazyObject
|
||||||
|
@ -54,11 +64,11 @@ class TestUtilsSimpleLazyObject(TestCase):
|
||||||
# proxy __repr__
|
# proxy __repr__
|
||||||
self.assertTrue("SimpleLazyObject" in repr(SimpleLazyObject(complex_object)))
|
self.assertTrue("SimpleLazyObject" in repr(SimpleLazyObject(complex_object)))
|
||||||
|
|
||||||
def test_str(self):
|
def test_bytes(self):
|
||||||
self.assertEqual(str_prefix("I am _ComplexObject(%(_)s'joe')"),
|
self.assertEqual(b"I am _ComplexObject('joe')",
|
||||||
str(SimpleLazyObject(complex_object)))
|
bytes(SimpleLazyObject(complex_object)))
|
||||||
|
|
||||||
def test_unicode(self):
|
def test_text(self):
|
||||||
self.assertEqual("joe", six.text_type(SimpleLazyObject(complex_object)))
|
self.assertEqual("joe", six.text_type(SimpleLazyObject(complex_object)))
|
||||||
|
|
||||||
def test_class(self):
|
def test_class(self):
|
||||||
|
|
Loading…
Reference in New Issue