From b78eff7be5b0f93a095b01765f309342bb7369ea Mon Sep 17 00:00:00 2001 From: Avasam Date: Sat, 18 Feb 2023 15:10:44 -0500 Subject: [PATCH 1/7] Fix potentially unbound issues in stubsabot --- scripts/stubsabot.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/scripts/stubsabot.py b/scripts/stubsabot.py index a9a19e333c2b..fdbc23aec682 100644 --- a/scripts/stubsabot.py +++ b/scripts/stubsabot.py @@ -170,8 +170,9 @@ async def release_contains_py_typed(release_to_download: PypiReleaseDownload, *, raise AssertionError(f"Unknown package type: {packagetype!r}") -async def find_first_release_with_py_typed(pypi_info: PypiInfo, *, session: aiohttp.ClientSession) -> PypiReleaseDownload: +async def find_first_release_with_py_typed(pypi_info: PypiInfo, *, session: aiohttp.ClientSession) -> PypiReleaseDownload | None: release_iter = pypi_info.releases_in_descending_order() + first_release_with_py_typed: PypiReleaseDownload | None = None while await release_contains_py_typed(release := next(release_iter), session=session): if not release.version.is_prerelease: first_release_with_py_typed = release @@ -418,10 +419,12 @@ async def determine_action(stub_path: Path, session: aiohttp.ClientSession) -> U if latest_version in spec: return NoUpdate(stub_info.distribution, "up to date") + obsolete_since: PypiReleaseDownload | None = None is_obsolete = await release_contains_py_typed(latest_release, session=session) if is_obsolete: - first_release_with_py_typed = await find_first_release_with_py_typed(pypi_info, session=session) - relevant_version = version_obsolete_since = first_release_with_py_typed.version + obsolete_since = await find_first_release_with_py_typed(pypi_info, session=session) + assert obsolete_since is not None + relevant_version = obsolete_since.version else: relevant_version = latest_version @@ -437,23 +440,21 @@ async def determine_action(stub_path: Path, session: aiohttp.ClientSession) -> U if diff_info is not None: github_repo_path, old_tag, new_tag, diff_url = diff_info links["Diff"] = diff_url + diff_analysis = await analyze_diff( + github_repo_path=github_repo_path, stub_path=stub_path, old_tag=old_tag, new_tag=new_tag, session=session + ) + else: + diff_analysis = None - if is_obsolete: + if obsolete_since: return Obsolete( stub_info.distribution, stub_path, - obsolete_since_version=str(version_obsolete_since), - obsolete_since_date=first_release_with_py_typed.upload_date, + obsolete_since_version=str(obsolete_since.version), + obsolete_since_date=obsolete_since.upload_date, links=links, ) - if diff_info is None: - diff_analysis: DiffAnalysis | None = None - else: - diff_analysis = await analyze_diff( - github_repo_path=github_repo_path, stub_path=stub_path, old_tag=old_tag, new_tag=new_tag, session=session - ) - return Update( distribution=stub_info.distribution, stub_path=stub_path, From 20720cc8614bf2afd51848851afea6313e73252f Mon Sep 17 00:00:00 2001 From: Avasam Date: Sat, 18 Feb 2023 15:52:02 -0500 Subject: [PATCH 2/7] Don't do diff analysis if obsolete --- scripts/stubsabot.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/scripts/stubsabot.py b/scripts/stubsabot.py index fdbc23aec682..6eff198c8be4 100644 --- a/scripts/stubsabot.py +++ b/scripts/stubsabot.py @@ -438,13 +438,8 @@ async def determine_action(stub_path: Path, session: aiohttp.ClientSession) -> U diff_info = await get_diff_info(session, stub_info, pypi_info, relevant_version) if diff_info is not None: - github_repo_path, old_tag, new_tag, diff_url = diff_info + *_, diff_url = diff_info links["Diff"] = diff_url - diff_analysis = await analyze_diff( - github_repo_path=github_repo_path, stub_path=stub_path, old_tag=old_tag, new_tag=new_tag, session=session - ) - else: - diff_analysis = None if obsolete_since: return Obsolete( @@ -455,6 +450,14 @@ async def determine_action(stub_path: Path, session: aiohttp.ClientSession) -> U links=links, ) + if diff_info is None: + diff_analysis: DiffAnalysis | None = None + else: + github_repo_path, old_tag, new_tag, _ = diff_info + diff_analysis = await analyze_diff( + github_repo_path=github_repo_path, stub_path=stub_path, old_tag=old_tag, new_tag=new_tag, session=session + ) + return Update( distribution=stub_info.distribution, stub_path=stub_path, From 5262fe9f7948840167f40b47a11b8813f419cc8e Mon Sep 17 00:00:00 2001 From: Avasam Date: Sat, 18 Feb 2023 16:11:28 -0500 Subject: [PATCH 3/7] More PR comments --- scripts/stubsabot.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/scripts/stubsabot.py b/scripts/stubsabot.py index 6eff198c8be4..a5552b2de6f0 100644 --- a/scripts/stubsabot.py +++ b/scripts/stubsabot.py @@ -170,12 +170,13 @@ async def release_contains_py_typed(release_to_download: PypiReleaseDownload, *, raise AssertionError(f"Unknown package type: {packagetype!r}") -async def find_first_release_with_py_typed(pypi_info: PypiInfo, *, session: aiohttp.ClientSession) -> PypiReleaseDownload | None: +async def find_first_release_with_py_typed(pypi_info: PypiInfo, *, session: aiohttp.ClientSession) -> PypiReleaseDownload: release_iter = pypi_info.releases_in_descending_order() first_release_with_py_typed: PypiReleaseDownload | None = None while await release_contains_py_typed(release := next(release_iter), session=session): if not release.version.is_prerelease: first_release_with_py_typed = release + assert first_release_with_py_typed is not None, f"{pypi_info.distribution} has no non-prerelease `py.typed` version" return first_release_with_py_typed @@ -420,10 +421,8 @@ async def determine_action(stub_path: Path, session: aiohttp.ClientSession) -> U return NoUpdate(stub_info.distribution, "up to date") obsolete_since: PypiReleaseDownload | None = None - is_obsolete = await release_contains_py_typed(latest_release, session=session) - if is_obsolete: + if await release_contains_py_typed(latest_release, session=session): obsolete_since = await find_first_release_with_py_typed(pypi_info, session=session) - assert obsolete_since is not None relevant_version = obsolete_since.version else: relevant_version = latest_version @@ -438,8 +437,7 @@ async def determine_action(stub_path: Path, session: aiohttp.ClientSession) -> U diff_info = await get_diff_info(session, stub_info, pypi_info, relevant_version) if diff_info is not None: - *_, diff_url = diff_info - links["Diff"] = diff_url + links["Diff"] = diff_info.diff_url if obsolete_since: return Obsolete( @@ -453,9 +451,12 @@ async def determine_action(stub_path: Path, session: aiohttp.ClientSession) -> U if diff_info is None: diff_analysis: DiffAnalysis | None = None else: - github_repo_path, old_tag, new_tag, _ = diff_info diff_analysis = await analyze_diff( - github_repo_path=github_repo_path, stub_path=stub_path, old_tag=old_tag, new_tag=new_tag, session=session + github_repo_path=diff_info.repo_path, + stub_path=stub_path, + old_tag=diff_info.old_tag, + new_tag=diff_info.new_tag, + session=session, ) return Update( From 85a2d266590177dd29b4a87176a71af4fcae7b47 Mon Sep 17 00:00:00 2001 From: Avasam Date: Sat, 18 Feb 2023 16:15:52 -0500 Subject: [PATCH 4/7] Move release_contains_py_typed call in find_first_release_with_py_typed --- scripts/stubsabot.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/stubsabot.py b/scripts/stubsabot.py index a5552b2de6f0..49ea6ef1eac4 100644 --- a/scripts/stubsabot.py +++ b/scripts/stubsabot.py @@ -170,13 +170,17 @@ async def release_contains_py_typed(release_to_download: PypiReleaseDownload, *, raise AssertionError(f"Unknown package type: {packagetype!r}") -async def find_first_release_with_py_typed(pypi_info: PypiInfo, *, session: aiohttp.ClientSession) -> PypiReleaseDownload: +async def find_first_release_with_py_typed( + pypi_info: PypiInfo, latest_release: PypiReleaseDownload, *, session: aiohttp.ClientSession +) -> PypiReleaseDownload | None: + if await release_contains_py_typed(latest_release, session=session): + return None + release_iter = pypi_info.releases_in_descending_order() first_release_with_py_typed: PypiReleaseDownload | None = None while await release_contains_py_typed(release := next(release_iter), session=session): if not release.version.is_prerelease: first_release_with_py_typed = release - assert first_release_with_py_typed is not None, f"{pypi_info.distribution} has no non-prerelease `py.typed` version" return first_release_with_py_typed @@ -420,12 +424,8 @@ async def determine_action(stub_path: Path, session: aiohttp.ClientSession) -> U if latest_version in spec: return NoUpdate(stub_info.distribution, "up to date") - obsolete_since: PypiReleaseDownload | None = None - if await release_contains_py_typed(latest_release, session=session): - obsolete_since = await find_first_release_with_py_typed(pypi_info, session=session) - relevant_version = obsolete_since.version - else: - relevant_version = latest_version + obsolete_since = await find_first_release_with_py_typed(pypi_info, latest_release, session=session) + relevant_version = obsolete_since.version if obsolete_since else latest_version project_urls = pypi_info.info["project_urls"] or {} maybe_links: dict[str, str | None] = { From 286823b2d5b14cd56359ac1fad2adcda56a44379 Mon Sep 17 00:00:00 2001 From: Avasam Date: Sat, 18 Feb 2023 16:17:55 -0500 Subject: [PATCH 5/7] inverted condition --- scripts/stubsabot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/stubsabot.py b/scripts/stubsabot.py index 49ea6ef1eac4..b6465c2836a2 100644 --- a/scripts/stubsabot.py +++ b/scripts/stubsabot.py @@ -173,7 +173,7 @@ async def release_contains_py_typed(release_to_download: PypiReleaseDownload, *, async def find_first_release_with_py_typed( pypi_info: PypiInfo, latest_release: PypiReleaseDownload, *, session: aiohttp.ClientSession ) -> PypiReleaseDownload | None: - if await release_contains_py_typed(latest_release, session=session): + if not (await release_contains_py_typed(latest_release, session=session)): return None release_iter = pypi_info.releases_in_descending_order() From 193dd1e28eb37bb8c3958ef2ddf6ef2d495986f4 Mon Sep 17 00:00:00 2001 From: Avasam Date: Sat, 18 Feb 2023 16:41:14 -0500 Subject: [PATCH 6/7] Don't check the latest_release for py.typed twice --- scripts/stubsabot.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/scripts/stubsabot.py b/scripts/stubsabot.py index b6465c2836a2..6d24a13ad30c 100644 --- a/scripts/stubsabot.py +++ b/scripts/stubsabot.py @@ -170,13 +170,12 @@ async def release_contains_py_typed(release_to_download: PypiReleaseDownload, *, raise AssertionError(f"Unknown package type: {packagetype!r}") -async def find_first_release_with_py_typed( - pypi_info: PypiInfo, latest_release: PypiReleaseDownload, *, session: aiohttp.ClientSession -) -> PypiReleaseDownload | None: - if not (await release_contains_py_typed(latest_release, session=session)): +async def find_first_release_with_py_typed(pypi_info: PypiInfo, *, session: aiohttp.ClientSession) -> PypiReleaseDownload | None: + release_iter = pypi_info.releases_in_descending_order() + # If the latest release is not py.typed, assume none are. + if not (await release_contains_py_typed(release := next(release_iter), session=session)): return None - release_iter = pypi_info.releases_in_descending_order() first_release_with_py_typed: PypiReleaseDownload | None = None while await release_contains_py_typed(release := next(release_iter), session=session): if not release.version.is_prerelease: From b95d93bc902d11536c31eca0188b77c996204f42 Mon Sep 17 00:00:00 2001 From: Avasam Date: Sat, 18 Feb 2023 16:59:11 -0500 Subject: [PATCH 7/7] accidentally left in argument --- scripts/stubsabot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/stubsabot.py b/scripts/stubsabot.py index 6d24a13ad30c..8153fb11f564 100644 --- a/scripts/stubsabot.py +++ b/scripts/stubsabot.py @@ -423,7 +423,7 @@ async def determine_action(stub_path: Path, session: aiohttp.ClientSession) -> U if latest_version in spec: return NoUpdate(stub_info.distribution, "up to date") - obsolete_since = await find_first_release_with_py_typed(pypi_info, latest_release, session=session) + obsolete_since = await find_first_release_with_py_typed(pypi_info, session=session) relevant_version = obsolete_since.version if obsolete_since else latest_version project_urls = pypi_info.info["project_urls"] or {}