Commit 3c669886 authored by Hanno Schlichting's avatar Hanno Schlichting

Replace `__cmp__` with Python 3 compatible ordering methods.

parent ecc18276
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
Extensions currently include external methods. Extensions currently include external methods.
""" """
from functools import total_ordering
import imp import imp
import os import os
...@@ -23,20 +24,24 @@ import Products ...@@ -23,20 +24,24 @@ import Products
from zExceptions import NotFound from zExceptions import NotFound
class FuncCode: @total_ordering
class FuncCode(object):
def __init__(self, f, im=0): def __init__(self, f, im=0):
self.co_varnames = f.func_code.co_varnames[im:] self.co_varnames = f.func_code.co_varnames[im:]
self.co_argcount = f.func_code.co_argcount - im self.co_argcount = f.func_code.co_argcount - im
def __cmp__(self, other): def __eq__(self, other):
if other is None: if not isinstance(other, FuncCode):
return 1 return False
try: return ((self.co_argcount, self.co_varnames) ==
return cmp((self.co_argcount, self.co_varnames), (other.co_argcount, other.co_varnames))
(other.co_argcount, other.co_varnames))
except Exception: def __lt__(self, other):
return 1 if not isinstance(other, FuncCode):
return False
return ((self.co_argcount, self.co_varnames) <
(other.co_argcount, other.co_varnames))
def _getPath(home, prefix, name, suffixes): def _getPath(home, prefix, name, suffixes):
......
...@@ -47,7 +47,8 @@ def test_menu(): ...@@ -47,7 +47,8 @@ def test_menu():
Sort menu items by title so we get a stable testable result: Sort menu items by title so we get a stable testable result:
>>> menu.sort(lambda x, y: cmp(x['title'], y['title'])) >>> from operator import itemgetter
>>> menu.sort(key=itemgetter('title'))
>>> from pprint import pprint >>> from pprint import pprint
>>> pprint(menu[0]) >>> pprint(menu[0])
{'action': '@@cockatiel_menu_public.html', {'action': '@@cockatiel_menu_public.html',
...@@ -99,7 +100,7 @@ def test_menu(): ...@@ -99,7 +100,7 @@ def test_menu():
>>> len(menu) >>> len(menu)
7 7
>>> menu.sort(lambda x, y: cmp(x['title'], y['title'])) >>> menu.sort(key=itemgetter('title'))
>>> pprint(menu[0]) >>> pprint(menu[0])
{'action': '@@cockatiel_menu_protected.html', {'action': '@@cockatiel_menu_protected.html',
'description': u'', 'description': u'',
......
...@@ -754,6 +754,8 @@ two features are not part of the view logic, they should be treated with ...@@ -754,6 +754,8 @@ two features are not part of the view logic, they should be treated with
independent components. In this example, we are going to only implement independent components. In this example, we are going to only implement
sorting using a simple utility: sorting using a simple utility:
>>> from operator import attrgetter
>>> class ISorter(zope.interface.Interface): >>> class ISorter(zope.interface.Interface):
... ...
... def sort(values): ... def sort(values):
...@@ -763,7 +765,7 @@ sorting using a simple utility: ...@@ -763,7 +765,7 @@ sorting using a simple utility:
... zope.interface.implements(ISorter) ... zope.interface.implements(ISorter)
... ...
... def sort(self, values): ... def sort(self, values):
... return sorted(values, lambda x, y: cmp(x.__name__, y.__name__)) ... return sorted(values, key=attrgetter('__name__'))
>>> zope.component.provideUtility(SortByName(), name='name') >>> zope.component.provideUtility(SortByName(), name='name')
...@@ -771,10 +773,9 @@ sorting using a simple utility: ...@@ -771,10 +773,9 @@ sorting using a simple utility:
... zope.interface.implements(ISorter) ... zope.interface.implements(ISorter)
... ...
... def sort(self, values): ... def sort(self, values):
... return sorted( ... def _key(value):
... values, ... return size.interfaces.ISized(value).sizeForSorting()
... lambda x, y: cmp(size.interfaces.ISized(x).sizeForSorting(), ... return sorted(values, key=_key)
... size.interfaces.ISized(y).sizeForSorting()))
>>> zope.component.provideUtility(SortBySize(), name='size') >>> zope.component.provideUtility(SortBySize(), name='size')
......
<html> <html>
<body> <body>
<ul tal:define="refs options/refs; <ul tal:define="refs options/refs;
refs python:sorted(refs, lambda x,y: cmp(x.order, y.order))"> refs python:sorted(refs, key=lambda x: x.order)">
<li tal:repeat="ref refs" tal:content="ref" /> <li tal:repeat="ref refs" tal:content="ref" />
</ul> </ul>
</body> </body>
......
...@@ -15,26 +15,31 @@ ...@@ -15,26 +15,31 @@
This provides support for simulating function signatures This provides support for simulating function signatures
""" """
from functools import total_ordering
class FuncCode:
@total_ordering
class FuncCode(object):
def __init__(self, varnames, argcount): def __init__(self, varnames, argcount):
self.co_varnames = varnames self.co_varnames = varnames
self.co_argcount = argcount self.co_argcount = argcount
def __cmp__(self, other): def __eq__(self, other):
if other is None: if not isinstance(other, FuncCode):
return 1 return False
try: return ((self.co_argcount, self.co_varnames) ==
return cmp((self.co_argcount, self.co_varnames), (other.co_argcount, other.co_varnames))
(other.co_argcount, other.co_varnames))
except Exception:
return 1
# This is meant to be imported directly into a class. def __lt__(self, other):
if not isinstance(other, FuncCode):
return False
return ((self.co_argcount, self.co_varnames) <
(other.co_argcount, other.co_varnames))
def _setFuncSignature(self, defaults=None, varnames=(), argcount=-1): def _setFuncSignature(self, defaults=None, varnames=(), argcount=-1):
# This is meant to be imported directly into a class.
# Simplify calls. # Simplify calls.
if argcount < 0 and varnames: if argcount < 0 and varnames:
argcount = len(varnames) argcount = len(varnames)
......
...@@ -1743,7 +1743,7 @@ def parse_cookie(text, ...@@ -1743,7 +1743,7 @@ def parse_cookie(text,
return parse_cookie(text[l:], result) return parse_cookie(text[l:], result)
class record: class record(object):
# Allow access to record methods and values from DTML # Allow access to record methods and values from DTML
__allow_access_to_unprotected_subobjects__ = 1 __allow_access_to_unprotected_subobjects__ = 1
...@@ -1766,21 +1766,19 @@ class record: ...@@ -1766,21 +1766,19 @@ class record:
return self.__dict__[key] return self.__dict__[key]
def __str__(self): def __str__(self):
L1 = self.__dict__.items() return ", ".join("%s: %s" % item for item in
L1.sort() sorted(self.__dict__.items()))
return ", ".join("%s: %s" % item for item in L1)
def __repr__(self): def __repr__(self):
# return repr( self.__dict__ ) # return repr( self.__dict__ )
L1 = self.__dict__.items()
L1.sort()
return '{%s}' % ', '.join( return '{%s}' % ', '.join(
"'%s': %s" % (item[0], repr(item[1])) for item in L1) "'%s': %s" % (item[0], repr(item[1])) for item in
sorted(self.__dict__.items()))
def __cmp__(self, other): def __eq__(self, other):
return (cmp(type(self), type(other)) or if not isinstance(other, record):
cmp(self.__class__, other.__class__) or return False
cmp(self.__dict__.items(), other.__dict__.items())) return self.__dict__.items() == other.__dict__.items()
def _filterPasswordFields(items): def _filterPasswordFields(items):
......
...@@ -300,6 +300,7 @@ def decodeExpansion(s, nth=None, maxsize=8192): ...@@ -300,6 +300,7 @@ def decodeExpansion(s, nth=None, maxsize=8192):
nth_pair = None nth_pair = None
if nth is not None: if nth is not None:
nth_pair = (None, None) nth_pair = (None, None)
obid = None
for step in s.split(':'): for step in s.split(':'):
if step.startswith('_'): if step.startswith('_'):
pop = len(step) - 1 pop = len(step) - 1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment