From 7cd83ca9adefadee172f252f4f89f24dc10cd715 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Fri, 8 Nov 2002 17:03:36 +0000 Subject: [PATCH] Another attempt at making the set constructor both safe and fast. [SF bug 628246] --- Lib/sets.py | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/Lib/sets.py b/Lib/sets.py index 5a66a2e0a66..a05c66f73c2 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):