summaryrefslogtreecommitdiff
path: root/giscanner
diff options
context:
space:
mode:
authorSimon Feltman <sfeltman@src.gnome.org>2014-04-30 17:08:29 -0700
committerColin Walters <walters@verbum.org>2015-09-29 23:16:32 -0400
commit10175a1b54fff30291bbb5ff849dc3a048a4b8dc (patch)
treee1e58f59728a2abac60e579cea3c929bd46b2ea8 /giscanner
parent3dca44e3f1aba172b8a71d3860d55167dc35a5dc (diff)
downloadgobject-introspection-10175a1b54fff30291bbb5ff849dc3a048a4b8dc.tar.gz
giscanner: Use rich comparison methods for Python 3 compatibility
Add lt, le, gt, ge, eq, ne, and hash dunder methods to all classes that implement custom comparisons with __cmp__. This is needed to support Python 3 compatible sorting of instances of these classes. Avoid using @functools.total_ordering which does not work for some of these classes and also is not available in Python 2.6. https://bugzilla.gnome.org/show_bug.cgi?id=679438
Diffstat (limited to 'giscanner')
-rw-r--r--giscanner/annotationparser.py26
-rw-r--r--giscanner/ast.py136
-rw-r--r--giscanner/girwriter.py15
-rw-r--r--giscanner/message.py31
4 files changed, 173 insertions, 35 deletions
diff --git a/giscanner/annotationparser.py b/giscanner/annotationparser.py
index cd6fa4fa..d48ed616 100644
--- a/giscanner/annotationparser.py
+++ b/giscanner/annotationparser.py
@@ -114,6 +114,7 @@ from __future__ import unicode_literals
import os
import re
+import operator
from collections import namedtuple
from operator import ne, gt, lt
@@ -1054,11 +1055,32 @@ class GtkDocCommentBlock(GtkDocAnnotatable):
#: applied to this :class:`GtkDocCommentBlock`.
self.tags = OrderedDict()
- def __cmp__(self, other):
+ def _compare(self, other, op):
# Note: This is used by g-ir-annotation-tool, which does a ``sorted(blocks.values())``,
# meaning that keeping this around makes update-glib-annotations.py patches
# easier to review.
- return cmp(self.name, other.name)
+ return op(self.name, other.name)
+
+ def __lt__(self, other):
+ return self._compare(other, operator.lt)
+
+ def __gt__(self, other):
+ return self._compare(other, operator.gt)
+
+ def __ge__(self, other):
+ return self._compare(other, operator.ge)
+
+ def __le__(self, other):
+ return self._compare(other, operator.le)
+
+ def __eq__(self, other):
+ return self._compare(other, operator.eq)
+
+ def __ne__(self, other):
+ return self._compare(other, operator.ne)
+
+ def __hash__(self):
+ return hash(self.name)
def __repr__(self):
return "<GtkDocCommentBlock '%s' %r>" % (self.name, self.annotations)
diff --git a/giscanner/ast.py b/giscanner/ast.py
index 74a70811..f0fb7df1 100644
--- a/giscanner/ast.py
+++ b/giscanner/ast.py
@@ -25,6 +25,7 @@ from __future__ import print_function
from __future__ import unicode_literals
import copy
+import operator
from itertools import chain
from . import message
@@ -123,15 +124,37 @@ in contrast to the other create_type() functions."""
assert self.target_giname is not None
return self.target_giname.split('.')[1]
- def __cmp__(self, other):
+ def _compare(self, other, op):
if self.target_fundamental:
- return cmp(self.target_fundamental, other.target_fundamental)
+ return op(self.target_fundamental, other.target_fundamental)
elif self.target_giname:
- return cmp(self.target_giname, other.target_giname)
+ return op(self.target_giname, other.target_giname)
elif self.target_foreign:
- return cmp(self.target_foreign, other.target_foreign)
+ return op(self.target_foreign, other.target_foreign)
else:
- return cmp(self.ctype, other.ctype)
+ return op(self.ctype, other.ctype)
+
+ def __lt__(self, other):
+ return self._compare(other, operator.lt)
+
+ def __gt__(self, other):
+ return self._compare(other, operator.gt)
+
+ def __ge__(self, other):
+ return self._compare(other, operator.ge)
+
+ def __le__(self, other):
+ return self._compare(other, operator.le)
+
+ def __eq__(self, other):
+ return self._compare(other, operator.eq)
+
+ def __ne__(self, other):
+ return self._compare(other, operator.ne)
+
+ def __hash__(self):
+ return hash((self.target_fundamental, self.target_giname,
+ self.target_foreign, self.ctype))
def is_equiv(self, typeval):
"""Return True if the specified types are compatible at
@@ -498,11 +521,26 @@ class Include(object):
def from_string(cls, string):
return cls(*string.split('-', 1))
- def __cmp__(self, other):
- namecmp = cmp(self.name, other.name)
- if namecmp != 0:
- return namecmp
- return cmp(self.version, other.version)
+ def _compare(self, other, op):
+ return op((self.name, self.version), (other.name, other.version))
+
+ def __lt__(self, other):
+ return self._compare(other, operator.lt)
+
+ def __gt__(self, other):
+ return self._compare(other, operator.gt)
+
+ def __ge__(self, other):
+ return self._compare(other, operator.ge)
+
+ def __le__(self, other):
+ return self._compare(other, operator.le)
+
+ def __eq__(self, other):
+ return self._compare(other, operator.eq)
+
+ def __ne__(self, other):
+ return self._compare(other, operator.ne)
def __hash__(self):
return hash(str(self))
@@ -558,11 +596,29 @@ GIName. It's possible for nodes to contain or point to other nodes."""
assert self.namespace is not None
return Type(target_giname=('%s.%s' % (self.namespace.name, self.name)))
- def __cmp__(self, other):
- nscmp = cmp(self.namespace, other.namespace)
- if nscmp != 0:
- return nscmp
- return cmp(self.name, other.name)
+ def _compare(self, other, op):
+ return op((self.namespace, self.name), (other.namespace, other.name))
+
+ def __lt__(self, other):
+ return self._compare(other, operator.lt)
+
+ def __gt__(self, other):
+ return self._compare(other, operator.gt)
+
+ def __ge__(self, other):
+ return self._compare(other, operator.ge)
+
+ def __le__(self, other):
+ return self._compare(other, operator.le)
+
+ def __eq__(self, other):
+ return self._compare(other, operator.eq)
+
+ def __ne__(self, other):
+ return self._compare(other, operator.ne)
+
+ def __hash__(self):
+ return hash((self.namespace, self.name))
def __repr__(self):
return "%s('%s')" % (self.__class__.__name__, self.name)
@@ -858,8 +914,29 @@ class Member(Annotated):
self.nick = nick
self.parent = None
- def __cmp__(self, other):
- return cmp(self.name, other.name)
+ def _compare(self, other, op):
+ return op(self.name, other.name)
+
+ def __lt__(self, other):
+ return self._compare(other, operator.lt)
+
+ def __gt__(self, other):
+ return self._compare(other, operator.gt)
+
+ def __ge__(self, other):
+ return self._compare(other, operator.ge)
+
+ def __le__(self, other):
+ return self._compare(other, operator.le)
+
+ def __eq__(self, other):
+ return self._compare(other, operator.eq)
+
+ def __ne__(self, other):
+ return self._compare(other, operator.ne)
+
+ def __hash__(self):
+ return hash(self.name)
def __repr__(self):
return "%s('%s')" % (self.__class__.__name__, self.name)
@@ -931,8 +1008,29 @@ class Field(Annotated):
self.namespace = None
self.parent = None # a compound
- def __cmp__(self, other):
- return cmp(self.name, other.name)
+ def _compare(self, other, op):
+ return op(self.name, other.name)
+
+ def __lt__(self, other):
+ return self._compare(other, operator.lt)
+
+ def __gt__(self, other):
+ return self._compare(other, operator.gt)
+
+ def __ge__(self, other):
+ return self._compare(other, operator.ge)
+
+ def __le__(self, other):
+ return self._compare(other, operator.le)
+
+ def __eq__(self, other):
+ return self._compare(other, operator.eq)
+
+ def __ne__(self, other):
+ return self._compare(other, operator.ne)
+
+ def __hash__(self):
+ return hash(self.name)
def __repr__(self):
return "%s('%s')" % (self.__class__.__name__, self.name)
diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py
index 0df87ed4..e73dcaca 100644
--- a/giscanner/girwriter.py
+++ b/giscanner/girwriter.py
@@ -82,17 +82,12 @@ class GIRWriter(XMLWriter):
# We define a custom sorting function here because
# we want aliases to be first. They're a bit
# special because the typelib compiler expands them.
- def nscmp(a, b):
- if isinstance(a, ast.Alias):
- if isinstance(b, ast.Alias):
- return cmp(a.name, b.name)
- else:
- return -1
- elif isinstance(b, ast.Alias):
- return 1
+ def nscmp(val):
+ if isinstance(val, ast.Alias):
+ return 0, val
else:
- return cmp(a, b)
- for node in sorted(namespace.values(), cmp=nscmp):
+ return 1, val
+ for node in sorted(namespace.values(), key=nscmp):
self._write_node(node)
def _write_node(self, node):
diff --git a/giscanner/message.py b/giscanner/message.py
index d474ae9d..f36bcbc1 100644
--- a/giscanner/message.py
+++ b/giscanner/message.py
@@ -27,6 +27,7 @@ from __future__ import unicode_literals
import os
import sys
+import operator
from . import utils
@@ -48,12 +49,34 @@ class Position(object):
self.line = line
self.column = column
- def __cmp__(self, other):
- return cmp((self.filename, self.line, self.column),
- (other.filename, other.line, other.column))
+ def _compare(self, other, op):
+ return op((self.filename, self.line, self.column),
+ (other.filename, other.line, other.column))
+
+ def __lt__(self, other):
+ return self._compare(other, operator.lt)
+
+ def __gt__(self, other):
+ return self._compare(other, operator.gt)
+
+ def __ge__(self, other):
+ return self._compare(other, operator.ge)
+
+ def __le__(self, other):
+ return self._compare(other, operator.le)
+
+ def __eq__(self, other):
+ return self._compare(other, operator.eq)
+
+ def __ne__(self, other):
+ return self._compare(other, operator.ne)
+
+ def __hash__(self):
+ return hash((self.filename, self.line, self.column))
def __repr__(self):
- return '<Position %s:%d:%d>' % (os.path.basename(self.filename), self.line or -1,
+ return '<Position %s:%d:%d>' % (os.path.basename(self.filename),
+ self.line or -1,
self.column or -1)
def format(self, cwd):