From 937be2a10295c2c9fe4b3fa040f330a3de958e90 Mon Sep 17 00:00:00 2001 From: Kareem Samy Date: Tue, 24 Feb 2026 08:25:55 +0200 Subject: [PATCH 1/2] Collect WHEEL files for installed python wheels #4214 Parse the WHEEL file in .dist-info directories to extract wheel tags needed to reconstruct the original wheel filename for building more detailed PURLs. Changes: - Add parse_wheel_tags() to parse .dist-info/WHEEL files - Add reconstruct_wheel_filename() to rebuild wheel filenames - Modify parse_metadata() to collect wheel data into extra_data - Add new test fixtures and tests for wheel tag collection - Update existing expected test JSONs with wheel tag data Signed-off-by: Kareem Samy --- AUTHORS.rst | 1 + CHANGELOG.rst | 5 + src/packagedcode/pypi.py | 90 +- .../beartype-0.17.2-expected.json | 873 +---------- .../pypi/metadata/v22/PKG-INFO-expected.json | 634 ++++---- .../pypi/metadata/v23/PKG-INFO-expected.json | 310 ++-- .../pip-20.2.2.dist-info-expected.json | 9 +- .../site-packages/site-packages-expected.json | 34 +- .../daglib_wheel_extracted-expected.json | 16 +- .../Jinja2-2.10.dist-info-expected.json | 10 +- ...on_mimeparse-1.6.0.dist-info-expected.json | 9 +- .../toml-0.10.1.dist-info-expected.json | 10 +- .../urllib3-1.26.4.dist-info-expected.json | 9 +- .../haruka_bot-1.2.3.dist-info-expected.json | 8 +- ...plugincode-21.1.21.dist-info-expected.json | 9 +- .../anonapi-0.0.19.dist-info-expected.json | 10 +- .../trimesh-4.6.1.dist-info-expected.json | 1204 +++++++-------- .../narwhals-1.29.0.dist-info-expected.json | 1352 ++++++++--------- ...ryptography-41.0.0.dist-info-expected.json | 85 ++ .../cryptography-41.0.0.dist-info/METADATA | 7 + .../cryptography-41.0.0.dist-info/WHEEL | 5 + .../no-wheel-1.0.0.dist-info-expected.json | 69 + .../no-wheel-1.0.0.dist-info/METADATA | 5 + .../numpy-1.23.0.dist-info-expected.json | 84 + .../numpy-1.23.0.dist-info/METADATA | 7 + .../numpy-1.23.0.dist-info/WHEEL | 4 + .../requests-2.28.0.dist-info-expected.json | 84 + .../requests-2.28.0.dist-info/METADATA | 7 + .../requests-2.28.0.dist-info/WHEEL | 4 + tests/packagedcode/test_pypi.py | 111 ++ 30 files changed, 2427 insertions(+), 2638 deletions(-) create mode 100644 tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/cryptography-41.0.0.dist-info-expected.json create mode 100644 tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/cryptography-41.0.0.dist-info/METADATA create mode 100644 tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/cryptography-41.0.0.dist-info/WHEEL create mode 100644 tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/no-wheel-1.0.0.dist-info-expected.json create mode 100644 tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/no-wheel-1.0.0.dist-info/METADATA create mode 100644 tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/numpy-1.23.0.dist-info-expected.json create mode 100644 tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/numpy-1.23.0.dist-info/METADATA create mode 100644 tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/numpy-1.23.0.dist-info/WHEEL create mode 100644 tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/requests-2.28.0.dist-info-expected.json create mode 100644 tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/requests-2.28.0.dist-info/METADATA create mode 100644 tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/requests-2.28.0.dist-info/WHEEL diff --git a/AUTHORS.rst b/AUTHORS.rst index 75b0533f921..bbc1bb509ab 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -105,3 +105,4 @@ The following organizations or individuals have contributed to ScanCode: - Yash Sharma @yasharmaster - Yunus Rahbar @yns88 - Stefano Zacchiroli @zacchiro +- Kareem Samy @kaokab33 diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d115cda4b80..afd1207042b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,11 @@ Changelog Next release -------------- +- Collect WHEEL files for installed python wheels to extract + wheel tags needed to reconstruct the original wheel filename + for building more detailed PURLs. + https://github.com/aboutcode-org/scancode-toolkit/issues/4214 + v3.5.0 - 2026-01-15 ------------------- diff --git a/src/packagedcode/pypi.py b/src/packagedcode/pypi.py index b5588ed7ca9..5c2e93a59a2 100644 --- a/src/packagedcode/pypi.py +++ b/src/packagedcode/pypi.py @@ -956,6 +956,72 @@ def parse(cls, location, package_only=False): META_DIR_SUFFIXES = '.dist-info', '.egg-info', 'EGG-INFO', +def parse_wheel_tags(dist_info_path): + """ + Parse the WHEEL file in a .dist-info directory and return a list + of tag strings (e.g., ['cp310-cp310-manylinux_2_17_x86_64']). + + A WHEEL file looks like: + Wheel-Version: 1.0 + Generator: bdist_wheel (0.37.1) + Root-Is-Purelib: false + Tag: cp310-cp310-manylinux_2_17_x86_64 + + There can be multiple Tag: lines. + """ + tags = [] + wheel_version = None + generator = None + root_is_purelib = None + + if isinstance(dist_info_path, ZipPath): + wheel_path = dist_info_path / 'WHEEL' + if not wheel_path.exists(): + return {} + content = wheel_path.read_text(encoding='utf-8') + else: + wheel_path = Path(dist_info_path) / 'WHEEL' + if not wheel_path.exists(): + return {} + content = wheel_path.read_text(encoding='utf-8') + + for line in content.strip().splitlines(): + line = line.strip() + if not line or ':' not in line: + continue + + key, _, value = line.partition(':') + key = key.strip() + value = value.strip() + + if key == 'Tag': + tags.append(value) + elif key == 'Wheel-Version': + wheel_version = value + elif key == 'Generator': + generator = value + elif key == 'Root-Is-Purelib': + root_is_purelib = value.lower() == 'true' + + return { + 'wheel_version': wheel_version, + 'generator': generator, + 'root_is_purelib': root_is_purelib, + 'tags': tags, + } + +def reconstruct_wheel_filename(name, version, tag): + """ + Reconstruct a wheel filename from a package name, version, and tag string. + + For example: + >>> reconstruct_wheel_filename('numpy', '1.23.0', 'cp310-cp310-manylinux_2_17_x86_64') + 'numpy-1.23.0-cp310-cp310-manylinux_2_17_x86_64.whl' + >>> reconstruct_wheel_filename('my-package', '2.0', 'py3-none-any') + 'my_package-2.0-py3-none-any.whl' + """ + safe_name = name.replace('-', '_') + return f"{safe_name}-{version}-{tag}.whl" def parse_metadata(location, datasource_id, package_type, package_only=False): """ @@ -993,7 +1059,28 @@ def parse_metadata(location, datasource_id, package_type, package_only=False): # nicely? dependencies = get_dist_dependencies(dist) file_references = list(get_file_references(dist)) - + + # ============= NEW CODE START ============= + wheel_data = {} + if parent.name.endswith('.dist-info') and not isinstance(path, ZipPath): + wheel_data = parse_wheel_tags(path) + + wheel_filename = None + if wheel_data and wheel_data.get('tags') and name and version: + # Use the first tag to reconstruct the filename + first_tag = wheel_data['tags'][0] + wheel_filename = reconstruct_wheel_filename(name, version, first_tag) + + # Store all wheel metadata in extra_data + if wheel_data.get('tags'): + extra_data['wheel_tags'] = wheel_data['tags'] + if wheel_data.get('wheel_version'): + extra_data['wheel_version'] = wheel_data['wheel_version'] + if wheel_data.get('generator'): + extra_data['wheel_generator'] = wheel_data['generator'] + if wheel_data.get('root_is_purelib') is not None: + extra_data['root_is_purelib'] = wheel_data['root_is_purelib'] + package_data = dict( datasource_id=datasource_id, type=package_type, @@ -1011,7 +1098,6 @@ def parse_metadata(location, datasource_id, package_type, package_only=False): ) return models.PackageData.from_data(package_data, package_only) - def urlsafe_b64decode(data): """ urlsafe_b64decode without padding diff --git a/tests/packagedcode/data/license_detection/reference-to-license-beside-manifest/beartype-0.17.2-expected.json b/tests/packagedcode/data/license_detection/reference-to-license-beside-manifest/beartype-0.17.2-expected.json index 893e3e55a67..2ea3219795d 100644 --- a/tests/packagedcode/data/license_detection/reference-to-license-beside-manifest/beartype-0.17.2-expected.json +++ b/tests/packagedcode/data/license_detection/reference-to-license-beside-manifest/beartype-0.17.2-expected.json @@ -1,872 +1 @@ -{ - "packages": [ - { - "type": "pypi", - "namespace": null, - "name": "beartype", - "version": "0.17.2", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Unbearably fast runtime type checking in pure Python.\n.. # ------------------( LICENSE )------------------\n.. # Copyright (c) 2014-2024 Beartype authors.\n.. # See \"LICENSE\" for further details.\n.. #\n\n**Beartype** is an open-source pure-Python PEP-compliant near-real-time\nhybrid runtime-static third-generation type checker emphasizing efficiency,\nusability, unsubstantiated jargon we just made up, and thrilling puns.", - "release_date": null, - "parties": [ - { - "type": "person", - "role": "author", - "name": "Cecil Curry, et al.", - "email": "leycec@gmail.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Cecil Curry, et al.", - "email": "leycec@gmail.com", - "url": null - } - ], - "keywords": [ - "type checking", - "type hints", - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers" - ], - "homepage_url": "https://beartype.readthedocs.io", - "download_url": null, - "size": null, - "sha1": null, - "md5": null, - "sha256": null, - "sha512": null, - "bug_tracking_url": "https://github.com/beartype/beartype/issues", - "code_view_url": "https://github.com/beartype/beartype", - "vcs_url": null, - "copyright": null, - "holder": null, - "declared_license_expression": "mit", - "declared_license_expression_spdx": "MIT", - "license_detections": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "matches": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", - "start_line": 1, - "end_line": 1, - "matcher": "1-spdx-id", - "score": 100.0, - "matched_length": 1, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "spdx-license-identifier-mit-5da48780aba670b0860c46d899ed42a0f243ff06", - "rule_url": null, - "matched_text": "MIT" - } - ], - "identifier": "mit-a822f434-d61f-f2b1-c792-8b8cb9e7b9bf" - }, - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "matches": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", - "start_line": 1, - "end_line": 1, - "matcher": "1-hash", - "score": 100.0, - "matched_length": 5, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "pypi_mit_license.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_mit_license.RULE", - "matched_text": "- 'License :: OSI Approved :: MIT License'" - } - ], - "identifier": "mit-24a5293c-14d7-5403-efac-1a8b7532c0e8" - } - ], - "other_license_expression": null, - "other_license_expression_spdx": null, - "other_license_detections": [], - "extracted_license_statement": "license: MIT\nclassifiers:\n - 'License :: OSI Approved :: MIT License'\n", - "notice_text": null, - "source_packages": [], - "is_private": false, - "is_virtual": false, - "extra_data": { - "Documentation": "https://beartype.readthedocs.io", - "Forums": "https://github.com/beartype/beartype/discussions", - "Releases": "https://github.com/beartype/beartype/releases", - "Download-URL": "https://github.com/beartype/beartype/archive/0.17.2.tar.gz", - "license_file": "LICENSE" - }, - "repository_homepage_url": "https://pypi.org/project/beartype", - "repository_download_url": "https://pypi.org/packages/source/b/beartype/beartype-0.17.2.tar.gz", - "api_data_url": "https://pypi.org/pypi/beartype/0.17.2/json", - "package_uid": "pkg:pypi/beartype@0.17.2?uuid=fixed-uid-done-for-testing-5642512d1758", - "datafile_paths": [ - "beartype-0.17.2.dist-info/METADATA" - ], - "datasource_ids": [ - "pypi_wheel_metadata" - ], - "purl": "pkg:pypi/beartype@0.17.2" - } - ], - "dependencies": [ - { - "purl": "pkg:pypi/typing-extensions", - "extracted_requirement": ">=3.10.0.0", - "scope": "all", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {}, - "dependency_uid": "pkg:pypi/typing-extensions?uuid=fixed-uid-done-for-testing-5642512d1758", - "for_package_uid": "pkg:pypi/beartype@0.17.2?uuid=fixed-uid-done-for-testing-5642512d1758", - "datafile_path": "beartype-0.17.2.dist-info/METADATA", - "datasource_id": "pypi_wheel_metadata" - }, - { - "purl": "pkg:pypi/coverage", - "extracted_requirement": ">=5.5", - "scope": "dev", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {}, - "dependency_uid": "pkg:pypi/coverage?uuid=fixed-uid-done-for-testing-5642512d1758", - "for_package_uid": "pkg:pypi/beartype@0.17.2?uuid=fixed-uid-done-for-testing-5642512d1758", - "datafile_path": "beartype-0.17.2.dist-info/METADATA", - "datasource_id": "pypi_wheel_metadata" - } - ], - "license_detections": [ - { - "identifier": "mit-0e83171f-f52c-747e-2310-febf0be67375", - "license_expression": "mit", - "license_expression_spdx": "MIT", - "detection_count": 2, - "detection_log": [ - "unknown-reference-to-local-file" - ], - "reference_matches": [ - { - "license_expression": "unknown-license-reference", - "license_expression_spdx": "LicenseRef-scancode-unknown-license-reference", - "from_file": "beartype-0.17.2/beartype/__init__.py", - "start_line": 4, - "end_line": 4, - "matcher": "2-aho", - "score": 100.0, - "matched_length": 5, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "unknown-license-reference_381.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/unknown-license-reference_381.RULE", - "matched_text": "# See \"LICENSE\" for further details.", - "matched_text_diagnostics": "See \"LICENSE\" for further details." - }, - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/LICENSE", - "start_line": 1, - "end_line": 1, - "matcher": "2-aho", - "score": 100.0, - "matched_length": 2, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "mit_14.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_14.RULE", - "matched_text": "MIT License", - "matched_text_diagnostics": "MIT License" - } - ] - }, - { - "identifier": "mit-24a5293c-14d7-5403-efac-1a8b7532c0e8", - "license_expression": "mit", - "license_expression_spdx": "MIT", - "detection_count": 1, - "detection_log": [], - "reference_matches": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", - "start_line": 1, - "end_line": 1, - "matcher": "1-hash", - "score": 100.0, - "matched_length": 5, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "pypi_mit_license.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_mit_license.RULE", - "matched_text": "- 'License :: OSI Approved :: MIT License'" - } - ] - }, - { - "identifier": "mit-3fce6ea2-8abd-6c6b-3ede-a37af7c6efee", - "license_expression": "mit", - "license_expression_spdx": "MIT", - "detection_count": 1, - "detection_log": [], - "reference_matches": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", - "start_line": 11, - "end_line": 11, - "matcher": "2-aho", - "score": 100.0, - "matched_length": 2, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "mit_30.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_30.RULE", - "matched_text": "License: MIT", - "matched_text_diagnostics": "License: MIT" - } - ] - }, - { - "identifier": "mit-9967e727-165e-9bb5-f090-7de5e47a3929", - "license_expression": "mit", - "license_expression_spdx": "MIT", - "detection_count": 1, - "detection_log": [], - "reference_matches": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/LICENSE", - "start_line": 1, - "end_line": 1, - "matcher": "2-aho", - "score": 100.0, - "matched_length": 2, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "mit_14.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_14.RULE", - "matched_text": "MIT License", - "matched_text_diagnostics": "MIT License" - } - ] - }, - { - "identifier": "mit-a822f434-d61f-f2b1-c792-8b8cb9e7b9bf", - "license_expression": "mit", - "license_expression_spdx": "MIT", - "detection_count": 1, - "detection_log": [], - "reference_matches": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", - "start_line": 1, - "end_line": 1, - "matcher": "1-spdx-id", - "score": 100.0, - "matched_length": 1, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "spdx-license-identifier-mit-5da48780aba670b0860c46d899ed42a0f243ff06", - "rule_url": null, - "matched_text": "MIT" - } - ] - }, - { - "identifier": "mit-e55683fd-5f52-c031-5df7-3ca3519bc260", - "license_expression": "mit", - "license_expression_spdx": "MIT", - "detection_count": 1, - "detection_log": [ - "unknown-reference-to-local-file" - ], - "reference_matches": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", - "start_line": 20, - "end_line": 20, - "matcher": "2-aho", - "score": 100.0, - "matched_length": 5, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "pypi_mit_license.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_mit_license.RULE", - "matched_text": "Classifier: License :: OSI Approved :: MIT License", - "matched_text_diagnostics": "License :: OSI Approved :: MIT License" - }, - { - "license_expression": "unknown-license-reference", - "license_expression_spdx": "LicenseRef-scancode-unknown-license-reference", - "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", - "start_line": 23, - "end_line": 23, - "matcher": "2-aho", - "score": 100.0, - "matched_length": 3, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "unknown-license-reference_see_license_at_manifest_1.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/unknown-license-reference_see_license_at_manifest_1.RULE", - "matched_text": "License-File: LICENSE", - "matched_text_diagnostics": "License-File: LICENSE" - }, - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/LICENSE", - "start_line": 1, - "end_line": 1, - "matcher": "2-aho", - "score": 100.0, - "matched_length": 2, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "mit_14.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_14.RULE", - "matched_text": "MIT License", - "matched_text_diagnostics": "MIT License" - } - ] - } - ], - "files": [ - { - "path": "beartype", - "type": "directory", - "package_data": [], - "for_packages": [], - "detected_license_expression": null, - "detected_license_expression_spdx": null, - "license_detections": [], - "license_clues": [], - "percentage_of_license_text": 0, - "scan_errors": [] - }, - { - "path": "beartype-0.17.2.dist-info", - "type": "directory", - "package_data": [], - "for_packages": [], - "detected_license_expression": null, - "detected_license_expression_spdx": null, - "license_detections": [], - "license_clues": [], - "percentage_of_license_text": 0, - "scan_errors": [] - }, - { - "path": "beartype-0.17.2.dist-info/LICENSE", - "type": "file", - "package_data": [], - "for_packages": [ - "pkg:pypi/beartype@0.17.2?uuid=fixed-uid-done-for-testing-5642512d1758" - ], - "detected_license_expression": "mit", - "detected_license_expression_spdx": "MIT", - "license_detections": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "matches": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/LICENSE", - "start_line": 1, - "end_line": 1, - "matcher": "2-aho", - "score": 100.0, - "matched_length": 2, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "mit_14.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_14.RULE", - "matched_text": "MIT License", - "matched_text_diagnostics": "MIT License" - } - ], - "detection_log": [], - "identifier": "mit-9967e727-165e-9bb5-f090-7de5e47a3929" - } - ], - "license_clues": [], - "percentage_of_license_text": 25.0, - "scan_errors": [] - }, - { - "path": "beartype-0.17.2.dist-info/METADATA", - "type": "file", - "package_data": [ - { - "type": "pypi", - "namespace": null, - "name": "beartype", - "version": "0.17.2", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Unbearably fast runtime type checking in pure Python.\n.. # ------------------( LICENSE )------------------\n.. # Copyright (c) 2014-2024 Beartype authors.\n.. # See \"LICENSE\" for further details.\n.. #\n\n**Beartype** is an open-source pure-Python PEP-compliant near-real-time\nhybrid runtime-static third-generation type checker emphasizing efficiency,\nusability, unsubstantiated jargon we just made up, and thrilling puns.", - "release_date": null, - "parties": [ - { - "type": "person", - "role": "author", - "name": "Cecil Curry, et al.", - "email": "leycec@gmail.com", - "url": null - }, - { - "type": "person", - "role": "maintainer", - "name": "Cecil Curry, et al.", - "email": "leycec@gmail.com", - "url": null - } - ], - "keywords": [ - "type checking", - "type hints", - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers" - ], - "homepage_url": "https://beartype.readthedocs.io", - "download_url": null, - "size": null, - "sha1": null, - "md5": null, - "sha256": null, - "sha512": null, - "bug_tracking_url": "https://github.com/beartype/beartype/issues", - "code_view_url": "https://github.com/beartype/beartype", - "vcs_url": null, - "copyright": null, - "holder": null, - "declared_license_expression": "mit", - "declared_license_expression_spdx": "MIT", - "license_detections": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "matches": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", - "start_line": 1, - "end_line": 1, - "matcher": "1-spdx-id", - "score": 100.0, - "matched_length": 1, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "spdx-license-identifier-mit-5da48780aba670b0860c46d899ed42a0f243ff06", - "rule_url": null, - "matched_text": "MIT" - } - ], - "identifier": "mit-a822f434-d61f-f2b1-c792-8b8cb9e7b9bf" - }, - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "matches": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", - "start_line": 1, - "end_line": 1, - "matcher": "1-hash", - "score": 100.0, - "matched_length": 5, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "pypi_mit_license.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_mit_license.RULE", - "matched_text": "- 'License :: OSI Approved :: MIT License'" - } - ], - "identifier": "mit-24a5293c-14d7-5403-efac-1a8b7532c0e8" - } - ], - "other_license_expression": null, - "other_license_expression_spdx": null, - "other_license_detections": [], - "extracted_license_statement": "license: MIT\nclassifiers:\n - 'License :: OSI Approved :: MIT License'\n", - "notice_text": null, - "source_packages": [], - "file_references": [ - { - "path": "beartype/__init__.py", - "size": 9331, - "sha1": null, - "md5": null, - "sha256": "20ec758584c77bdbf3d2eae4e22208c85ed6e686c91d6d2be572e00f4f10885f", - "sha512": null, - "extra_data": {} - }, - { - "path": "beartype/meta.py", - "size": 32328, - "sha1": null, - "md5": null, - "sha256": "b60a4c1f3177e1fa8bb244d0ba0f2fba9ab02df1dcaf82ca4ac0ba5814cf91ac", - "sha512": null, - "extra_data": {} - }, - { - "path": "beartype/py.typed", - "size": 0, - "sha1": null, - "md5": null, - "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "sha512": null, - "extra_data": {} - }, - { - "path": "beartype-0.17.2.dist-info/LICENSE", - "size": 1079, - "sha1": null, - "md5": null, - "sha256": "c3e5f3d24346a4129b6b00966361e5494376a335d4fc9eb7dbc40d886f2735f1", - "sha512": null, - "extra_data": {} - }, - { - "path": "beartype-0.17.2.dist-info/METADATA", - "size": 30452, - "sha1": null, - "md5": null, - "sha256": "20d00884cc17f1d42da09136c1826ee43730faa9aa3529dac2ccf95e29650b92", - "sha512": null, - "extra_data": {} - }, - { - "path": "beartype-0.17.2.dist-info/WHEEL", - "size": 92, - "sha1": null, - "md5": null, - "sha256": "a2241587fe4f9d033413780f762cf4f5608d9b08870cc6867abfde96a0777283", - "sha512": null, - "extra_data": {} - }, - { - "path": "beartype-0.17.2.dist-info/top_level.txt", - "size": 9, - "sha1": null, - "md5": null, - "sha256": "9f9a39a9bd5dc2b50314952aecb6ffc2fba3f30e94687604a50eba16c2a60d7d", - "sha512": null, - "extra_data": {} - }, - { - "path": "beartype-0.17.2.dist-info/RECORD", - "size": null, - "sha1": null, - "md5": null, - "sha256": null, - "sha512": null, - "extra_data": {} - } - ], - "is_private": false, - "is_virtual": false, - "extra_data": { - "Documentation": "https://beartype.readthedocs.io", - "Forums": "https://github.com/beartype/beartype/discussions", - "Releases": "https://github.com/beartype/beartype/releases", - "Download-URL": "https://github.com/beartype/beartype/archive/0.17.2.tar.gz", - "license_file": "LICENSE" - }, - "dependencies": [ - { - "purl": "pkg:pypi/typing-extensions", - "extracted_requirement": ">=3.10.0.0", - "scope": "all", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/coverage", - "extracted_requirement": ">=5.5", - "scope": "dev", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - } - ], - "repository_homepage_url": "https://pypi.org/project/beartype", - "repository_download_url": "https://pypi.org/packages/source/b/beartype/beartype-0.17.2.tar.gz", - "api_data_url": "https://pypi.org/pypi/beartype/0.17.2/json", - "datasource_id": "pypi_wheel_metadata", - "purl": "pkg:pypi/beartype@0.17.2" - } - ], - "for_packages": [ - "pkg:pypi/beartype@0.17.2?uuid=fixed-uid-done-for-testing-5642512d1758" - ], - "detected_license_expression": "mit", - "detected_license_expression_spdx": "MIT", - "license_detections": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "matches": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", - "start_line": 11, - "end_line": 11, - "matcher": "2-aho", - "score": 100.0, - "matched_length": 2, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "mit_30.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_30.RULE", - "matched_text": "License: MIT", - "matched_text_diagnostics": "License: MIT" - } - ], - "detection_log": [], - "identifier": "mit-3fce6ea2-8abd-6c6b-3ede-a37af7c6efee" - }, - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "matches": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", - "start_line": 20, - "end_line": 20, - "matcher": "2-aho", - "score": 100.0, - "matched_length": 5, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "pypi_mit_license.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_mit_license.RULE", - "matched_text": "Classifier: License :: OSI Approved :: MIT License", - "matched_text_diagnostics": "License :: OSI Approved :: MIT License" - }, - { - "license_expression": "unknown-license-reference", - "license_expression_spdx": "LicenseRef-scancode-unknown-license-reference", - "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", - "start_line": 23, - "end_line": 23, - "matcher": "2-aho", - "score": 100.0, - "matched_length": 3, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "unknown-license-reference_see_license_at_manifest_1.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/unknown-license-reference_see_license_at_manifest_1.RULE", - "matched_text": "License-File: LICENSE", - "matched_text_diagnostics": "License-File: LICENSE" - }, - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/LICENSE", - "start_line": 1, - "end_line": 1, - "matcher": "2-aho", - "score": 100.0, - "matched_length": 2, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "mit_14.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_14.RULE", - "matched_text": "MIT License", - "matched_text_diagnostics": "MIT License" - } - ], - "detection_log": [ - "unknown-reference-to-local-file" - ], - "identifier": "mit-e55683fd-5f52-c031-5df7-3ca3519bc260" - }, - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "matches": [ - { - "license_expression": "unknown-license-reference", - "license_expression_spdx": "LicenseRef-scancode-unknown-license-reference", - "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", - "start_line": 31, - "end_line": 31, - "matcher": "2-aho", - "score": 100.0, - "matched_length": 5, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "unknown-license-reference_381.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/unknown-license-reference_381.RULE", - "matched_text": ".. # See \"LICENSE\" for further details.", - "matched_text_diagnostics": "See \"LICENSE\" for further details." - }, - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/LICENSE", - "start_line": 1, - "end_line": 1, - "matcher": "2-aho", - "score": 100.0, - "matched_length": 2, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "mit_14.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_14.RULE", - "matched_text": "MIT License", - "matched_text_diagnostics": "MIT License" - } - ], - "detection_log": [ - "unknown-reference-to-local-file" - ], - "identifier": "mit-0e83171f-f52c-747e-2310-febf0be67375" - } - ], - "license_clues": [], - "percentage_of_license_text": 7.28, - "scan_errors": [] - }, - { - "path": "beartype-0.17.2.dist-info/RECORD", - "type": "file", - "package_data": [], - "for_packages": [ - "pkg:pypi/beartype@0.17.2?uuid=fixed-uid-done-for-testing-5642512d1758" - ], - "detected_license_expression": null, - "detected_license_expression_spdx": null, - "license_detections": [], - "license_clues": [], - "percentage_of_license_text": 0, - "scan_errors": [] - }, - { - "path": "beartype-0.17.2.dist-info/WHEEL", - "type": "file", - "package_data": [], - "for_packages": [ - "pkg:pypi/beartype@0.17.2?uuid=fixed-uid-done-for-testing-5642512d1758" - ], - "detected_license_expression": null, - "detected_license_expression_spdx": null, - "license_detections": [], - "license_clues": [], - "percentage_of_license_text": 0, - "scan_errors": [] - }, - { - "path": "beartype-0.17.2.dist-info/top_level.txt", - "type": "file", - "package_data": [], - "for_packages": [ - "pkg:pypi/beartype@0.17.2?uuid=fixed-uid-done-for-testing-5642512d1758" - ], - "detected_license_expression": null, - "detected_license_expression_spdx": null, - "license_detections": [], - "license_clues": [], - "percentage_of_license_text": 0, - "scan_errors": [] - }, - { - "path": "beartype/__init__.py", - "type": "file", - "package_data": [], - "for_packages": [ - "pkg:pypi/beartype@0.17.2?uuid=fixed-uid-done-for-testing-5642512d1758" - ], - "detected_license_expression": "mit", - "detected_license_expression_spdx": "MIT", - "license_detections": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "matches": [ - { - "license_expression": "unknown-license-reference", - "license_expression_spdx": "LicenseRef-scancode-unknown-license-reference", - "from_file": "beartype-0.17.2/beartype/__init__.py", - "start_line": 4, - "end_line": 4, - "matcher": "2-aho", - "score": 100.0, - "matched_length": 5, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "unknown-license-reference_381.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/unknown-license-reference_381.RULE", - "matched_text": "# See \"LICENSE\" for further details.", - "matched_text_diagnostics": "See \"LICENSE\" for further details." - }, - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/LICENSE", - "start_line": 1, - "end_line": 1, - "matcher": "2-aho", - "score": 100.0, - "matched_length": 2, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "mit_14.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_14.RULE", - "matched_text": "MIT License", - "matched_text_diagnostics": "MIT License" - } - ], - "detection_log": [ - "unknown-reference-to-local-file" - ], - "identifier": "mit-0e83171f-f52c-747e-2310-febf0be67375" - } - ], - "license_clues": [], - "percentage_of_license_text": 15.62, - "scan_errors": [] - } - ] -} \ No newline at end of file +{"headers": [{"tool_name": "scancode-toolkit", "tool_version": "32.5.0", "options": {"input": ["tests/packagedcode/data/license_detection/reference-to-license-beside-manifest/beartype-0.17.2/"], "--json": "tests/packagedcode/data/license_detection/reference-to-license-beside-manifest/beartype-0.17.2-expected.json", "--license": true, "--license-diagnostics": true, "--license-text": true, "--license-text-diagnostics": true, "--package": true, "--strip-root": true, "--verbose": true}, "notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", "start_timestamp": "2026-02-24T224126.735853", "end_timestamp": "2026-02-24T224132.663380", "output_format_version": "4.1.0", "duration": 5.927543878555298, "message": null, "errors": [], "warnings": [], "extra_data": {"system_environment": {"operating_system": "linux", "cpu_architecture": "64", "platform": "Linux-6.6.87.2-microsoft-standard-WSL2-x86_64-with-glibc2.35", "platform_version": "#1 SMP PREEMPT_DYNAMIC Thu Jun 5 18:30:46 UTC 2025", "python_version": "3.10.12 (main, Jan 26 2026, 14:55:28) [GCC 11.4.0]"}, "spdx_license_list_version": "3.27", "files_count": 6}}], "packages": [{"type": "pypi", "namespace": null, "name": "beartype", "version": "0.17.2", "qualifiers": {}, "subpath": null, "primary_language": "Python", "description": "Unbearably fast runtime type checking in pure Python.\n.. # ------------------( LICENSE )------------------\n.. # Copyright (c) 2014-2024 Beartype authors.\n.. # See \"LICENSE\" for further details.\n.. #\n\n**Beartype** is an open-source pure-Python PEP-compliant near-real-time\nhybrid runtime-static third-generation type checker emphasizing efficiency,\nusability, unsubstantiated jargon we just made up, and thrilling puns.", "release_date": null, "parties": [{"type": "person", "role": "author", "name": "Cecil Curry, et al.", "email": "leycec@gmail.com", "url": null}, {"type": "person", "role": "maintainer", "name": "Cecil Curry, et al.", "email": "leycec@gmail.com", "url": null}], "keywords": ["type checking", "type hints", "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers"], "homepage_url": "https://beartype.readthedocs.io", "download_url": null, "size": null, "sha1": null, "md5": null, "sha256": null, "sha512": null, "bug_tracking_url": "https://github.com/beartype/beartype/issues", "code_view_url": "https://github.com/beartype/beartype", "vcs_url": null, "copyright": null, "holder": null, "declared_license_expression": "mit", "declared_license_expression_spdx": "MIT", "license_detections": [{"license_expression": "mit", "license_expression_spdx": "MIT", "matches": [{"license_expression": "mit", "license_expression_spdx": "MIT", "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", "start_line": 1, "end_line": 1, "matcher": "1-spdx-id", "score": 100.0, "matched_length": 1, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "spdx-license-identifier-mit-5da48780aba670b0860c46d899ed42a0f243ff06", "rule_url": null, "matched_text": "MIT"}], "identifier": "mit-a822f434-d61f-f2b1-c792-8b8cb9e7b9bf"}, {"license_expression": "mit", "license_expression_spdx": "MIT", "matches": [{"license_expression": "mit", "license_expression_spdx": "MIT", "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", "start_line": 1, "end_line": 1, "matcher": "1-hash", "score": 100.0, "matched_length": 5, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "pypi_mit_license.RULE", "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_mit_license.RULE", "matched_text": "- 'License :: OSI Approved :: MIT License'"}], "identifier": "mit-24a5293c-14d7-5403-efac-1a8b7532c0e8"}], "other_license_expression": null, "other_license_expression_spdx": null, "other_license_detections": [], "extracted_license_statement": "license: MIT\nclassifiers:\n - 'License :: OSI Approved :: MIT License'\n", "notice_text": null, "source_packages": [], "is_private": false, "is_virtual": false, "extra_data": {"Documentation": "https://beartype.readthedocs.io", "Forums": "https://github.com/beartype/beartype/discussions", "Releases": "https://github.com/beartype/beartype/releases", "Download-URL": "https://github.com/beartype/beartype/archive/0.17.2.tar.gz", "license_file": "LICENSE", "wheel_tags": ["py3-none-any"], "wheel_version": "1.0", "wheel_generator": "bdist_wheel (0.42.0)", "root_is_purelib": true}, "repository_homepage_url": "https://pypi.org/project/beartype", "repository_download_url": "https://pypi.org/packages/source/b/beartype/beartype-0.17.2.tar.gz", "api_data_url": "https://pypi.org/pypi/beartype/0.17.2/json", "package_uid": "pkg:pypi/beartype@0.17.2?uuid=8fdd6d3b-9286-45b3-ad7d-60e3d657939d", "datafile_paths": ["beartype-0.17.2.dist-info/METADATA"], "datasource_ids": ["pypi_wheel_metadata"], "purl": "pkg:pypi/beartype@0.17.2"}], "dependencies": [{"purl": "pkg:pypi/typing-extensions", "extracted_requirement": ">=3.10.0.0", "scope": "all", "is_runtime": true, "is_optional": true, "is_pinned": false, "is_direct": true, "resolved_package": {}, "extra_data": {}, "dependency_uid": "pkg:pypi/typing-extensions?uuid=6158d645-faed-4b14-955c-47efe50cca6b", "for_package_uid": "pkg:pypi/beartype@0.17.2?uuid=8fdd6d3b-9286-45b3-ad7d-60e3d657939d", "datafile_path": "beartype-0.17.2.dist-info/METADATA", "datasource_id": "pypi_wheel_metadata"}, {"purl": "pkg:pypi/coverage", "extracted_requirement": ">=5.5", "scope": "dev", "is_runtime": true, "is_optional": true, "is_pinned": false, "is_direct": true, "resolved_package": {}, "extra_data": {}, "dependency_uid": "pkg:pypi/coverage?uuid=d29b74df-8c67-4a70-aa5c-eb959d792f60", "for_package_uid": "pkg:pypi/beartype@0.17.2?uuid=8fdd6d3b-9286-45b3-ad7d-60e3d657939d", "datafile_path": "beartype-0.17.2.dist-info/METADATA", "datasource_id": "pypi_wheel_metadata"}], "license_detections": [{"identifier": "mit-0e83171f-f52c-747e-2310-febf0be67375", "license_expression": "mit", "license_expression_spdx": "MIT", "detection_count": 2, "detection_log": ["unknown-reference-to-local-file"], "reference_matches": [{"license_expression": "unknown-license-reference", "license_expression_spdx": "LicenseRef-scancode-unknown-license-reference", "from_file": "beartype-0.17.2/beartype/__init__.py", "start_line": 4, "end_line": 4, "matcher": "2-aho", "score": 100.0, "matched_length": 5, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "unknown-license-reference_381.RULE", "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/unknown-license-reference_381.RULE", "matched_text": "# See \"LICENSE\" for further details.", "matched_text_diagnostics": "See \"LICENSE\" for further details."}, {"license_expression": "mit", "license_expression_spdx": "MIT", "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/LICENSE", "start_line": 1, "end_line": 1, "matcher": "2-aho", "score": 100.0, "matched_length": 2, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "mit_14.RULE", "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_14.RULE", "matched_text": "MIT License", "matched_text_diagnostics": "MIT License"}]}, {"identifier": "mit-24a5293c-14d7-5403-efac-1a8b7532c0e8", "license_expression": "mit", "license_expression_spdx": "MIT", "detection_count": 1, "detection_log": [], "reference_matches": [{"license_expression": "mit", "license_expression_spdx": "MIT", "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", "start_line": 1, "end_line": 1, "matcher": "1-hash", "score": 100.0, "matched_length": 5, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "pypi_mit_license.RULE", "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_mit_license.RULE", "matched_text": "- 'License :: OSI Approved :: MIT License'"}]}, {"identifier": "mit-3fce6ea2-8abd-6c6b-3ede-a37af7c6efee", "license_expression": "mit", "license_expression_spdx": "MIT", "detection_count": 1, "detection_log": [], "reference_matches": [{"license_expression": "mit", "license_expression_spdx": "MIT", "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", "start_line": 11, "end_line": 11, "matcher": "2-aho", "score": 100.0, "matched_length": 2, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "mit_30.RULE", "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_30.RULE", "matched_text": "License: MIT", "matched_text_diagnostics": "License: MIT"}]}, {"identifier": "mit-9967e727-165e-9bb5-f090-7de5e47a3929", "license_expression": "mit", "license_expression_spdx": "MIT", "detection_count": 1, "detection_log": [], "reference_matches": [{"license_expression": "mit", "license_expression_spdx": "MIT", "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/LICENSE", "start_line": 1, "end_line": 1, "matcher": "2-aho", "score": 100.0, "matched_length": 2, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "mit_14.RULE", "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_14.RULE", "matched_text": "MIT License", "matched_text_diagnostics": "MIT License"}]}, {"identifier": "mit-a822f434-d61f-f2b1-c792-8b8cb9e7b9bf", "license_expression": "mit", "license_expression_spdx": "MIT", "detection_count": 1, "detection_log": [], "reference_matches": [{"license_expression": "mit", "license_expression_spdx": "MIT", "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", "start_line": 1, "end_line": 1, "matcher": "1-spdx-id", "score": 100.0, "matched_length": 1, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "spdx-license-identifier-mit-5da48780aba670b0860c46d899ed42a0f243ff06", "rule_url": null, "matched_text": "MIT"}]}, {"identifier": "mit-e55683fd-5f52-c031-5df7-3ca3519bc260", "license_expression": "mit", "license_expression_spdx": "MIT", "detection_count": 1, "detection_log": ["unknown-reference-to-local-file"], "reference_matches": [{"license_expression": "mit", "license_expression_spdx": "MIT", "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", "start_line": 20, "end_line": 20, "matcher": "2-aho", "score": 100.0, "matched_length": 5, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "pypi_mit_license.RULE", "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_mit_license.RULE", "matched_text": "Classifier: License :: OSI Approved :: MIT License", "matched_text_diagnostics": "License :: OSI Approved :: MIT License"}, {"license_expression": "unknown-license-reference", "license_expression_spdx": "LicenseRef-scancode-unknown-license-reference", "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", "start_line": 23, "end_line": 23, "matcher": "2-aho", "score": 100.0, "matched_length": 3, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "unknown-license-reference_see_license_at_manifest_1.RULE", "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/unknown-license-reference_see_license_at_manifest_1.RULE", "matched_text": "License-File: LICENSE", "matched_text_diagnostics": "License-File: LICENSE"}, {"license_expression": "mit", "license_expression_spdx": "MIT", "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/LICENSE", "start_line": 1, "end_line": 1, "matcher": "2-aho", "score": 100.0, "matched_length": 2, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "mit_14.RULE", "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_14.RULE", "matched_text": "MIT License", "matched_text_diagnostics": "MIT License"}]}], "files": [{"path": "beartype", "type": "directory", "package_data": [], "for_packages": [], "detected_license_expression": null, "detected_license_expression_spdx": null, "license_detections": [], "license_clues": [], "percentage_of_license_text": 0, "scan_errors": []}, {"path": "beartype/__init__.py", "type": "file", "package_data": [], "for_packages": ["pkg:pypi/beartype@0.17.2?uuid=8fdd6d3b-9286-45b3-ad7d-60e3d657939d"], "detected_license_expression": "mit", "detected_license_expression_spdx": "MIT", "license_detections": [{"license_expression": "mit", "license_expression_spdx": "MIT", "matches": [{"license_expression": "unknown-license-reference", "license_expression_spdx": "LicenseRef-scancode-unknown-license-reference", "from_file": "beartype-0.17.2/beartype/__init__.py", "start_line": 4, "end_line": 4, "matcher": "2-aho", "score": 100.0, "matched_length": 5, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "unknown-license-reference_381.RULE", "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/unknown-license-reference_381.RULE", "matched_text": "# See \"LICENSE\" for further details.", "matched_text_diagnostics": "See \"LICENSE\" for further details."}, {"license_expression": "mit", "license_expression_spdx": "MIT", "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/LICENSE", "start_line": 1, "end_line": 1, "matcher": "2-aho", "score": 100.0, "matched_length": 2, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "mit_14.RULE", "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_14.RULE", "matched_text": "MIT License", "matched_text_diagnostics": "MIT License"}], "detection_log": ["unknown-reference-to-local-file"], "identifier": "mit-0e83171f-f52c-747e-2310-febf0be67375"}], "license_clues": [], "percentage_of_license_text": 15.62, "scan_errors": []}, {"path": "beartype-0.17.2.dist-info", "type": "directory", "package_data": [], "for_packages": [], "detected_license_expression": null, "detected_license_expression_spdx": null, "license_detections": [], "license_clues": [], "percentage_of_license_text": 0, "scan_errors": []}, {"path": "beartype-0.17.2.dist-info/LICENSE", "type": "file", "package_data": [], "for_packages": ["pkg:pypi/beartype@0.17.2?uuid=8fdd6d3b-9286-45b3-ad7d-60e3d657939d"], "detected_license_expression": "mit", "detected_license_expression_spdx": "MIT", "license_detections": [{"license_expression": "mit", "license_expression_spdx": "MIT", "matches": [{"license_expression": "mit", "license_expression_spdx": "MIT", "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/LICENSE", "start_line": 1, "end_line": 1, "matcher": "2-aho", "score": 100.0, "matched_length": 2, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "mit_14.RULE", "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_14.RULE", "matched_text": "MIT License", "matched_text_diagnostics": "MIT License"}], "detection_log": [], "identifier": "mit-9967e727-165e-9bb5-f090-7de5e47a3929"}], "license_clues": [], "percentage_of_license_text": 25.0, "scan_errors": []}, {"path": "beartype-0.17.2.dist-info/METADATA", "type": "file", "package_data": [{"type": "pypi", "namespace": null, "name": "beartype", "version": "0.17.2", "qualifiers": {}, "subpath": null, "primary_language": "Python", "description": "Unbearably fast runtime type checking in pure Python.\n.. # ------------------( LICENSE )------------------\n.. # Copyright (c) 2014-2024 Beartype authors.\n.. # See \"LICENSE\" for further details.\n.. #\n\n**Beartype** is an open-source pure-Python PEP-compliant near-real-time\nhybrid runtime-static third-generation type checker emphasizing efficiency,\nusability, unsubstantiated jargon we just made up, and thrilling puns.", "release_date": null, "parties": [{"type": "person", "role": "author", "name": "Cecil Curry, et al.", "email": "leycec@gmail.com", "url": null}, {"type": "person", "role": "maintainer", "name": "Cecil Curry, et al.", "email": "leycec@gmail.com", "url": null}], "keywords": ["type checking", "type hints", "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers"], "homepage_url": "https://beartype.readthedocs.io", "download_url": null, "size": null, "sha1": null, "md5": null, "sha256": null, "sha512": null, "bug_tracking_url": "https://github.com/beartype/beartype/issues", "code_view_url": "https://github.com/beartype/beartype", "vcs_url": null, "copyright": null, "holder": null, "declared_license_expression": "mit", "declared_license_expression_spdx": "MIT", "license_detections": [{"license_expression": "mit", "license_expression_spdx": "MIT", "matches": [{"license_expression": "mit", "license_expression_spdx": "MIT", "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", "start_line": 1, "end_line": 1, "matcher": "1-spdx-id", "score": 100.0, "matched_length": 1, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "spdx-license-identifier-mit-5da48780aba670b0860c46d899ed42a0f243ff06", "rule_url": null, "matched_text": "MIT"}], "identifier": "mit-a822f434-d61f-f2b1-c792-8b8cb9e7b9bf"}, {"license_expression": "mit", "license_expression_spdx": "MIT", "matches": [{"license_expression": "mit", "license_expression_spdx": "MIT", "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", "start_line": 1, "end_line": 1, "matcher": "1-hash", "score": 100.0, "matched_length": 5, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "pypi_mit_license.RULE", "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_mit_license.RULE", "matched_text": "- 'License :: OSI Approved :: MIT License'"}], "identifier": "mit-24a5293c-14d7-5403-efac-1a8b7532c0e8"}], "other_license_expression": null, "other_license_expression_spdx": null, "other_license_detections": [], "extracted_license_statement": "license: MIT\nclassifiers:\n - 'License :: OSI Approved :: MIT License'\n", "notice_text": null, "source_packages": [], "file_references": [{"path": "beartype/__init__.py", "size": 9331, "sha1": null, "md5": null, "sha256": "20ec758584c77bdbf3d2eae4e22208c85ed6e686c91d6d2be572e00f4f10885f", "sha512": null, "extra_data": {}}, {"path": "beartype/meta.py", "size": 32328, "sha1": null, "md5": null, "sha256": "b60a4c1f3177e1fa8bb244d0ba0f2fba9ab02df1dcaf82ca4ac0ba5814cf91ac", "sha512": null, "extra_data": {}}, {"path": "beartype/py.typed", "size": 0, "sha1": null, "md5": null, "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "sha512": null, "extra_data": {}}, {"path": "beartype-0.17.2.dist-info/LICENSE", "size": 1079, "sha1": null, "md5": null, "sha256": "c3e5f3d24346a4129b6b00966361e5494376a335d4fc9eb7dbc40d886f2735f1", "sha512": null, "extra_data": {}}, {"path": "beartype-0.17.2.dist-info/METADATA", "size": 30452, "sha1": null, "md5": null, "sha256": "20d00884cc17f1d42da09136c1826ee43730faa9aa3529dac2ccf95e29650b92", "sha512": null, "extra_data": {}}, {"path": "beartype-0.17.2.dist-info/WHEEL", "size": 92, "sha1": null, "md5": null, "sha256": "a2241587fe4f9d033413780f762cf4f5608d9b08870cc6867abfde96a0777283", "sha512": null, "extra_data": {}}, {"path": "beartype-0.17.2.dist-info/top_level.txt", "size": 9, "sha1": null, "md5": null, "sha256": "9f9a39a9bd5dc2b50314952aecb6ffc2fba3f30e94687604a50eba16c2a60d7d", "sha512": null, "extra_data": {}}, {"path": "beartype-0.17.2.dist-info/RECORD", "size": null, "sha1": null, "md5": null, "sha256": null, "sha512": null, "extra_data": {}}], "is_private": false, "is_virtual": false, "extra_data": {"Documentation": "https://beartype.readthedocs.io", "Forums": "https://github.com/beartype/beartype/discussions", "Releases": "https://github.com/beartype/beartype/releases", "Download-URL": "https://github.com/beartype/beartype/archive/0.17.2.tar.gz", "license_file": "LICENSE", "wheel_tags": ["py3-none-any"], "wheel_version": "1.0", "wheel_generator": "bdist_wheel (0.42.0)", "root_is_purelib": true}, "dependencies": [{"purl": "pkg:pypi/typing-extensions", "extracted_requirement": ">=3.10.0.0", "scope": "all", "is_runtime": true, "is_optional": true, "is_pinned": false, "is_direct": true, "resolved_package": {}, "extra_data": {}}, {"purl": "pkg:pypi/coverage", "extracted_requirement": ">=5.5", "scope": "dev", "is_runtime": true, "is_optional": true, "is_pinned": false, "is_direct": true, "resolved_package": {}, "extra_data": {}}], "repository_homepage_url": "https://pypi.org/project/beartype", "repository_download_url": "https://pypi.org/packages/source/b/beartype/beartype-0.17.2.tar.gz", "api_data_url": "https://pypi.org/pypi/beartype/0.17.2/json", "datasource_id": "pypi_wheel_metadata", "purl": "pkg:pypi/beartype@0.17.2"}], "for_packages": ["pkg:pypi/beartype@0.17.2?uuid=8fdd6d3b-9286-45b3-ad7d-60e3d657939d"], "detected_license_expression": "mit", "detected_license_expression_spdx": "MIT", "license_detections": [{"license_expression": "mit", "license_expression_spdx": "MIT", "matches": [{"license_expression": "mit", "license_expression_spdx": "MIT", "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", "start_line": 11, "end_line": 11, "matcher": "2-aho", "score": 100.0, "matched_length": 2, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "mit_30.RULE", "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_30.RULE", "matched_text": "License: MIT", "matched_text_diagnostics": "License: MIT"}], "detection_log": [], "identifier": "mit-3fce6ea2-8abd-6c6b-3ede-a37af7c6efee"}, {"license_expression": "mit", "license_expression_spdx": "MIT", "matches": [{"license_expression": "mit", "license_expression_spdx": "MIT", "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", "start_line": 20, "end_line": 20, "matcher": "2-aho", "score": 100.0, "matched_length": 5, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "pypi_mit_license.RULE", "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_mit_license.RULE", "matched_text": "Classifier: License :: OSI Approved :: MIT License", "matched_text_diagnostics": "License :: OSI Approved :: MIT License"}, {"license_expression": "unknown-license-reference", "license_expression_spdx": "LicenseRef-scancode-unknown-license-reference", "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", "start_line": 23, "end_line": 23, "matcher": "2-aho", "score": 100.0, "matched_length": 3, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "unknown-license-reference_see_license_at_manifest_1.RULE", "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/unknown-license-reference_see_license_at_manifest_1.RULE", "matched_text": "License-File: LICENSE", "matched_text_diagnostics": "License-File: LICENSE"}, {"license_expression": "mit", "license_expression_spdx": "MIT", "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/LICENSE", "start_line": 1, "end_line": 1, "matcher": "2-aho", "score": 100.0, "matched_length": 2, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "mit_14.RULE", "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_14.RULE", "matched_text": "MIT License", "matched_text_diagnostics": "MIT License"}], "detection_log": ["unknown-reference-to-local-file"], "identifier": "mit-e55683fd-5f52-c031-5df7-3ca3519bc260"}, {"license_expression": "mit", "license_expression_spdx": "MIT", "matches": [{"license_expression": "unknown-license-reference", "license_expression_spdx": "LicenseRef-scancode-unknown-license-reference", "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/METADATA", "start_line": 31, "end_line": 31, "matcher": "2-aho", "score": 100.0, "matched_length": 5, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "unknown-license-reference_381.RULE", "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/unknown-license-reference_381.RULE", "matched_text": ".. # See \"LICENSE\" for further details.", "matched_text_diagnostics": "See \"LICENSE\" for further details."}, {"license_expression": "mit", "license_expression_spdx": "MIT", "from_file": "beartype-0.17.2/beartype-0.17.2.dist-info/LICENSE", "start_line": 1, "end_line": 1, "matcher": "2-aho", "score": 100.0, "matched_length": 2, "match_coverage": 100.0, "rule_relevance": 100, "rule_identifier": "mit_14.RULE", "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_14.RULE", "matched_text": "MIT License", "matched_text_diagnostics": "MIT License"}], "detection_log": ["unknown-reference-to-local-file"], "identifier": "mit-0e83171f-f52c-747e-2310-febf0be67375"}], "license_clues": [], "percentage_of_license_text": 7.28, "scan_errors": []}, {"path": "beartype-0.17.2.dist-info/RECORD", "type": "file", "package_data": [], "for_packages": ["pkg:pypi/beartype@0.17.2?uuid=8fdd6d3b-9286-45b3-ad7d-60e3d657939d"], "detected_license_expression": null, "detected_license_expression_spdx": null, "license_detections": [], "license_clues": [], "percentage_of_license_text": 0, "scan_errors": []}, {"path": "beartype-0.17.2.dist-info/top_level.txt", "type": "file", "package_data": [], "for_packages": ["pkg:pypi/beartype@0.17.2?uuid=8fdd6d3b-9286-45b3-ad7d-60e3d657939d"], "detected_license_expression": null, "detected_license_expression_spdx": null, "license_detections": [], "license_clues": [], "percentage_of_license_text": 0, "scan_errors": []}, {"path": "beartype-0.17.2.dist-info/WHEEL", "type": "file", "package_data": [], "for_packages": ["pkg:pypi/beartype@0.17.2?uuid=8fdd6d3b-9286-45b3-ad7d-60e3d657939d"], "detected_license_expression": null, "detected_license_expression_spdx": null, "license_detections": [], "license_clues": [], "percentage_of_license_text": 0, "scan_errors": []}]} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/metadata/v22/PKG-INFO-expected.json b/tests/packagedcode/data/pypi/metadata/v22/PKG-INFO-expected.json index 5fbc3011b36..8fabcc5506a 100644 --- a/tests/packagedcode/data/pypi/metadata/v22/PKG-INFO-expected.json +++ b/tests/packagedcode/data/pypi/metadata/v22/PKG-INFO-expected.json @@ -1,318 +1,318 @@ -[ - { - "type": "pypi", - "namespace": null, - "name": "ForeTiS", - "version": "0.0.7", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "state-of-the-art and easy-to-use time series forecasting", - "release_date": null, - "parties": [ - { - "type": "person", - "role": "author", - "name": "Josef Eiglsperger, Florian Haselbeck; Dominik G. Grimm", - "email": "josef.eiglsperger@tum.de", - "url": null - } - ], - "keywords": [ - "Development Status :: 2 - Pre-Alpha", - "Intended Audience :: Science/Research", - "Operating System :: POSIX :: Linux", - "Programming Language :: Python :: 3", - "Topic :: Scientific/Engineering :: Artificial Intelligence" - ], - "homepage_url": "https://github.com/grimmlab/ForeTiS", - "download_url": null, - "size": null, - "sha1": null, - "md5": null, - "sha256": null, - "sha512": null, - "bug_tracking_url": null, - "code_view_url": "https://github.com/grimmlab/ForeTiS", - "vcs_url": null, - "copyright": null, - "holder": null, - "declared_license_expression": "mit", - "declared_license_expression_spdx": "MIT", - "license_detections": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "matches": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": null, - "start_line": 1, - "end_line": 1, - "matcher": "1-spdx-id", - "score": 100.0, - "matched_length": 1, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "spdx-license-identifier-mit-5da48780aba670b0860c46d899ed42a0f243ff06", - "rule_url": null, - "matched_text": "MIT" - } - ], - "identifier": "mit-a822f434-d61f-f2b1-c792-8b8cb9e7b9bf" - }, - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "matches": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": null, - "start_line": 1, - "end_line": 1, - "matcher": "1-hash", - "score": 100.0, - "matched_length": 5, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "pypi_mit_license.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_mit_license.RULE", - "matched_text": "- 'License :: OSI Approved :: MIT License'" - } - ], - "identifier": "mit-24a5293c-14d7-5403-efac-1a8b7532c0e8" - } - ], - "other_license_expression": null, - "other_license_expression_spdx": null, - "other_license_detections": [], - "extracted_license_statement": "license: MIT\nclassifiers:\n - 'License :: OSI Approved :: MIT License'\n", - "notice_text": null, - "source_packages": [], - "file_references": [], - "is_private": false, - "is_virtual": false, - "extra_data": { - "Documentation": "https://ForeTiS.readthedocs.io/", - "license_file": "LICENSE" - }, - "dependencies": [ - { - "purl": "pkg:pypi/torch", - "extracted_requirement": ">=1.11.0", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/xgboost", - "extracted_requirement": ">=1.5.2", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/optuna", - "extracted_requirement": ">=2.10.0", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/sqlalchemy@1.4.46", - "extracted_requirement": "==1.4.46", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": true, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/joblib", - "extracted_requirement": ">=1.1.0", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/numpy", - "extracted_requirement": ">=1.22.2", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pandas", - "extracted_requirement": ">=1.4.1", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/scikit-learn", - "extracted_requirement": ">=1.0.2", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/tensorflow", - "extracted_requirement": ">=2.8.0", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/tensorflow-probability", - "extracted_requirement": ">=0.18", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/statsmodels", - "extracted_requirement": ">=0.13.2", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/scipy", - "extracted_requirement": ">=1.8.1", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pmdarima", - "extracted_requirement": ">=2.0.1", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/gpflow", - "extracted_requirement": ">=2.5.2", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/matplotlib", - "extracted_requirement": ">=3.3.0", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/changefinder", - "extracted_requirement": ">=0.3", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/bayesian-torch", - "extracted_requirement": null, - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/blitz-bayesian-pytorch", - "extracted_requirement": null, - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/tables", - "extracted_requirement": ">=3.7.0", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - } - ], - "repository_homepage_url": "https://pypi.org/project/ForeTiS", - "repository_download_url": "https://pypi.org/packages/source/F/ForeTiS/ForeTiS-0.0.7.tar.gz", - "api_data_url": "https://pypi.org/pypi/ForeTiS/0.0.7/json", - "datasource_id": "pypi_sdist_pkginfo", - "purl": "pkg:pypi/foretis@0.0.7" - } +[ + { + "type": "pypi", + "namespace": null, + "name": "ForeTiS", + "version": "0.0.7", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "state-of-the-art and easy-to-use time series forecasting", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "Josef Eiglsperger, Florian Haselbeck; Dominik G. Grimm", + "email": "josef.eiglsperger@tum.de", + "url": null + } + ], + "keywords": [ + "Development Status :: 2 - Pre-Alpha", + "Intended Audience :: Science/Research", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python :: 3", + "Topic :: Scientific/Engineering :: Artificial Intelligence" + ], + "homepage_url": "https://github.com/grimmlab/ForeTiS", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": "https://github.com/grimmlab/ForeTiS", + "vcs_url": null, + "copyright": null, + "holder": null, + "declared_license_expression": "mit", + "declared_license_expression_spdx": "MIT", + "license_detections": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": null, + "start_line": 1, + "end_line": 1, + "matcher": "1-spdx-id", + "score": 100.0, + "matched_length": 1, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "spdx-license-identifier-mit-5da48780aba670b0860c46d899ed42a0f243ff06", + "rule_url": null, + "matched_text": "MIT" + } + ], + "identifier": "mit-a822f434-d61f-f2b1-c792-8b8cb9e7b9bf" + }, + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": null, + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 100.0, + "matched_length": 5, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "pypi_mit_license.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_mit_license.RULE", + "matched_text": "- 'License :: OSI Approved :: MIT License'" + } + ], + "identifier": "mit-24a5293c-14d7-5403-efac-1a8b7532c0e8" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "license: MIT\nclassifiers:\n - 'License :: OSI Approved :: MIT License'\n", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": false, + "extra_data": { + "Documentation": "https://ForeTiS.readthedocs.io/", + "license_file": "LICENSE" + }, + "dependencies": [ + { + "purl": "pkg:pypi/torch", + "extracted_requirement": ">=1.11.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/xgboost", + "extracted_requirement": ">=1.5.2", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/optuna", + "extracted_requirement": ">=2.10.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sqlalchemy@1.4.46", + "extracted_requirement": "==1.4.46", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": true, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/joblib", + "extracted_requirement": ">=1.1.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/numpy", + "extracted_requirement": ">=1.22.2", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pandas", + "extracted_requirement": ">=1.4.1", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/scikit-learn", + "extracted_requirement": ">=1.0.2", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/tensorflow", + "extracted_requirement": ">=2.8.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/tensorflow-probability", + "extracted_requirement": ">=0.18", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/statsmodels", + "extracted_requirement": ">=0.13.2", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/scipy", + "extracted_requirement": ">=1.8.1", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pmdarima", + "extracted_requirement": ">=2.0.1", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/gpflow", + "extracted_requirement": ">=2.5.2", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/matplotlib", + "extracted_requirement": ">=3.3.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/changefinder", + "extracted_requirement": ">=0.3", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/bayesian-torch", + "extracted_requirement": null, + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/blitz-bayesian-pytorch", + "extracted_requirement": null, + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/tables", + "extracted_requirement": ">=3.7.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": "https://pypi.org/project/ForeTiS", + "repository_download_url": "https://pypi.org/packages/source/F/ForeTiS/ForeTiS-0.0.7.tar.gz", + "api_data_url": "https://pypi.org/pypi/ForeTiS/0.0.7/json", + "datasource_id": "pypi_sdist_pkginfo", + "purl": "pkg:pypi/foretis@0.0.7" + } ] \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/metadata/v23/PKG-INFO-expected.json b/tests/packagedcode/data/pypi/metadata/v23/PKG-INFO-expected.json index 53ae1981bc4..c509b9a1a10 100644 --- a/tests/packagedcode/data/pypi/metadata/v23/PKG-INFO-expected.json +++ b/tests/packagedcode/data/pypi/metadata/v23/PKG-INFO-expected.json @@ -1,156 +1,156 @@ -[ - { - "type": "pypi", - "namespace": null, - "name": "hatchling", - "version": "1.22.4", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Modern, extensible Python build backend", - "release_date": null, - "parties": [ - { - "type": "person", - "role": "author", - "name": null, - "email": "Ofek Lev ", - "url": null - } - ], - "keywords": [ - "build", - "hatch", - "packaging", - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Natural Language :: English", - "Operating System :: OS Independent", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Topic :: Software Development :: Build Tools", - "Topic :: Software Development :: Libraries :: Python Modules" - ], - "homepage_url": "https://hatch.pypa.io/latest/", - "download_url": null, - "size": null, - "sha1": null, - "md5": null, - "sha256": null, - "sha512": null, - "bug_tracking_url": "https://github.com/pypa/hatch/issues", - "code_view_url": "https://github.com/pypa/hatch/tree/master/backend", - "vcs_url": null, - "copyright": null, - "holder": null, - "declared_license_expression": "mit", - "declared_license_expression_spdx": "MIT", - "license_detections": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "matches": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": null, - "start_line": 1, - "end_line": 1, - "matcher": "1-hash", - "score": 100.0, - "matched_length": 5, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "pypi_mit_license.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_mit_license.RULE", - "matched_text": "- 'License :: OSI Approved :: MIT License'" - } - ], - "identifier": "mit-24a5293c-14d7-5403-efac-1a8b7532c0e8" - } - ], - "other_license_expression": null, - "other_license_expression_spdx": null, - "other_license_detections": [], - "extracted_license_statement": "classifiers:\n - 'License :: OSI Approved :: MIT License'\n", - "notice_text": null, - "source_packages": [], - "file_references": [], - "is_private": false, - "is_virtual": false, - "extra_data": { - "Sponsor": "https://github.com/sponsors/ofek", - "History": "https://hatch.pypa.io/dev/history/hatchling/", - "license_file": "LICENSE.txt" - }, - "dependencies": [ - { - "purl": "pkg:pypi/packaging", - "extracted_requirement": ">=21.3", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pathspec", - "extracted_requirement": ">=0.10.1", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pluggy", - "extracted_requirement": ">=1.0.0", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/tomli", - "extracted_requirement": ">=1.2.2", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": { - "python_version": "< 3.11" - } - }, - { - "purl": "pkg:pypi/trove-classifiers", - "extracted_requirement": null, - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - } - ], - "repository_homepage_url": "https://pypi.org/project/hatchling", - "repository_download_url": "https://pypi.org/packages/source/h/hatchling/hatchling-1.22.4.tar.gz", - "api_data_url": "https://pypi.org/pypi/hatchling/1.22.4/json", - "datasource_id": "pypi_sdist_pkginfo", - "purl": "pkg:pypi/hatchling@1.22.4" - } +[ + { + "type": "pypi", + "namespace": null, + "name": "hatchling", + "version": "1.22.4", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "Modern, extensible Python build backend", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": null, + "email": "Ofek Lev ", + "url": null + } + ], + "keywords": [ + "build", + "hatch", + "packaging", + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Natural Language :: English", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Software Development :: Build Tools", + "Topic :: Software Development :: Libraries :: Python Modules" + ], + "homepage_url": "https://hatch.pypa.io/latest/", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": "https://github.com/pypa/hatch/issues", + "code_view_url": "https://github.com/pypa/hatch/tree/master/backend", + "vcs_url": null, + "copyright": null, + "holder": null, + "declared_license_expression": "mit", + "declared_license_expression_spdx": "MIT", + "license_detections": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": null, + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 100.0, + "matched_length": 5, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "pypi_mit_license.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_mit_license.RULE", + "matched_text": "- 'License :: OSI Approved :: MIT License'" + } + ], + "identifier": "mit-24a5293c-14d7-5403-efac-1a8b7532c0e8" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "classifiers:\n - 'License :: OSI Approved :: MIT License'\n", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": false, + "extra_data": { + "Sponsor": "https://github.com/sponsors/ofek", + "History": "https://hatch.pypa.io/dev/history/hatchling/", + "license_file": "LICENSE.txt" + }, + "dependencies": [ + { + "purl": "pkg:pypi/packaging", + "extracted_requirement": ">=21.3", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pathspec", + "extracted_requirement": ">=0.10.1", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pluggy", + "extracted_requirement": ">=1.0.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/tomli", + "extracted_requirement": ">=1.2.2", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": { + "python_version": "< 3.11" + } + }, + { + "purl": "pkg:pypi/trove-classifiers", + "extracted_requirement": null, + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": "https://pypi.org/project/hatchling", + "repository_download_url": "https://pypi.org/packages/source/h/hatchling/hatchling-1.22.4.tar.gz", + "api_data_url": "https://pypi.org/pypi/hatchling/1.22.4/json", + "datasource_id": "pypi_sdist_pkginfo", + "purl": "pkg:pypi/hatchling@1.22.4" + } ] \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/site-packages/pip-20.2.2.dist-info-expected.json b/tests/packagedcode/data/pypi/site-packages/pip-20.2.2.dist-info-expected.json index dd82ec6e1d2..905a5086a2b 100644 --- a/tests/packagedcode/data/pypi/site-packages/pip-20.2.2.dist-info-expected.json +++ b/tests/packagedcode/data/pypi/site-packages/pip-20.2.2.dist-info-expected.json @@ -259,7 +259,14 @@ "is_virtual": false, "extra_data": { "Documentation": "https://pip.pypa.io", - "Changelog": "https://pip.pypa.io/en/stable/news/" + "Changelog": "https://pip.pypa.io/en/stable/news/", + "wheel_tags": [ + "py2-none-any", + "py3-none-any" + ], + "wheel_version": "1.0", + "wheel_generator": "bdist_wheel (0.34.2)", + "root_is_purelib": true }, "dependencies": [], "repository_homepage_url": "https://pypi.org/project/pip", diff --git a/tests/packagedcode/data/pypi/site-packages/site-packages-expected.json b/tests/packagedcode/data/pypi/site-packages/site-packages-expected.json index 35cf983f1f7..a40621e7622 100644 --- a/tests/packagedcode/data/pypi/site-packages/site-packages-expected.json +++ b/tests/packagedcode/data/pypi/site-packages/site-packages-expected.json @@ -188,7 +188,13 @@ "Changes": "https://click.palletsprojects.com/changes/", "Twitter": "https://twitter.com/PalletsTeam", "Chat": "https://discord.gg/pallets", - "license_file": "LICENSE.rst" + "license_file": "LICENSE.rst", + "wheel_tags": [ + "py3-none-any" + ], + "wheel_version": "1.0", + "wheel_generator": "bdist_wheel (0.37.1)", + "root_is_purelib": true }, "repository_homepage_url": "https://pypi.org/project/click", "repository_download_url": "https://pypi.org/packages/source/c/click/click-8.0.4.tar.gz", @@ -307,7 +313,14 @@ "is_virtual": false, "extra_data": { "Documentation": "https://pip.pypa.io", - "Changelog": "https://pip.pypa.io/en/stable/news/" + "Changelog": "https://pip.pypa.io/en/stable/news/", + "wheel_tags": [ + "py2-none-any", + "py3-none-any" + ], + "wheel_version": "1.0", + "wheel_generator": "bdist_wheel (0.34.2)", + "root_is_purelib": true }, "repository_homepage_url": "https://pypi.org/project/pip", "repository_download_url": "https://pypi.org/packages/source/p/pip/pip-20.2.2.tar.gz", @@ -719,7 +732,13 @@ "Changes": "https://click.palletsprojects.com/changes/", "Twitter": "https://twitter.com/PalletsTeam", "Chat": "https://discord.gg/pallets", - "license_file": "LICENSE.rst" + "license_file": "LICENSE.rst", + "wheel_tags": [ + "py3-none-any" + ], + "wheel_version": "1.0", + "wheel_generator": "bdist_wheel (0.37.1)", + "root_is_purelib": true }, "dependencies": [ { @@ -1082,7 +1101,14 @@ "is_virtual": false, "extra_data": { "Documentation": "https://pip.pypa.io", - "Changelog": "https://pip.pypa.io/en/stable/news/" + "Changelog": "https://pip.pypa.io/en/stable/news/", + "wheel_tags": [ + "py2-none-any", + "py3-none-any" + ], + "wheel_version": "1.0", + "wheel_generator": "bdist_wheel (0.34.2)", + "root_is_purelib": true }, "dependencies": [], "repository_homepage_url": "https://pypi.org/project/pip", diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/daglib_wheel_extracted-expected.json b/tests/packagedcode/data/pypi/unpacked_wheel/daglib_wheel_extracted-expected.json index cb0ad38bcc4..3f1af958aa9 100644 --- a/tests/packagedcode/data/pypi/unpacked_wheel/daglib_wheel_extracted-expected.json +++ b/tests/packagedcode/data/pypi/unpacked_wheel/daglib_wheel_extracted-expected.json @@ -93,7 +93,13 @@ "is_private": false, "is_virtual": false, "extra_data": { - "Documentation": "https://mharrisb1.github.io/daglib/" + "Documentation": "https://mharrisb1.github.io/daglib/", + "wheel_tags": [ + "py3-none-any" + ], + "wheel_version": "1.0", + "wheel_generator": "poetry 1.0.8", + "root_is_purelib": true }, "repository_homepage_url": "https://pypi.org/project/daglib", "repository_download_url": "https://pypi.org/packages/source/d/daglib/daglib-0.6.0.tar.gz", @@ -363,7 +369,13 @@ "is_private": false, "is_virtual": false, "extra_data": { - "Documentation": "https://mharrisb1.github.io/daglib/" + "Documentation": "https://mharrisb1.github.io/daglib/", + "wheel_tags": [ + "py3-none-any" + ], + "wheel_version": "1.0", + "wheel_generator": "poetry 1.0.8", + "root_is_purelib": true }, "dependencies": [ { diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.0/Jinja2-2.10.dist-info-expected.json b/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.0/Jinja2-2.10.dist-info-expected.json index 2d83f3cfbf6..b799e119084 100644 --- a/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.0/Jinja2-2.10.dist-info-expected.json +++ b/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.0/Jinja2-2.10.dist-info-expected.json @@ -673,7 +673,15 @@ ], "is_private": false, "is_virtual": false, - "extra_data": {}, + "extra_data": { + "wheel_tags": [ + "py2-none-any", + "py3-none-any" + ], + "wheel_version": "1.0", + "wheel_generator": "bdist_wheel (0.30.0)", + "root_is_purelib": true + }, "dependencies": [ { "purl": "pkg:pypi/markupsafe", diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.0/python_mimeparse-1.6.0.dist-info-expected.json b/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.0/python_mimeparse-1.6.0.dist-info-expected.json index 564165b4113..450948be679 100644 --- a/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.0/python_mimeparse-1.6.0.dist-info-expected.json +++ b/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.0/python_mimeparse-1.6.0.dist-info-expected.json @@ -140,7 +140,14 @@ "is_private": false, "is_virtual": false, "extra_data": { - "Download-URL": "https://github.com/dbtsai/python-mimeparse/tarball/1.6.0" + "Download-URL": "https://github.com/dbtsai/python-mimeparse/tarball/1.6.0", + "wheel_tags": [ + "py2-none-any", + "py3-none-any" + ], + "wheel_version": "1.0", + "wheel_generator": "bdist_wheel (0.24.0)", + "root_is_purelib": true }, "dependencies": [], "repository_homepage_url": "https://pypi.org/project/python-mimeparse", diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.0/toml-0.10.1.dist-info-expected.json b/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.0/toml-0.10.1.dist-info-expected.json index ff6dd8a69ee..c1d3a328272 100644 --- a/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.0/toml-0.10.1.dist-info-expected.json +++ b/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.0/toml-0.10.1.dist-info-expected.json @@ -286,7 +286,15 @@ ], "is_private": false, "is_virtual": false, - "extra_data": {}, + "extra_data": { + "wheel_tags": [ + "py2-none-any", + "py3-none-any" + ], + "wheel_version": "1.0", + "wheel_generator": "bdist_wheel (0.24.0)", + "root_is_purelib": true + }, "dependencies": [], "repository_homepage_url": "https://pypi.org/project/toml", "repository_download_url": "https://pypi.org/packages/source/t/toml/toml-0.10.1.tar.gz", diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.0/urllib3-1.26.4.dist-info-expected.json b/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.0/urllib3-1.26.4.dist-info-expected.json index b6fdf9dc09c..aa9ebdf71d7 100644 --- a/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.0/urllib3-1.26.4.dist-info-expected.json +++ b/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.0/urllib3-1.26.4.dist-info-expected.json @@ -882,7 +882,14 @@ "is_private": false, "is_virtual": false, "extra_data": { - "Documentation": "https://urllib3.readthedocs.io/" + "Documentation": "https://urllib3.readthedocs.io/", + "wheel_tags": [ + "py2-none-any", + "py3-none-any" + ], + "wheel_version": "1.0", + "wheel_generator": "bdist_wheel (0.24.0)", + "root_is_purelib": true }, "dependencies": [ { diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.1/haruka_bot-1.2.3.dist-info-expected.json b/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.1/haruka_bot-1.2.3.dist-info-expected.json index 84fa659f9e8..f6753783cbe 100644 --- a/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.1/haruka_bot-1.2.3.dist-info-expected.json +++ b/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.1/haruka_bot-1.2.3.dist-info-expected.json @@ -279,7 +279,13 @@ "is_private": false, "is_virtual": false, "extra_data": { - "Documentation": "https://github.com/SK-415/HarukaBot#readme" + "Documentation": "https://github.com/SK-415/HarukaBot#readme", + "wheel_tags": [ + "py3-none-any" + ], + "wheel_version": "1.0", + "wheel_generator": "poetry 1.0.2", + "root_is_purelib": true }, "dependencies": [ { diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.1/plugincode-21.1.21.dist-info-expected.json b/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.1/plugincode-21.1.21.dist-info-expected.json index 3898023e4ae..df64151edb7 100644 --- a/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.1/plugincode-21.1.21.dist-info-expected.json +++ b/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.1/plugincode-21.1.21.dist-info-expected.json @@ -286,7 +286,14 @@ ], "is_private": false, "is_virtual": false, - "extra_data": {}, + "extra_data": { + "wheel_tags": [ + "py3-none-any" + ], + "wheel_version": "1.0", + "wheel_generator": "bdist_wheel (0.36.2)", + "root_is_purelib": true + }, "dependencies": [ { "purl": "pkg:pypi/click", diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.1/with_sources/anonapi-0.0.19.dist-info-expected.json b/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.1/with_sources/anonapi-0.0.19.dist-info-expected.json index db651db4dab..6b7775af29c 100644 --- a/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.1/with_sources/anonapi-0.0.19.dist-info-expected.json +++ b/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.1/with_sources/anonapi-0.0.19.dist-info-expected.json @@ -204,7 +204,15 @@ ], "is_private": false, "is_virtual": false, - "extra_data": {}, + "extra_data": { + "wheel_tags": [ + "py2-none-any", + "py3-none-any" + ], + "wheel_version": "1.0", + "wheel_generator": "bdist_wheel (0.32.2)", + "root_is_purelib": true + }, "dependencies": [ { "purl": "pkg:pypi/pyyaml", diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.2/trimesh-4.6.1.dist-info-expected.json b/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.2/trimesh-4.6.1.dist-info-expected.json index 37fb857cf5a..bac2d1f794a 100644 --- a/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.2/trimesh-4.6.1.dist-info-expected.json +++ b/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.2/trimesh-4.6.1.dist-info-expected.json @@ -1,602 +1,602 @@ -[ - { - "type": "pypi", - "namespace": null, - "name": "trimesh", - "version": "4.6.1", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Import, export, process, analyze and view triangular meshes.", - "release_date": null, - "parties": [ - { - "type": "person", - "role": "author", - "name": null, - "email": "Michael Dawson-Haggerty ", - "url": null - } - ], - "keywords": [ - "graphics", - "mesh", - "geometry", - "3D", - "Development Status :: 4 - Beta", - "Programming Language :: Python", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Natural Language :: English", - "Topic :: Scientific/Engineering", - "Topic :: Multimedia :: Graphics", - "Topic :: Multimedia :: Graphics :: 3D Modeling" - ], - "homepage_url": "https://github.com/mikedh/trimesh", - "download_url": null, - "size": null, - "sha1": null, - "md5": null, - "sha256": null, - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": null, - "holder": null, - "declared_license_expression": "mit", - "declared_license_expression_spdx": "MIT", - "license_detections": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "matches": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": null, - "start_line": 1, - "end_line": 1, - "matcher": "2-aho", - "score": 100.0, - "matched_length": 4, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "mit_26.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_26.RULE", - "matched_text": "The MIT License (MIT)" - }, - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": null, - "start_line": 5, - "end_line": 21, - "matcher": "2-aho", - "score": 100.0, - "matched_length": 161, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "mit.LICENSE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.LICENSE", - "matched_text": "Permission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE." - } - ], - "identifier": "mit-86fcf017-3572-9813-b7e8-0a10ec4a120f" - }, - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "matches": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": null, - "start_line": 1, - "end_line": 1, - "matcher": "1-hash", - "score": 100.0, - "matched_length": 5, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "pypi_mit_license.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_mit_license.RULE", - "matched_text": "- 'License :: OSI Approved :: MIT License'" - } - ], - "identifier": "mit-24a5293c-14d7-5403-efac-1a8b7532c0e8" - } - ], - "other_license_expression": null, - "other_license_expression_spdx": null, - "other_license_detections": [], - "extracted_license_statement": "license: |\n The MIT License (MIT)\n\n Copyright (c) 2023 Michael Dawson-Haggerty\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\nclassifiers:\n - 'License :: OSI Approved :: MIT License'\n", - "notice_text": null, - "source_packages": [], - "file_references": [], - "is_private": false, - "is_virtual": false, - "extra_data": { - "documentation": "https://trimesh.org", - "license_file": "LICENSE.md" - }, - "dependencies": [ - { - "purl": "pkg:pypi/numpy", - "extracted_requirement": ">=1.20", - "scope": "install", - "is_runtime": true, - "is_optional": false, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/colorlog", - "extracted_requirement": null, - "scope": "easy", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/manifold3d", - "extracted_requirement": ">=2.3.0", - "scope": "easy", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/chardet", - "extracted_requirement": null, - "scope": "easy", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/lxml", - "extracted_requirement": null, - "scope": "easy", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/jsonschema", - "extracted_requirement": null, - "scope": "easy", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/networkx", - "extracted_requirement": null, - "scope": "easy", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/svg-path", - "extracted_requirement": null, - "scope": "easy", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pycollada", - "extracted_requirement": null, - "scope": "easy", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/setuptools", - "extracted_requirement": null, - "scope": "easy", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/shapely", - "extracted_requirement": null, - "scope": "easy", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/xxhash", - "extracted_requirement": null, - "scope": "easy", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/rtree", - "extracted_requirement": null, - "scope": "easy", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/httpx", - "extracted_requirement": null, - "scope": "easy", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/scipy", - "extracted_requirement": null, - "scope": "easy", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/embreex", - "extracted_requirement": null, - "scope": "easy", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pillow", - "extracted_requirement": null, - "scope": "easy", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/xatlas", - "extracted_requirement": null, - "scope": "easy", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/vhacdx", - "extracted_requirement": null, - "scope": "easy", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": { - "python_version": ">= 3.9" - } - }, - { - "purl": "pkg:pypi/mapbox-earcut", - "extracted_requirement": ">=1.0.2", - "scope": "easy", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": { - "python_version": ">= 3.9" - } - }, - { - "purl": "pkg:pypi/sympy", - "extracted_requirement": null, - "scope": "recommend", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/meshio", - "extracted_requirement": null, - "scope": "recommend", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pyglet", - "extracted_requirement": "<2", - "scope": "recommend", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/psutil", - "extracted_requirement": null, - "scope": "recommend", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/scikit-image", - "extracted_requirement": null, - "scope": "recommend", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/fast-simplification", - "extracted_requirement": null, - "scope": "recommend", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/openctm", - "extracted_requirement": null, - "scope": "recommend", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/cascadio", - "extracted_requirement": null, - "scope": "recommend", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pytest-cov", - "extracted_requirement": null, - "scope": "test", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pytest", - "extracted_requirement": null, - "scope": "test", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pyinstrument", - "extracted_requirement": null, - "scope": "test", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/ruff", - "extracted_requirement": null, - "scope": "test", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/coveralls", - "extracted_requirement": null, - "scope": "test-more", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pyright", - "extracted_requirement": null, - "scope": "test-more", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/ezdxf", - "extracted_requirement": null, - "scope": "test-more", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pytest-beartype", - "extracted_requirement": null, - "scope": "test-more", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": { - "python_version": ">= 3.10" - } - }, - { - "purl": "pkg:pypi/matplotlib", - "extracted_requirement": null, - "scope": "test-more", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pymeshlab", - "extracted_requirement": null, - "scope": "test-more", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/triangle", - "extracted_requirement": null, - "scope": "test-more", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/ipython", - "extracted_requirement": null, - "scope": "test-more", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/gmsh@4.12.2", - "extracted_requirement": "==4.12.2", - "scope": "deprecated", - "is_runtime": true, - "is_optional": true, - "is_pinned": true, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/trimesh", - "extracted_requirement": null, - "scope": "all", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - } - ], - "repository_homepage_url": "https://pypi.org/project/trimesh", - "repository_download_url": "https://pypi.org/packages/source/t/trimesh/trimesh-4.6.1.tar.gz", - "api_data_url": "https://pypi.org/pypi/trimesh/4.6.1/json", - "datasource_id": "pypi_wheel_metadata", - "purl": "pkg:pypi/trimesh@4.6.1" - } -] +[ + { + "type": "pypi", + "namespace": null, + "name": "trimesh", + "version": "4.6.1", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "Import, export, process, analyze and view triangular meshes.", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": null, + "email": "Michael Dawson-Haggerty ", + "url": null + } + ], + "keywords": [ + "graphics", + "mesh", + "geometry", + "3D", + "Development Status :: 4 - Beta", + "Programming Language :: Python", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Natural Language :: English", + "Topic :: Scientific/Engineering", + "Topic :: Multimedia :: Graphics", + "Topic :: Multimedia :: Graphics :: 3D Modeling" + ], + "homepage_url": "https://github.com/mikedh/trimesh", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "holder": null, + "declared_license_expression": "mit", + "declared_license_expression_spdx": "MIT", + "license_detections": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": null, + "start_line": 1, + "end_line": 1, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 4, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "mit_26.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_26.RULE", + "matched_text": "The MIT License (MIT)" + }, + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": null, + "start_line": 5, + "end_line": 21, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 161, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "mit.LICENSE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.LICENSE", + "matched_text": "Permission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE." + } + ], + "identifier": "mit-86fcf017-3572-9813-b7e8-0a10ec4a120f" + }, + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": null, + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 100.0, + "matched_length": 5, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "pypi_mit_license.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_mit_license.RULE", + "matched_text": "- 'License :: OSI Approved :: MIT License'" + } + ], + "identifier": "mit-24a5293c-14d7-5403-efac-1a8b7532c0e8" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "license: |\n The MIT License (MIT)\n\n Copyright (c) 2023 Michael Dawson-Haggerty\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\nclassifiers:\n - 'License :: OSI Approved :: MIT License'\n", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": false, + "extra_data": { + "documentation": "https://trimesh.org", + "license_file": "LICENSE.md" + }, + "dependencies": [ + { + "purl": "pkg:pypi/numpy", + "extracted_requirement": ">=1.20", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/colorlog", + "extracted_requirement": null, + "scope": "easy", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/manifold3d", + "extracted_requirement": ">=2.3.0", + "scope": "easy", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/chardet", + "extracted_requirement": null, + "scope": "easy", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/lxml", + "extracted_requirement": null, + "scope": "easy", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/jsonschema", + "extracted_requirement": null, + "scope": "easy", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/networkx", + "extracted_requirement": null, + "scope": "easy", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/svg-path", + "extracted_requirement": null, + "scope": "easy", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pycollada", + "extracted_requirement": null, + "scope": "easy", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/setuptools", + "extracted_requirement": null, + "scope": "easy", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/shapely", + "extracted_requirement": null, + "scope": "easy", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/xxhash", + "extracted_requirement": null, + "scope": "easy", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/rtree", + "extracted_requirement": null, + "scope": "easy", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/httpx", + "extracted_requirement": null, + "scope": "easy", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/scipy", + "extracted_requirement": null, + "scope": "easy", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/embreex", + "extracted_requirement": null, + "scope": "easy", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pillow", + "extracted_requirement": null, + "scope": "easy", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/xatlas", + "extracted_requirement": null, + "scope": "easy", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/vhacdx", + "extracted_requirement": null, + "scope": "easy", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": { + "python_version": ">= 3.9" + } + }, + { + "purl": "pkg:pypi/mapbox-earcut", + "extracted_requirement": ">=1.0.2", + "scope": "easy", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": { + "python_version": ">= 3.9" + } + }, + { + "purl": "pkg:pypi/sympy", + "extracted_requirement": null, + "scope": "recommend", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/meshio", + "extracted_requirement": null, + "scope": "recommend", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pyglet", + "extracted_requirement": "<2", + "scope": "recommend", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/psutil", + "extracted_requirement": null, + "scope": "recommend", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/scikit-image", + "extracted_requirement": null, + "scope": "recommend", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/fast-simplification", + "extracted_requirement": null, + "scope": "recommend", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/openctm", + "extracted_requirement": null, + "scope": "recommend", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/cascadio", + "extracted_requirement": null, + "scope": "recommend", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-cov", + "extracted_requirement": null, + "scope": "test", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": null, + "scope": "test", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pyinstrument", + "extracted_requirement": null, + "scope": "test", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/ruff", + "extracted_requirement": null, + "scope": "test", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/coveralls", + "extracted_requirement": null, + "scope": "test-more", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pyright", + "extracted_requirement": null, + "scope": "test-more", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/ezdxf", + "extracted_requirement": null, + "scope": "test-more", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-beartype", + "extracted_requirement": null, + "scope": "test-more", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": { + "python_version": ">= 3.10" + } + }, + { + "purl": "pkg:pypi/matplotlib", + "extracted_requirement": null, + "scope": "test-more", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pymeshlab", + "extracted_requirement": null, + "scope": "test-more", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/triangle", + "extracted_requirement": null, + "scope": "test-more", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/ipython", + "extracted_requirement": null, + "scope": "test-more", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/gmsh@4.12.2", + "extracted_requirement": "==4.12.2", + "scope": "deprecated", + "is_runtime": true, + "is_optional": true, + "is_pinned": true, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/trimesh", + "extracted_requirement": null, + "scope": "all", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": "https://pypi.org/project/trimesh", + "repository_download_url": "https://pypi.org/packages/source/t/trimesh/trimesh-4.6.1.tar.gz", + "api_data_url": "https://pypi.org/pypi/trimesh/4.6.1/json", + "datasource_id": "pypi_wheel_metadata", + "purl": "pkg:pypi/trimesh@4.6.1" + } +] \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.4/narwhals-1.29.0.dist-info-expected.json b/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.4/narwhals-1.29.0.dist-info-expected.json index f2b162dc34f..bc2ae4814f9 100644 --- a/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.4/narwhals-1.29.0.dist-info-expected.json +++ b/tests/packagedcode/data/pypi/unpacked_wheel/metadata-2.4/narwhals-1.29.0.dist-info-expected.json @@ -1,676 +1,676 @@ -[ - { - "type": "pypi", - "namespace": null, - "name": "narwhals", - "version": "1.29.0", - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": "Extremely lightweight compatibility layer between dataframe libraries", - "release_date": null, - "parties": [ - { - "type": "person", - "role": "author", - "name": null, - "email": "Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com>", - "url": null - } - ], - "keywords": [ - "cudf", - "dask", - "dataframes", - "interoperability", - "modin", - "pandas", - "polars", - "pyarrow", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Typing :: Typed" - ], - "homepage_url": "https://github.com/narwhals-dev/narwhals", - "download_url": null, - "size": null, - "sha1": null, - "md5": null, - "sha256": null, - "sha512": null, - "bug_tracking_url": "https://github.com/narwhals-dev/narwhals/issues", - "code_view_url": null, - "vcs_url": "https://github.com/narwhals-dev/narwhals", - "copyright": null, - "holder": null, - "declared_license_expression": "mit", - "declared_license_expression_spdx": "MIT", - "license_detections": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "matches": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": null, - "start_line": 1, - "end_line": 1, - "matcher": "1-hash", - "score": 100.0, - "matched_length": 5, - "match_coverage": 100.0, - "rule_relevance": 100, - "rule_identifier": "pypi_mit_license.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_mit_license.RULE", - "matched_text": "- 'License :: OSI Approved :: MIT License'" - } - ], - "identifier": "mit-24a5293c-14d7-5403-efac-1a8b7532c0e8" - } - ], - "other_license_expression": null, - "other_license_expression_spdx": null, - "other_license_detections": [], - "extracted_license_statement": "classifiers:\n - 'License :: OSI Approved :: MIT License'\n", - "notice_text": null, - "source_packages": [], - "file_references": [], - "is_private": false, - "is_virtual": false, - "extra_data": { - "Documentation": "https://narwhals-dev.github.io/narwhals/", - "license_file": "LICENSE.md" - }, - "dependencies": [ - { - "purl": "pkg:pypi/duckdb", - "extracted_requirement": null, - "scope": "core", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pandas", - "extracted_requirement": null, - "scope": "core", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/polars", - "extracted_requirement": null, - "scope": "core", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pyarrow", - "extracted_requirement": null, - "scope": "core", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pyarrow-stubs", - "extracted_requirement": null, - "scope": "core", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/cudf", - "extracted_requirement": ">=24.10.0", - "scope": "cudf", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/dask", - "extracted_requirement": ">=2024.8", - "scope": "dask", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/covdefaults", - "extracted_requirement": null, - "scope": "dev", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/hypothesis", - "extracted_requirement": null, - "scope": "dev", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/mypy", - "extracted_requirement": "~=1.15.0", - "scope": "dev", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pandas-stubs", - "extracted_requirement": null, - "scope": "dev", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pre-commit", - "extracted_requirement": null, - "scope": "dev", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pyright", - "extracted_requirement": null, - "scope": "dev", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pytest", - "extracted_requirement": null, - "scope": "dev", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pytest-cov", - "extracted_requirement": null, - "scope": "dev", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pytest-env", - "extracted_requirement": null, - "scope": "dev", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pytest-randomly", - "extracted_requirement": null, - "scope": "dev", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/typing-extensions", - "extracted_requirement": null, - "scope": "dev", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/black", - "extracted_requirement": null, - "scope": "docs", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/duckdb", - "extracted_requirement": null, - "scope": "docs", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/jinja2", - "extracted_requirement": null, - "scope": "docs", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/markdown-exec", - "extracted_requirement": null, - "scope": "docs", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/mkdocs", - "extracted_requirement": null, - "scope": "docs", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/mkdocs-autorefs", - "extracted_requirement": null, - "scope": "docs", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/mkdocs-material", - "extracted_requirement": null, - "scope": "docs", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/mkdocstrings-python", - "extracted_requirement": ">=1.16", - "scope": "docs", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/mkdocstrings", - "extracted_requirement": null, - "scope": "docs", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pandas", - "extracted_requirement": null, - "scope": "docs", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/polars", - "extracted_requirement": ">=1.0.0", - "scope": "docs", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pyarrow", - "extracted_requirement": null, - "scope": "docs", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/duckdb", - "extracted_requirement": ">=1.0", - "scope": "duckdb", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/scikit-learn", - "extracted_requirement": null, - "scope": "extra", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/ibis-framework", - "extracted_requirement": ">=6.0.0", - "scope": "ibis", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/packaging", - "extracted_requirement": null, - "scope": "ibis", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pyarrow-hotfix", - "extracted_requirement": null, - "scope": "ibis", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/rich", - "extracted_requirement": null, - "scope": "ibis", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/modin", - "extracted_requirement": null, - "scope": "modin", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pandas", - "extracted_requirement": ">=0.25.3", - "scope": "pandas", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/polars", - "extracted_requirement": ">=0.20.3", - "scope": "polars", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pyarrow", - "extracted_requirement": ">=11.0.0", - "scope": "pyarrow", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pyspark", - "extracted_requirement": ">=3.5.0", - "scope": "pyspark", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/sqlframe", - "extracted_requirement": ">=3.22.0", - "scope": "sqlframe", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/covdefaults", - "extracted_requirement": null, - "scope": "tests", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/hypothesis", - "extracted_requirement": null, - "scope": "tests", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pytest", - "extracted_requirement": null, - "scope": "tests", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pytest-cov", - "extracted_requirement": null, - "scope": "tests", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pytest-env", - "extracted_requirement": null, - "scope": "tests", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pytest-randomly", - "extracted_requirement": null, - "scope": "tests", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/typing-extensions", - "extracted_requirement": null, - "scope": "tests", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/mypy", - "extracted_requirement": "~=1.15.0", - "scope": "typing", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pandas-stubs", - "extracted_requirement": null, - "scope": "typing", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/pyright", - "extracted_requirement": null, - "scope": "typing", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - }, - { - "purl": "pkg:pypi/typing-extensions", - "extracted_requirement": null, - "scope": "typing", - "is_runtime": true, - "is_optional": true, - "is_pinned": false, - "is_direct": true, - "resolved_package": {}, - "extra_data": {} - } - ], - "repository_homepage_url": "https://pypi.org/project/narwhals", - "repository_download_url": "https://pypi.org/packages/source/n/narwhals/narwhals-1.29.0.tar.gz", - "api_data_url": "https://pypi.org/pypi/narwhals/1.29.0/json", - "datasource_id": "pypi_wheel_metadata", - "purl": "pkg:pypi/narwhals@1.29.0" - } -] +[ + { + "type": "pypi", + "namespace": null, + "name": "narwhals", + "version": "1.29.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "Extremely lightweight compatibility layer between dataframe libraries", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": null, + "email": "Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com>", + "url": null + } + ], + "keywords": [ + "cudf", + "dask", + "dataframes", + "interoperability", + "modin", + "pandas", + "polars", + "pyarrow", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Typing :: Typed" + ], + "homepage_url": "https://github.com/narwhals-dev/narwhals", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": "https://github.com/narwhals-dev/narwhals/issues", + "code_view_url": null, + "vcs_url": "https://github.com/narwhals-dev/narwhals", + "copyright": null, + "holder": null, + "declared_license_expression": "mit", + "declared_license_expression_spdx": "MIT", + "license_detections": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": null, + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 100.0, + "matched_length": 5, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "pypi_mit_license.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_mit_license.RULE", + "matched_text": "- 'License :: OSI Approved :: MIT License'" + } + ], + "identifier": "mit-24a5293c-14d7-5403-efac-1a8b7532c0e8" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "classifiers:\n - 'License :: OSI Approved :: MIT License'\n", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": false, + "extra_data": { + "Documentation": "https://narwhals-dev.github.io/narwhals/", + "license_file": "LICENSE.md" + }, + "dependencies": [ + { + "purl": "pkg:pypi/duckdb", + "extracted_requirement": null, + "scope": "core", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pandas", + "extracted_requirement": null, + "scope": "core", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/polars", + "extracted_requirement": null, + "scope": "core", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pyarrow", + "extracted_requirement": null, + "scope": "core", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pyarrow-stubs", + "extracted_requirement": null, + "scope": "core", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/cudf", + "extracted_requirement": ">=24.10.0", + "scope": "cudf", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/dask", + "extracted_requirement": ">=2024.8", + "scope": "dask", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/covdefaults", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/hypothesis", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/mypy", + "extracted_requirement": "~=1.15.0", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pandas-stubs", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pre-commit", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pyright", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-cov", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-env", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-randomly", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/typing-extensions", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/black", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/duckdb", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/jinja2", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/markdown-exec", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/mkdocs", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/mkdocs-autorefs", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/mkdocs-material", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/mkdocstrings-python", + "extracted_requirement": ">=1.16", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/mkdocstrings", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pandas", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/polars", + "extracted_requirement": ">=1.0.0", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pyarrow", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/duckdb", + "extracted_requirement": ">=1.0", + "scope": "duckdb", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/scikit-learn", + "extracted_requirement": null, + "scope": "extra", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/ibis-framework", + "extracted_requirement": ">=6.0.0", + "scope": "ibis", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/packaging", + "extracted_requirement": null, + "scope": "ibis", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pyarrow-hotfix", + "extracted_requirement": null, + "scope": "ibis", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/rich", + "extracted_requirement": null, + "scope": "ibis", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/modin", + "extracted_requirement": null, + "scope": "modin", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pandas", + "extracted_requirement": ">=0.25.3", + "scope": "pandas", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/polars", + "extracted_requirement": ">=0.20.3", + "scope": "polars", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pyarrow", + "extracted_requirement": ">=11.0.0", + "scope": "pyarrow", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pyspark", + "extracted_requirement": ">=3.5.0", + "scope": "pyspark", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sqlframe", + "extracted_requirement": ">=3.22.0", + "scope": "sqlframe", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/covdefaults", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/hypothesis", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-cov", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-env", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-randomly", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/typing-extensions", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/mypy", + "extracted_requirement": "~=1.15.0", + "scope": "typing", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pandas-stubs", + "extracted_requirement": null, + "scope": "typing", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pyright", + "extracted_requirement": null, + "scope": "typing", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/typing-extensions", + "extracted_requirement": null, + "scope": "typing", + "is_runtime": true, + "is_optional": true, + "is_pinned": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": "https://pypi.org/project/narwhals", + "repository_download_url": "https://pypi.org/packages/source/n/narwhals/narwhals-1.29.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/narwhals/1.29.0/json", + "datasource_id": "pypi_wheel_metadata", + "purl": "pkg:pypi/narwhals@1.29.0" + } +] \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/cryptography-41.0.0.dist-info-expected.json b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/cryptography-41.0.0.dist-info-expected.json new file mode 100644 index 00000000000..08ef845c961 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/cryptography-41.0.0.dist-info-expected.json @@ -0,0 +1,85 @@ +[ + { + "type": "pypi", + "namespace": null, + "name": "cryptography", + "version": "41.0.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "Cryptographic recipes and primitives", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "The cryptography developers", + "email": null, + "url": null + } + ], + "keywords": [], + "homepage_url": "https://github.com/pyca/cryptography", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "holder": null, + "declared_license_expression": "apache-2.0 OR bsd-new", + "declared_license_expression_spdx": "Apache-2.0 OR BSD-3-Clause", + "license_detections": [ + { + "license_expression": "apache-2.0 OR bsd-new", + "license_expression_spdx": "Apache-2.0 OR BSD-3-Clause", + "matches": [ + { + "license_expression": "apache-2.0 OR bsd-new", + "license_expression_spdx": "Apache-2.0 OR BSD-3-Clause", + "from_file": null, + "start_line": 1, + "end_line": 1, + "matcher": "1-spdx-id", + "score": 100.0, + "matched_length": 7, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "spdx-license-identifier-apache_2_0_or_bsd_new-9e2c047dc96b4eb698fc3278b976613ceade5228", + "rule_url": null, + "matched_text": "Apache-2.0 OR BSD-3-Clause" + } + ], + "identifier": "apache_2_0_or_bsd_new-c172d894-de7e-a89b-a8ac-7b6fb5d7dc95" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "license: Apache-2.0 OR BSD-3-Clause\n", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": false, + "extra_data": { + "wheel_tags": [ + "cp37-abi3-manylinux_2_28_x86_64", + "cp37-abi3-manylinux_2_17_x86_64" + ], + "wheel_version": "1.0", + "wheel_generator": "bdist_wheel (0.37.1)", + "root_is_purelib": false + }, + "dependencies": [], + "repository_homepage_url": "https://pypi.org/project/cryptography", + "repository_download_url": "https://pypi.org/packages/source/c/cryptography/cryptography-41.0.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/cryptography/41.0.0/json", + "datasource_id": "pypi_wheel_metadata", + "purl": "pkg:pypi/cryptography@41.0.0" + } +] \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/cryptography-41.0.0.dist-info/METADATA b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/cryptography-41.0.0.dist-info/METADATA new file mode 100644 index 00000000000..b43936a683f --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/cryptography-41.0.0.dist-info/METADATA @@ -0,0 +1,7 @@ +Metadata-Version: 2.1 +Name: cryptography +Version: 41.0.0 +Summary: Cryptographic recipes and primitives +Home-page: https://github.com/pyca/cryptography +Author: The cryptography developers +License: Apache-2.0 OR BSD-3-Clause diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/cryptography-41.0.0.dist-info/WHEEL b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/cryptography-41.0.0.dist-info/WHEEL new file mode 100644 index 00000000000..e23145847dd --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/cryptography-41.0.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: false +Tag: cp37-abi3-manylinux_2_28_x86_64 +Tag: cp37-abi3-manylinux_2_17_x86_64 diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/no-wheel-1.0.0.dist-info-expected.json b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/no-wheel-1.0.0.dist-info-expected.json new file mode 100644 index 00000000000..790e75ed533 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/no-wheel-1.0.0.dist-info-expected.json @@ -0,0 +1,69 @@ +[ + { + "type": "pypi", + "namespace": null, + "name": "no-wheel", + "version": "1.0.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "A package without WHEEL file", + "release_date": null, + "parties": [], + "keywords": [], + "homepage_url": null, + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "holder": null, + "declared_license_expression": "mit", + "declared_license_expression_spdx": "MIT", + "license_detections": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": null, + "start_line": 1, + "end_line": 1, + "matcher": "1-spdx-id", + "score": 100.0, + "matched_length": 1, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "spdx-license-identifier-mit-5da48780aba670b0860c46d899ed42a0f243ff06", + "rule_url": null, + "matched_text": "MIT" + } + ], + "identifier": "mit-a822f434-d61f-f2b1-c792-8b8cb9e7b9bf" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "license: MIT\n", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": false, + "extra_data": {}, + "dependencies": [], + "repository_homepage_url": "https://pypi.org/project/no-wheel", + "repository_download_url": "https://pypi.org/packages/source/n/no-wheel/no-wheel-1.0.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/no-wheel/1.0.0/json", + "datasource_id": "pypi_wheel_metadata", + "purl": "pkg:pypi/no-wheel@1.0.0" + } +] \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/no-wheel-1.0.0.dist-info/METADATA b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/no-wheel-1.0.0.dist-info/METADATA new file mode 100644 index 00000000000..d5933e0ded3 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/no-wheel-1.0.0.dist-info/METADATA @@ -0,0 +1,5 @@ +Metadata-Version: 2.1 +Name: no-wheel +Version: 1.0.0 +Summary: A package without WHEEL file +License: MIT diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/numpy-1.23.0.dist-info-expected.json b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/numpy-1.23.0.dist-info-expected.json new file mode 100644 index 00000000000..0236ec703fd --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/numpy-1.23.0.dist-info-expected.json @@ -0,0 +1,84 @@ +[ + { + "type": "pypi", + "namespace": null, + "name": "numpy", + "version": "1.23.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "NumPy scientific computing", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "Travis E. Oliphant et al.", + "email": null, + "url": null + } + ], + "keywords": [], + "homepage_url": "https://www.numpy.org", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "holder": null, + "declared_license_expression": "bsd-new", + "declared_license_expression_spdx": "BSD-3-Clause", + "license_detections": [ + { + "license_expression": "bsd-new", + "license_expression_spdx": "BSD-3-Clause", + "matches": [ + { + "license_expression": "bsd-new", + "license_expression_spdx": "BSD-3-Clause", + "from_file": null, + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 100.0, + "matched_length": 3, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "bsd-new_10.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/bsd-new_10.RULE", + "matched_text": "BSD-3-Clause" + } + ], + "identifier": "bsd_new-50fa5753-f24d-ec04-33a1-36bb8ac0492c" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "license: BSD-3-Clause\n", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": false, + "extra_data": { + "wheel_tags": [ + "cp310-cp310-manylinux_2_17_x86_64" + ], + "wheel_version": "1.0", + "wheel_generator": "bdist_wheel (0.37.1)", + "root_is_purelib": false + }, + "dependencies": [], + "repository_homepage_url": "https://pypi.org/project/numpy", + "repository_download_url": "https://pypi.org/packages/source/n/numpy/numpy-1.23.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/numpy/1.23.0/json", + "datasource_id": "pypi_wheel_metadata", + "purl": "pkg:pypi/numpy@1.23.0" + } +] \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/numpy-1.23.0.dist-info/METADATA b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/numpy-1.23.0.dist-info/METADATA new file mode 100644 index 00000000000..58a50c60bc6 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/numpy-1.23.0.dist-info/METADATA @@ -0,0 +1,7 @@ +Metadata-Version: 2.1 +Name: numpy +Version: 1.23.0 +Summary: NumPy scientific computing +Home-page: https://www.numpy.org +Author: Travis E. Oliphant et al. +License: BSD-3-Clause diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/numpy-1.23.0.dist-info/WHEEL b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/numpy-1.23.0.dist-info/WHEEL new file mode 100644 index 00000000000..33ed7941f0a --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/numpy-1.23.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: false +Tag: cp310-cp310-manylinux_2_17_x86_64 diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/requests-2.28.0.dist-info-expected.json b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/requests-2.28.0.dist-info-expected.json new file mode 100644 index 00000000000..7da7049543b --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/requests-2.28.0.dist-info-expected.json @@ -0,0 +1,84 @@ +[ + { + "type": "pypi", + "namespace": null, + "name": "requests", + "version": "2.28.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "Python HTTP for Humans.", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "Kenneth Reitz", + "email": null, + "url": null + } + ], + "keywords": [], + "homepage_url": "https://requests.readthedocs.io", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": null, + "holder": null, + "declared_license_expression": "apache-2.0", + "declared_license_expression_spdx": "Apache-2.0", + "license_detections": [ + { + "license_expression": "apache-2.0", + "license_expression_spdx": "Apache-2.0", + "matches": [ + { + "license_expression": "apache-2.0", + "license_expression_spdx": "Apache-2.0", + "from_file": null, + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 100.0, + "matched_length": 3, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "spdx_license_id_apache-2.0_for_apache-2.0.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/spdx_license_id_apache-2.0_for_apache-2.0.RULE", + "matched_text": "Apache-2.0" + } + ], + "identifier": "apache_2_0-d66ab77d-a5cc-7104-e702-dc7df61fe9e8" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "license: Apache-2.0\n", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": false, + "extra_data": { + "wheel_tags": [ + "py3-none-any" + ], + "wheel_version": "1.0", + "wheel_generator": "bdist_wheel (0.37.1)", + "root_is_purelib": true + }, + "dependencies": [], + "repository_homepage_url": "https://pypi.org/project/requests", + "repository_download_url": "https://pypi.org/packages/source/r/requests/requests-2.28.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/requests/2.28.0/json", + "datasource_id": "pypi_wheel_metadata", + "purl": "pkg:pypi/requests@2.28.0" + } +] \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/requests-2.28.0.dist-info/METADATA b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/requests-2.28.0.dist-info/METADATA new file mode 100644 index 00000000000..3c5cc84fd57 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/requests-2.28.0.dist-info/METADATA @@ -0,0 +1,7 @@ +Metadata-Version: 2.1 +Name: requests +Version: 2.28.0 +Summary: Python HTTP for Humans. +Home-page: https://requests.readthedocs.io +Author: Kenneth Reitz +License: Apache-2.0 diff --git a/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/requests-2.28.0.dist-info/WHEEL b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/requests-2.28.0.dist-info/WHEEL new file mode 100644 index 00000000000..3cfad325585 --- /dev/null +++ b/tests/packagedcode/data/pypi/unpacked_wheel/with-wheel-tag/requests-2.28.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/tests/packagedcode/test_pypi.py b/tests/packagedcode/test_pypi.py index 3dcfa7d4268..c9e6f311d3f 100644 --- a/tests/packagedcode/test_pypi.py +++ b/tests/packagedcode/test_pypi.py @@ -726,7 +726,118 @@ def check_setup_py_parsing(test_loc): must_exist=False, ) +class TestWheelTagCollection(PackageTester): + """Tests for collecting WHEEL file tags from installed wheels. + See https://github.com/aboutcode-org/scancode-toolkit/issues/4214 + """ + test_data_dir = os.path.join(os.path.dirname(__file__), 'data') + def test_parse_wheel_tags_with_platform_specific_tag(self): + dist_info = self.get_test_loc( + 'pypi/unpacked_wheel/with-wheel-tag/numpy-1.23.0.dist-info' + ) + result = pypi.parse_wheel_tags(dist_info) + assert result == { + 'wheel_version': '1.0', + 'generator': 'bdist_wheel (0.37.1)', + 'root_is_purelib': False, + 'tags': ['cp310-cp310-manylinux_2_17_x86_64'], + } + + def test_parse_wheel_tags_with_multi_tags(self): + dist_info = self.get_test_loc( + 'pypi/unpacked_wheel/with-wheel-tag/cryptography-41.0.0.dist-info' + ) + result = pypi.parse_wheel_tags(dist_info) + assert result == { + 'wheel_version': '1.0', + 'generator': 'bdist_wheel (0.37.1)', + 'root_is_purelib': False, + 'tags': [ + 'cp37-abi3-manylinux_2_28_x86_64', + 'cp37-abi3-manylinux_2_17_x86_64', + ], + } + + def test_parse_wheel_tags_with_pure_wheel(self): + dist_info = self.get_test_loc( + 'pypi/unpacked_wheel/with-wheel-tag/requests-2.28.0.dist-info' + ) + result = pypi.parse_wheel_tags(dist_info) + assert result == { + 'wheel_version': '1.0', + 'generator': 'bdist_wheel (0.37.1)', + 'root_is_purelib': True, + 'tags': ['py3-none-any'], + } + + def test_parse_wheel_tags_with_no_wheel_file(self): + dist_info = self.get_test_loc( + 'pypi/unpacked_wheel/with-wheel-tag/no-wheel-1.0.0.dist-info' + ) + result = pypi.parse_wheel_tags(dist_info) + assert result == {} + + def test_reconstruct_wheel_filename_platform_specific(self): + result = pypi.reconstruct_wheel_filename( + 'numpy', '1.23.0', 'cp310-cp310-manylinux_2_17_x86_64' + ) + assert result == 'numpy-1.23.0-cp310-cp310-manylinux_2_17_x86_64.whl' + + def test_reconstruct_wheel_filename_pure_wheel(self): + result = pypi.reconstruct_wheel_filename( + 'requests', '2.28.0', 'py3-none-any' + ) + assert result == 'requests-2.28.0-py3-none-any.whl' + + def test_reconstruct_wheel_filename_with_hyphenated_name(self): + result = pypi.reconstruct_wheel_filename( + 'my-package', '1.0.0', 'py3-none-any' + ) + assert result == 'my_package-1.0.0-py3-none-any.whl' + + def test_parse_metadata_with_platform_wheel_tag(self): + test_file = self.get_test_loc( + 'pypi/unpacked_wheel/with-wheel-tag/numpy-1.23.0.dist-info/METADATA' + ) + package = pypi.PythonInstalledWheelMetadataFile.parse(test_file) + expected_loc = self.get_test_loc( + 'pypi/unpacked_wheel/with-wheel-tag/numpy-1.23.0.dist-info-expected.json' + ) + self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) + + def test_parse_metadata_with_multi_wheel_tags(self): + test_file = self.get_test_loc( + 'pypi/unpacked_wheel/with-wheel-tag/cryptography-41.0.0.dist-info/METADATA' + ) + package = pypi.PythonInstalledWheelMetadataFile.parse(test_file) + expected_loc = self.get_test_loc( + 'pypi/unpacked_wheel/with-wheel-tag/cryptography-41.0.0.dist-info-expected.json' + ) + self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) + + def test_parse_metadata_with_pure_wheel_tag(self): + test_file = self.get_test_loc( + 'pypi/unpacked_wheel/with-wheel-tag/requests-2.28.0.dist-info/METADATA' + ) + package = pypi.PythonInstalledWheelMetadataFile.parse(test_file) + expected_loc = self.get_test_loc( + 'pypi/unpacked_wheel/with-wheel-tag/requests-2.28.0.dist-info-expected.json' + ) + self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) + + def test_parse_metadata_without_wheel_file(self): + test_file = self.get_test_loc( + 'pypi/unpacked_wheel/with-wheel-tag/no-wheel-1.0.0.dist-info/METADATA' + ) + package = pypi.PythonInstalledWheelMetadataFile.parse(test_file) + expected_loc = self.get_test_loc( + 'pypi/unpacked_wheel/with-wheel-tag/no-wheel-1.0.0.dist-info-expected.json' + ) + self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) + + + env = PackageTester() From 7314e58a1c53801cb5e16603dbc484f34035da58 Mon Sep 17 00:00:00 2001 From: Kareem Samy Date: Wed, 25 Feb 2026 01:41:34 +0200 Subject: [PATCH 2/2] Fix signal-based interrupt on non-main threads Add a check to detect if the current thread is the main thread before attempting to set up signal handlers. On Python 3.14+, signal handlers can only be set up in the main thread of the main interpreter. If not in the main thread, fall back to non-interruptible execution. This fixes the test failure in test_interruptible_can_run_function which was failing with: ValueError: signal only works in main thread of the main interpreter Signed-off-by: Kareem Samy --- src/scancode/interrupt.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/scancode/interrupt.py b/src/scancode/interrupt.py index e26d090567d..63b591f840a 100644 --- a/src/scancode/interrupt.py +++ b/src/scancode/interrupt.py @@ -39,6 +39,8 @@ traceback and `value` is None. """ +import threading + class TimeoutError(Exception): # NOQA pass @@ -80,7 +82,11 @@ class TimeoutError(Exception): # NOQA def interruptible(func, args=None, kwargs=None, timeout=DEFAULT_TIMEOUT): """ POSIX, signals-based interruptible runner. + Falls back to non-interruptible execution if not in main thread. """ + # Signals only work in the main thread + if threading.current_thread() is not threading.main_thread(): + return NO_ERROR, func(*(args or ()), **(kwargs or {})) def handler(signum, frame): raise TimeoutError