summaryrefslogtreecommitdiffstats
path: root/Lib/sets.py
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2002-11-08 17:03:36 (GMT)
committerGuido van Rossum <guido@python.org>2002-11-08 17:03:36 (GMT)
commit7cd83ca9adefadee172f252f4f89f24dc10cd715 (patch)
treeb1c99ffd4402fbeeb3e70884e3a06457df58bbb4 /Lib/sets.py
parent91e77536e8285bd2276a40bb891efc9001b9f8a6 (diff)
downloadcpython-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.py42
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):