From 4f7723649ab01f17311b50817577479b33e7c763 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Thu, 27 Apr 2017 11:50:30 -0700 Subject: [PATCH] Implement an actual set interface for the OrderedSet class. Closes #1670 This uses the ABC's in collections to implement an OrderedSet class. Internally an OrderedDict is still wrapped so that the ordering is maintained, this adds the full interface and behavior of an Set, but with ordering by first insertion. --- mesonbuild/mesonlib.py | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py index ae2f88c62..026376837 100644 --- a/mesonbuild/mesonlib.py +++ b/mesonbuild/mesonlib.py @@ -687,17 +687,37 @@ def get_filenames_templates_dict(inputs, outputs): values['@OUTDIR@'] = '.' return values -class OrderedSet(collections.OrderedDict): - ''' - A 'set' equivalent that preserves the order in which items are added. - - This is a hack implementation that wraps OrderedDict. It may not be the - most efficient solution and might need fixing to override more methods. - ''' +class OrderedSet(collections.MutableSet): + """A set that preserves the order in which items are added, by first + insertion. + """ def __init__(self, iterable=None): + self.__container = collections.OrderedDict() if iterable: self.update(iterable) + def __contains__(self, value): + return value in self.__container + + def __iter__(self): + return iter(self.__container.keys()) + + def __len__(self): + return len(self.__container) + + def __repr__(self): + # Don't print 'OrderedSet("")' for an empty set. + if self.__container: + return 'OrderedSet("{}")'.format('", "'.join(self.__container.keys())) + return 'OrderedSet()' + + def add(self, value): + self.__container[value] = None + + def discard(self, value): + if value in self.__container: + del self.__container[value] + def update(self, iterable): for item in iterable: - self[item] = True + self.__container[item] = None