]> granicus.if.org Git - python/commitdiff
Another attempt at making the set constructor both safe and fast. [SF
authorGuido van Rossum <guido@python.org>
Fri, 8 Nov 2002 17:03:36 +0000 (17:03 +0000)
committerGuido van Rossum <guido@python.org>
Fri, 8 Nov 2002 17:03:36 +0000 (17:03 +0000)
bug 628246]

Lib/sets.py

index 5a66a2e0a6612fc5e17412a034729b7882224cc4..a05c66f73c2faa9fc85cb47719a0cd540f5ab54b 100644 (file)
@@ -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):