Fixed #18963 -- Used a subclass-friendly pattern

for Python 2 object model compatibility methods.
This commit is contained in:
Aymeric Augustin 2012-11-03 21:43:11 +01:00
parent 973f539ab8
commit fc10418fba
14 changed files with 61 additions and 50 deletions

View File

@ -18,7 +18,9 @@ class PermLookupDict(object):
def __bool__(self): def __bool__(self):
return self.user.has_module_perms(self.module_name) 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): class PermWrapper(object):

View File

@ -151,7 +151,9 @@ class MeasureBase(object):
**{self.STANDARD_UNIT: (self.standard / other)}) **{self.STANDARD_UNIT: (self.standard / other)})
else: else:
raise TypeError('%(class)s must be divided with number or %(class)s' % {"class":pretty_name(self)}) 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): def __itruediv__(self, other):
if isinstance(other, NUMERIC_TYPES): if isinstance(other, NUMERIC_TYPES):
@ -159,11 +161,15 @@ class MeasureBase(object):
return self return self
else: else:
raise TypeError('%(class)s must be divided with number' % {"class":pretty_name(self)}) 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): def __bool__(self):
return bool(self.standard) 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): def default_units(self, kwargs):
""" """
@ -314,7 +320,9 @@ class Area(MeasureBase):
**{self.STANDARD_UNIT: (self.standard / other)}) **{self.STANDARD_UNIT: (self.standard / other)})
else: else:
raise TypeError('%(class)s must be divided by a number' % {"class":pretty_name(self)}) 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 # Shortcuts

View File

@ -28,7 +28,9 @@ class File(FileProxyMixin):
def __bool__(self): def __bool__(self):
return bool(self.name) return bool(self.name)
__nonzero__ = __bool__ # Python 2
def __nonzero__(self): # Python 2 compatibility
return type(self).__bool__(self)
def __len__(self): def __len__(self):
return self.size return self.size
@ -142,7 +144,9 @@ class ContentFile(File):
def __bool__(self): def __bool__(self):
return True return True
__nonzero__ = __bool__ # Python 2
def __nonzero__(self): # Python 2 compatibility
return type(self).__bool__(self)
def open(self, mode=None): def open(self, mode=None):
self.seek(0) self.seek(0)

View File

@ -112,7 +112,7 @@ class Serializer(object):
if callable(getattr(self.stream, 'getvalue', None)): if callable(getattr(self.stream, 'getvalue', None)):
return self.stream.getvalue() return self.stream.getvalue()
class Deserializer(object): class Deserializer(six.Iterator):
""" """
Abstract base deserializer class. Abstract base deserializer class.
""" """
@ -138,8 +138,6 @@ class Deserializer(object):
"""Iteration iterface -- return the next item in the stream""" """Iteration iterface -- return the next item in the stream"""
raise NotImplementedError raise NotImplementedError
next = __next__ # Python 2 compatibility
class DeserializedObject(object): class DeserializedObject(object):
""" """
A deserialized model. A deserialized model.

View File

@ -161,8 +161,6 @@ class Deserializer(base.Deserializer):
return self._handle_object(node) return self._handle_object(node)
raise StopIteration raise StopIteration
next = __next__ # Python 2 compatibility
def _handle_object(self, node): def _handle_object(self, node):
""" """
Convert an <object> node to a DeserializedObject. Convert an <object> node to a DeserializedObject.

View File

@ -774,7 +774,7 @@ class FormatStylePlaceholderCursor(object):
return CursorIterator(self.cursor) return CursorIterator(self.cursor)
class CursorIterator(object): class CursorIterator(six.Iterator):
"""Cursor iterator wrapper that invokes our custom row factory.""" """Cursor iterator wrapper that invokes our custom row factory."""
@ -788,8 +788,6 @@ class CursorIterator(object):
def __next__(self): def __next__(self):
return _rowfactory(next(self.iter), self.cursor) return _rowfactory(next(self.iter), self.cursor)
next = __next__ # Python 2 compatibility
def _rowfactory(row, cursor): def _rowfactory(row, cursor):
# Cast numeric values as the appropriate Python type based upon the # Cast numeric values as the appropriate Python type based upon the

View File

@ -62,7 +62,9 @@ class ExpressionNode(tree.Node):
def __truediv__(self, other): def __truediv__(self, other):
return self._combine(other, self.DIV, False) 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): def __mod__(self, other):
return self._combine(other, self.MOD, False) return self._combine(other, self.MOD, False)
@ -94,7 +96,9 @@ class ExpressionNode(tree.Node):
def __rtruediv__(self, other): def __rtruediv__(self, other):
return self._combine(other, self.DIV, True) 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): def __rmod__(self, other):
return self._combine(other, self.MOD, True) return self._combine(other, self.MOD, True)

View File

@ -136,7 +136,9 @@ class QuerySet(object):
except StopIteration: except StopIteration:
return False return False
return True return True
__nonzero__ = __bool__ # Python 2
def __nonzero__(self): # Python 2 compatibility
return type(self).__bool__(self)
def __contains__(self, val): def __contains__(self, val):
# The 'in' operator works without this method, due to __iter__. This # The 'in' operator works without this method, due to __iter__. This

View File

@ -157,7 +157,9 @@ class BoundMethodWeakref(object):
def __bool__( self ): def __bool__( self ):
"""Whether we are still a valid reference""" """Whether we are still a valid reference"""
return self() is not None return self() is not None
__nonzero__ = __bool__ # Python 2
def __nonzero__(self): # Python 2 compatibility
return type(self).__bool__(self)
def __eq__(self, other): def __eq__(self, other):
"""Compare with another reference""" """Compare with another reference"""

View File

@ -69,7 +69,9 @@ class BaseFormSet(object):
def __bool__(self): def __bool__(self):
"""All formsets have a management form which is not included in the length""" """All formsets have a management form which is not included in the length"""
return True return True
__nonzero__ = __bool__ # Python 2
def __nonzero__(self): # Python 2 compatibility
return type(self).__bool__(self)
@property @property
def management_form(self): def management_form(self):

View File

@ -256,7 +256,7 @@ class MultiPartParser(object):
"""Cleanup filename from Internet Explorer full paths.""" """Cleanup filename from Internet Explorer full paths."""
return filename and filename[filename.rfind("\\")+1:].strip() 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. The LazyStream wrapper allows one to get and "unget" bytes from a stream.
@ -323,8 +323,6 @@ class LazyStream(object):
self.position += len(output) self.position += len(output)
return output return output
next = __next__ # Python 2 compatibility
def close(self): def close(self):
""" """
Used to invalidate/disable this lazy stream. Used to invalidate/disable this lazy stream.
@ -369,7 +367,7 @@ class LazyStream(object):
" if there is none, report this to the Django developers." " 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 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 constructor, this object will yield chunks of read operations from that
@ -389,12 +387,10 @@ class ChunkIter(object):
else: else:
raise StopIteration() raise StopIteration()
next = __next__ # Python 2 compatibility
def __iter__(self): def __iter__(self):
return self return self
class InterBoundaryIter(object): class InterBoundaryIter(six.Iterator):
""" """
A Producer that will iterate over boundaries. A Producer that will iterate over boundaries.
""" """
@ -411,9 +407,7 @@ class InterBoundaryIter(object):
except InputStreamExhausted: except InputStreamExhausted:
raise StopIteration() raise StopIteration()
next = __next__ # Python 2 compatibility class BoundaryIter(six.Iterator):
class BoundaryIter(object):
""" """
A Producer that is sensitive to boundaries. A Producer that is sensitive to boundaries.
@ -489,8 +483,6 @@ class BoundaryIter(object):
stream.unget(chunk[-rollback:]) stream.unget(chunk[-rollback:])
return chunk[:-rollback] return chunk[:-rollback]
next = __next__ # Python 2 compatibility
def _find_boundary(self, data, eof = False): def _find_boundary(self, data, eof = False):
""" """
Finds a multipart boundary in data. Finds a multipart boundary in data.

View File

@ -23,7 +23,7 @@ class BadHeaderError(ValueError):
pass pass
class HttpResponseBase(object): class HttpResponseBase(six.Iterator):
""" """
An HTTP response base class with dictionary-accessed headers. An HTTP response base class with dictionary-accessed headers.
@ -218,8 +218,6 @@ class HttpResponseBase(object):
# Subclasses must define self._iterator for this function. # Subclasses must define self._iterator for this function.
return self.make_bytes(next(self._iterator)) return self.make_bytes(next(self._iterator))
next = __next__ # Python 2 compatibility
# These methods partially implement the file-like object interface. # These methods partially implement the file-like object interface.
# See http://docs.python.org/lib/bltin-file-objects.html # See http://docs.python.org/lib/bltin-file-objects.html

View File

@ -73,7 +73,9 @@ class Node(object):
For truth value testing. For truth value testing.
""" """
return bool(self.children) return bool(self.children)
__nonzero__ = __bool__ # Python 2
def __nonzero__(self): # Python 2 compatibility
return type(self).__bool__(self)
def __contains__(self, other): def __contains__(self, other):
""" """

View File

@ -278,15 +278,13 @@ Iterators
:: ::
class MyIterator(object): class MyIterator(six.Iterator):
def __iter__(self): def __iter__(self):
return self # implement some logic here return self # implement some logic here
def __next__(self): def __next__(self):
raise StopIteration # implement some logic here raise StopIteration # implement some logic here
next = __next__ # Python 2 compatibility
Boolean evaluation Boolean evaluation
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
@ -297,7 +295,8 @@ Boolean evaluation
def __bool__(self): def __bool__(self):
return True # implement some logic here return True # implement some logic here
__nonzero__ = __bool__ # Python 2 compatibility def __nonzero__(self): # Python 2 compatibility
return type(self).__bool__(self)
Division Division
~~~~~~~~ ~~~~~~~~
@ -309,12 +308,14 @@ Division
def __truediv__(self, other): def __truediv__(self, other):
return self / other # implement some logic here 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): def __itruediv__(self, other):
return self // other # implement some logic here 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 .. module: django.utils.six