Permalink
Browse files

[1.5.x] Fixed #18963 -- Used a subclass-friendly pattern

for Python 2 object model compatibility methods.

Backport of fc10418 from master.
  • Loading branch information...
aaugustin committed Nov 3, 2012
1 parent be65225 commit d7688a010a34033a5cc8eecf7b1460169c0e056e
@@ -18,7 +18,9 @@ def __iter__(self):
def __bool__(self):
return self.user.has_module_perms(self.module_name)
__nonzero__ = __bool__ # Python 2
def __nonzero__(self): # Python 2 compatibility
return type(self).__bool__(self)
class PermWrapper(object):
@@ -151,19 +151,25 @@ def __truediv__(self, other):
**{self.STANDARD_UNIT: (self.standard / other)})
else:
raise TypeError('%(class)s must be divided with number or %(class)s' % {"class":pretty_name(self)})
__div__ = __truediv__ # Python 2 compatibility
def __div__(self, other): # Python 2 compatibility
return type(self).__truediv__(self, other)
def __itruediv__(self, other):
if isinstance(other, NUMERIC_TYPES):
self.standard /= float(other)
return self
else:
raise TypeError('%(class)s must be divided with number' % {"class":pretty_name(self)})
__idiv__ = __itruediv__ # Python 2 compatibility
def __idiv__(self, other): # Python 2 compatibility
return type(self).__itruediv__(self, other)
def __bool__(self):
return bool(self.standard)
__nonzero__ = __bool__ # Python 2 compatibility
def __nonzero__(self): # Python 2 compatibility
return type(self).__bool__(self)
def default_units(self, kwargs):
"""
@@ -314,7 +320,9 @@ def __truediv__(self, other):
**{self.STANDARD_UNIT: (self.standard / other)})
else:
raise TypeError('%(class)s must be divided by a number' % {"class":pretty_name(self)})
__div__ = __truediv__ # Python 2 compatibility
def __div__(self, other): # Python 2 compatibility
return type(self).__truediv__(self, other)
# Shortcuts
@@ -28,7 +28,9 @@ def __repr__(self):
def __bool__(self):
return bool(self.name)
__nonzero__ = __bool__ # Python 2
def __nonzero__(self): # Python 2 compatibility
return type(self).__bool__(self)
def __len__(self):
return self.size
@@ -142,7 +144,9 @@ def __str__(self):
def __bool__(self):
return True
__nonzero__ = __bool__ # Python 2
def __nonzero__(self): # Python 2 compatibility
return type(self).__bool__(self)
def open(self, mode=None):
self.seek(0)
@@ -112,7 +112,7 @@ def getvalue(self):
if callable(getattr(self.stream, 'getvalue', None)):
return self.stream.getvalue()
class Deserializer(object):
class Deserializer(six.Iterator):
"""
Abstract base deserializer class.
"""
@@ -138,8 +138,6 @@ def __next__(self):
"""Iteration iterface -- return the next item in the stream"""
raise NotImplementedError
next = __next__ # Python 2 compatibility
class DeserializedObject(object):
"""
A deserialized model.
@@ -161,8 +161,6 @@ def __next__(self):
return self._handle_object(node)
raise StopIteration
next = __next__ # Python 2 compatibility
def _handle_object(self, node):
"""
Convert an <object> node to a DeserializedObject.
@@ -774,7 +774,7 @@ def __iter__(self):
return CursorIterator(self.cursor)
class CursorIterator(object):
class CursorIterator(six.Iterator):
"""Cursor iterator wrapper that invokes our custom row factory."""
@@ -788,8 +788,6 @@ def __iter__(self):
def __next__(self):
return _rowfactory(next(self.iter), self.cursor)
next = __next__ # Python 2 compatibility
def _rowfactory(row, cursor):
# Cast numeric values as the appropriate Python type based upon the
@@ -62,7 +62,9 @@ def __mul__(self, other):
def __truediv__(self, other):
return self._combine(other, self.DIV, False)
__div__ = __truediv__ # Python 2 compatibility
def __div__(self, other): # Python 2 compatibility
return type(self).__truediv__(self, other)
def __mod__(self, other):
return self._combine(other, self.MOD, False)
@@ -94,7 +96,9 @@ def __rmul__(self, other):
def __rtruediv__(self, other):
return self._combine(other, self.DIV, True)
__rdiv__ = __rtruediv__ # Python 2 compatibility
def __rdiv__(self, other): # Python 2 compatibility
return type(self).__rtruediv__(self, other)
def __rmod__(self, other):
return self._combine(other, self.MOD, True)
@@ -151,10 +155,10 @@ class DateModifierNode(ExpressionNode):
(A custom function is used in order to preserve six digits of fractional
second information on sqlite, and to format both date and datetime values.)
Note that microsecond comparisons are not well supported with MySQL, since
Note that microsecond comparisons are not well supported with MySQL, since
MySQL does not store microsecond information.
Only adding and subtracting timedeltas is supported, attempts to use other
Only adding and subtracting timedeltas is supported, attempts to use other
operations raise a TypeError.
"""
def __init__(self, children, connector, negated=False):
@@ -136,7 +136,9 @@ def __bool__(self):
except StopIteration:
return False
return True
__nonzero__ = __bool__ # Python 2
def __nonzero__(self): # Python 2 compatibility
return type(self).__bool__(self)
def __contains__(self, val):
# The 'in' operator works without this method, due to __iter__. This
View
@@ -67,9 +67,9 @@ class BoundMethodWeakref(object):
same BoundMethodWeakref instance.
"""
_allInstances = weakref.WeakValueDictionary()
def __new__( cls, target, onDelete=None, *arguments,**named ):
"""Create new instance or return current instance
@@ -92,7 +92,7 @@ def __new__( cls, target, onDelete=None, *arguments,**named ):
cls._allInstances[key] = base
base.__init__( target, onDelete, *arguments,**named)
return base
def __init__(self, target, onDelete=None):
"""Return a weak-reference-like instance for a bound method
@@ -132,7 +132,7 @@ def remove(weak, self=self):
self.weakFunc = weakref.ref(target.__func__, remove)
self.selfName = str(target.__self__)
self.funcName = str(target.__func__.__name__)
def calculateKey( cls, target ):
"""Calculate the reference key for this reference
@@ -141,7 +141,7 @@ def calculateKey( cls, target ):
"""
return (id(target.__self__),id(target.__func__))
calculateKey = classmethod( calculateKey )
def __str__(self):
"""Give a friendly representation of the object"""
return """%s( %s.%s )"""%(
@@ -157,14 +157,16 @@ def __str__(self):
def __bool__( self ):
"""Whether we are still a valid reference"""
return self() is not None
__nonzero__ = __bool__ # Python 2
def __nonzero__(self): # Python 2 compatibility
return type(self).__bool__(self)
def __eq__(self, other):
"""Compare with another reference"""
if not isinstance(other, self.__class__):
return self.__class__ == type(other)
return self.key == other.key
def __call__(self):
"""Return a strong reference to the bound method
View
@@ -69,7 +69,9 @@ def __len__(self):
def __bool__(self):
"""All formsets have a management form which is not included in the length"""
return True
__nonzero__ = __bool__ # Python 2
def __nonzero__(self): # Python 2 compatibility
return type(self).__bool__(self)
@property
def management_form(self):
@@ -256,7 +256,7 @@ def IE_sanitize(self, filename):
"""Cleanup filename from Internet Explorer full paths."""
return filename and filename[filename.rfind("\\")+1:].strip()
class LazyStream(object):
class LazyStream(six.Iterator):
"""
The LazyStream wrapper allows one to get and "unget" bytes from a stream.
@@ -323,8 +323,6 @@ def __next__(self):
self.position += len(output)
return output
next = __next__ # Python 2 compatibility
def close(self):
"""
Used to invalidate/disable this lazy stream.
@@ -369,7 +367,7 @@ def _update_unget_history(self, num_bytes):
" if there is none, report this to the Django developers."
)
class ChunkIter(object):
class ChunkIter(six.Iterator):
"""
An iterable that will yield chunks of data. Given a file-like object as the
constructor, this object will yield chunks of read operations from that
@@ -389,12 +387,10 @@ def __next__(self):
else:
raise StopIteration()
next = __next__ # Python 2 compatibility
def __iter__(self):
return self
class InterBoundaryIter(object):
class InterBoundaryIter(six.Iterator):
"""
A Producer that will iterate over boundaries.
"""
@@ -411,9 +407,7 @@ def __next__(self):
except InputStreamExhausted:
raise StopIteration()
next = __next__ # Python 2 compatibility
class BoundaryIter(object):
class BoundaryIter(six.Iterator):
"""
A Producer that is sensitive to boundaries.
@@ -489,8 +483,6 @@ def __next__(self):
stream.unget(chunk[-rollback:])
return chunk[:-rollback]
next = __next__ # Python 2 compatibility
def _find_boundary(self, data, eof = False):
"""
Finds a multipart boundary in data.
View
@@ -23,7 +23,7 @@ class BadHeaderError(ValueError):
pass
class HttpResponseBase(object):
class HttpResponseBase(six.Iterator):
"""
An HTTP response base class with dictionary-accessed headers.
@@ -218,8 +218,6 @@ def __next__(self):
# Subclasses must define self._iterator for this function.
return self.make_bytes(next(self._iterator))
next = __next__ # Python 2 compatibility
# These methods partially implement the file-like object interface.
# See http://docs.python.org/lib/bltin-file-objects.html
View
@@ -73,7 +73,9 @@ def __bool__(self):
For truth value testing.
"""
return bool(self.children)
__nonzero__ = __bool__ # Python 2
def __nonzero__(self): # Python 2 compatibility
return type(self).__bool__(self)
def __contains__(self, other):
"""
View
@@ -278,15 +278,13 @@ Iterators
::
class MyIterator(object):
class MyIterator(six.Iterator):
def __iter__(self):
return self # implement some logic here
def __next__(self):
raise StopIteration # implement some logic here
next = __next__ # Python 2 compatibility
Boolean evaluation
~~~~~~~~~~~~~~~~~~
@@ -297,7 +295,8 @@ Boolean evaluation
def __bool__(self):
return True # implement some logic here
__nonzero__ = __bool__ # Python 2 compatibility
def __nonzero__(self): # Python 2 compatibility
return type(self).__bool__(self)
Division
~~~~~~~~
@@ -309,12 +308,14 @@ Division
def __truediv__(self, other):
return self / other # implement some logic here
__div__ = __truediv__ # Python 2 compatibility
def __div__(self, other): # Python 2 compatibility
return type(self).__truediv__(self, other)
def __itruediv__(self, other):
return self // other # implement some logic here
__idiv__ = __itruediv__ # Python 2 compatibility
def __idiv__(self, other): # Python 2 compatibility
return type(self).__itruediv__(self, other)
.. module: django.utils.six

0 comments on commit d7688a0

Please sign in to comment.