aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichał Górny <mgorny@gentoo.org>2023-02-07 18:36:15 +0100
committerArthur Zamarin <arthurzam@gentoo.org>2023-02-15 19:49:28 +0200
commit8e70727b745e8259fe0b9e5821b01947143367f5 (patch)
tree1c8a6717a10ccbe855d99a06b95e1038c41ed24f /testdata
parentpython: Generalize Python{GHDistfileSuffix → Fetchable}Check (diff)
downloadpkgcheck-8e70727b745e8259fe0b9e5821b01947143367f5.tar.gz
pkgcheck-8e70727b745e8259fe0b9e5821b01947143367f5.tar.bz2
pkgcheck-8e70727b745e8259fe0b9e5821b01947143367f5.zip
checks: Add a check for PyPI URL replacement with pypi.eclass
Signed-off-by: Michał Górny <mgorny@gentoo.org> Closes: https://github.com/pkgcore/pkgcheck/pull/543 Signed-off-by: Arthur Zamarin <arthurzam@gentoo.org>
Diffstat (limited to 'testdata')
-rw-r--r--testdata/data/repos/python/PythonFetchableCheck/PythonInlinePyPIURI/expected.json20
-rw-r--r--testdata/data/repos/python/PythonFetchableCheck/PythonInlinePyPIURI/fix.patch304
-rw-r--r--testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/Manifest10
-rw-r--r--testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-0.ebuild15
-rw-r--r--testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-1_alpha1-r1.ebuild16
-rw-r--r--testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-1_alpha1.ebuild13
-rw-r--r--testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-2_p4-r1.ebuild16
-rw-r--r--testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-2_p4.ebuild13
-rw-r--r--testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-3-r1.ebuild16
-rw-r--r--testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-3.ebuild21
-rw-r--r--testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-4.ebuild16
-rw-r--r--testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/metadata.xml7
-rw-r--r--testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/Manifest5
-rw-r--r--testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/metadata.xml7
-rw-r--r--testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-0.ebuild12
-rw-r--r--testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1.ebuild12
-rw-r--r--testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-100.ebuild12
-rw-r--r--testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r1.ebuild12
-rw-r--r--testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r100.ebuild12
-rw-r--r--testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r101.ebuild12
-rw-r--r--testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r200.ebuild12
-rw-r--r--testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000.ebuild12
-rw-r--r--testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-200.ebuild12
-rw-r--r--testdata/repos/python/app-arch/unzip/unzip-0.ebuild4
-rw-r--r--testdata/repos/python/eclass/pypi.eclass107
-rw-r--r--testdata/repos/python/metadata/stubs1
-rw-r--r--testdata/repos/python/profiles/thirdpartymirrors1
27 files changed, 700 insertions, 0 deletions
diff --git a/testdata/data/repos/python/PythonFetchableCheck/PythonInlinePyPIURI/expected.json b/testdata/data/repos/python/PythonFetchableCheck/PythonInlinePyPIURI/expected.json
new file mode 100644
index 00000000..e8c01812
--- /dev/null
+++ b/testdata/data/repos/python/PythonFetchableCheck/PythonInlinePyPIURI/expected.json
@@ -0,0 +1,20 @@
+{"__class__": "PythonInlinePyPIURI", "category": "PythonFetchableCheck", "package": "PythonInlinePyPIURL", "version": "0", "url": "https://files.pythonhosted.org/packages/source/P/PythonInlinePyPIURL/PythonInlinePyPIURL-0.zip", "replacement": ["pypi_sdist_url", "--no-normalize", "\"${PN}\"", "\"${PV}\"", ".zip"], "normalize": null, "append": null}
+{"__class__": "PythonInlinePyPIURI", "category": "PythonFetchableCheck", "package": "PythonInlinePyPIURL", "version": "1_alpha1", "url": "https://files.pythonhosted.org/packages/source/P/PythonInlinePyPIURL/PythonInlinePyPIURL-1a1.tar.gz", "replacement": null, "normalize": false, "append": false}
+{"__class__": "PythonInlinePyPIURI", "category": "PythonFetchableCheck", "package": "PythonInlinePyPIURL", "version": "1_alpha1-r1", "url": "https://files.pythonhosted.org/packages/source/P/PythonInlinePyPIURL/PythonInlinePyPIURL-1a1.tar.gz", "replacement": null, "normalize": false, "append": true}
+{"__class__": "PythonInlinePyPIURI", "category": "PythonFetchableCheck", "package": "PythonInlinePyPIURL", "version": "2_p4", "url": "https://files.pythonhosted.org/packages/source/P/PythonInlinePyPIURL/pythoninlinepypiurl-2.post4.tar.gz", "replacement": null, "normalize": true, "append": false}
+{"__class__": "PythonInlinePyPIURI", "category": "PythonFetchableCheck", "package": "PythonInlinePyPIURL", "version": "2_p4-r1", "url": "https://files.pythonhosted.org/packages/source/P/PythonInlinePyPIURL/pythoninlinepypiurl-2.post4.tar.gz", "replacement": null, "normalize": true, "append": true}
+{"__class__": "PythonInlinePyPIURI", "category": "PythonFetchableCheck", "package": "PythonInlinePyPIURL", "version": "3", "url": "https://files.pythonhosted.org/packages/py3/p/pypi-url/pypi_url-3-py3-none-any.whl", "replacement": ["pypi_wheel_url", "--unpack", "pypi-url"], "normalize": null, "append": null}
+{"__class__": "PythonInlinePyPIURI", "category": "PythonFetchableCheck", "package": "PythonInlinePyPIURL", "version": "3", "url": "https://files.pythonhosted.org/packages/source/p/pypi-url/pypi-url-3.zip", "replacement": ["pypi_sdist_url", "--no-normalize", "pypi-url", "\"${PV}\"", ".zip"], "normalize": null, "append": null}
+{"__class__": "PythonInlinePyPIURI", "category": "PythonFetchableCheck", "package": "PythonInlinePyPIURL", "version": "3-r1", "url": "https://files.pythonhosted.org/packages/py3/p/pypi-url/pypi_url-3-py3-none-any.whl", "replacement": ["pypi_wheel_url", "pypi-url"], "normalize": null, "append": null}
+{"__class__": "PythonInlinePyPIURI", "category": "PythonFetchableCheck", "package": "PythonInlinePyPIURL", "version": "3-r1", "url": "https://files.pythonhosted.org/packages/source/p/pypi-url/pypi-url-3.tar.gz", "replacement": ["pypi_sdist_url", "--no-normalize", "pypi-url"], "normalize": null, "append": null}
+{"__class__": "PythonInlinePyPIURI", "category": "PythonFetchableCheck", "package": "PythonInlinePyPIURL", "version": "4", "url": "https://files.pythonhosted.org/packages/cp310/P/PythonInlinePyPIURL/pythoninlinepypiurl-4-cp310-cp310-linux_x86_64.whl", "replacement": ["pypi_wheel_url", "\"${PN}\"", "\"${PV}\"", "cp310", "cp310-linux_x86_64"], "normalize": null, "append": null}
+{"__class__": "PythonInlinePyPIURI", "category": "PythonFetchableCheck", "package": "PythonInlinePyPIURL", "version": "4", "url": "https://files.pythonhosted.org/packages/source/p/pypi-url/pypi_url-4.tar.gz", "replacement": ["pypi_sdist_url", "pypi-url"], "normalize": null, "append": null}
+{"__class__": "PythonInlinePyPIURI", "category": "PythonFetchableCheck", "package": "python-inline-pypi-url", "version": "0", "url": "https://files.pythonhosted.org/packages/source/p/python.inline-pypi-url/python.inline-pypi-url-0.tar.gz", "replacement": ["pypi_sdist_url", "--no-normalize", "\"${PN/-/.}\""], "normalize": null, "append": null}
+{"__class__": "PythonInlinePyPIURI", "category": "PythonFetchableCheck", "package": "python-inline-pypi-url", "version": "1", "url": "https://files.pythonhosted.org/packages/source/p/python.inline.pypi.url/python.inline.pypi.url-1.tar.gz", "replacement": ["pypi_sdist_url", "--no-normalize", "\"${PN//-/.}\""], "normalize": null, "append": null}
+{"__class__": "PythonInlinePyPIURI", "category": "PythonFetchableCheck", "package": "python-inline-pypi-url", "version": "100", "url": "https://files.pythonhosted.org/packages/source/p/python_inline-pypi-url/python_inline-pypi-url-100.tar.gz", "replacement": ["pypi_sdist_url", "--no-normalize", "\"${PN/-/_}\""], "normalize": null, "append": null}
+{"__class__": "PythonInlinePyPIURI", "category": "PythonFetchableCheck", "package": "python-inline-pypi-url", "version": "200", "url": "https://files.pythonhosted.org/packages/source/P/Python-inline-pypi-url/Python-inline-pypi-url-200.tar.gz", "replacement": ["pypi_sdist_url", "--no-normalize", "\"${PN^}\""], "normalize": null, "append": null}
+{"__class__": "PythonInlinePyPIURI", "category": "PythonFetchableCheck", "package": "python-inline-pypi-url", "version": "1000", "url": "https://files.pythonhosted.org/packages/source/p/python.inline-pypi-url/python_inline_pypi_url-1000.tar.gz", "replacement": ["pypi_sdist_url", "\"${PN/-/.}\""], "normalize": null, "append": null}
+{"__class__": "PythonInlinePyPIURI", "category": "PythonFetchableCheck", "package": "python-inline-pypi-url", "version": "1000-r1", "url": "https://files.pythonhosted.org/packages/source/p/python.inline.pypi.url/python_inline_pypi_url-1000.tar.gz", "replacement": ["pypi_sdist_url", "\"${PN//-/.}\""], "normalize": null, "append": null}
+{"__class__": "PythonInlinePyPIURI", "category": "PythonFetchableCheck", "package": "python-inline-pypi-url", "version": "1000-r100", "url": "https://files.pythonhosted.org/packages/source/p/python_inline-pypi-url/python_inline_pypi_url-1000.tar.gz", "replacement": ["pypi_sdist_url", "\"${PN/-/_}\""], "normalize": null, "append": null}
+{"__class__": "PythonInlinePyPIURI", "category": "PythonFetchableCheck", "package": "python-inline-pypi-url", "version": "1000-r101", "url": "https://files.pythonhosted.org/packages/source/p/python_inline_pypi_url/python_inline_pypi_url-1000.tar.gz", "replacement": ["pypi_sdist_url", "\"${PN//-/_}\""], "normalize": null, "append": null}
+{"__class__": "PythonInlinePyPIURI", "category": "PythonFetchableCheck", "package": "python-inline-pypi-url", "version": "1000-r200", "url": "https://files.pythonhosted.org/packages/source/P/Python-inline-pypi-url/python_inline_pypi_url-1000.tar.gz", "replacement": ["pypi_sdist_url", "\"${PN^}\""], "normalize": null, "append": null}
diff --git a/testdata/data/repos/python/PythonFetchableCheck/PythonInlinePyPIURI/fix.patch b/testdata/data/repos/python/PythonFetchableCheck/PythonInlinePyPIURI/fix.patch
new file mode 100644
index 00000000..e30ff89e
--- /dev/null
+++ b/testdata/data/repos/python/PythonFetchableCheck/PythonInlinePyPIURI/fix.patch
@@ -0,0 +1,304 @@
+diff -Naur python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-0.ebuild fixed/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-0.ebuild
+--- python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-0.ebuild 2023-02-13 18:02:07.141313182 +0100
++++ fixed/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-0.ebuild 2023-02-13 18:16:47.391898323 +0100
+@@ -3,9 +3,11 @@
+
+ EAPI=8
+
++inherit pypi
++
+ DESCRIPTION="Ebuild with PyPI URL"
+ HOMEPAGE="https://example.com"
+-SRC_URI="mirror://pypi/${PN::1}/${PN/-/.}/${P/-/.}.tar.gz"
++SRC_URI="$(pypi_sdist_url --no-normalize "${PN/-/.}")"
+ S=${WORKDIR}/${P/-/.}
+
+ LICENSE="BSD"
+diff -Naur python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000.ebuild fixed/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000.ebuild
+--- python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000.ebuild 2023-02-13 18:02:37.101867819 +0100
++++ fixed/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000.ebuild 2023-02-13 18:16:52.222022177 +0100
+@@ -3,10 +3,11 @@
+
+ EAPI=8
+
++inherit pypi
++
+ DESCRIPTION="Ebuild with PyPI URL"
+ HOMEPAGE="https://example.com"
+-SRC_URI="mirror://pypi/${PN::1}/${PN/-/.}/${PN//-/_}-${PV}.tar.gz"
+-S=${WORKDIR}/${PN//-/_}-${PV}
++SRC_URI="$(pypi_sdist_url "${PN/-/.}")"
+
+ LICENSE="BSD"
+ SLOT="0"
+diff -Naur python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r100.ebuild fixed/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r100.ebuild
+--- python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r100.ebuild 2023-02-13 18:05:32.871560794 +0100
++++ fixed/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r100.ebuild 2023-02-13 18:16:55.365435891 +0100
+@@ -3,10 +3,11 @@
+
+ EAPI=8
+
++inherit pypi
++
+ DESCRIPTION="Ebuild with PyPI URL"
+ HOMEPAGE="https://example.com"
+-SRC_URI="mirror://pypi/${PN::1}/${PN/-/_}/${PN//-/_}-${PV}.tar.gz"
+-S=${WORKDIR}/${PN//-/_}-${PV}
++SRC_URI="$(pypi_sdist_url "${PN/-/_}")"
+
+ LICENSE="BSD"
+ SLOT="0"
+diff -Naur python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r101.ebuild fixed/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r101.ebuild
+--- python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r101.ebuild 2023-02-13 18:05:45.775104791 +0100
++++ fixed/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r101.ebuild 2023-02-13 18:16:57.982169331 +0100
+@@ -3,10 +3,11 @@
+
+ EAPI=8
+
++inherit pypi
++
+ DESCRIPTION="Ebuild with PyPI URL"
+ HOMEPAGE="https://example.com"
+-SRC_URI="mirror://pypi/${PN::1}/${PN//-/_}/${PN//-/_}-${PV}.tar.gz"
+-S=${WORKDIR}/${PN//-/_}-${PV}
++SRC_URI="$(pypi_sdist_url "${PN//-/_}")"
+
+ LICENSE="BSD"
+ SLOT="0"
+diff -Naur python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r1.ebuild fixed/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r1.ebuild
+--- python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r1.ebuild 2023-02-13 18:04:32.533891351 +0100
++++ fixed/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r1.ebuild 2023-02-13 18:17:01.165583737 +0100
+@@ -3,10 +3,11 @@
+
+ EAPI=8
+
++inherit pypi
++
+ DESCRIPTION="Ebuild with PyPI URL"
+ HOMEPAGE="https://example.com"
+-SRC_URI="mirror://pypi/${PN::1}/${PN//-/.}/${PN//-/_}-${PV}.tar.gz"
+-S=${WORKDIR}/${PN//-/_}-${PV}
++SRC_URI="$(pypi_sdist_url "${PN//-/.}")"
+
+ LICENSE="BSD"
+ SLOT="0"
+diff -Naur python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r200.ebuild fixed/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r200.ebuild
+--- python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r200.ebuild 2023-02-13 18:06:26.842434235 +0100
++++ fixed/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r200.ebuild 2023-02-13 18:17:04.392332387 +0100
+@@ -3,10 +3,11 @@
+
+ EAPI=8
+
++inherit pypi
++
+ DESCRIPTION="Ebuild with PyPI URL"
+ HOMEPAGE="https://example.com"
+-SRC_URI="mirror://pypi/P/${PN^}/${PN//-/_}-${PV}.tar.gz"
+-S=${WORKDIR}/${PN//-/_}-${PV}
++SRC_URI="$(pypi_sdist_url "${PN^}")"
+
+ LICENSE="BSD"
+ SLOT="0"
+diff -Naur python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-100.ebuild fixed/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-100.ebuild
+--- python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-100.ebuild 2023-02-13 18:10:56.409921917 +0100
++++ fixed/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-100.ebuild 2023-02-13 18:17:19.662717926 +0100
+@@ -3,9 +3,11 @@
+
+ EAPI=8
+
++inherit pypi
++
+ DESCRIPTION="Ebuild with PyPI URL"
+ HOMEPAGE="https://example.com"
+-SRC_URI="mirror://pypi/${PN::1}/${PN/-/_}/${P/-/_}.tar.gz"
++SRC_URI="$(pypi_sdist_url --no-normalize "${PN/-/_}")"
+ S=${WORKDIR}/${P/-/_}
+
+ LICENSE="BSD"
+diff -Naur python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1.ebuild fixed/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1.ebuild
+--- python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1.ebuild 2023-02-13 18:10:03.499125550 +0100
++++ fixed/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1.ebuild 2023-02-13 18:17:19.666051344 +0100
+@@ -3,9 +3,11 @@
+
+ EAPI=8
+
++inherit pypi
++
+ DESCRIPTION="Ebuild with PyPI URL"
+ HOMEPAGE="https://example.com"
+-SRC_URI="mirror://pypi/${PN::1}/${PN//-/.}/${PN//-/.}-${PV}.tar.gz"
++SRC_URI="$(pypi_sdist_url --no-normalize "${PN//-/.}")"
+ S=${WORKDIR}/${PN//-/.}-${PV}
+
+ LICENSE="BSD"
+diff -Naur python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-200.ebuild fixed/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-200.ebuild
+--- python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-200.ebuild 2023-02-13 18:12:05.330950479 +0100
++++ fixed/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-200.ebuild 2023-02-13 18:17:19.666051344 +0100
+@@ -3,9 +3,11 @@
+
+ EAPI=8
+
++inherit pypi
++
+ DESCRIPTION="Ebuild with PyPI URL"
+ HOMEPAGE="https://example.com"
+-SRC_URI="mirror://pypi/P/${PN^}/${P^}.tar.gz"
++SRC_URI="$(pypi_sdist_url --no-normalize "${PN^}")"
+ S=${WORKDIR}/${P^}
+
+ LICENSE="BSD"
+diff -Naur python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-0.ebuild fixed/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-0.ebuild
+--- python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-0.ebuild 2023-02-13 13:53:39.474144315 +0100
++++ fixed/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-0.ebuild 2023-02-13 18:13:52.757100032 +0100
+@@ -3,9 +3,11 @@
+
+ EAPI=8
+
++inherit pypi
++
+ DESCRIPTION="Ebuild with PyPI URL"
+ HOMEPAGE="https://example.com"
+-SRC_URI="mirror://pypi/${PN::1}/${PN}/${P}.zip"
++SRC_URI="$(pypi_sdist_url --no-normalize "${PN}" "${PV}" .zip)"
+
+ LICENSE="BSD"
+ SLOT="0"
+diff -Naur python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-1_alpha1.ebuild fixed/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-1_alpha1.ebuild
+--- python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-1_alpha1.ebuild 2023-02-13 13:45:21.784711215 +0100
++++ fixed/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-1_alpha1.ebuild 2023-02-13 18:13:52.757100032 +0100
+@@ -3,11 +3,11 @@
+
+ EAPI=8
+
+-MY_P=${P/_alpha/a}
++PYPI_NO_NORMALIZE=1
++inherit pypi
++
+ DESCRIPTION="Ebuild with PyPI URL"
+ HOMEPAGE="https://example.com"
+-SRC_URI="mirror://pypi/${PN::1}/${PN}/${MY_P}.tar.gz"
+-S=${WORKDIR}/${MY_P}
+
+ LICENSE="BSD"
+ SLOT="0"
+diff -Naur python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-1_alpha1-r1.ebuild fixed/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-1_alpha1-r1.ebuild
+--- python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-1_alpha1-r1.ebuild 2023-02-13 13:45:46.604987058 +0100
++++ fixed/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-1_alpha1-r1.ebuild 2023-02-13 18:13:52.757100032 +0100
+@@ -3,14 +3,14 @@
+
+ EAPI=8
+
+-MY_P=${P/_alpha/a}
++PYPI_NO_NORMALIZE=1
++inherit pypi
++
+ DESCRIPTION="Ebuild with PyPI URL"
+ HOMEPAGE="https://example.com"
+-SRC_URI="
+- mirror://pypi/${PN::1}/${PN}/${MY_P}.tar.gz
++SRC_URI+="
+ https://example.com/foo.patch
+ "
+-S=${WORKDIR}/${MY_P}
+
+ LICENSE="BSD"
+ SLOT="0"
+diff -Naur python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-2_p4.ebuild fixed/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-2_p4.ebuild
+--- python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-2_p4.ebuild 2023-02-13 13:46:34.949608190 +0100
++++ fixed/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-2_p4.ebuild 2023-02-13 18:13:52.757100032 +0100
+@@ -3,11 +3,10 @@
+
+ EAPI=8
+
+-MY_P=${PN,,}-${PV/_p/.post}
++inherit pypi
++
+ DESCRIPTION="Ebuild with PyPI URL"
+ HOMEPAGE="https://example.com"
+-SRC_URI="mirror://pypi/${PN::1}/${PN}/${MY_P}.tar.gz"
+-S=${WORKDIR}/${MY_P}
+
+ LICENSE="BSD"
+ SLOT="0"
+diff -Naur python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-2_p4-r1.ebuild fixed/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-2_p4-r1.ebuild
+--- python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-2_p4-r1.ebuild 2023-02-13 13:46:34.949608190 +0100
++++ fixed/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-2_p4-r1.ebuild 2023-02-13 18:13:52.757100032 +0100
+@@ -3,14 +3,13 @@
+
+ EAPI=8
+
+-MY_P=${PN,,}-${PV/_p/.post}
++inherit pypi
++
+ DESCRIPTION="Ebuild with PyPI URL"
+ HOMEPAGE="https://example.com"
+-SRC_URI="
+- mirror://pypi/${PN::1}/${PN}/${MY_P}.tar.gz
++SRC_URI+="
+ https://example.com/foo.patch
+ "
+-S=${WORKDIR}/${MY_P}
+
+ LICENSE="BSD"
+ SLOT="0"
+diff -Naur python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-3.ebuild fixed/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-3.ebuild
+--- python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-3.ebuild 2023-02-13 15:30:06.802489789 +0100
++++ fixed/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-3.ebuild 2023-02-13 18:13:52.757100032 +0100
+@@ -3,13 +3,14 @@
+
+ EAPI=8
+
++inherit pypi
++
+ MY_P=pypi-url-${PV}
+ DESCRIPTION="Ebuild with PyPI URL"
+ HOMEPAGE="https://example.com"
+ SRC_URI="
+- mirror://pypi/p/pypi-url/${MY_P}.zip
+- https://files.pythonhosted.org/packages/py3/p/pypi-url/pypi_url-${PV}-py3-none-any.whl
+- -> pypi_url-${PV}-py3-none-any.whl.zip
++ $(pypi_sdist_url --no-normalize pypi-url "${PV}" .zip)
++ $(pypi_wheel_url --unpack pypi-url)
+ "
+ S=${WORKDIR}/${MY_P}
+
+diff -Naur python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-3-r1.ebuild fixed/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-3-r1.ebuild
+--- python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-3-r1.ebuild 2023-02-13 15:24:31.819467907 +0100
++++ fixed/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-3-r1.ebuild 2023-02-13 18:13:52.757100032 +0100
+@@ -3,12 +3,14 @@
+
+ EAPI=8
+
++inherit pypi
++
+ MY_P=pypi-url-${PV}
+ DESCRIPTION="Ebuild with PyPI URL"
+ HOMEPAGE="https://example.com"
+ SRC_URI="
+- mirror://pypi/p/pypi-url/${MY_P}.tar.gz
+- https://files.pythonhosted.org/packages/py3/p/pypi-url/pypi_url-3-py3-none-any.whl
++ $(pypi_sdist_url --no-normalize pypi-url)
++ $(pypi_wheel_url pypi-url)
+ "
+ S=${WORKDIR}/${MY_P}
+
+diff -Naur python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-4.ebuild fixed/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-4.ebuild
+--- python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-4.ebuild 2023-02-13 15:30:54.598707954 +0100
++++ fixed/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-4.ebuild 2023-02-13 18:13:52.757100032 +0100
+@@ -3,12 +3,14 @@
+
+ EAPI=8
+
++inherit pypi
++
+ MY_P=pypi_url-${PV}
+ DESCRIPTION="Ebuild with PyPI URL"
+ HOMEPAGE="https://example.com"
+ SRC_URI="
+- mirror://pypi/p/pypi-url/${MY_P}.tar.gz
+- https://files.pythonhosted.org/packages/cp310/${PN::1}/${PN}/${P,,}-cp310-cp310-linux_x86_64.whl
++ $(pypi_sdist_url pypi-url)
++ $(pypi_wheel_url "${PN}" "${PV}" cp310 cp310-linux_x86_64)
+ "
+ S=${WORKDIR}/${MY_P}
+
diff --git a/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/Manifest b/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/Manifest
new file mode 100644
index 00000000..39d6377a
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/Manifest
@@ -0,0 +1,10 @@
+DIST PythonInlinePyPIURL-0.zip 153310 BLAKE2B b7484cd9bebe912f9c8877c0f09df059130c2dc5c4da8c926f8df7945bcb7b255cdf810ce8cd16a987fb5bca3d1e71c088cd894968641db5dfae1c4c059df836 SHA512 86ff9e1c4b9353b1fbb475c7bb9d2a97bd9db8421ea5190b5a84832930b34cb5b79f8c3da68a5eb8db334f06851ec129cc6611a371e47b7c5de7a615feec5e05
+DIST PythonInlinePyPIURL-1a1.tar.gz 153310 BLAKE2B b7484cd9bebe912f9c8877c0f09df059130c2dc5c4da8c926f8df7945bcb7b255cdf810ce8cd16a987fb5bca3d1e71c088cd894968641db5dfae1c4c059df836 SHA512 86ff9e1c4b9353b1fbb475c7bb9d2a97bd9db8421ea5190b5a84832930b34cb5b79f8c3da68a5eb8db334f06851ec129cc6611a371e47b7c5de7a615feec5e05
+DIST foo.patch 153310 BLAKE2B b7484cd9bebe912f9c8877c0f09df059130c2dc5c4da8c926f8df7945bcb7b255cdf810ce8cd16a987fb5bca3d1e71c088cd894968641db5dfae1c4c059df836 SHA512 86ff9e1c4b9353b1fbb475c7bb9d2a97bd9db8421ea5190b5a84832930b34cb5b79f8c3da68a5eb8db334f06851ec129cc6611a371e47b7c5de7a615feec5e05
+DIST pypi-url-3.tar.gz 153310 BLAKE2B b7484cd9bebe912f9c8877c0f09df059130c2dc5c4da8c926f8df7945bcb7b255cdf810ce8cd16a987fb5bca3d1e71c088cd894968641db5dfae1c4c059df836 SHA512 86ff9e1c4b9353b1fbb475c7bb9d2a97bd9db8421ea5190b5a84832930b34cb5b79f8c3da68a5eb8db334f06851ec129cc6611a371e47b7c5de7a615feec5e05
+DIST pypi-url-3.zip 153310 BLAKE2B b7484cd9bebe912f9c8877c0f09df059130c2dc5c4da8c926f8df7945bcb7b255cdf810ce8cd16a987fb5bca3d1e71c088cd894968641db5dfae1c4c059df836 SHA512 86ff9e1c4b9353b1fbb475c7bb9d2a97bd9db8421ea5190b5a84832930b34cb5b79f8c3da68a5eb8db334f06851ec129cc6611a371e47b7c5de7a615feec5e05
+DIST pypi_url-3-py3-none-any.whl 153310 BLAKE2B b7484cd9bebe912f9c8877c0f09df059130c2dc5c4da8c926f8df7945bcb7b255cdf810ce8cd16a987fb5bca3d1e71c088cd894968641db5dfae1c4c059df836 SHA512 86ff9e1c4b9353b1fbb475c7bb9d2a97bd9db8421ea5190b5a84832930b34cb5b79f8c3da68a5eb8db334f06851ec129cc6611a371e47b7c5de7a615feec5e05
+DIST pypi_url-3-py3-none-any.whl.zip 153310 BLAKE2B b7484cd9bebe912f9c8877c0f09df059130c2dc5c4da8c926f8df7945bcb7b255cdf810ce8cd16a987fb5bca3d1e71c088cd894968641db5dfae1c4c059df836 SHA512 86ff9e1c4b9353b1fbb475c7bb9d2a97bd9db8421ea5190b5a84832930b34cb5b79f8c3da68a5eb8db334f06851ec129cc6611a371e47b7c5de7a615feec5e05
+DIST pythoninlinepypiurl-4-cp310-cp310-linux_x86_64.whl 153310 BLAKE2B b7484cd9bebe912f9c8877c0f09df059130c2dc5c4da8c926f8df7945bcb7b255cdf810ce8cd16a987fb5bca3d1e71c088cd894968641db5dfae1c4c059df836 SHA512 86ff9e1c4b9353b1fbb475c7bb9d2a97bd9db8421ea5190b5a84832930b34cb5b79f8c3da68a5eb8db334f06851ec129cc6611a371e47b7c5de7a615feec5e05
+DIST pypi_url-4.tar.gz 153310 BLAKE2B b7484cd9bebe912f9c8877c0f09df059130c2dc5c4da8c926f8df7945bcb7b255cdf810ce8cd16a987fb5bca3d1e71c088cd894968641db5dfae1c4c059df836 SHA512 86ff9e1c4b9353b1fbb475c7bb9d2a97bd9db8421ea5190b5a84832930b34cb5b79f8c3da68a5eb8db334f06851ec129cc6611a371e47b7c5de7a615feec5e05
+DIST pythoninlinepypiurl-2.post4.tar.gz 153310 BLAKE2B b7484cd9bebe912f9c8877c0f09df059130c2dc5c4da8c926f8df7945bcb7b255cdf810ce8cd16a987fb5bca3d1e71c088cd894968641db5dfae1c4c059df836 SHA512 86ff9e1c4b9353b1fbb475c7bb9d2a97bd9db8421ea5190b5a84832930b34cb5b79f8c3da68a5eb8db334f06851ec129cc6611a371e47b7c5de7a615feec5e05
diff --git a/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-0.ebuild b/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-0.ebuild
new file mode 100644
index 00000000..e37d2061
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-0.ebuild
@@ -0,0 +1,15 @@
+# Copyright 2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+DESCRIPTION="Ebuild with PyPI URL"
+HOMEPAGE="https://example.com"
+SRC_URI="mirror://pypi/${PN::1}/${PN}/${P}.zip"
+
+LICENSE="BSD"
+SLOT="0"
+
+BDEPEND="
+ app-arch/unzip
+"
diff --git a/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-1_alpha1-r1.ebuild b/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-1_alpha1-r1.ebuild
new file mode 100644
index 00000000..ef9e9a25
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-1_alpha1-r1.ebuild
@@ -0,0 +1,16 @@
+# Copyright 2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MY_P=${P/_alpha/a}
+DESCRIPTION="Ebuild with PyPI URL"
+HOMEPAGE="https://example.com"
+SRC_URI="
+ mirror://pypi/${PN::1}/${PN}/${MY_P}.tar.gz
+ https://example.com/foo.patch
+"
+S=${WORKDIR}/${MY_P}
+
+LICENSE="BSD"
+SLOT="0"
diff --git a/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-1_alpha1.ebuild b/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-1_alpha1.ebuild
new file mode 100644
index 00000000..ed737716
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-1_alpha1.ebuild
@@ -0,0 +1,13 @@
+# Copyright 2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MY_P=${P/_alpha/a}
+DESCRIPTION="Ebuild with PyPI URL"
+HOMEPAGE="https://example.com"
+SRC_URI="mirror://pypi/${PN::1}/${PN}/${MY_P}.tar.gz"
+S=${WORKDIR}/${MY_P}
+
+LICENSE="BSD"
+SLOT="0"
diff --git a/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-2_p4-r1.ebuild b/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-2_p4-r1.ebuild
new file mode 100644
index 00000000..88b8ab43
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-2_p4-r1.ebuild
@@ -0,0 +1,16 @@
+# Copyright 2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MY_P=${PN,,}-${PV/_p/.post}
+DESCRIPTION="Ebuild with PyPI URL"
+HOMEPAGE="https://example.com"
+SRC_URI="
+ mirror://pypi/${PN::1}/${PN}/${MY_P}.tar.gz
+ https://example.com/foo.patch
+"
+S=${WORKDIR}/${MY_P}
+
+LICENSE="BSD"
+SLOT="0"
diff --git a/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-2_p4.ebuild b/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-2_p4.ebuild
new file mode 100644
index 00000000..3ff2d8bf
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-2_p4.ebuild
@@ -0,0 +1,13 @@
+# Copyright 2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MY_P=${PN,,}-${PV/_p/.post}
+DESCRIPTION="Ebuild with PyPI URL"
+HOMEPAGE="https://example.com"
+SRC_URI="mirror://pypi/${PN::1}/${PN}/${MY_P}.tar.gz"
+S=${WORKDIR}/${MY_P}
+
+LICENSE="BSD"
+SLOT="0"
diff --git a/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-3-r1.ebuild b/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-3-r1.ebuild
new file mode 100644
index 00000000..b6232cee
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-3-r1.ebuild
@@ -0,0 +1,16 @@
+# Copyright 2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MY_P=pypi-url-${PV}
+DESCRIPTION="Ebuild with PyPI URL"
+HOMEPAGE="https://example.com"
+SRC_URI="
+ mirror://pypi/p/pypi-url/${MY_P}.tar.gz
+ https://files.pythonhosted.org/packages/py3/p/pypi-url/pypi_url-3-py3-none-any.whl
+"
+S=${WORKDIR}/${MY_P}
+
+LICENSE="BSD"
+SLOT="0"
diff --git a/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-3.ebuild b/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-3.ebuild
new file mode 100644
index 00000000..ffa836be
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-3.ebuild
@@ -0,0 +1,21 @@
+# Copyright 2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MY_P=pypi-url-${PV}
+DESCRIPTION="Ebuild with PyPI URL"
+HOMEPAGE="https://example.com"
+SRC_URI="
+ mirror://pypi/p/pypi-url/${MY_P}.zip
+ https://files.pythonhosted.org/packages/py3/p/pypi-url/pypi_url-${PV}-py3-none-any.whl
+ -> pypi_url-${PV}-py3-none-any.whl.zip
+"
+S=${WORKDIR}/${MY_P}
+
+LICENSE="BSD"
+SLOT="0"
+
+BDEPEND="
+ app-arch/unzip
+"
diff --git a/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-4.ebuild b/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-4.ebuild
new file mode 100644
index 00000000..606bb4bc
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/PythonInlinePyPIURL-4.ebuild
@@ -0,0 +1,16 @@
+# Copyright 2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MY_P=pypi_url-${PV}
+DESCRIPTION="Ebuild with PyPI URL"
+HOMEPAGE="https://example.com"
+SRC_URI="
+ mirror://pypi/p/pypi-url/${MY_P}.tar.gz
+ https://files.pythonhosted.org/packages/cp310/${PN::1}/${PN}/${P,,}-cp310-cp310-linux_x86_64.whl
+"
+S=${WORKDIR}/${MY_P}
+
+LICENSE="BSD"
+SLOT="0"
diff --git a/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/metadata.xml b/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/metadata.xml
new file mode 100644
index 00000000..74fae2ac
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/PythonInlinePyPIURL/metadata.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+ <upstream>
+ <remote-id type="pypi">frobnicate</remote-id>
+ </upstream>
+</pkgmetadata>
diff --git a/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/Manifest b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/Manifest
new file mode 100644
index 00000000..d541566b
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/Manifest
@@ -0,0 +1,5 @@
+DIST python.inline-pypi-url-0.tar.gz 153310 BLAKE2B b7484cd9bebe912f9c8877c0f09df059130c2dc5c4da8c926f8df7945bcb7b255cdf810ce8cd16a987fb5bca3d1e71c088cd894968641db5dfae1c4c059df836 SHA512 86ff9e1c4b9353b1fbb475c7bb9d2a97bd9db8421ea5190b5a84832930b34cb5b79f8c3da68a5eb8db334f06851ec129cc6611a371e47b7c5de7a615feec5e05
+DIST python.inline.pypi.url-1.tar.gz 153310 BLAKE2B b7484cd9bebe912f9c8877c0f09df059130c2dc5c4da8c926f8df7945bcb7b255cdf810ce8cd16a987fb5bca3d1e71c088cd894968641db5dfae1c4c059df836 SHA512 86ff9e1c4b9353b1fbb475c7bb9d2a97bd9db8421ea5190b5a84832930b34cb5b79f8c3da68a5eb8db334f06851ec129cc6611a371e47b7c5de7a615feec5e05
+DIST python_inline-pypi-url-100.tar.gz 153310 BLAKE2B b7484cd9bebe912f9c8877c0f09df059130c2dc5c4da8c926f8df7945bcb7b255cdf810ce8cd16a987fb5bca3d1e71c088cd894968641db5dfae1c4c059df836 SHA512 86ff9e1c4b9353b1fbb475c7bb9d2a97bd9db8421ea5190b5a84832930b34cb5b79f8c3da68a5eb8db334f06851ec129cc6611a371e47b7c5de7a615feec5e05
+DIST Python-inline-pypi-url-200.tar.gz 153310 BLAKE2B b7484cd9bebe912f9c8877c0f09df059130c2dc5c4da8c926f8df7945bcb7b255cdf810ce8cd16a987fb5bca3d1e71c088cd894968641db5dfae1c4c059df836 SHA512 86ff9e1c4b9353b1fbb475c7bb9d2a97bd9db8421ea5190b5a84832930b34cb5b79f8c3da68a5eb8db334f06851ec129cc6611a371e47b7c5de7a615feec5e05
+DIST python_inline_pypi_url-1000.tar.gz 153310 BLAKE2B b7484cd9bebe912f9c8877c0f09df059130c2dc5c4da8c926f8df7945bcb7b255cdf810ce8cd16a987fb5bca3d1e71c088cd894968641db5dfae1c4c059df836 SHA512 86ff9e1c4b9353b1fbb475c7bb9d2a97bd9db8421ea5190b5a84832930b34cb5b79f8c3da68a5eb8db334f06851ec129cc6611a371e47b7c5de7a615feec5e05
diff --git a/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/metadata.xml b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/metadata.xml
new file mode 100644
index 00000000..74fae2ac
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/metadata.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+ <upstream>
+ <remote-id type="pypi">frobnicate</remote-id>
+ </upstream>
+</pkgmetadata>
diff --git a/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-0.ebuild b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-0.ebuild
new file mode 100644
index 00000000..2fb8d24e
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-0.ebuild
@@ -0,0 +1,12 @@
+# Copyright 2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+DESCRIPTION="Ebuild with PyPI URL"
+HOMEPAGE="https://example.com"
+SRC_URI="mirror://pypi/${PN::1}/${PN/-/.}/${P/-/.}.tar.gz"
+S=${WORKDIR}/${P/-/.}
+
+LICENSE="BSD"
+SLOT="0"
diff --git a/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1.ebuild b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1.ebuild
new file mode 100644
index 00000000..983d264f
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1.ebuild
@@ -0,0 +1,12 @@
+# Copyright 2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+DESCRIPTION="Ebuild with PyPI URL"
+HOMEPAGE="https://example.com"
+SRC_URI="mirror://pypi/${PN::1}/${PN//-/.}/${PN//-/.}-${PV}.tar.gz"
+S=${WORKDIR}/${PN//-/.}-${PV}
+
+LICENSE="BSD"
+SLOT="0"
diff --git a/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-100.ebuild b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-100.ebuild
new file mode 100644
index 00000000..34189990
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-100.ebuild
@@ -0,0 +1,12 @@
+# Copyright 2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+DESCRIPTION="Ebuild with PyPI URL"
+HOMEPAGE="https://example.com"
+SRC_URI="mirror://pypi/${PN::1}/${PN/-/_}/${P/-/_}.tar.gz"
+S=${WORKDIR}/${P/-/_}
+
+LICENSE="BSD"
+SLOT="0"
diff --git a/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r1.ebuild b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r1.ebuild
new file mode 100644
index 00000000..4528e886
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r1.ebuild
@@ -0,0 +1,12 @@
+# Copyright 2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+DESCRIPTION="Ebuild with PyPI URL"
+HOMEPAGE="https://example.com"
+SRC_URI="mirror://pypi/${PN::1}/${PN//-/.}/${PN//-/_}-${PV}.tar.gz"
+S=${WORKDIR}/${PN//-/_}-${PV}
+
+LICENSE="BSD"
+SLOT="0"
diff --git a/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r100.ebuild b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r100.ebuild
new file mode 100644
index 00000000..3b9ef524
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r100.ebuild
@@ -0,0 +1,12 @@
+# Copyright 2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+DESCRIPTION="Ebuild with PyPI URL"
+HOMEPAGE="https://example.com"
+SRC_URI="mirror://pypi/${PN::1}/${PN/-/_}/${PN//-/_}-${PV}.tar.gz"
+S=${WORKDIR}/${PN//-/_}-${PV}
+
+LICENSE="BSD"
+SLOT="0"
diff --git a/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r101.ebuild b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r101.ebuild
new file mode 100644
index 00000000..24c7fa9d
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r101.ebuild
@@ -0,0 +1,12 @@
+# Copyright 2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+DESCRIPTION="Ebuild with PyPI URL"
+HOMEPAGE="https://example.com"
+SRC_URI="mirror://pypi/${PN::1}/${PN//-/_}/${PN//-/_}-${PV}.tar.gz"
+S=${WORKDIR}/${PN//-/_}-${PV}
+
+LICENSE="BSD"
+SLOT="0"
diff --git a/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r200.ebuild b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r200.ebuild
new file mode 100644
index 00000000..543eda6e
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000-r200.ebuild
@@ -0,0 +1,12 @@
+# Copyright 2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+DESCRIPTION="Ebuild with PyPI URL"
+HOMEPAGE="https://example.com"
+SRC_URI="mirror://pypi/P/${PN^}/${PN//-/_}-${PV}.tar.gz"
+S=${WORKDIR}/${PN//-/_}-${PV}
+
+LICENSE="BSD"
+SLOT="0"
diff --git a/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000.ebuild b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000.ebuild
new file mode 100644
index 00000000..07e3a6dd
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-1000.ebuild
@@ -0,0 +1,12 @@
+# Copyright 2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+DESCRIPTION="Ebuild with PyPI URL"
+HOMEPAGE="https://example.com"
+SRC_URI="mirror://pypi/${PN::1}/${PN/-/.}/${PN//-/_}-${PV}.tar.gz"
+S=${WORKDIR}/${PN//-/_}-${PV}
+
+LICENSE="BSD"
+SLOT="0"
diff --git a/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-200.ebuild b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-200.ebuild
new file mode 100644
index 00000000..e2a5eeb8
--- /dev/null
+++ b/testdata/repos/python/PythonFetchableCheck/python-inline-pypi-url/python-inline-pypi-url-200.ebuild
@@ -0,0 +1,12 @@
+# Copyright 2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+DESCRIPTION="Ebuild with PyPI URL"
+HOMEPAGE="https://example.com"
+SRC_URI="mirror://pypi/P/${PN^}/${P^}.tar.gz"
+S=${WORKDIR}/${P^}
+
+LICENSE="BSD"
+SLOT="0"
diff --git a/testdata/repos/python/app-arch/unzip/unzip-0.ebuild b/testdata/repos/python/app-arch/unzip/unzip-0.ebuild
new file mode 100644
index 00000000..0b7766f5
--- /dev/null
+++ b/testdata/repos/python/app-arch/unzip/unzip-0.ebuild
@@ -0,0 +1,4 @@
+DESCRIPTION="Stub unzip package to suppress NonexistentDeps results"
+HOMEPAGE="https://github.com/pkgcore/pkgcheck"
+SLOT="0"
+LICENSE="BSD"
diff --git a/testdata/repos/python/eclass/pypi.eclass b/testdata/repos/python/eclass/pypi.eclass
new file mode 100644
index 00000000..af21dc7f
--- /dev/null
+++ b/testdata/repos/python/eclass/pypi.eclass
@@ -0,0 +1,107 @@
+# Copyright 2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: pypi.eclass
+# @MAINTAINER:
+# Michał Górny <mgorny@gentoo.org>
+# @AUTHOR:
+# Michał Górny <mgorny@gentoo.org>
+# @SUPPORTED_EAPIS: 7 8
+
+# @ECLASS_VARIABLE: PYPI_NO_NORMALIZE
+# @PRE_INHERIT
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+
+# @FUNCTION: pypi_normalize_name
+# @USAGE: <name>
+# @DESCRIPTION:
+# Normalize the project name according to sdist/wheel normalization
+# rules. That is, convert to lowercase and replace runs of [._-]
+# with a single underscore.
+#
+# Based on the spec, as of 2023-02-10:
+# https://packaging.python.org/en/latest/specifications/#package-distribution-file-formats
+pypi_normalize_name() {
+ local name=${1}
+ shopt -s extglob
+ name=${name//+([._-])/_}
+ echo "${name,,}"
+}
+
+# @FUNCTION: pypi_translate_version
+# @USAGE: <version>
+# @DESCRIPTION:
+# Translate the specified Gentoo version into the usual Python
+# counterpart. Assumes PEP 440 versions.
+#
+# Note that we do not have clear counterparts for the epoch segment,
+# nor for development release segment.
+pypi_translate_version() {
+ local version=${1}
+ version=${version/_alpha/a}
+ version=${version/_beta/b}
+ version=${version/_rc/rc}
+ version=${version/_p/.post}
+ echo "${version}"
+}
+
+# @FUNCTION: pypi_sdist_url
+# @USAGE: [--no-normalize] [<project> [<version> [<suffix>]]]
+# @DESCRIPTION:
+pypi_sdist_url() {
+ local normalize=1
+ if [[ ${1} == --no-normalize ]]; then
+ normalize=
+ shift
+ fi
+
+ local project=${1-"${PN}"}
+ local version=${2-"$(pypi_translate_version "${PV}")"}
+ local suffix=${3-.tar.gz}
+ local fn_project=${project}
+ [[ ${normalize} ]] && fn_project=$(pypi_normalize_name "${project}")
+ printf "https://files.pythonhosted.org/packages/source/%s" \
+ "${project::1}/${project}/${fn_project}-${version}${suffix}"
+}
+
+# @FUNCTION: pypi_wheel_name
+# @USAGE: [<project> [<version> [<python-tag> [<abi-platform-tag>]]]]
+# @DESCRIPTION:
+pypi_wheel_name() {
+ local project=$(pypi_normalize_name "${1-"${PN}"}")
+ local version=${2-"$(pypi_translate_version "${PV}")"}
+ local pytag=${3-py3}
+ local abitag=${4-none-any}
+ echo "${project}-${version}-${pytag}-${abitag}.whl"
+}
+
+# @FUNCTION: pypi_wheel_url
+# @USAGE: [--unpack] [<project> [<version> [<python-tag> [<abi-platform-tag>]]]]
+# @DESCRIPTION:
+pypi_wheel_url() {
+ local unpack=
+ if [[ ${1} == --unpack ]]; then
+ unpack=1
+ shift
+ fi
+
+ local filename=$(pypi_wheel_name "${@}")
+ local project=${1-"${PN}"}
+ local version=${2-"$(pypi_translate_version "${PV}")"}
+ local pytag=${3-py3}
+ printf "https://files.pythonhosted.org/packages/%s" \
+ "${pytag}/${project::1}/${project}/${filename}"
+
+ if [[ ${unpack} ]]; then
+ echo " -> ${filename}.zip"
+ fi
+}
+
+if [[ ${PYPI_NO_NORMALIZE} ]]; then
+ SRC_URI="$(pypi_sdist_url --no-normalize)"
+ S="${WORKDIR}/${PN}-$(pypi_translate_version "${PV}")"
+else
+ SRC_URI="$(pypi_sdist_url)"
+ S="${WORKDIR}/$(pypi_normalize_name "${PN}")-$(pypi_translate_version "${PV}")"
+fi
diff --git a/testdata/repos/python/metadata/stubs b/testdata/repos/python/metadata/stubs
index 466e30c2..7a9e32b7 100644
--- a/testdata/repos/python/metadata/stubs
+++ b/testdata/repos/python/metadata/stubs
@@ -1 +1,2 @@
+app-arch/unzip
dev-lang/python
diff --git a/testdata/repos/python/profiles/thirdpartymirrors b/testdata/repos/python/profiles/thirdpartymirrors
new file mode 100644
index 00000000..1605d348
--- /dev/null
+++ b/testdata/repos/python/profiles/thirdpartymirrors
@@ -0,0 +1 @@
+pypi https://files.pythonhosted.org/packages/source