aboutsummaryrefslogtreecommitdiffstats
path: root/yt_dlp/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'yt_dlp/utils.py')
-rw-r--r--yt_dlp/utils.py81
1 files changed, 37 insertions, 44 deletions
diff --git a/yt_dlp/utils.py b/yt_dlp/utils.py
index f21d70672..8dda5e931 100644
--- a/yt_dlp/utils.py
+++ b/yt_dlp/utils.py
@@ -770,13 +770,16 @@ def expand_path(s):
return os.path.expandvars(compat_expanduser(s))
-def orderedSet(iterable):
- """ Remove all duplicates from the input iterable """
- res = []
- for el in iterable:
- if el not in res:
- res.append(el)
- return res
+def orderedSet(iterable, *, lazy=False):
+ """Remove all duplicates from the input iterable"""
+ def _iter():
+ seen = [] # Do not use set since the items can be unhashable
+ for x in iterable:
+ if x not in seen:
+ seen.append(x)
+ yield x
+
+ return _iter() if lazy else list(_iter())
def _htmlentity_transform(entity_with_semicolon):
@@ -2820,7 +2823,26 @@ class PlaylistEntries:
is_exhausted = False
def __init__(self, ydl, info_dict):
- self.ydl, self.info_dict = ydl, info_dict
+ self.ydl = ydl
+
+ # _entries must be assigned now since infodict can change during iteration
+ entries = info_dict.get('entries')
+ if entries is None:
+ raise EntryNotInPlaylist('There are no entries')
+ elif isinstance(entries, list):
+ self.is_exhausted = True
+
+ requested_entries = info_dict.get('requested_entries')
+ self.is_incomplete = bool(requested_entries)
+ if self.is_incomplete:
+ assert self.is_exhausted
+ self._entries = [self.MissingEntry] * max(requested_entries)
+ for i, entry in zip(requested_entries, entries):
+ self._entries[i - 1] = entry
+ elif isinstance(entries, (list, PagedList, LazyList)):
+ self._entries = entries
+ else:
+ self._entries = LazyList(entries)
PLAYLIST_ITEMS_RE = re.compile(r'''(?x)
(?P<start>[+-]?\d+)?
@@ -2863,38 +2885,14 @@ class PlaylistEntries:
except (ExistingVideoReached, RejectedVideoReached):
return
- @property
- def full_count(self):
- if self.info_dict.get('playlist_count'):
- return self.info_dict['playlist_count']
- elif self.is_exhausted and not self.is_incomplete:
+ def get_full_count(self):
+ if self.is_exhausted and not self.is_incomplete:
return len(self)
elif isinstance(self._entries, InAdvancePagedList):
if self._entries._pagesize == 1:
return self._entries._pagecount
@functools.cached_property
- def _entries(self):
- entries = self.info_dict.get('entries')
- if entries is None:
- raise EntryNotInPlaylist('There are no entries')
- elif isinstance(entries, list):
- self.is_exhausted = True
-
- indices = self.info_dict.get('requested_entries')
- self.is_incomplete = bool(indices)
- if self.is_incomplete:
- assert self.is_exhausted
- ret = [self.MissingEntry] * max(indices)
- for i, entry in zip(indices, entries):
- ret[i - 1] = entry
- return ret
-
- if isinstance(entries, (list, PagedList, LazyList)):
- return entries
- return LazyList(entries)
-
- @functools.cached_property
def _getter(self):
if isinstance(self._entries, list):
def get_entry(i):
@@ -2937,17 +2935,12 @@ class PlaylistEntries:
if i < 0:
continue
try:
- try:
- entry = self._getter(i)
- except self.IndexError:
- self.is_exhausted = True
- if step > 0:
- break
- continue
- except IndexError:
- if self.is_exhausted:
+ entry = self._getter(i)
+ except self.IndexError:
+ self.is_exhausted = True
+ if step > 0:
break
- raise
+ continue
yield i + 1, entry
def __len__(self):