diff options
author | Guido van Rossum <guido@python.org> | 2002-11-08 17:03:36 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2002-11-08 17:03:36 (GMT) |
commit | 7cd83ca9adefadee172f252f4f89f24dc10cd715 (patch) | |
tree | b1c99ffd4402fbeeb3e70884e3a06457df58bbb4 /Lib/sets.py | |
parent | 91e77536e8285bd2276a40bb891efc9001b9f8a6 (diff) | |
download | cpython-7cd83ca9adefadee172f252f4f89f24dc10cd715.zip cpython-7cd83ca9adefadee172f252f4f89f24dc10cd715.tar.gz cpython-7cd83ca9adefadee172f252f4f89f24dc10cd715.tar.bz2 |
Another attempt at making the set constructor both safe and fast. [SF
bug 628246]
Diffstat (limited to 'Lib/sets.py')
-rw-r--r-- | Lib/sets.py | 42 |
1 files changed, 24 insertions, 18 deletions
diff --git a/Lib/sets.py b/Lib/sets.py index 5a66a2e..a05c66f 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): |