From: Guido van Rossum Date: Fri, 8 Nov 2002 17:03:36 +0000 (+0000) Subject: Another attempt at making the set constructor both safe and fast. [SF X-Git-Tag: v2.3c1~3511 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7cd83ca9adefadee172f252f4f89f24dc10cd715;p=thirdparty%2FPython%2Fcpython.git Another attempt at making the set constructor both safe and fast. [SF bug 628246] --- diff --git a/Lib/sets.py b/Lib/sets.py index 5a66a2e0a661..a05c66f73c2f 100644 --- a/Lib/sets.py +++ b/Lib/sets.py @@ -319,26 +319,32 @@ class BaseSet(object): data.update(iterable) return - # If the mere process of iterating may raise TypeError, materialize - # the iterable into a tuple first. Then the TypeError will get - # raised here and propagated back to the caller. Once we get into - # the loop following, TypeError is assumed to mean that element - # can't be used as a dict key. - if type(iterable) not in (list, tuple, dict, file, xrange, str): - iterable = tuple(iterable) - - it = iter(iterable) value = True - while True: - try: - for element in it: + + if type(iterable) in (list, tuple, xrange): + # Optimized: we know that __iter__() and next() can't + # raise TypeError, so we can move 'try:' out of the loop. + it = iter(iterable) + while True: + try: + for element in it: + data[element] = value + return + except TypeError: + transform = getattr(element, "_as_immutable", None) + if transform is None: + raise # re-raise the TypeError exception we caught + data[transform()] = value + else: + # Safe: only catch TypeError where intended + for element in iterable: + try: data[element] = value - return - except TypeError: - transform = getattr(element, "_as_immutable", None) - if transform is None: - raise # re-raise the TypeError exception we caught - data[transform()] = value + except TypeError: + transform = getattr(element, "_as_immutable", None) + if transform is None: + raise # re-raise the TypeError exception we caught + data[transform()] = value class ImmutableSet(BaseSet):