mirror of
https://github.com/python/cpython.git
synced 2025-09-27 18:59:43 +00:00
Another attempt at making the set constructor both safe and fast. [SF
bug 628246]
This commit is contained in:
parent
91e77536e8
commit
7cd83ca9ad
1 changed files with 24 additions and 18 deletions
42
Lib/sets.py
42
Lib/sets.py
|
@ -319,26 +319,32 @@ class BaseSet(object):
|
||||||
data.update(iterable)
|
data.update(iterable)
|
||||||
return
|
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
|
value = True
|
||||||
while True:
|
|
||||||
try:
|
if type(iterable) in (list, tuple, xrange):
|
||||||
for element in it:
|
# 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
|
data[element] = value
|
||||||
return
|
except TypeError:
|
||||||
except TypeError:
|
transform = getattr(element, "_as_immutable", None)
|
||||||
transform = getattr(element, "_as_immutable", None)
|
if transform is None:
|
||||||
if transform is None:
|
raise # re-raise the TypeError exception we caught
|
||||||
raise # re-raise the TypeError exception we caught
|
data[transform()] = value
|
||||||
data[transform()] = value
|
|
||||||
|
|
||||||
|
|
||||||
class ImmutableSet(BaseSet):
|
class ImmutableSet(BaseSet):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue