From dc430c6fd7fdfeb7a3a3f7e2ccd02fd3e958dbcd Mon Sep 17 00:00:00 2001 From: Steve Erlenborn <1751095+SteveErl@users.noreply.github.com> Date: Thu, 3 Sep 2026 14:13:42 -0500 Subject: [PATCH] Remove raise of StopIteration in generator Tom Peterson's suggested change to replace the "raise StopIteration" lines with "return" inside the generator routine has been implemented in ttvdbv4_api.py. This is the PEP 479-compliant way to end a generator. In myth4ttvdbv4.py, the buildSingle() routine has been updated to accommodate a possible StopIteration exception when the generator is called. If that exception happens, we will exit with a "No matching episode found" error message. Similarly, buildCollection() has been updated to exit with a "No matching collection found" error message when the provided reference identifier does not correspond to a known TV series. The tvmaze metadata grabber had similar vague failures. For a non-existent episode: tvmaze.py -l en -a US -D 32938 2 35 ERROR: : 'NoneType' object has no attribute 'name' For a non-existent series: tvmaze.py -l en -a US -C 99999 ERROR: : 'NoneType' object has no attribute 'name' The tvmaze.py script has been updated to switch these to: tvmaze.py -l en -a US -D 32938 2 35 ERROR: : No matching episode found tvmaze.py -l en -a US -C 99999 ERROR: : No matching collection found This provides consistent behavior between ttvdb4.py and tvmaze.py grabbers for these types of failures. Resolves #1433 --- .../bindings/python/ttvdbv4/myth4ttvdbv4.py | 45 ++++++++++--------- mythtv/bindings/python/ttvdbv4/ttvdbv4_api.py | 5 +-- .../scripts/metadata/Television/tvmaze.py | 4 ++ 3 files changed, 31 insertions(+), 23 deletions(-) diff --git a/mythtv/bindings/python/ttvdbv4/myth4ttvdbv4.py b/mythtv/bindings/python/ttvdbv4/myth4ttvdbv4.py index 2f677bf31cf..f2bac3a2790 100644 --- a/mythtv/bindings/python/ttvdbv4/myth4ttvdbv4.py +++ b/mythtv/bindings/python/ttvdbv4/myth4ttvdbv4.py @@ -556,26 +556,29 @@ def buildSingle(self): gen_episodes = ttvdb.getSeriesEpisodes(inetref, season_type='default', season=season, episodeNumber=episode, yielded=True) - ep = next(gen_episodes) - epi_x = ttvdb.getEpisodeExtended(ep.id) - for lang in self._select_preferred_langs(epi_x.nameTranslations): - translation = ttvdb.getEpisodeTranslation(epi_x.id, lang) - epi_x.fetched_translations.append(translation) - if self.debug: - print("%04d: buildSingle: Episode Information for %s : %s : %s" - % (self._get_ellapsed_time(), inetref, season, episode)) - _print_class_content(epi_x) - - # get season information: - sea_x = None - for s in epi_x.seasons: - if s.type.id == ser_x.defaultSeasonType: - sea_x = ttvdb.getSeasonExtended(s.id) - if self.debug: - print("%04d: buildSingle: Season Information for %s : %s" - % (self._get_ellapsed_time(), inetref, season)) - _print_class_content(sea_x) - break + try: + ep = next(gen_episodes) + epi_x = ttvdb.getEpisodeExtended(ep.id) + for lang in self._select_preferred_langs(epi_x.nameTranslations): + translation = ttvdb.getEpisodeTranslation(epi_x.id, lang) + epi_x.fetched_translations.append(translation) + if self.debug: + print("%04d: buildSingle: Episode Information for %s : %s : %s" + % (self._get_ellapsed_time(), inetref, season, episode)) + _print_class_content(epi_x) + + # get season information: + sea_x = None + for s in epi_x.seasons: + if s.type.id == ser_x.defaultSeasonType: + sea_x = ttvdb.getSeasonExtended(s.id) + if self.debug: + print("%04d: buildSingle: Season Information for %s : %s" + % (self._get_ellapsed_time(), inetref, season)) + _print_class_content(sea_x) + break + except StopIteration: + sys.exit("No matching episode found") # no we have all extended records for series, season, episode, create xml for them self._format_xml(ser_x, sea_x, epi_x) @@ -605,6 +608,8 @@ def buildCollection(self, other_inetref=None, xml_output=True): # get data for passed inetref and preferred translations ser_x = ttvdb.getSeriesExtended(tvinetref) + if not ser_x: + sys.exit("No matching collection found") ser_x.fetched_translations = [] for lang in self._select_preferred_langs(ser_x.nameTranslations): diff --git a/mythtv/bindings/python/ttvdbv4/ttvdbv4_api.py b/mythtv/bindings/python/ttvdbv4/ttvdbv4_api.py index 3a64f78eaca..245acc72e76 100644 --- a/mythtv/bindings/python/ttvdbv4/ttvdbv4_api.py +++ b/mythtv/bindings/python/ttvdbv4/ttvdbv4_api.py @@ -83,10 +83,9 @@ def _query_yielded(record, path, params, listname=None): for item in datalist: yield record(item) else: - raise StopIteration + return else: - #break - raise StopIteration + return curr_page += 1 params['page'] = curr_page diff --git a/mythtv/programs/scripts/metadata/Television/tvmaze.py b/mythtv/programs/scripts/metadata/Television/tvmaze.py index 4e72206348d..9e25577efd4 100755 --- a/mythtv/programs/scripts/metadata/Television/tvmaze.py +++ b/mythtv/programs/scripts/metadata/Television/tvmaze.py @@ -424,6 +424,8 @@ def buildSingleItem(inetref, season, episode_id): # get info for season episodes: ep_info = tvmaze.get_episode_information(episode_id) + if not ep_info: + sys.exit("No matching episode found") m = VideoMetadata() if show_info.genres is not None and len(show_info.genres) > 0: for g in show_info.genres: @@ -534,6 +536,8 @@ def buildCollection(tvinetref, opts): print("Function 'buildCollection' called with argument '%s'" % tvinetref) show_info = tvmaze.get_show(tvinetref) + if not show_info: + sys.exit("No matching collection found") if opts.debug: for k, v in show_info.__dict__.items(): print(k, " : ", v)