From e555ab1b1bba047830f3d2f3ab0348a5faa44c0f Mon Sep 17 00:00:00 2001 From: Ee Durbin Date: Wed, 23 Oct 2024 10:28:01 -0400 Subject: [PATCH] harmonize with the definition of "root license directory"/"license directory" from PEP 639 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > The directory under which license files are stored in a project source tree, distribution archive or installed project. Also, the root directory that their paths recorded in the License-File Core Metadata field are relative to. Defined to be the project root directory for a project source tree or source distribution; and a subdirectory named licenses of the directory containing the built metadata— i.e., the .dist-info/licenses directory— for a Built Distribution or installed project. --- tests/unit/forklift/test_legacy.py | 30 +++++++++++++++++------------- warehouse/forklift/legacy.py | 19 +++++++++++-------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/tests/unit/forklift/test_legacy.py b/tests/unit/forklift/test_legacy.py index 4c0262548b26..3459311aa81d 100644 --- a/tests/unit/forklift/test_legacy.py +++ b/tests/unit/forklift/test_legacy.py @@ -73,8 +73,8 @@ def _get_tar_testdata(compression_type=""): temp_f = io.BytesIO() with tarfile.open(fileobj=temp_f, mode=f"w:{compression_type}") as tar: tar.add("/dev/null", arcname="fake_package/PKG-INFO") - tar.add("/dev/null", arcname="licenses/LICENSE.MIT") - tar.add("/dev/null", arcname="licenses/LICENSE.APACHE") + tar.add("/dev/null", arcname="LICENSE.MIT") + tar.add("/dev/null", arcname="LICENSE.APACHE") return temp_f.getvalue() @@ -82,8 +82,8 @@ def _get_zip_testdata(): temp_f = io.BytesIO() with zipfile.ZipFile(file=temp_f, mode="w") as zfp: zfp.writestr("fake_package/PKG-INFO", "Fake PKG-INFO") - zfp.writestr("licenses/LICENSE.MIT", "Fake License") - zfp.writestr("licenses/LICENSE.APACHE", "Fake License") + zfp.writestr("LICENSE.MIT", "Fake License") + zfp.writestr("LICENSE.APACHE", "Fake License") return temp_f.getvalue() @@ -91,8 +91,10 @@ def _get_whl_testdata(name="fake_package", version="1.0"): temp_f = io.BytesIO() with zipfile.ZipFile(file=temp_f, mode="w") as zfp: zfp.writestr(f"{name}-{version}.dist-info/METADATA", "Fake metadata") - zfp.writestr("licenses/LICENSE.MIT", "Fake License") - zfp.writestr("licenses/LICENSE.APACHE", "Fake License") + zfp.writestr(f"{name}-{version}.dist-info/licenses/LICENSE.MIT", "Fake License") + zfp.writestr( + f"{name}-{version}.dist-info/licenses/LICENSE.APACHE", "Fake License" + ) return temp_f.getvalue() @@ -4773,8 +4775,8 @@ def test_upload_succeeds_creates_release_metadata_2_4( db_request.POST.extend( [ ("license_expression", "MIT OR Apache-2.0"), - ("license_files", "licenses/LICENSE.APACHE"), - ("license_files", "licenses/LICENSE.MIT"), + ("license_files", "LICENSE.APACHE"), + ("license_files", "LICENSE.MIT"), ] ) if filetype == "bdist_wheel": @@ -4804,8 +4806,8 @@ def test_upload_succeeds_creates_release_metadata_2_4( assert release.uploaded_via == "warehouse-tests/6.6.6" assert release.license_expression == "MIT OR Apache-2.0" assert set(release.license_files) == { - "licenses/LICENSE.APACHE", - "licenses/LICENSE.MIT", + "LICENSE.APACHE", + "LICENSE.MIT", } # Ensure that a File object has been created. @@ -4852,11 +4854,13 @@ def test_upload_fails_missing_license_file_metadata_2_4( filename = "{}-{}.zip".format(project.name, "1.0") digest = _ZIP_PKG_MD5 data = _ZIP_PKG_TESTDATA + license_filename = "LICENSE" elif filetype == "bdist_wheel": filename = "{}-{}-py3-none-any.whl".format(project.name, "1.0") data = _get_whl_testdata(name=project.name, version="1.0") digest = hashlib.md5(data).hexdigest() monkeypatch.setattr(legacy, "_is_valid_dist_file", lambda *a, **kw: True) + license_filename = f"{project.name}-1.0.dist-info/licenses/LICENSE" pyramid_config.testing_securitypolicy(identity=user) db_request.user = user @@ -4879,8 +4883,8 @@ def test_upload_fails_missing_license_file_metadata_2_4( db_request.POST.extend( [ ("license_expression", "MIT OR Apache-2.0"), - ("license_files", "licenses/LICENSE"), # Does not exist in test data - ("license_files", "licenses/LICENSE.MIT"), + ("license_files", "LICENSE"), # Does not exist in test data + ("license_files", "LICENSE.MIT"), ] ) if filetype == "bdist_wheel": @@ -4899,7 +4903,7 @@ def test_upload_fails_missing_license_file_metadata_2_4( assert resp.status_code == 400 assert resp.status == ( - "400 License-File licenses/LICENSE does not exist " + f"400 License-File {license_filename} does not exist " f"in distribution file {filename}" ) diff --git a/warehouse/forklift/legacy.py b/warehouse/forklift/legacy.py index fa64c051f50a..120bd12354a1 100644 --- a/warehouse/forklift/legacy.py +++ b/warehouse/forklift/legacy.py @@ -1061,7 +1061,7 @@ def file_upload(request): with zipfile.ZipFile(temporary_filename) as zfp: for license_file in meta.license_files: try: - _ = zfp.read(license_file) + zfp.read(license_file) except KeyError: raise _exc_with_message( HTTPBadRequest, @@ -1176,6 +1176,11 @@ def file_upload(request): ) filename = os.path.basename(temporary_filename) + # Get the name and version from the original filename. Eventually this + # should use packaging.utils.parse_wheel_filename(filename), but until then + # we can't use this as it adds additional normailzation to the project name + # and version. + name, version, _ = filename.split("-", 2) if meta.license_files and packaging.version.Version( meta.metadata_version @@ -1186,12 +1191,15 @@ def file_upload(request): """ with zipfile.ZipFile(temporary_filename) as zfp: for license_file in meta.license_files: + license_filename = ( + f"{name}-{version}.dist-info/licenses/{license_file}" + ) try: - _ = zfp.read(license_file) + zfp.read(license_filename) except KeyError: raise _exc_with_message( HTTPBadRequest, - f"License-File {license_file} does not exist in " + f"License-File {license_filename} does not exist in " f"distribution file {filename}", ) @@ -1200,11 +1208,6 @@ def file_upload(request): The name of the .whl file is used to find the corresponding .dist-info dir. See https://peps.python.org/pep-0491/#file-contents """ - # Get the name and version from the original filename. Eventually this - # should use packaging.utils.parse_wheel_filename(filename), but until then - # we can't use this as it adds additional normailzation to the project name - # and version. - name, version, _ = filename.split("-", 2) metadata_filename = f"{name}-{version}.dist-info/METADATA" try: with zipfile.ZipFile(temporary_filename) as zfp: