[Piglit] [PATCH 04/12] registry/gl.py: Replace __cmp__ methods with rich comparison methods
Dylan Baker
baker.dylan.c at gmail.com
Tue Jan 13 17:48:14 PST 2015
From: Dylan Baker <dylanx.c.baker at intel.com>
In the days of yore python had a single magic method for comparison,
__cmp__, which was called with the cmp() function. __cmp__ would return
a negative number for less than, 0 for equal, and a positive for greater
than. Then in python 2.1 this single method was replace by the "rich
comparison methods", __lt__, __gt__, __le__, __ge__, __eq__, and __ne__.
These methods provide a more fine grained way to compare objects.
Finally, in 2.7 a class decorator was added (functools.total_ordering)
which allows one to implement __eq__ and either __lt__ or __gt__, and it
fills in the rest.
So, why bother? Well, in python 2.1 cmp was deprecated, but in 3.0 it
was removed. As we continue to look toward a future that includes
python 3 not having features that bind us to python2.ancient is just a
good plan.
Thanks Chad for looking at this and realizing why my logic was failing.
Signed-off-by: Dylan Baker <dylanx.c.baker at intel.com>
---
registry/gl.py | 116 ++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 70 insertions(+), 46 deletions(-)
diff --git a/registry/gl.py b/registry/gl.py
index 6136f5c..f483138 100644
--- a/registry/gl.py
+++ b/registry/gl.py
@@ -29,6 +29,7 @@ from __future__ import print_function
import os.path
import re
import sys
+import functools
from copy import copy, deepcopy
@@ -271,8 +272,7 @@ class OrderedKeyedSet(object):
return node[3]
def sort_by_key(self):
- sorted_items = sorted(self.__map.iteritems(),
- cmp=lambda x, y: cmp(x[0], y[0]))
+ sorted_items = sorted(self.__map.iteritems())
self.clear()
for item in sorted_items:
self.add(item[1])
@@ -391,6 +391,7 @@ class Registry(object):
self.vendor_namespaces.remove(None)
+ at functools.total_ordering
class Feature(object):
"""A <feature> XML element.
@@ -451,20 +452,25 @@ class Feature(object):
assert(self.api in VALID_APIS)
assert(len(self.requirements) > 0)
- def __cmp__(self, other):
+ def __eq__(self, other):
if self is other:
- return 0
+ return True
+ elif isinstance(other, Extension):
+ return False
+ elif self.is_gles != other.is_gles:
+ return False
+ return self.name == other.name
- # Sort features before extensions.
+ def __lt__(self, other):
if isinstance(other, Extension):
- return -1
-
- # Sort GL before GLES.
- diff = cmp(self.is_gles, other.is_gles)
- if diff != 0:
- return diff
-
- return cmp(self.name, other.name)
+ return True
+ # Desktop GL before GLES
+ elif self.is_gles != other.is_gles:
+ if self.is_gles:
+ return False
+ else:
+ return True
+ return self.name < other.name
def __repr__(self):
templ = '{self.__class__.__name__}({self.name!r})'
@@ -490,6 +496,7 @@ class Feature(object):
link(enum)
+ at functools.total_ordering
class Extension(object):
"""An <extension> XML element.
@@ -539,26 +546,33 @@ class Extension(object):
self.__parse_requirements(xml_extension, command_map, enum_map)
- def __cmp__(self, other):
+ def __eq__(self, other):
if self is other:
- return 0
-
- # Sort features before extensions.
+ return True
+ elif isinstance(other, Feature):
+ return False
+ elif self.is_ratified != other.is_ratified:
+ return False
+ elif self.vendor_namespace == 'EXT' != other.vendor_namespace == 'EXT':
+ return False
+ return self.name == other.name
+
+ def __lt__(self, other):
if isinstance(other, Feature):
- return 1
-
- # Sort ratified before unratified.
- diff = cmp(other.is_ratified, self.is_ratified)
- if diff != 0:
- return diff
-
- # Sort EXT before others.
- diff = cmp(other.vendor_namespace == 'EXT',
- self.vendor_namespace == 'EXT')
- if diff != 0:
- return diff
-
- return cmp(self.name, other.name)
+ return False
+ elif self.is_ratified != other.is_ratified:
+ # sort ratified before unratified
+ if self.is_ratified:
+ return True
+ else:
+ return False
+ elif (other.vendor_namespace == 'EXT') != (self.vendor_namespace == 'EXT'):
+ # Sort EXT before others
+ if self.vendor_namespace == 'EXT':
+ return True
+ else:
+ return False
+ return self.name < other.name
def __repr__(self):
templ = '{self.__class__.__name__}(name={self.name!r})'
@@ -598,6 +612,7 @@ class Extension(object):
link(xml_req, enum)
+ at functools.total_ordering
class Requirement(object):
"""A <require> XML element, which links a provider (Feature or Extension)
to a provided (Command or Enum) for a set of apis.
@@ -630,18 +645,19 @@ class Requirement(object):
_log_debug('created {0}'.format(self))
- def __cmp__(self, other):
- """Sort by 'provider', then by 'provided'."""
-
- diff = cmp(self.provider, other.provider)
- if diff != 0:
- return diff
-
- diff = cmp(self.provided, other.provided)
- if diff != 0:
- return diff
+ def __eq__(self, other):
+ if self.provider != other.provider:
+ return False
+ elif self.provided != other.provided:
+ return False
+ return True
- return 0
+ def __lt__(self, other):
+ if self.provider < other.provider:
+ return True
+ elif self.provided < other.provided:
+ return True
+ return False
def __repr__(self):
templ = ('{self.__class__.__name__}'
@@ -702,6 +718,7 @@ class CommandParam(object):
return templ.format(self=self)
+ at functools.total_ordering
class Command(object):
"""A <command> XML element.
@@ -775,8 +792,11 @@ class Command(object):
'alias={self.alias!r}, '
'prototype={self.c_prototype!r})').format(self=self))
- def __cmp__(self, other):
- return cmp(self.name, other.name)
+ def __eq__(self, other):
+ return self.name == other.name
+
+ def __lt__(self, other):
+ return self.name < other.name
def __repr__(self):
templ = '{self.__class__.__name__}({self.name!r})'
@@ -833,6 +853,7 @@ class Command(object):
)
+ at functools.total_ordering
class CommandAliasSet(ImmutableOrderedKeyedSet):
def __init__(self, commands):
@@ -841,8 +862,11 @@ class CommandAliasSet(ImmutableOrderedKeyedSet):
self.__primary_command = None
self.__requirements = None
- def __cmp__(self, other):
- return cmp(self.name, other.name)
+ def __eq__(self, other):
+ return self.name == other.name
+
+ def __lt__(self, other):
+ return self.name < other.name
def __repr__(self):
templ = '{self.__class__.__name__}({self.name!r})'
--
2.2.1
More information about the Piglit
mailing list