Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
Changelog
=========

v34.10.1 (unreleased)
---------------------

- Convert the ``declared_license`` field value return by ``python-inspector`` in
``resolve_pypi_packages``.
Resolving requirements.txt files will now return proper license data.
https://github.com/aboutcode-org/scancode.io/issues/1598

v34.10.0 (2025-03-21)
---------------------

Expand Down
9 changes: 8 additions & 1 deletion scanpipe/pipes/resolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,14 @@ def resolve_pypi_packages(input_location):
prefer_source=True,
)

return inspector_output.packages
packages = inspector_output.packages

# python-inspector returns the `extracted_license_statement` under the
# `declared_license` field.
for package in packages:
package["extracted_license_statement"] = package.get("declared_license", "")

return packages


def resolve_about_package(input_location):
Expand Down
153 changes: 153 additions & 0 deletions scanpipe/tests/data/resolve/python_inspector_resolve_dependencies.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
{
"headers": {
"tool_name": "python-inspector",
"tool_homepageurl": "https://github.com/aboutcode-org/python-inspector",
"tool_version": "0.13.0",
"options": [
"--json -",
"--operating-system linux",
"--python-version 3.12",
"--specifier pip==25.0.1"
],
"notice": "Dependency tree generated with python-inspector.\npython-inspector is a free software tool from nexB Inc. and others.\nVisit https://github.com/aboutcode-org/python-inspector/ for support and download.",
"warnings": [],
"errors": []
},
"files": [],
"packages": [
{
"type": "pypi",
"namespace": null,
"name": "pip",
"version": "25.0.1",
"qualifiers": {},
"subpath": null,
"primary_language": "Python",
"description": "The PyPA recommended tool for installing Python packages.\npip - The Python Package Installer\n==================================\n\n.. |pypi-version| image:: https://img.shields.io/pypi/v/pip.svg\n :target: https://pypi.org/project/pip/\n :alt: PyPI\n\n.. |python-versions| image:: https://img.shields.io/pypi/pyversions/pip\n :target: https://pypi.org/project/pip\n :alt: PyPI - Python Version\n\n.. |docs-badge| image:: https://readthedocs.org/projects/pip/badge/?version=latest\n :target: https://pip.pypa.io/en/latest\n :alt: Documentation\n\n|pypi-version| |python-versions| |docs-badge|\n\npip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes.\n\nPlease take a look at our documentation for how to install and use pip:\n\n* `Installation`_\n* `Usage`_\n\nWe release updates regularly, with a new version every 3 months. Find more details in our documentation:\n\n* `Release notes`_\n* `Release process`_\n\nIf you find bugs, need help, or want to talk to the developers, please use our mailing lists or chat rooms:\n\n* `Issue tracking`_\n* `Discourse channel`_\n* `User IRC`_\n\nIf you want to get involved head over to GitHub to get the source code, look at our development documentation and feel free to jump on the developer mailing lists and chat rooms:\n\n* `GitHub page`_\n* `Development documentation`_\n* `Development IRC`_\n\nCode of Conduct\n---------------\n\nEveryone interacting in the pip project's codebases, issue trackers, chat\nrooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.\n\n.. _package installer: https://packaging.python.org/guides/tool-recommendations/\n.. _Python Package Index: https://pypi.org\n.. _Installation: https://pip.pypa.io/en/stable/installation/\n.. _Usage: https://pip.pypa.io/en/stable/\n.. _Release notes: https://pip.pypa.io/en/stable/news.html\n.. _Release process: https://pip.pypa.io/en/latest/development/release-process/\n.. _GitHub page: https://github.com/pypa/pip\n.. _Development documentation: https://pip.pypa.io/en/latest/development\n.. _Issue tracking: https://github.com/pypa/pip/issues\n.. _Discourse channel: https://discuss.python.org/c/packaging\n.. _User IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa\n.. _Development IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa-dev\n.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md",
"release_date": "2025-02-09T17:14:01",
"parties": [
{
"type": "person",
"role": "author",
"name": null,
"email": "The pip developers <[email protected]>",
"url": null
}
],
"keywords": [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Software Development :: Build Tools"
],
"homepage_url": null,
"download_url": "https://files.pythonhosted.org/packages/c9/bc/b7db44f5f39f9d0494071bddae6880eb645970366d0a200022a1a93d57f5/pip-25.0.1-py3-none-any.whl",
"size": 1841526,
"sha1": null,
"md5": "99f43f22d5321305507b804a2be662c0",
"sha256": "c46efd13b6aa8279f33f2864459c8ce587ea6a1a59ee20de055868d8f7688f7f",
"sha512": null,
"bug_tracking_url": null,
"code_view_url": "https://github.com/pypa/pip",
"vcs_url": null,
"copyright": null,
"license_expression": null,
"declared_license": {
"license": "MIT",
"classifiers": [
"License :: OSI Approved :: MIT License"
]
},
"notice_text": null,
"source_packages": [],
"file_references": [],
"extra_data": {},
"dependencies": [],
"repository_homepage_url": null,
"repository_download_url": null,
"api_data_url": "https://pypi.org/pypi/pip/25.0.1/json",
"datasource_id": null,
"purl": "pkg:pypi/[email protected]"
},
{
"type": "pypi",
"namespace": null,
"name": "pip",
"version": "25.0.1",
"qualifiers": {},
"subpath": null,
"primary_language": "Python",
"description": "The PyPA recommended tool for installing Python packages.\npip - The Python Package Installer\n==================================\n\n.. |pypi-version| image:: https://img.shields.io/pypi/v/pip.svg\n :target: https://pypi.org/project/pip/\n :alt: PyPI\n\n.. |python-versions| image:: https://img.shields.io/pypi/pyversions/pip\n :target: https://pypi.org/project/pip\n :alt: PyPI - Python Version\n\n.. |docs-badge| image:: https://readthedocs.org/projects/pip/badge/?version=latest\n :target: https://pip.pypa.io/en/latest\n :alt: Documentation\n\n|pypi-version| |python-versions| |docs-badge|\n\npip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes.\n\nPlease take a look at our documentation for how to install and use pip:\n\n* `Installation`_\n* `Usage`_\n\nWe release updates regularly, with a new version every 3 months. Find more details in our documentation:\n\n* `Release notes`_\n* `Release process`_\n\nIf you find bugs, need help, or want to talk to the developers, please use our mailing lists or chat rooms:\n\n* `Issue tracking`_\n* `Discourse channel`_\n* `User IRC`_\n\nIf you want to get involved head over to GitHub to get the source code, look at our development documentation and feel free to jump on the developer mailing lists and chat rooms:\n\n* `GitHub page`_\n* `Development documentation`_\n* `Development IRC`_\n\nCode of Conduct\n---------------\n\nEveryone interacting in the pip project's codebases, issue trackers, chat\nrooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.\n\n.. _package installer: https://packaging.python.org/guides/tool-recommendations/\n.. _Python Package Index: https://pypi.org\n.. _Installation: https://pip.pypa.io/en/stable/installation/\n.. _Usage: https://pip.pypa.io/en/stable/\n.. _Release notes: https://pip.pypa.io/en/stable/news.html\n.. _Release process: https://pip.pypa.io/en/latest/development/release-process/\n.. _GitHub page: https://github.com/pypa/pip\n.. _Development documentation: https://pip.pypa.io/en/latest/development\n.. _Issue tracking: https://github.com/pypa/pip/issues\n.. _Discourse channel: https://discuss.python.org/c/packaging\n.. _User IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa\n.. _Development IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa-dev\n.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md",
"release_date": "2025-02-09T17:14:04",
"parties": [
{
"type": "person",
"role": "author",
"name": null,
"email": "The pip developers <[email protected]>",
"url": null
}
],
"keywords": [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Software Development :: Build Tools"
],
"homepage_url": null,
"download_url": "https://files.pythonhosted.org/packages/70/53/b309b4a497b09655cb7e07088966881a57d082f48ac3cb54ea729fd2c6cf/pip-25.0.1.tar.gz",
"size": 1950850,
"sha1": null,
"md5": "1bf81564bf9738efbe48439c230f25bf",
"sha256": "88f96547ea48b940a3a385494e181e29fb8637898f88d88737c5049780f196ea",
"sha512": null,
"bug_tracking_url": null,
"code_view_url": "https://github.com/pypa/pip",
"vcs_url": null,
"copyright": null,
"license_expression": null,
"declared_license": {
"license": "MIT",
"classifiers": [
"License :: OSI Approved :: MIT License"
]
},
"notice_text": null,
"source_packages": [],
"file_references": [],
"extra_data": {},
"dependencies": [],
"repository_homepage_url": null,
"repository_download_url": null,
"api_data_url": "https://pypi.org/pypi/pip/25.0.1/json",
"datasource_id": null,
"purl": "pkg:pypi/[email protected]"
}
],
"resolved_dependencies_graph": [
{
"package": "pkg:pypi/[email protected]",
"dependencies": []
}
]
}
40 changes: 40 additions & 0 deletions scanpipe/tests/pipes/test_resolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
# ScanCode.io is a free software code scanning tool from nexB Inc. and others.
# Visit https://github.com/nexB/scancode.io for support and download.

import json
from pathlib import Path
from unittest import mock

Expand All @@ -31,6 +32,7 @@
from scanpipe.pipes.input import copy_inputs
from scanpipe.pipes.scancode import extract_archives
from scanpipe.tests import make_package
from scanpipe.tests import make_project
from scanpipe.tests import package_data1


Expand Down Expand Up @@ -111,6 +113,44 @@ def test_scanpipe_pipes_resolve_get_packages_from_manifest(self):
}
self.assertEqual([expected], packages)

@mock.patch("scanpipe.pipes.resolve.resolve_dependencies")
def test_scanpipe_pipes_resolve_resolve_pypi_packages(self, mock_resolve):
# Generated with:
# $ python-inspector --python-version 3.12 --operating-system linux \
# --specifier pip==25.0.1 --json -
inspector_output_location = (
self.data / "resolve" / "python_inspector_resolve_dependencies.json"
)
with open(inspector_output_location) as f:
inspector_output = json.loads(f.read())

mock_resolve.return_value = mock.Mock(packages=inspector_output["packages"])

packages = resolve.resolve_pypi_packages("")
self.assertEqual(2, len(packages))
package_data = packages[0]
self.assertEqual("pip", package_data["name"])
self.assertEqual("25.0.1", package_data["version"])
self.assertEqual("Python", package_data["primary_language"])
self.assertIsNone(package_data["license_expression"])
expected_license = {
"license": "MIT",
"classifiers": ["License :: OSI Approved :: MIT License"],
}
self.assertEqual(expected_license, package_data["extracted_license_statement"])

project = make_project()
resolve.create_packages_and_dependencies(
project=project,
packages=packages,
resolved=True,
)

self.assertEqual(2, project.discoveredpackages.count())

package = project.discoveredpackages.all()[0]
self.assertEqual(str(expected_license), package.extracted_license_statement)

def test_scanpipe_pipes_resolve_resolve_about_packages(self):
input_location = self.manifest_location / "Django-4.0.8-py3-none-any.whl.ABOUT"
package = resolve.resolve_about_packages(str(input_location))
Expand Down