Another attempt at making the set constructor both safe and fast. [SF

bug 628246]
This commit is contained in:
Guido van Rossum 2002-11-08 17:03:36 +00:00
parent 91e77536e8
commit 7cd83ca9ad
1 changed files with 24 additions and 18 deletions

View 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):