diff options
author | Simon Feltman <sfeltman@src.gnome.org> | 2014-04-30 17:08:29 -0700 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2015-09-29 23:16:32 -0400 |
commit | 10175a1b54fff30291bbb5ff849dc3a048a4b8dc (patch) | |
tree | e1e58f59728a2abac60e579cea3c929bd46b2ea8 /giscanner | |
parent | 3dca44e3f1aba172b8a71d3860d55167dc35a5dc (diff) | |
download | gobject-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.py | 26 | ||||
-rw-r--r-- | giscanner/ast.py | 136 | ||||
-rw-r--r-- | giscanner/girwriter.py | 15 | ||||
-rw-r--r-- | giscanner/message.py | 31 |
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): |