From 77ae3ed1d6858b51448182d82d87f951dfc13570 Mon Sep 17 00:00:00 2001 From: Ayan Sinha Mahapatra Date: Wed, 1 May 2024 02:13:51 +0530 Subject: [PATCH 01/10] Add basic pyproject.toml parsers #3753 Reference: https://github.com/nexB/scancode-toolkit/issues/3753 Signed-off-by: Ayan Sinha Mahapatra --- src/packagedcode/__init__.py | 1 + src/packagedcode/debian.py | 27 +-- src/packagedcode/pypi.py | 211 ++++++++++++++++-- src/packagedcode/utils.py | 20 ++ ...cted-with-test-manifests-with-license.json | 69 +----- ...instance-expected-with-test-manifests.json | 45 +--- tests/packagedcode/data/plugin/help.txt | 9 +- .../gerapy-pyproject.toml-expected.json | 103 +++++++++ .../poetry/gerapy/pyproject.toml | 56 +++++ .../poetry/gino-pyproject.toml-expected.json | 127 +++++++++++ .../pyproject-toml/poetry/gino/pyproject.toml | 81 +++++++ ...flow-pyclient-pyproject.toml-expected.json | 95 ++++++++ .../apache-airflow-pyclient/pyproject.toml | 97 ++++++++ ...pache-airflow-pyproject.toml-expected.json | 109 +++++++++ .../standard/apache-airflow/pyproject.toml | 100 +++++++++ .../attrs-pyproject.toml-expected.json | 117 ++++++++++ .../standard/attrs/pyproject.toml | 78 +++++++ .../flask-pyproject.toml-expected.json | 93 ++++++++ .../pyproject-toml/standard/flask/LICENSE.txt | 3 + .../standard/flask/pyproject.toml | 75 +++++++ .../standard/lc0-pyproject.toml-expected.json | 59 +++++ .../pypi/pyproject-toml/standard/lc0/COPYING | 1 + .../standard/lc0/pyproject.toml | 23 ++ .../pip-22.0.4-pypi-package-expected.json | 98 ++++++-- ...pip-22.0.4-pypi-package-only-expected.json | 47 +++- ....4-pypi-package-with-license-expected.json | 164 ++++++++++---- .../source-package/pip-22.0.4/pyproject.toml | 112 ++++------ tests/packagedcode/test_pypi.py | 54 +++++ 28 files changed, 1785 insertions(+), 289 deletions(-) create mode 100644 tests/packagedcode/data/pypi/pyproject-toml/poetry/gerapy-pyproject.toml-expected.json create mode 100644 tests/packagedcode/data/pypi/pyproject-toml/poetry/gerapy/pyproject.toml create mode 100644 tests/packagedcode/data/pypi/pyproject-toml/poetry/gino-pyproject.toml-expected.json create mode 100644 tests/packagedcode/data/pypi/pyproject-toml/poetry/gino/pyproject.toml create mode 100644 tests/packagedcode/data/pypi/pyproject-toml/standard/apache-airflow-pyclient-pyproject.toml-expected.json create mode 100644 tests/packagedcode/data/pypi/pyproject-toml/standard/apache-airflow-pyclient/pyproject.toml create mode 100644 tests/packagedcode/data/pypi/pyproject-toml/standard/apache-airflow-pyproject.toml-expected.json create mode 100644 tests/packagedcode/data/pypi/pyproject-toml/standard/apache-airflow/pyproject.toml create mode 100644 tests/packagedcode/data/pypi/pyproject-toml/standard/attrs-pyproject.toml-expected.json create mode 100644 tests/packagedcode/data/pypi/pyproject-toml/standard/attrs/pyproject.toml create mode 100644 tests/packagedcode/data/pypi/pyproject-toml/standard/flask-pyproject.toml-expected.json create mode 100644 tests/packagedcode/data/pypi/pyproject-toml/standard/flask/LICENSE.txt create mode 100644 tests/packagedcode/data/pypi/pyproject-toml/standard/flask/pyproject.toml create mode 100644 tests/packagedcode/data/pypi/pyproject-toml/standard/lc0-pyproject.toml-expected.json create mode 100644 tests/packagedcode/data/pypi/pyproject-toml/standard/lc0/COPYING create mode 100644 tests/packagedcode/data/pypi/pyproject-toml/standard/lc0/pyproject.toml diff --git a/src/packagedcode/__init__.py b/src/packagedcode/__init__.py index a6d84c1e56e..b507d1efb42 100644 --- a/src/packagedcode/__init__.py +++ b/src/packagedcode/__init__.py @@ -168,6 +168,7 @@ # pypi.PypiSdistArchiveHandler, pypi.PypiWheelHandler, pypi.PyprojectTomlHandler, + pypi.PoetryPyprojectTomlHandler, pypi.PythonEditableInstallationPkgInfoFile, pypi.PythonEggPkgInfoFile, pypi.PythonInstalledWheelMetadataFile, diff --git a/src/packagedcode/debian.py b/src/packagedcode/debian.py index c6dd5420b1a..ff1d618fd20 100644 --- a/src/packagedcode/debian.py +++ b/src/packagedcode/debian.py @@ -21,6 +21,7 @@ from packagedcode import models from packagedcode.utils import get_ancestor +from packagedcode.utils import parse_maintainer_name_email """ Handle Debian package archives, control files and installed databases. @@ -653,20 +654,20 @@ def build_package_data(debian_data, datasource_id, package_type='deb', distro=No maintainer = debian_data.get('maintainer') if maintainer: - maintainer_name, maintainer_email = parse_debian_maintainers(maintainer) + maintainer_name, maintainer_email = parse_maintainer_name_email(maintainer) party = models.Party(role='maintainer', name=maintainer_name, email=maintainer_email) parties.append(party) orig_maintainer = debian_data.get('original_maintainer') if orig_maintainer: - maintainer_name, maintainer_email = parse_debian_maintainers(orig_maintainer) + maintainer_name, maintainer_email = parse_maintainer_name_email(orig_maintainer) party = models.Party(role='maintainer', name=maintainer_name, email=maintainer_email) parties.append(party) uploaders = debian_data.get('uploaders') if uploaders: for uploader in uploaders.split(", "): - uploader_name, uploader_email = parse_debian_maintainers(uploader) + uploader_name, uploader_email = parse_maintainer_name_email(uploader) party = models.Party(role='uploader', name=uploader_name, email=uploader_email) parties.append(party) @@ -736,26 +737,6 @@ def build_package_data(debian_data, datasource_id, package_type='deb', distro=No return models.PackageData.from_data(package_data, package_only) -def parse_debian_maintainers(maintainer): - """ - Get name and email values from a debian maintainer string. - - Example string: - Debian systemd Maintainers - """ - email_wrappers = ["<", ">"] - has_email = "@" in maintainer and all([ - True - for char in email_wrappers - if char in maintainer - ]) - if not has_email: - return maintainer, None - - name, _, email = maintainer.rpartition("<") - return name.rstrip(" "), email.rstrip(">") - - def populate_debian_namespace(packages): """ For an iterable of debian `packages`, populate the diff --git a/src/packagedcode/pypi.py b/src/packagedcode/pypi.py index 33f2ec394ea..445a0562969 100644 --- a/src/packagedcode/pypi.py +++ b/src/packagedcode/pypi.py @@ -27,6 +27,7 @@ import packvers as packaging import pip_requirements_parser import pkginfo2 +import toml from commoncode import fileutils from commoncode.fileutils import as_posixpath from commoncode.resource import Resource @@ -38,6 +39,7 @@ from packagedcode import models from packagedcode.utils import build_description +from packagedcode.utils import parse_maintainer_name_email from packagedcode.utils import yield_dependencies_from_package_data from packagedcode.utils import yield_dependencies_from_package_resource @@ -149,7 +151,7 @@ def assemble(cls, package_data, resource, codebase, package_adder): datafile_name_patterns = ( 'Pipfile.lock', 'Pipfile', - ) + PipRequirementsFileHandler.path_patterns + ) + PipRequirementsFileHandler.path_patterns + PyprojectTomlHandler.path_patterns # TODO: we want PKG-INFO first, then (setup.py, setup.cfg), then pyproject.toml for poetry # then we have the rest of the lock files (pipfile, pipfile.lock, etc.) @@ -448,14 +450,119 @@ def get_resource_for_path(path, root, codebase): return root -# FIXME: Implement me -class PyprojectTomlHandler(models.NonAssemblableDatafileHandler): +class PyprojectTomlHandler(BaseExtractedPythonLayout): datasource_id = 'pypi_pyproject_toml' path_patterns = ('*pyproject.toml',) default_package_type = 'pypi' default_primary_language = 'Python' description = 'Python pyproject.toml' - documentation_url = 'https://peps.python.org/pep-0621/' + documentation_url = 'https://packaging.python.org/en/latest/specifications/pyproject-toml/' + + @classmethod + def is_datafile(cls, location, filetypes=tuple()): + return ( + super().is_datafile(location, filetypes=filetypes) + and not is_poetry_pyproject_toml(location) + ) + + @classmethod + def parse(cls, location, package_only=False): + package_data = toml.load(location, _dict=dict) + project_data = package_data.get("project") + if not project_data: + return + + name = project_data.get('name') + version = project_data.get('version') + description = project_data.get('description') or '' + description = description.strip() + + urls, extra_data = get_urls(metainfo=project_data, name=name, version=version) + + extracted_license_statement, license_file = get_declared_license(project_data) + if license_file: + extra_data['license_file'] = license_file + + package_data = dict( + datasource_id=cls.datasource_id, + type=cls.default_package_type, + primary_language='Python', + name=name, + version=version, + extracted_license_statement=extracted_license_statement, + description=description, + keywords=get_keywords(project_data), + parties=get_pyproject_toml_parties(project_data), + extra_data=extra_data, + **urls, + ) + yield models.PackageData.from_data(package_data, package_only) + + +def is_poetry_pyproject_toml(location): + with open(location, 'r') as file: + data = file.read() + + if "tool.poetry" in data: + return True + else: + return False + + +class PoetryPyprojectTomlHandler(BaseExtractedPythonLayout): + datasource_id = 'pypi_poetry_pyproject_toml' + path_patterns = ('*pyproject.toml',) + default_package_type = 'pypi' + default_primary_language = 'Python' + description = 'Python poetry pyproject.toml' + documentation_url = 'https://packaging.python.org/en/latest/specifications/pyproject-toml/' + + @classmethod + def is_datafile(cls, location, filetypes=tuple()): + return ( + super().is_datafile(location, filetypes=filetypes) + and is_poetry_pyproject_toml(location) + ) + + @classmethod + def parse(cls, location, package_only=False): + toml_data = toml.load(location, _dict=dict) + + tool_data = toml_data.get('tool') + if not tool_data: + return + + poetry_data = tool_data.get('poetry') + if not poetry_data: + return + + name = poetry_data.get('name') + version = poetry_data.get('version') + description = poetry_data.get('description') or '' + description = description.strip() + + urls, extra_data = get_urls(metainfo=poetry_data, name=name, version=version, poetry=True) + + extracted_license_statement, license_file = get_declared_license(poetry_data) + if license_file: + extra_data['license_file'] = license_file + + package_data = dict( + datasource_id=cls.datasource_id, + type=cls.default_package_type, + primary_language='Python', + name=name, + version=version, + extracted_license_statement=extracted_license_statement, + description=description, + keywords=get_keywords(poetry_data), + parties=get_pyproject_toml_parties(poetry_data), + extra_data=extra_data, + **urls, + ) + yield models.PackageData.from_data(package_data, package_only) + + META_DIR_SUFFIXES = '.dist-info', '.egg-info', 'EGG-INFO', @@ -487,8 +594,11 @@ def parse_metadata(location, datasource_id, package_type, package_only=False): urls, extra_data = get_urls(metainfo=meta, name=name, version=version) - dependencies = get_dist_dependencies(dist) + extracted_license_statement, license_file = get_declared_license(metainfo=meta) + if license_file: + extra_data['license_file'] = license_file + dependencies = get_dist_dependencies(dist) file_references = list(get_file_references(dist)) package_data = dict( @@ -497,7 +607,7 @@ def parse_metadata(location, datasource_id, package_type, package_only=False): primary_language='Python', name=name, version=version, - extracted_license_statement=get_declared_license(meta), + extracted_license_statement=extracted_license_statement, description=get_description(metainfo=meta, location=str(location)), keywords=get_keywords(meta), parties=get_parties(meta), @@ -628,6 +738,9 @@ def parse(cls, location, package_only=False): name = sdist.name version = sdist.version urls, extra_data = get_urls(metainfo=sdist, name=name, version=version) + extracted_license_statement, license_file = get_declared_license(metainfo=sdist) + if license_file: + extra_data['license_file'] = license_file package_data = dict( datasource_id=cls.datasource_id, @@ -636,7 +749,7 @@ def parse(cls, location, package_only=False): name=name, version=version, description=get_description(sdist, location=location), - extracted_license_statement=get_declared_license(sdist), + extracted_license_statement=extracted_license_statement, keywords=get_keywords(sdist), parties=get_parties(sdist), extra_data=extra_data, @@ -672,6 +785,10 @@ def parse(cls, location, package_only=False): python_requires = get_setup_py_python_requires(setup_args) extra_data.update(python_requires) + extracted_license_statement, license_file = get_declared_license(metainfo=setup_args) + if license_file: + extra_data['license_file'] = license_file + package_data = dict( datasource_id=cls.datasource_id, type=cls.default_package_type, @@ -680,7 +797,7 @@ def parse(cls, location, package_only=False): version=version, description=get_description(setup_args), parties=get_setup_parties(setup_args), - extracted_license_statement=get_declared_license(setup_args), + extracted_license_statement=extracted_license_statement, dependencies=dependencies, keywords=get_keywords(setup_args), extra_data=extra_data, @@ -1146,15 +1263,23 @@ def get_legacy_description(location): def get_declared_license(metainfo): """ - Return a mapping of declared license information found in a ``metainfo`` - object or mapping. + Return a mapping of declared license information and license file name + found in a ``metainfo`` package data mapping. """ declared_license = {} # TODO: We should make the declared license as it is, this should be # updated in scancode to parse a pure string lic = get_attribute(metainfo, 'License') + + license_file = None + if lic and 'file' in lic: + license_file = lic.pop('file') + if lic and not lic == 'UNKNOWN': - declared_license['license'] = lic + if 'text' in lic: + declared_license['license'] = lic.get('text') + else: + declared_license['license'] = lic license_classifiers, _ = get_classifiers(metainfo) if license_classifiers: @@ -1163,7 +1288,7 @@ def get_declared_license(metainfo): if not declared_license: declared_license = None - return declared_license + return declared_license, license_file def get_classifiers(metainfo): @@ -1175,6 +1300,7 @@ def get_classifiers(metainfo): classifiers = ( get_attribute(metainfo, 'Classifier', multiple=True) or get_attribute(metainfo, 'Classifiers', multiple=True) + or get_attribute(metainfo, 'classifiers', multiple=True) ) if not classifiers: return [], [] @@ -1218,7 +1344,6 @@ def get_parties( author_email_key='Author-email', maintainer_key='Maintainer', maintainer_email_key='Maintainer-email', - ): """ Return a list of parties found in a ``metainfo`` object or mapping. @@ -1265,6 +1390,47 @@ def get_setup_parties(setup_kwargs): ) +def get_pyproject_toml_parties(metainfo): + + parties = [] + authors = metainfo.get('authors') or [] + for author in authors: + add_pyproject_toml_party( + parties=parties, + party=author, + role='author', + ) + + maintainers = metainfo.get('maintainers') or [] + for maintainer in maintainers: + add_pyproject_toml_party( + parties=parties, + party=maintainer, + role='maintainer', + ) + + return parties + + +def add_pyproject_toml_party(parties, party, role): + + if type(party) is str: + name, email = parse_maintainer_name_email(party) + parties.append(models.Party( + type=models.party_person, + name=name, + role=role, + email=email, + )) + else: + parties.append(models.Party( + type=models.party_person, + name=party.get('name'), + role=role, + email=party.get('email'), + )) + + def get_setup_py_python_requires(setup_args): """ Return a mapping of {python_requires: value} or an empty mapping found in a @@ -1643,7 +1809,7 @@ def get_pypi_urls(name, version, **kwargs): ) -def get_urls(metainfo, name, version): +def get_urls(metainfo, name, version, poetry=False): """ Return a mapping of standard URLs and a mapping of extra-data URls for URLs of this package: @@ -1706,11 +1872,18 @@ def add_url(_url, _utype=None, _attribute=None): ) add_url(homepage_url, _attribute='homepage_url') - project_urls = ( - get_attribute(metainfo, 'Project-URL', multiple=True) - or get_attribute(metainfo, 'project_urls') - or [] - ) + if poetry: + url_fields = ["homepage", "repository", "documentation"] + project_urls = {} + for url_field in url_fields: + project_urls[url_field] = metainfo.get(url_field) + else: + project_urls = ( + get_attribute(metainfo, 'Project-URL', multiple=True) + or get_attribute(metainfo, 'project_urls') + or get_attribute(metainfo, 'urls') + or [] + ) if isinstance(project_urls, list): # these come from METADATA and we convert them back to a mapping diff --git a/src/packagedcode/utils.py b/src/packagedcode/utils.py index a954b882d3d..6cd8381643d 100644 --- a/src/packagedcode/utils.py +++ b/src/packagedcode/utils.py @@ -207,6 +207,26 @@ def yield_dependencies_from_package_data(package_data, datafile_path, package_ui ) +def parse_maintainer_name_email(maintainer): + """ + Get name and email values from a author/maintainer string. + + Example string: + Debian systemd Maintainers + """ + email_wrappers = ["<", ">"] + has_email = "@" in maintainer and all([ + True + for char in email_wrappers + if char in maintainer + ]) + if not has_email: + return maintainer, None + + name, _, email = maintainer.rpartition("<") + return name.rstrip(" "), email.rstrip(">") + + def yield_dependencies_from_package_resource(resource, package_uid=None): """ Yield a Dependency for each dependency from each package from``resource.package_data`` diff --git a/tests/packagedcode/data/instance/python-package-instance-expected-with-test-manifests-with-license.json b/tests/packagedcode/data/instance/python-package-instance-expected-with-test-manifests-with-license.json index 8d6ebf9f0cc..10b4f755518 100644 --- a/tests/packagedcode/data/instance/python-package-instance-expected-with-test-manifests-with-license.json +++ b/tests/packagedcode/data/instance/python-package-instance-expected-with-test-manifests-with-license.json @@ -118,7 +118,7 @@ "identifier": "mit-cacd5c0c-204a-85c2-affc-e4c125b2492a", "license_expression": "mit", "license_expression_spdx": "MIT", - "detection_count": 3, + "detection_count": 2, "reference_matches": [ { "license_expression": "mit", @@ -463,72 +463,7 @@ { "path": "pyproject.toml", "type": "file", - "package_data": [ - { - "type": "pypi", - "namespace": null, - "name": null, - "version": null, - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": null, - "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", - "spdx_license_expression": "MIT", - "from_file": "pypi-with-test-manifests/LICENSE", - "start_line": 3, - "end_line": 19, - "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" - } - ], - "identifier": "mit-cacd5c0c-204a-85c2-affc-e4c125b2492a" - } - ], - "other_license_expression": null, - "other_license_expression_spdx": null, - "other_license_detections": [], - "extracted_license_statement": null, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": null, - "datasource_id": "pypi_pyproject_toml", - "purl": null - } - ], + "package_data": [], "for_packages": [ "pkg:pypi/setuptools@58.2.0?uuid=fixed-uid-done-for-testing-5642512d1758" ], diff --git a/tests/packagedcode/data/instance/python-package-instance-expected-with-test-manifests.json b/tests/packagedcode/data/instance/python-package-instance-expected-with-test-manifests.json index 2d8dc56bbc1..75773a62657 100644 --- a/tests/packagedcode/data/instance/python-package-instance-expected-with-test-manifests.json +++ b/tests/packagedcode/data/instance/python-package-instance-expected-with-test-manifests.json @@ -254,50 +254,7 @@ { "path": "pyproject.toml", "type": "file", - "package_data": [ - { - "type": "pypi", - "namespace": null, - "name": null, - "version": null, - "qualifiers": {}, - "subpath": null, - "primary_language": "Python", - "description": null, - "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": null, - "declared_license_expression_spdx": null, - "license_detections": [], - "other_license_expression": null, - "other_license_expression_spdx": null, - "other_license_detections": [], - "extracted_license_statement": null, - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": null, - "repository_download_url": null, - "api_data_url": null, - "datasource_id": "pypi_pyproject_toml", - "purl": null - } - ], + "package_data": [], "for_packages": [ "pkg:pypi/setuptools@58.2.0?uuid=fixed-uid-done-for-testing-5642512d1758" ], diff --git a/tests/packagedcode/data/plugin/help.txt b/tests/packagedcode/data/plugin/help.txt index 839a91fcefc..41ca37f2fa5 100755 --- a/tests/packagedcode/data/plugin/help.txt +++ b/tests/packagedcode/data/plugin/help.txt @@ -692,9 +692,16 @@ Package type: pypi description: PyPI extracted egg PKG-INFO path_patterns: '*/EGG-INFO/PKG-INFO' -------------------------------------------- +Package type: pypi + datasource_id: pypi_poetry_pyproject_toml + documentation URL: https://packaging.python.org/en/latest/specifications/pyproject-toml/ + primary language: Python + description: Python poetry pyproject.toml + path_patterns: '*pyproject.toml' +-------------------------------------------- Package type: pypi datasource_id: pypi_pyproject_toml - documentation URL: https://peps.python.org/pep-0621/ + documentation URL: https://packaging.python.org/en/latest/specifications/pyproject-toml/ primary language: Python description: Python pyproject.toml path_patterns: '*pyproject.toml' diff --git a/tests/packagedcode/data/pypi/pyproject-toml/poetry/gerapy-pyproject.toml-expected.json b/tests/packagedcode/data/pypi/pyproject-toml/poetry/gerapy-pyproject.toml-expected.json new file mode 100644 index 00000000000..401de07be85 --- /dev/null +++ b/tests/packagedcode/data/pypi/pyproject-toml/poetry/gerapy-pyproject.toml-expected.json @@ -0,0 +1,103 @@ +[ + { + "type": "pypi", + "namespace": null, + "name": "gerapy", + "version": "0.9.13", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "Distributed Crawler Management Framework Based on Scrapy, Scrapyd, Scrapyd-Client, Scrapyd-API, Django and Vue.js.", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "Germey", + "email": "cqc@cuiqingcai.com", + "url": null + } + ], + "keywords": [ + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy" + ], + "homepage_url": "https://github.com/Gerapy/Gerapy", + "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", + "spdx_license_expression": "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", + "spdx_license_expression": "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": [], + "extra_data": {}, + "dependencies": [], + "repository_homepage_url": "https://pypi.org/project/gerapy", + "repository_download_url": "https://pypi.org/packages/source/g/gerapy/gerapy-0.9.13.tar.gz", + "api_data_url": "https://pypi.org/pypi/gerapy/0.9.13/json", + "datasource_id": "pypi_poetry_pyproject_toml", + "purl": "pkg:pypi/gerapy@0.9.13" + } +] \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/pyproject-toml/poetry/gerapy/pyproject.toml b/tests/packagedcode/data/pypi/pyproject-toml/poetry/gerapy/pyproject.toml new file mode 100644 index 00000000000..6014013301a --- /dev/null +++ b/tests/packagedcode/data/pypi/pyproject-toml/poetry/gerapy/pyproject.toml @@ -0,0 +1,56 @@ +# Copied from https://github.com/Gerapy/Gerapy/blob/e0fdd816e495ff52682b34f3136bc785e960263a/pyproject.toml + +[tool.poetry] +name = "gerapy" +version = "0.9.13" +description = "Distributed Crawler Management Framework Based on Scrapy, Scrapyd, Scrapyd-Client, Scrapyd-API, Django and Vue.js." +authors = ["Germey "] +license = "MIT" +readme = "README.md" +homepage = "https://github.com/Gerapy/Gerapy" +include = [ + "LICENSE" +] +classifiers = [ + # Trove classifiers - https://packaging.python.org/specifications/core-metadata/#metadata-classifier + # Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers + 'License :: OSI Approved :: MIT License', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: Implementation :: CPython', + 'Programming Language :: Python :: Implementation :: PyPy' +] + +[tool.poetry.dependencies] +python = "^3.7" +apscheduler = ">=3.5.1,<=3.7.0" +cryptography = ">=2.8" +django = ">=2.2,<3.0" +django-cors-headers = ">=3.2.0,<=3.7.0" +django-apscheduler = ">=0.3.0,<=0.6.0" +furl = ">=2.1.0" +jinja2 = ">=2.11.3" +scrapy = ">=2.7.1" +scrapy-redis = ">=0.6.8" +scrapy-splash = ">=0.7.2" +python-scrapyd-api = ">=2.1.2" +redis = ">=2.10.5" +requests = ">=2.20.0" +pymongo = ">=3.9.0" +pymysql = ">=0.7.10" +pyquery = ">=1.2.17" +beautifulsoup4 = ">=4.7.0" +djangorestframework = ">=3.11.2" +websocket = ">=0.2.1" +pyppeteer = ">=0.0.25" +uberegg = "^0.1.1" + +[tool.poetry.dev-dependencies] + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" + +[tool.poetry.scripts] +gerapy = "gerapy.cmd:cmd" diff --git a/tests/packagedcode/data/pypi/pyproject-toml/poetry/gino-pyproject.toml-expected.json b/tests/packagedcode/data/pypi/pyproject-toml/poetry/gino-pyproject.toml-expected.json new file mode 100644 index 00000000000..28836dd85f7 --- /dev/null +++ b/tests/packagedcode/data/pypi/pyproject-toml/poetry/gino-pyproject.toml-expected.json @@ -0,0 +1,127 @@ +[ + { + "type": "pypi", + "namespace": null, + "name": "gino", + "version": "1.1.0-rc.1", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "GINO Is Not ORM - a Python asyncio ORM on SQLAlchemy core.", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "Fantix King", + "email": "fantix.king@gmail.com", + "url": null + }, + { + "type": "person", + "role": "maintainer", + "name": "Tony Wang", + "email": "tony@initialcommit.net", + "url": null + }, + { + "type": "person", + "role": "maintainer", + "name": "Fantix King", + "email": "fantix.king@gmail.com", + "url": null + } + ], + "keywords": [ + "orm", + "asyncio", + "sqlalchemy", + "asyncpg", + "python3", + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Natural Language :: English", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9" + ], + "homepage_url": "https://python-gino.org", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": "https://github.com/python-gino/gino", + "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", + "spdx_license_expression": "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" + }, + { + "license_expression": "bsd-new", + "license_expression_spdx": "BSD-3-Clause", + "matches": [ + { + "license_expression": "bsd-new", + "spdx_license_expression": "BSD-3-Clause", + "from_file": null, + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 99.0, + "matched_length": 5, + "match_coverage": 100.0, + "rule_relevance": 99, + "rule_identifier": "pypi_bsd_license.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_bsd_license.RULE", + "matched_text": "- 'License :: OSI Approved :: BSD License'" + } + ], + "identifier": "bsd_new-f4e99f86-00ab-18d9-a65d-a3a12767dcf5" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "license: BSD-3-Clause\nclassifiers:\n - 'License :: OSI Approved :: BSD License'\n", + "notice_text": null, + "source_packages": [], + "file_references": [], + "extra_data": { + "documentation": "https://python-gino.org/docs/" + }, + "dependencies": [], + "repository_homepage_url": "https://pypi.org/project/gino", + "repository_download_url": "https://pypi.org/packages/source/g/gino/gino-1.1.0-rc.1.tar.gz", + "api_data_url": "https://pypi.org/pypi/gino/1.1.0-rc.1/json", + "datasource_id": "pypi_poetry_pyproject_toml", + "purl": "pkg:pypi/gino@1.1.0-rc.1" + } +] \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/pyproject-toml/poetry/gino/pyproject.toml b/tests/packagedcode/data/pypi/pyproject-toml/poetry/gino/pyproject.toml new file mode 100644 index 00000000000..c0ed6395366 --- /dev/null +++ b/tests/packagedcode/data/pypi/pyproject-toml/poetry/gino/pyproject.toml @@ -0,0 +1,81 @@ +# From https://github.com/python-gino/gino/blob/6218b902cc8a31198f1a0b42d67e689140b68c8b/pyproject.toml +# with unessential parts deleted + +[tool.poetry] +name = "gino" +version = "1.1.0-rc.1" +description = "GINO Is Not ORM - a Python asyncio ORM on SQLAlchemy core." +license = "BSD-3-Clause" +authors = ["Fantix King "] +maintainers = ["Tony Wang ", "Fantix King "] +readme = "README.rst" +homepage = "https://python-gino.org" +repository = "https://github.com/python-gino/gino" +documentation = "https://python-gino.org/docs/" +keywords = ["orm", "asyncio", "sqlalchemy", "asyncpg", "python3"] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: BSD License", + "Natural Language :: English", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", +] + +[tool.poetry.dependencies] +python = "^3.6" +SQLAlchemy = ">=1.3,<1.4" + +# drivers +asyncpg = { version = ">=0.18,<1.0", optional = true } +aiomysql = "^0.0.22" + +# compatibility +contextvars = { version = "^2.4", python = "<3.7" } +importlib_metadata = { version = "^2.0.0", python = "<3.8" } + +# extensions +gino-starlette = { version = "^0.1.1", optional = true, python = "^3.6" } +gino-aiohttp = {version = "^0.2.0", optional = true, python = "^3.6"} +gino-tornado = { version = "^0.1.0", optional = true, python = "^3.5.2" } +gino-sanic = { version = "^0.1.0", optional = true, python = "^3.6" } +gino-quart = { version = "^0.1.0", optional = true, python = "^3.7" } + +[tool.poetry.extras] +postgresql = ["asyncpg"] +postgres = ["asyncpg"] +pg = ["asyncpg"] +asyncpg = ["asyncpg"] +mysql = ["aiomysql"] +aiomysql = ["aiomysql"] +starlette = ["gino-starlette"] +aiohttp = ["gino-aiohttp"] +tornado = ["gino-tornado"] +sanic = ["gino-sanic"] +quart = ["gino-quart"] + +[tool.poetry.dev-dependencies] +psycopg2-binary = "^2.9.3" +click = "^8.0.3" + +# tests +pytest = "^7.0.1" +pytest-asyncio = "^0.16.0" +pytest-mock = "^3.6.0" +pytest-cov = "^3.0.0" +black = { version = "^22.1.0", python = ">=3.6.2" } +mypy = "^0.931" + +# docs +sphinx = "^4.3.0" +sphinx-rtd-theme = "^1.0.0" +sphinxcontrib-apidoc = "^0.3.0" +sphinx-autobuild = "^2021.3.14" +sphinx-intl = {extras = ["transifex"], version = "^2.0.1"} + +[build-system] +requires = ["poetry>=1.0"] +build-backend = "poetry.masonry.api" diff --git a/tests/packagedcode/data/pypi/pyproject-toml/standard/apache-airflow-pyclient-pyproject.toml-expected.json b/tests/packagedcode/data/pypi/pyproject-toml/standard/apache-airflow-pyclient-pyproject.toml-expected.json new file mode 100644 index 00000000000..8549cc9c015 --- /dev/null +++ b/tests/packagedcode/data/pypi/pyproject-toml/standard/apache-airflow-pyclient-pyproject.toml-expected.json @@ -0,0 +1,95 @@ +[ + { + "type": "pypi", + "namespace": null, + "name": "apache-airflow-client", + "version": null, + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "Apache Airflow API (Stable)", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "Apache Software Foundation", + "email": "dev@airflow.apache.org", + "url": null + } + ], + "keywords": [ + "Apache Airflow API (Stable)", + "OpenAPI", + "OpenAPI-Generator", + "Development Status :: 5 - Production/Stable", + "Environment :: Console", + "Environment :: Web Environment", + "Framework :: Apache Airflow", + "Intended Audience :: Developers", + "Intended Audience :: System Administrators", + "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", + "Topic :: System :: Monitoring" + ], + "homepage_url": "https://airflow.apache.org/", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": "https://github.com/apache/airflow-client-python/issues", + "code_view_url": "https://github.com/apache/airflow/clients/python", + "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", + "spdx_license_expression": "Apache-2.0", + "from_file": null, + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 95.0, + "matched_length": 6, + "match_coverage": 100.0, + "rule_relevance": 95, + "rule_identifier": "pypi_apache_no-version.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_apache_no-version.RULE", + "matched_text": "- 'License :: OSI Approved :: Apache Software License'" + } + ], + "identifier": "apache_2_0-e267f9d9-ae62-e9c9-9cc2-8cd0a1e4928f" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "classifiers:\n - 'License :: OSI Approved :: Apache Software License'\n", + "notice_text": null, + "source_packages": [], + "file_references": [], + "extra_data": { + "Changelog": "https://github.com/apache/airflow-client-python/blob/main/CHANGELOG.md", + "Documentation": "https://airflow.apache.org/docs/apache-airflow/stable/stable-rest-api-ref.html", + "Download": "https://archive.apache.org/dist/airflow/clients/python/" + }, + "dependencies": [], + "repository_homepage_url": "https://pypi.org/project/apache-airflow-client", + "repository_download_url": null, + "api_data_url": "https://pypi.org/pypi/apache-airflow-client/json", + "datasource_id": "pypi_pyproject_toml", + "purl": "pkg:pypi/apache-airflow-client" + } +] \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/pyproject-toml/standard/apache-airflow-pyclient/pyproject.toml b/tests/packagedcode/data/pypi/pyproject-toml/standard/apache-airflow-pyclient/pyproject.toml new file mode 100644 index 00000000000..54132fc3aee --- /dev/null +++ b/tests/packagedcode/data/pypi/pyproject-toml/standard/apache-airflow-pyclient/pyproject.toml @@ -0,0 +1,97 @@ +# Copied from https://raw.githubusercontent.com/apache/airflow/d4bdffc45cd2e55783bba1e7442c346aef7ca573/clients/python/pyproject.toml + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +[build-system] +requires = ["hatchling==1.24.2"] +build-backend = "hatchling.build" + +[project] +name = "apache-airflow-client" +dynamic = ["version"] +description = "Apache Airflow API (Stable)" +readme = "README.md" +license-files.globs = ["LICENSE", "NOTICE"] +requires-python = "~=3.8" +authors = [ + { name = "Apache Software Foundation", email = "dev@airflow.apache.org" }, +] +keywords = [ + "Apache Airflow API (Stable)", + "OpenAPI", + "OpenAPI-Generator", +] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Environment :: Console", + "Environment :: Web Environment", + "Framework :: Apache Airflow", + "Intended Audience :: Developers", + "Intended Audience :: System Administrators", + "License :: OSI Approved :: Apache Software License", + "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", + "Topic :: System :: Monitoring", +] + +dependencies = [ + "python-dateutil", + "urllib3 >= 1.25.3", +] + +[project.urls] +"Bug Tracker" = "https://github.com/apache/airflow-client-python/issues" +Changelog = "https://github.com/apache/airflow-client-python/blob/main/CHANGELOG.md" +Documentation = "https://airflow.apache.org/docs/apache-airflow/stable/stable-rest-api-ref.html" +Download = "https://archive.apache.org/dist/airflow/clients/python/" +Homepage = "https://airflow.apache.org/" +"Source Code" = "https://github.com/apache/airflow/clients/python" + +[tool.hatch.envs.test] +dependencies = [ + "pytest-cov>=2.8.1", + "urllib3 >= 1.25.3", +] + +[tool.hatch.envs.test.scripts] +run-coverage = "pytest test" +run = "run-coverage --no-cov" + +[[tool.hatch.envs.test.matrix]] +python = ["3.8", "3.9", "3.10", "3.11"] + +[tool.hatch.version] +path = "./version.txt" +pattern = "^(?P.+)$" + +[tool.hatch.build.targets.sdist] +artifacts = [ + "/airflow_client", + "/docs", + "/test", + "v1.yaml", +] +include = [ + "version.txt", + "INSTALL", + "README.md", +] + diff --git a/tests/packagedcode/data/pypi/pyproject-toml/standard/apache-airflow-pyproject.toml-expected.json b/tests/packagedcode/data/pypi/pyproject-toml/standard/apache-airflow-pyproject.toml-expected.json new file mode 100644 index 00000000000..95226beab54 --- /dev/null +++ b/tests/packagedcode/data/pypi/pyproject-toml/standard/apache-airflow-pyproject.toml-expected.json @@ -0,0 +1,109 @@ +[ + { + "type": "pypi", + "namespace": null, + "name": "apache-airflow", + "version": null, + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "Programmatically author, schedule and monitor data pipelines", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "Apache Software Foundation", + "email": "dev@airflow.apache.org", + "url": null + }, + { + "type": "person", + "role": "maintainer", + "name": "Apache Software Foundation", + "email": "dev@airflow.apache.org", + "url": null + } + ], + "keywords": [ + "airflow", + "orchestration", + "workflow", + "dag", + "pipelines", + "automation", + "data", + "Development Status :: 5 - Production/Stable", + "Environment :: Console", + "Environment :: Web Environment", + "Framework :: Apache Airflow", + "Intended Audience :: Developers", + "Intended Audience :: System Administrators", + "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", + "Topic :: System :: Monitoring" + ], + "homepage_url": "https://airflow.apache.org/", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": "https://github.com/apache/airflow/issues", + "code_view_url": "https://github.com/apache/airflow", + "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", + "spdx_license_expression": "Apache-2.0", + "from_file": null, + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 95.0, + "matched_length": 6, + "match_coverage": 100.0, + "rule_relevance": 95, + "rule_identifier": "pypi_apache_no-version.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_apache_no-version.RULE", + "matched_text": "- 'License :: OSI Approved :: Apache Software License'" + } + ], + "identifier": "apache_2_0-e267f9d9-ae62-e9c9-9cc2-8cd0a1e4928f" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "classifiers:\n - 'License :: OSI Approved :: Apache Software License'\n", + "notice_text": null, + "source_packages": [], + "file_references": [], + "extra_data": { + "Documentation": "https://airflow.apache.org/docs/", + "Downloads": "https://archive.apache.org/dist/airflow/", + "Release Notes": "https://airflow.apache.org/docs/apache-airflow/stable/release_notes.html", + "Slack Chat": "https://s.apache.org/airflow-slack", + "Twitter": "https://twitter.com/ApacheAirflow", + "YouTube": "https://www.youtube.com/channel/UCSXwxpWZQ7XZ1WL3wqevChA/" + }, + "dependencies": [], + "repository_homepage_url": "https://pypi.org/project/apache-airflow", + "repository_download_url": null, + "api_data_url": "https://pypi.org/pypi/apache-airflow/json", + "datasource_id": "pypi_pyproject_toml", + "purl": "pkg:pypi/apache-airflow" + } +] \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/pyproject-toml/standard/apache-airflow/pyproject.toml b/tests/packagedcode/data/pypi/pyproject-toml/standard/apache-airflow/pyproject.toml new file mode 100644 index 00000000000..13f8a69ab12 --- /dev/null +++ b/tests/packagedcode/data/pypi/pyproject-toml/standard/apache-airflow/pyproject.toml @@ -0,0 +1,100 @@ +# copied from https://github.com/apache/airflow/blob/e5bf91b7afeb585e9e70c1708fa290c39ce8094e/pyproject.toml + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +[build-system] +# build dependencies should be fixed - including all transitive dependencies. This way we can ensure +# reproducibility of the build and make sure that any future releases of any dependencies will not +# break the build of released airflow sources in the future. +# The dependencies can be automatically upgraded by running: +# pre-commit run --hook-stage manual update-build-dependencies --all-files +requires = [ + "GitPython==3.1.43", + "gitdb==4.0.11", + "hatchling==1.24.2", + "packaging==24.0", + "pathspec==0.12.1", + "pluggy==1.5.0", + "smmap==5.0.1", + "tomli==2.0.1; python_version < '3.11'", + "trove-classifiers==2024.4.10", +] +build-backend = "hatchling.build" + +[project] +name = "apache-airflow" +description = "Programmatically author, schedule and monitor data pipelines" +readme = { file = "generated/PYPI_README.md", content-type = "text/markdown" } +license-files.globs = ["LICENSE", "3rd-party-licenses/*.txt"] +requires-python = "~=3.8,<3.13" +authors = [ + { name = "Apache Software Foundation", email = "dev@airflow.apache.org" }, +] +maintainers = [ + { name = "Apache Software Foundation", email="dev@airflow.apache.org" }, +] +keywords = [ "airflow", "orchestration", "workflow", "dag", "pipelines", "automation", "data" ] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Environment :: Console", + "Environment :: Web Environment", + "Framework :: Apache Airflow", + "Intended Audience :: Developers", + "Intended Audience :: System Administrators", + "License :: OSI Approved :: Apache Software License", + "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", + "Topic :: System :: Monitoring", +] + +dynamic = ["version", "optional-dependencies", "dependencies"] + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# !!! YOU MIGHT BE SURPRISED NOT SEEING THE DEPENDENCIES AS `project.dependencies` !!!!!!!!! +# !!! AND EXTRAS AS `project.optional-dependencies` !!!!!!!!! +# !!! THEY ARE marked as `dynamic` GENERATED by `hatch_build.py` !!!!!!!!! +# !!! SEE COMMENTS BELOW TO FIND WHERE DEPENDENCIES ARE MAINTAINED !!!!!!!!! +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# +# !!!!!! Those providers are defined in `hatch_build.py` and should be maintained there !!!!!!! +# +# Those extras are available as regular core airflow extras - they install optional features of Airflow. +# +# START CORE EXTRAS HERE +# +# aiobotocore, apache-atlas, apache-webhdfs, async, cgroups, cloudpickle, deprecated-api, github- +# enterprise, google-auth, graphviz, kerberos, ldap, leveldb, otel, pandas, password, pydantic, +# rabbitmq, s3fs, saml, sentry, statsd, uv, virtualenv +# +# END CORE EXTRAS HERE + +[project.scripts] +airflow = "airflow.__main__:main" +[project.urls] +"Bug Tracker" = "https://github.com/apache/airflow/issues" +Documentation = "https://airflow.apache.org/docs/" +Downloads = "https://archive.apache.org/dist/airflow/" +Homepage = "https://airflow.apache.org/" +"Release Notes" = "https://airflow.apache.org/docs/apache-airflow/stable/release_notes.html" +"Slack Chat" = "https://s.apache.org/airflow-slack" +"Source Code" = "https://github.com/apache/airflow" +Twitter = "https://twitter.com/ApacheAirflow" +YouTube = "https://www.youtube.com/channel/UCSXwxpWZQ7XZ1WL3wqevChA/" diff --git a/tests/packagedcode/data/pypi/pyproject-toml/standard/attrs-pyproject.toml-expected.json b/tests/packagedcode/data/pypi/pyproject-toml/standard/attrs-pyproject.toml-expected.json new file mode 100644 index 00000000000..4d7686688f4 --- /dev/null +++ b/tests/packagedcode/data/pypi/pyproject-toml/standard/attrs-pyproject.toml-expected.json @@ -0,0 +1,117 @@ +[ + { + "type": "pypi", + "namespace": null, + "name": "attrs", + "version": null, + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "Classes Without Boilerplate", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "Hynek Schlawack", + "email": "hs@ox.cx", + "url": null + } + ], + "keywords": [ + "class", + "attribute", + "boilerplate", + "Development Status :: 5 - Production/Stable", + "Programming Language :: Python :: 3.7", + "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 :: 3.13", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Typing :: Typed" + ], + "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": "https://github.com/python-attrs/attrs", + "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", + "spdx_license_expression": "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", + "spdx_license_expression": "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": [], + "extra_data": { + "Documentation": "https://www.attrs.org/", + "Changelog": "https://www.attrs.org/en/stable/changelog.html", + "Funding": "https://github.com/sponsors/hynek", + "Tidelift": "https://tidelift.com/subscription/pkg/pypi-attrs?utm_source=pypi-attrs&utm_medium=pypi" + }, + "dependencies": [], + "repository_homepage_url": "https://pypi.org/project/attrs", + "repository_download_url": null, + "api_data_url": "https://pypi.org/pypi/attrs/json", + "datasource_id": "pypi_pyproject_toml", + "purl": "pkg:pypi/attrs" + } +] \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/pyproject-toml/standard/attrs/pyproject.toml b/tests/packagedcode/data/pypi/pyproject-toml/standard/attrs/pyproject.toml new file mode 100644 index 00000000000..49cef1813d7 --- /dev/null +++ b/tests/packagedcode/data/pypi/pyproject-toml/standard/attrs/pyproject.toml @@ -0,0 +1,78 @@ +# SPDX-License-Identifier: MIT +# This is copied from https://github.com/python-attrs/attrs/blob/f7f317ae4c3790f23ae027db626593d50e8a4e88/pyproject.toml +# and deleted non-essential parts + +[build-system] +requires = ["hatchling", "hatch-vcs", "hatch-fancy-pypi-readme>=23.2.0"] +build-backend = "hatchling.build" + +[project] +name = "attrs" +authors = [{ name = "Hynek Schlawack", email = "hs@ox.cx" }] +license = "MIT" +requires-python = ">=3.7" +description = "Classes Without Boilerplate" +keywords = ["class", "attribute", "boilerplate"] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3.7", + "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 :: 3.13", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Typing :: Typed", +] +dependencies = ["importlib_metadata;python_version<'3.8'"] +dynamic = ["version", "readme"] + +[project.optional-dependencies] +tests-mypy = [ + 'pytest-mypy-plugins; platform_python_implementation == "CPython" and python_version >= "3.8"', + # Since the mypy error messages keep changing, we have to keep updating this + # pin. + 'mypy>=1.6,<1.10; platform_python_implementation == "CPython" and python_version >= "3.8"', +] +tests = [ + # For regression test to ensure cloudpickle compat doesn't break. + 'cloudpickle; platform_python_implementation == "CPython"', + "hypothesis", + "pympler", + # 4.3.0 dropped last use of `convert` + "pytest>=4.3.0", + "pytest-xdist[psutil]", + "attrs[tests-mypy]", +] +cov = [ + "attrs[tests]", + # Ensure coverage is new enough for `source_pkgs`. + "coverage[toml]>=5.3", +] +docs = [ + "furo", + "myst-parser", + "sphinx", + "sphinx-notfound-page", + "sphinxcontrib-towncrier", + "towncrier", +] +dev = ["attrs[tests]", "pre-commit"] + +[project.urls] +Documentation = "https://www.attrs.org/" +Changelog = "https://www.attrs.org/en/stable/changelog.html" +GitHub = "https://github.com/python-attrs/attrs" +Funding = "https://github.com/sponsors/hynek" +Tidelift = "https://tidelift.com/subscription/pkg/pypi-attrs?utm_source=pypi-attrs&utm_medium=pypi" + +[tool.black] +line-length = 79 + +[tool.mypy] +pretty = true +disallow_untyped_defs = true +check_untyped_defs = true diff --git a/tests/packagedcode/data/pypi/pyproject-toml/standard/flask-pyproject.toml-expected.json b/tests/packagedcode/data/pypi/pyproject-toml/standard/flask-pyproject.toml-expected.json new file mode 100644 index 00000000000..0142448ac84 --- /dev/null +++ b/tests/packagedcode/data/pypi/pyproject-toml/standard/flask-pyproject.toml-expected.json @@ -0,0 +1,93 @@ +[ + { + "type": "pypi", + "namespace": null, + "name": "Flask", + "version": "3.1.0.dev", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "A simple framework for building complex web applications.", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "maintainer", + "name": "Pallets", + "email": "contact@palletsprojects.com", + "url": null + } + ], + "keywords": [ + "Development Status :: 5 - Production/Stable", + "Environment :: Web Environment", + "Framework :: Flask", + "Intended Audience :: Developers", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Topic :: Internet :: WWW/HTTP :: Dynamic Content", + "Topic :: Internet :: WWW/HTTP :: WSGI", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", + "Topic :: Software Development :: Libraries :: Application Frameworks", + "Typing :: Typed" + ], + "homepage_url": null, + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": "https://github.com/pallets/flask/", + "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", + "spdx_license_expression": "BSD-3-Clause", + "from_file": null, + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 99.0, + "matched_length": 5, + "match_coverage": 100.0, + "rule_relevance": 99, + "rule_identifier": "pypi_bsd_license.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_bsd_license.RULE", + "matched_text": "- 'License :: OSI Approved :: BSD License'" + } + ], + "identifier": "bsd_new-f4e99f86-00ab-18d9-a65d-a3a12767dcf5" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "classifiers:\n - 'License :: OSI Approved :: BSD License'\n", + "notice_text": null, + "source_packages": [], + "file_references": [], + "extra_data": { + "Donate": "https://palletsprojects.com/donate", + "Documentation": "https://flask.palletsprojects.com/", + "Changes": "https://flask.palletsprojects.com/changes/", + "Chat": "https://discord.gg/pallets", + "license_file": "LICENSE.txt" + }, + "dependencies": [], + "repository_homepage_url": "https://pypi.org/project/Flask", + "repository_download_url": "https://pypi.org/packages/source/F/Flask/Flask-3.1.0.dev.tar.gz", + "api_data_url": "https://pypi.org/pypi/Flask/3.1.0.dev/json", + "datasource_id": "pypi_pyproject_toml", + "purl": "pkg:pypi/flask@3.1.0.dev" + } +] \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/pyproject-toml/standard/flask/LICENSE.txt b/tests/packagedcode/data/pypi/pyproject-toml/standard/flask/LICENSE.txt new file mode 100644 index 00000000000..114234c21d6 --- /dev/null +++ b/tests/packagedcode/data/pypi/pyproject-toml/standard/flask/LICENSE.txt @@ -0,0 +1,3 @@ +Copyright 2010 Pallets + +license: bsd-new diff --git a/tests/packagedcode/data/pypi/pyproject-toml/standard/flask/pyproject.toml b/tests/packagedcode/data/pypi/pyproject-toml/standard/flask/pyproject.toml new file mode 100644 index 00000000000..3529fbcf709 --- /dev/null +++ b/tests/packagedcode/data/pypi/pyproject-toml/standard/flask/pyproject.toml @@ -0,0 +1,75 @@ +# Copied from https://github.com/pallets/flask/blob/19610a9e46e0989054ecd0f6be2fcb981013d8eb/pyproject.toml +# with non-essential parts deleted + +[project] +name = "Flask" +version = "3.1.0.dev" +description = "A simple framework for building complex web applications." +readme = "README.md" +license = {file = "LICENSE.txt"} +maintainers = [{name = "Pallets", email = "contact@palletsprojects.com"}] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Environment :: Web Environment", + "Framework :: Flask", + "Intended Audience :: Developers", + "License :: OSI Approved :: BSD License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Topic :: Internet :: WWW/HTTP :: Dynamic Content", + "Topic :: Internet :: WWW/HTTP :: WSGI", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", + "Topic :: Software Development :: Libraries :: Application Frameworks", + "Typing :: Typed", +] +requires-python = ">=3.8" +dependencies = [ + "Werkzeug>=3.0.0", + "Jinja2>=3.1.2", + "itsdangerous>=2.1.2", + "click>=8.1.3", + "blinker>=1.6.2", + "importlib-metadata>=3.6.0; python_version < '3.10'", +] + +[project.urls] +Donate = "https://palletsprojects.com/donate" +Documentation = "https://flask.palletsprojects.com/" +Changes = "https://flask.palletsprojects.com/changes/" +Source = "https://github.com/pallets/flask/" +Chat = "https://discord.gg/pallets" + +[project.optional-dependencies] +async = ["asgiref>=3.2"] +dotenv = ["python-dotenv"] + +[project.scripts] +flask = "flask.cli:main" + +[build-system] +requires = ["flit_core<4"] +build-backend = "flit_core.buildapi" + +[tool.flit.module] +name = "flask" + +[tool.flit.sdist] +include = [ + "docs/", + "examples/", + "requirements/", + "tests/", + "CHANGES.rst", + "CONTRIBUTING.rst", + "tox.ini", +] +exclude = [ + "docs/_build/", +] + +[tool.pytest.ini_options] +testpaths = ["tests"] +filterwarnings = [ + "error", +] + diff --git a/tests/packagedcode/data/pypi/pyproject-toml/standard/lc0-pyproject.toml-expected.json b/tests/packagedcode/data/pypi/pyproject-toml/standard/lc0-pyproject.toml-expected.json new file mode 100644 index 00000000000..615c5027693 --- /dev/null +++ b/tests/packagedcode/data/pypi/pyproject-toml/standard/lc0-pyproject.toml-expected.json @@ -0,0 +1,59 @@ +[ + { + "type": "pypi", + "namespace": null, + "name": "lczero_bindings", + "version": "0.1.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "Leela Chess Zero Python bindings", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "The LCZero Authors", + "email": null, + "url": null + } + ], + "keywords": [ + "Programming Language :: Python :: 3", + "Topic :: Games/Entertainment :: Board Games", + "Topic :: Scientific/Engineering :: Artificial Intelligence", + "Environment :: GPU" + ], + "homepage_url": "https://github.com/LeelaChessZero/lc0", + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "extra_data": { + "license_file": "COPYING" + }, + "dependencies": [], + "repository_homepage_url": "https://pypi.org/project/lczero_bindings", + "repository_download_url": "https://pypi.org/packages/source/l/lczero_bindings/lczero_bindings-0.1.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/lczero_bindings/0.1.0/json", + "datasource_id": "pypi_pyproject_toml", + "purl": "pkg:pypi/lczero-bindings@0.1.0" + } +] \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/pyproject-toml/standard/lc0/COPYING b/tests/packagedcode/data/pypi/pyproject-toml/standard/lc0/COPYING new file mode 100644 index 00000000000..cb2594e6936 --- /dev/null +++ b/tests/packagedcode/data/pypi/pyproject-toml/standard/lc0/COPYING @@ -0,0 +1 @@ +GNU GENERAL PUBLIC LICENSE Version 3 \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/pyproject-toml/standard/lc0/pyproject.toml b/tests/packagedcode/data/pypi/pyproject-toml/standard/lc0/pyproject.toml new file mode 100644 index 00000000000..1b9ee74da0d --- /dev/null +++ b/tests/packagedcode/data/pypi/pyproject-toml/standard/lc0/pyproject.toml @@ -0,0 +1,23 @@ +# copied from https://github.com/LeelaChessZero/lc0/blob/6df87ad33ab2ebe12abb70ddbd7dde9c4ea242c6/pyproject.toml + +[build-system] +requires = ["meson-python"] +build-backend = "mesonpy" + +[project] +name = "lczero_bindings" +version = "0.1.0" +description = "Leela Chess Zero Python bindings" +authors = [{ name = "The LCZero Authors" }] +license = {file = "COPYING"} +readme = "README.md" +requires-python = ">=3.7" +classifiers = [ + "Programming Language :: Python :: 3", + "Topic :: Games/Entertainment :: Board Games", + "Topic :: Scientific/Engineering :: Artificial Intelligence", + "Environment :: GPU" +] + +[project.urls] +homepage = "https://github.com/LeelaChessZero/lc0" diff --git a/tests/packagedcode/data/pypi/source-package/pip-22.0.4-pypi-package-expected.json b/tests/packagedcode/data/pypi/source-package/pip-22.0.4-pypi-package-expected.json index c6a9cff51f1..cfd788ea037 100644 --- a/tests/packagedcode/data/pypi/source-package/pip-22.0.4-pypi-package-expected.json +++ b/tests/packagedcode/data/pypi/source-package/pip-22.0.4-pypi-package-expected.json @@ -519,16 +519,38 @@ { "type": "pypi", "namespace": null, - "name": null, + "name": "pip", "version": null, "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": null, + "description": "The PyPA recommended tool for installing Python packages.", "release_date": null, - "parties": [], - "keywords": [], - "homepage_url": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "The pip developers", + "email": "distutils-sig@python.org", + "url": null + } + ], + "keywords": [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Topic :: Software Development :: Build Tools", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "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" + ], + "homepage_url": "https://pip.pypa.io/", "download_url": null, "size": null, "sha1": null, @@ -536,27 +558,75 @@ "sha256": null, "sha512": null, "bug_tracking_url": null, - "code_view_url": null, + "code_view_url": "https://github.com/pypa/pip", "vcs_url": null, "copyright": null, "holder": null, - "declared_license_expression": null, - "declared_license_expression_spdx": null, - "license_detections": [], + "declared_license_expression": "mit", + "declared_license_expression_spdx": "MIT", + "license_detections": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "spdx_license_expression": "MIT", + "from_file": "pip-22.0.4/pyproject.toml", + "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", + "spdx_license_expression": "MIT", + "from_file": "pip-22.0.4/pyproject.toml", + "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": null, + "extracted_license_statement": "license: MIT\nclassifiers:\n - 'License :: OSI Approved :: MIT License'\n", "notice_text": null, "source_packages": [], "file_references": [], - "extra_data": {}, + "extra_data": { + "Documentation": "https://pip.pypa.io", + "Changelog": "https://pip.pypa.io/en/stable/news/" + }, "dependencies": [], - "repository_homepage_url": null, + "repository_homepage_url": "https://pypi.org/project/pip", "repository_download_url": null, - "api_data_url": null, + "api_data_url": "https://pypi.org/pypi/pip/json", "datasource_id": "pypi_pyproject_toml", - "purl": null + "purl": "pkg:pypi/pip" } ], "for_packages": [ diff --git a/tests/packagedcode/data/pypi/source-package/pip-22.0.4-pypi-package-only-expected.json b/tests/packagedcode/data/pypi/source-package/pip-22.0.4-pypi-package-only-expected.json index 57199d08212..942a7d36d34 100644 --- a/tests/packagedcode/data/pypi/source-package/pip-22.0.4-pypi-package-only-expected.json +++ b/tests/packagedcode/data/pypi/source-package/pip-22.0.4-pypi-package-only-expected.json @@ -344,16 +344,38 @@ { "type": "pypi", "namespace": null, - "name": null, + "name": "pip", "version": null, "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": null, + "description": "The PyPA recommended tool for installing Python packages.", "release_date": null, - "parties": [], - "keywords": [], - "homepage_url": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "The pip developers", + "email": "distutils-sig@python.org", + "url": null + } + ], + "keywords": [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Topic :: Software Development :: Build Tools", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "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" + ], + "homepage_url": "https://pip.pypa.io/", "download_url": null, "size": null, "sha1": null, @@ -361,7 +383,7 @@ "sha256": null, "sha512": null, "bug_tracking_url": null, - "code_view_url": null, + "code_view_url": "https://github.com/pypa/pip", "vcs_url": null, "copyright": null, "holder": null, @@ -371,17 +393,20 @@ "other_license_expression": null, "other_license_expression_spdx": null, "other_license_detections": [], - "extracted_license_statement": null, + "extracted_license_statement": "license: MIT\nclassifiers:\n - 'License :: OSI Approved :: MIT License'\n", "notice_text": null, "source_packages": [], "file_references": [], - "extra_data": {}, + "extra_data": { + "Documentation": "https://pip.pypa.io", + "Changelog": "https://pip.pypa.io/en/stable/news/" + }, "dependencies": [], - "repository_homepage_url": null, + "repository_homepage_url": "https://pypi.org/project/pip", "repository_download_url": null, - "api_data_url": null, + "api_data_url": "https://pypi.org/pypi/pip/json", "datasource_id": "pypi_pyproject_toml", - "purl": null + "purl": "pkg:pypi/pip" } ], "for_packages": [], diff --git a/tests/packagedcode/data/pypi/source-package/pip-22.0.4-pypi-package-with-license-expected.json b/tests/packagedcode/data/pypi/source-package/pip-22.0.4-pypi-package-with-license-expected.json index d5172b954d6..cc43e925229 100644 --- a/tests/packagedcode/data/pypi/source-package/pip-22.0.4-pypi-package-with-license-expected.json +++ b/tests/packagedcode/data/pypi/source-package/pip-22.0.4-pypi-package-with-license-expected.json @@ -122,7 +122,7 @@ "identifier": "mit-24a5293c-14d7-5403-efac-1a8b7532c0e8", "license_expression": "mit", "license_expression_spdx": "MIT", - "detection_count": 5, + "detection_count": 7, "reference_matches": [ { "license_expression": "mit", @@ -144,7 +144,7 @@ "identifier": "mit-a822f434-d61f-f2b1-c792-8b8cb9e7b9bf", "license_expression": "mit", "license_expression_spdx": "MIT", - "detection_count": 3, + "detection_count": 4, "reference_matches": [ { "license_expression": "mit", @@ -270,28 +270,6 @@ } ] }, - { - "identifier": "mit-cacd5c0c-204a-85c2-affc-e4c125b2492a", - "license_expression": "mit", - "license_expression_spdx": "MIT", - "detection_count": 2, - "reference_matches": [ - { - "license_expression": "mit", - "license_expression_spdx": "MIT", - "from_file": "pip-22.0.4/LICENSE.txt", - "start_line": 3, - "end_line": 20, - "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" - } - ] - }, { "identifier": "mit-6e6256c5-00ca-dcb6-8033-2fc4b6ff86be", "license_expression": "mit", @@ -327,6 +305,28 @@ "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_mit_license.RULE" } ] + }, + { + "identifier": "mit-cacd5c0c-204a-85c2-affc-e4c125b2492a", + "license_expression": "mit", + "license_expression_spdx": "MIT", + "detection_count": 1, + "reference_matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": "pip-22.0.4/LICENSE.txt", + "start_line": 3, + "end_line": 20, + "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" + } + ] } ], "files": [ @@ -874,16 +874,38 @@ { "type": "pypi", "namespace": null, - "name": null, + "name": "pip", "version": null, "qualifiers": {}, "subpath": null, "primary_language": "Python", - "description": null, + "description": "The PyPA recommended tool for installing Python packages.", "release_date": null, - "parties": [], - "keywords": [], - "homepage_url": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "The pip developers", + "email": "distutils-sig@python.org", + "url": null + } + ], + "keywords": [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Topic :: Software Development :: Build Tools", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "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" + ], + "homepage_url": "https://pip.pypa.io/", "download_url": null, "size": null, "sha1": null, @@ -891,7 +913,7 @@ "sha256": null, "sha512": null, "bug_tracking_url": null, - "code_view_url": null, + "code_view_url": "https://github.com/pypa/pip", "vcs_url": null, "copyright": null, "holder": null, @@ -905,45 +927,93 @@ { "license_expression": "mit", "spdx_license_expression": "MIT", - "from_file": "pip-22.0.4/LICENSE.txt", - "start_line": 3, - "end_line": 20, - "matcher": "2-aho", + "from_file": "pip-22.0.4/pyproject.toml", + "start_line": 1, + "end_line": 1, + "matcher": "1-spdx-id", "score": 100.0, - "matched_length": 161, + "matched_length": 1, "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" + "rule_identifier": "spdx-license-identifier-mit-5da48780aba670b0860c46d899ed42a0f243ff06", + "rule_url": null, + "matched_text": "MIT" } ], - "identifier": "mit-cacd5c0c-204a-85c2-affc-e4c125b2492a" + "identifier": "mit-a822f434-d61f-f2b1-c792-8b8cb9e7b9bf" + }, + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "spdx_license_expression": "MIT", + "from_file": "pip-22.0.4/pyproject.toml", + "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": null, + "extracted_license_statement": "license: MIT\nclassifiers:\n - 'License :: OSI Approved :: MIT License'\n", "notice_text": null, "source_packages": [], "file_references": [], - "extra_data": {}, + "extra_data": { + "Documentation": "https://pip.pypa.io", + "Changelog": "https://pip.pypa.io/en/stable/news/" + }, "dependencies": [], - "repository_homepage_url": null, + "repository_homepage_url": "https://pypi.org/project/pip", "repository_download_url": null, - "api_data_url": null, + "api_data_url": "https://pypi.org/pypi/pip/json", "datasource_id": "pypi_pyproject_toml", - "purl": null + "purl": "pkg:pypi/pip" } ], "for_packages": [ "pkg:pypi/pip@22.0.4?uuid=fixed-uid-done-for-testing-5642512d1758" ], - "detected_license_expression": null, - "detected_license_expression_spdx": null, - "license_detections": [], + "detected_license_expression": "mit", + "detected_license_expression_spdx": "MIT", + "license_detections": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "spdx_license_expression": "MIT", + "from_file": "pip-22.0.4/pyproject.toml", + "start_line": 11, + "end_line": 11, + "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" + } + ], + "identifier": "mit-24a5293c-14d7-5403-efac-1a8b7532c0e8" + } + ], "license_clues": [], - "percentage_of_license_text": 0, + "percentage_of_license_text": 2.38, "scan_errors": [] }, { diff --git a/tests/packagedcode/data/pypi/source-package/pip-22.0.4/pyproject.toml b/tests/packagedcode/data/pypi/source-package/pip-22.0.4/pyproject.toml index a02457eeffd..373866fa7f6 100644 --- a/tests/packagedcode/data/pypi/source-package/pip-22.0.4/pyproject.toml +++ b/tests/packagedcode/data/pypi/source-package/pip-22.0.4/pyproject.toml @@ -1,71 +1,57 @@ -[build-system] -requires = ["setuptools", "wheel"] -build-backend = "setuptools.build_meta" - -[tool.towncrier] -# For finding the __version__ -package = "pip" -package_dir = "src" -# For writing into the correct file -filename = "NEWS.rst" -# For finding the news fragments -directory = "news/" +[project] +dynamic = ["version"] + +name = "pip" +description = "The PyPA recommended tool for installing Python packages." +readme = "README.rst" +license = {text = "MIT"} +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Topic :: Software Development :: Build Tools", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "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", +] +authors = [ + {name = "The pip developers", email = "distutils-sig@python.org"}, +] -# For rendering properly for this project -issue_format = "`#{issue} `_" -template = "tools/news/template.rst" +# NOTE: requires-python is duplicated in __pip-runner__.py. +# When changing this value, please change the other copy as well. +requires-python = ">=3.8" -# Grouping of entries, within our changelog -type = [ - { name = "Process", directory = "process", showcontent = true }, - { name = "Deprecations and Removals", directory = "removal", showcontent = true }, - { name = "Features", directory = "feature", showcontent = true }, - { name = "Bug Fixes", directory = "bugfix", showcontent = true }, - { name = "Vendored Libraries", directory = "vendor", showcontent = true }, - { name = "Improved Documentation", directory = "doc", showcontent = true }, - { name = "Trivial Changes", directory = "trivial", showcontent = false }, -] +[project.scripts] +pip = "pip._internal.cli.main:main" +pip3 = "pip._internal.cli.main:main" -[tool.vendoring] -destination = "src/pip/_vendor/" -requirements = "src/pip/_vendor/vendor.txt" -namespace = "pip._vendor" +[project.urls] +Homepage = "https://pip.pypa.io/" +Documentation = "https://pip.pypa.io" +Source = "https://github.com/pypa/pip" +Changelog = "https://pip.pypa.io/en/stable/news/" -protected-files = ["__init__.py", "README.rst", "vendor.txt"] -patches-dir = "tools/vendoring/patches" +[build-system] +# The lower bound is for . +requires = ["setuptools>=67.6.1", "wheel"] +build-backend = "setuptools.build_meta" -[tool.vendoring.transformations] -substitute = [ - # pkg_resource's vendored packages are directly vendored in pip. - { match='pkg_resources\.extern', replace="pip._vendor" }, - { match='from \.extern', replace="from pip._vendor" }, - { match='''\('pygments\.lexers\.''', replace="('pip._vendor.pygments.lexers." }, -] -drop = [ - # contains unnecessary scripts - "bin/", - # interpreter and OS specific msgpack libs - "msgpack/*.so", - # unneeded parts of setuptools - "easy_install.py", - "setuptools", - "pkg_resources/_vendor/", - "pkg_resources/extern/", - # trim vendored pygments styles and lexers - "pygments/styles/[!_]*.py", - '^pygments/lexers/(?!python|__init__|_mapping).*\.py$', - # trim rich's markdown support - "rich/markdown.py", -] +[tool.setuptools] +package-dir = {"" = "src"} +include-package-data = false -[tool.vendoring.typing-stubs] -six = ["six.__init__", "six.moves.__init__", "six.moves.configparser"] -distro = [] +[tool.setuptools.dynamic] +version = {attr = "pip.__version__"} -[tool.vendoring.license.directories] -setuptools = "pkg_resources" +[tool.setuptools.packages.find] +where = ["src"] +exclude = ["contrib", "docs", "tests*", "tasks"] -[tool.vendoring.license.fallback-urls] -CacheControl = "https://raw.githubusercontent.com/ionrock/cachecontrol/v0.12.6/LICENSE.txt" -distlib = "https://bitbucket.org/pypa/distlib/raw/master/LICENSE.txt" -webencodings = "https://github.com/SimonSapin/python-webencodings/raw/master/LICENSE" diff --git a/tests/packagedcode/test_pypi.py b/tests/packagedcode/test_pypi.py index b38e7e5b5ad..1bf786b11fc 100644 --- a/tests/packagedcode/test_pypi.py +++ b/tests/packagedcode/test_pypi.py @@ -295,6 +295,60 @@ def test_parse_metadata_prefer_pkg_info_from_egg_info_from_command_line(self): assert path == 'celery/celery.egg-info/PKG-INFO' +class TestPyprojectTomlFileHandler(PackageTester): + test_data_dir = os.path.join(os.path.dirname(__file__), 'data') + + def test_is_pyproject_toml_standard(self): + test_file = self.get_test_loc('pypi/pyproject-toml/standard/attrs/pyproject.toml') + assert pypi.PyprojectTomlHandler.is_datafile(test_file) + + def test_parse_pyproject_toml_standard_attrs(self): + test_file = self.get_test_loc('pypi/pyproject-toml/standard/attrs/pyproject.toml') + package = pypi.PyprojectTomlHandler.parse(test_file) + expected_loc = self.get_test_loc('pypi/pyproject-toml/standard/attrs-pyproject.toml-expected.json') + self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) + + def test_parse_pyproject_toml_standard_apache_airflow(self): + test_file = self.get_test_loc('pypi/pyproject-toml/standard/apache-airflow/pyproject.toml') + package = pypi.PyprojectTomlHandler.parse(test_file) + expected_loc = self.get_test_loc('pypi/pyproject-toml/standard/apache-airflow-pyproject.toml-expected.json') + self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) + + def test_parse_pyproject_toml_standard_apache_airflow_client(self): + test_file = self.get_test_loc('pypi/pyproject-toml/standard/apache-airflow-pyclient/pyproject.toml') + package = pypi.PyprojectTomlHandler.parse(test_file) + expected_loc = self.get_test_loc('pypi/pyproject-toml/standard/apache-airflow-pyclient-pyproject.toml-expected.json') + self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) + + def test_parse_pyproject_toml_standard_flask(self): + test_file = self.get_test_loc('pypi/pyproject-toml/standard/flask/pyproject.toml') + package = pypi.PyprojectTomlHandler.parse(test_file) + expected_loc = self.get_test_loc('pypi/pyproject-toml/standard/flask-pyproject.toml-expected.json') + self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) + + def test_parse_pyproject_toml_standard_lc0(self): + test_file = self.get_test_loc('pypi/pyproject-toml/standard/lc0/pyproject.toml') + package = pypi.PyprojectTomlHandler.parse(test_file) + expected_loc = self.get_test_loc('pypi/pyproject-toml/standard/lc0-pyproject.toml-expected.json') + self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) + + def test_is_pyproject_toml_poetry(self): + test_file = self.get_test_loc('pypi/pyproject-toml/poetry/gerapy/pyproject.toml') + assert pypi.PoetryPyprojectTomlHandler.is_datafile(test_file) + + def test_parse_pyproject_toml_poetry_gerapy(self): + test_file = self.get_test_loc('pypi/pyproject-toml/poetry/gerapy/pyproject.toml') + package = pypi.PoetryPyprojectTomlHandler.parse(test_file) + expected_loc = self.get_test_loc('pypi/pyproject-toml/poetry/gerapy-pyproject.toml-expected.json') + self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) + + def test_parse_pyproject_toml_poetry_gino(self): + test_file = self.get_test_loc('pypi/pyproject-toml/poetry/gino/pyproject.toml') + package = pypi.PoetryPyprojectTomlHandler.parse(test_file) + expected_loc = self.get_test_loc('pypi/pyproject-toml/poetry/gino-pyproject.toml-expected.json') + self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) + + class TestPipRequirementsFileHandler(PackageTester): test_data_dir = os.path.join(os.path.dirname(__file__), 'data') From fc4ada968adbbb2aeed6b79921cc2589ace497c4 Mon Sep 17 00:00:00 2001 From: Ayan Sinha Mahapatra Date: Wed, 26 Jun 2024 21:27:15 +0530 Subject: [PATCH 02/10] Add support for pip-inspect.deplock files Add parser for pip-inspect.deplock files generated by deplock which has all the package metadata, i.e. the resolved versions and the dependency relationships. Reference: https://github.com/nexB/scancode.io/issues/1262 Signed-off-by: Ayan Sinha Mahapatra --- src/packagedcode/__init__.py | 3 + src/packagedcode/pypi.py | 121 +- tests/packagedcode/data/plugin/help.txt | 7 + .../pypi/deplock/univers/pip-inspect.deplock | 519 ++++++ .../univers/pip-inspect.deplock-expected.json | 1628 +++++++++++++++++ tests/packagedcode/test_pypi.py | 14 + 6 files changed, 2291 insertions(+), 1 deletion(-) create mode 100644 tests/packagedcode/data/pypi/deplock/univers/pip-inspect.deplock create mode 100644 tests/packagedcode/data/pypi/deplock/univers/pip-inspect.deplock-expected.json diff --git a/src/packagedcode/__init__.py b/src/packagedcode/__init__.py index fc4028fc13d..aef9936ea69 100644 --- a/src/packagedcode/__init__.py +++ b/src/packagedcode/__init__.py @@ -207,6 +207,9 @@ windows.MicrosoftUpdateManifestHandler, win_pe.WindowsExecutableHandler, + + # These are handlers for deplock generated files + pypi.PipInspectDeplockHandler, ] if on_linux: diff --git a/src/packagedcode/pypi.py b/src/packagedcode/pypi.py index 445a0562969..9268a44694e 100644 --- a/src/packagedcode/pypi.py +++ b/src/packagedcode/pypi.py @@ -42,6 +42,7 @@ from packagedcode.utils import parse_maintainer_name_email from packagedcode.utils import yield_dependencies_from_package_data from packagedcode.utils import yield_dependencies_from_package_resource +from packagedcode.utils import get_base_purl try: from zipfile import Path as ZipPath @@ -563,6 +564,123 @@ def parse(cls, location, package_only=False): yield models.PackageData.from_data(package_data, package_only) +class PipInspectDeplockHandler(models.DatafileHandler): + datasource_id = 'pypi_inspect_deplock' + path_patterns = ('*pip-inspect.deplock',) + default_package_type = 'pypi' + default_primary_language = 'Python' + description = 'Python poetry pyproject.toml' + # These are files generated by deplock, see https://github.com/nexB/dependency-inspector + documentation_url = 'https://pip.pypa.io/en/stable/cli/pip_inspect/' + + @classmethod + def get_resolved_package_from_metadata(cls, metadata, package_only=False): + + requires_dist = metadata.get('requires_dist') + dependencies_for_resolved = get_requires_dependencies( + requires=requires_dist, + ) + package_data = dict( + datasource_id=cls.datasource_id, + type=cls.default_package_type, + primary_language='Python', + name=metadata.get('name'), + version=metadata.get('version'), + extracted_license_statement=metadata.get('license'), + description=metadata.get('description'), + keywords=metadata.get('keywords'), + is_virtual=True, + dependencies=[ + dep.to_dict() + for dep in dependencies_for_resolved + ], + ) + return models.PackageData.from_data(package_data, package_only) + + @classmethod + def parse(cls, location, package_only=False): + + with open(location) as f: + content = f.read() + + data = json.loads(content) + installed_packages = data.get('installed') + if not installed_packages: + return + + main_package_metadata = {} + dependencies = [] + + direct_deps_of_main_package = [] + + for package_metadata in installed_packages: + package_metadata_dep = package_metadata.get('metadata') + + # `direct_url` is only present for root package + # `requested` is true for root package and direct dependencies only + if package_metadata.get('requested') and 'direct_url' in package_metadata: + main_package_metadata = package_metadata_dep + main_package_requires = main_package_metadata.get('requires_dist') + dependencies_for_main = get_requires_dependencies( + requires=main_package_requires, + ) + direct_deps_of_main_package.extend([ + get_base_purl(dep.purl) + for dep in dependencies_for_main + ]) + continue + + package_data_dep = cls.get_resolved_package_from_metadata( + metadata=package_metadata_dep, + package_only=package_only, + ) + dep_purl = package_data_dep.purl + dependency = models.DependentPackage( + purl=dep_purl, + extracted_requirement=None, + scope=None, + is_runtime=True, + is_optional=False, + is_direct=False, + is_resolved=True, + resolved_package=package_data_dep.to_dict() + ) + dependencies.append(dependency) + + dependency_mappings = [] + resolved_main_dependencies = [] + + # Update is_direct for direct dependencies + for dep in dependencies: + base_purl = get_base_purl(dep.purl) + if base_purl in direct_deps_of_main_package: + dep.is_direct = True + resolved_main_dependencies.append(base_purl) + + dependency_mappings.append(dep.to_dict()) + + pip_version = data.get('pip_version') + inspect_version = data.get('version') + extra_data = { + "pip_version": pip_version, + "inspect_version": inspect_version, + } + + package_data_main = cls.get_resolved_package_from_metadata( + metadata=main_package_metadata, + package_only=package_only, + ) + + main_dependencies = [] + for dep in package_data_main.dependencies: + base_purl = get_base_purl(purl=dep.get('purl')) + if base_purl not in resolved_main_dependencies: + main_dependencies.append(dep) + + package_data_main.dependencies = dependencies + package_data_main.dependencies.extend(main_dependencies) + package_data_main.extra_data = extra_data + yield package_data_main META_DIR_SUFFIXES = '.dist-info', '.egg-info', 'EGG-INFO', @@ -1494,7 +1612,7 @@ def get_dist_dependencies(dist): return get_requires_dependencies(requires=dist.requires) -def get_requires_dependencies(requires, default_scope='install'): +def get_requires_dependencies(requires, default_scope='install', is_direct=True): """ Return a list of DependentPackage found in a ``requires`` list of requirement strings or an empty list. @@ -1539,6 +1657,7 @@ def get_requires_dependencies(requires, default_scope='install'): is_runtime=True, is_optional=True if bool(extra) else False, is_resolved=is_resolved, + is_direct=is_direct, extracted_requirement=str(req), )) diff --git a/tests/packagedcode/data/plugin/help.txt b/tests/packagedcode/data/plugin/help.txt index 7b2caac9cc7..5712bb11dad 100755 --- a/tests/packagedcode/data/plugin/help.txt +++ b/tests/packagedcode/data/plugin/help.txt @@ -713,6 +713,13 @@ Package type: pypi description: PyPI extracted egg PKG-INFO path_patterns: '*/EGG-INFO/PKG-INFO' -------------------------------------------- +Package type: pypi + datasource_id: pypi_inspect_deplock + documentation URL: https://pip.pypa.io/en/stable/cli/pip_inspect/ + primary language: Python + description: Python poetry pyproject.toml + path_patterns: '*pip-inspect.deplock' +-------------------------------------------- Package type: pypi datasource_id: pypi_poetry_pyproject_toml documentation URL: https://packaging.python.org/en/latest/specifications/pyproject-toml/ diff --git a/tests/packagedcode/data/pypi/deplock/univers/pip-inspect.deplock b/tests/packagedcode/data/pypi/deplock/univers/pip-inspect.deplock new file mode 100644 index 00000000000..6eac7b58711 --- /dev/null +++ b/tests/packagedcode/data/pypi/deplock/univers/pip-inspect.deplock @@ -0,0 +1,519 @@ +{ + "version": "1", + "pip_version": "24.1", + "installed": [ + { + "metadata": { + "metadata_version": "2.1", + "name": "attrs", + "version": "21.2.0", + "platform": [ + "UNKNOWN" + ], + "summary": "Classes Without Boilerplate", + "description_content_type": "text/x-rst", + "keywords": [ + "class", + "attribute", + "boilerplate" + ], + "home_page": "https://www.attrs.org/", + "author": "Hynek Schlawack", + "author_email": "hs@ox.cx", + "maintainer": "Hynek Schlawack", + "maintainer_email": "hs@ox.cx", + "license": "MIT", + "classifier": [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Natural Language :: English", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Software Development :: Libraries :: Python Modules" + ], + "requires_dist": [ + "coverage[toml] (>=5.0.2) ; extra == 'dev'", + "hypothesis ; extra == 'dev'", + "pympler ; extra == 'dev'", + "pytest (>=4.3.0) ; extra == 'dev'", + "six ; extra == 'dev'", + "mypy ; extra == 'dev'", + "pytest-mypy-plugins ; extra == 'dev'", + "zope.interface ; extra == 'dev'", + "furo ; extra == 'dev'", + "sphinx ; extra == 'dev'", + "sphinx-notfound-page ; extra == 'dev'", + "pre-commit ; extra == 'dev'", + "furo ; extra == 'docs'", + "sphinx ; extra == 'docs'", + "zope.interface ; extra == 'docs'", + "sphinx-notfound-page ; extra == 'docs'", + "coverage[toml] (>=5.0.2) ; extra == 'tests'", + "hypothesis ; extra == 'tests'", + "pympler ; extra == 'tests'", + "pytest (>=4.3.0) ; extra == 'tests'", + "six ; extra == 'tests'", + "mypy ; extra == 'tests'", + "pytest-mypy-plugins ; extra == 'tests'", + "zope.interface ; extra == 'tests'", + "coverage[toml] (>=5.0.2) ; extra == 'tests_no_zope'", + "hypothesis ; extra == 'tests_no_zope'", + "pympler ; extra == 'tests_no_zope'", + "pytest (>=4.3.0) ; extra == 'tests_no_zope'", + "six ; extra == 'tests_no_zope'", + "mypy ; extra == 'tests_no_zope'", + "pytest-mypy-plugins ; extra == 'tests_no_zope'" + ], + "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*", + "project_url": [ + "Documentation, https://www.attrs.org/", + "Changelog, https://www.attrs.org/en/stable/changelog.html", + "Bug Tracker, https://github.com/python-attrs/attrs/issues", + "Source Code, https://github.com/python-attrs/attrs", + "Funding, https://github.com/sponsors/hynek", + "Tidelift, https://tidelift.com/subscription/pkg/pypi-attrs?utm_source=pypi-attrs&utm_medium=pypi", + "Ko-fi, https://ko-fi.com/the_hynek" + ], + "provides_extra": [ + "dev", + "docs", + "tests", + "tests_no_zope" + ], + "description": "======================================\n``attrs``: Classes Without Boilerplate\n======================================\n\n\n``attrs`` is the Python package that will bring back the **joy** of **writing classes** by relieving you from the drudgery of implementing object protocols (aka `dunder `_ methods).\n`Trusted by NASA `_ for Mars missions since 2020!\n\nIts main goal is to help you to write **concise** and **correct** software without slowing down your code.\n\n.. teaser-end\n\nFor that, it gives you a class decorator and a way to declaratively define the attributes on that class:\n\n.. -code-begin-\n\n.. code-block:: pycon\n\n >>> import attr\n\n >>> @attr.s\n ... class SomeClass(object):\n ... a_number = attr.ib(default=42)\n ... list_of_numbers = attr.ib(factory=list)\n ...\n ... def hard_math(self, another_number):\n ... return self.a_number + sum(self.list_of_numbers) * another_number\n\n\n >>> sc = SomeClass(1, [1, 2, 3])\n >>> sc\n SomeClass(a_number=1, list_of_numbers=[1, 2, 3])\n\n >>> sc.hard_math(3)\n 19\n >>> sc == SomeClass(1, [1, 2, 3])\n True\n >>> sc != SomeClass(2, [3, 2, 1])\n True\n\n >>> attr.asdict(sc)\n {'a_number': 1, 'list_of_numbers': [1, 2, 3]}\n\n >>> SomeClass()\n SomeClass(a_number=42, list_of_numbers=[])\n\n >>> C = attr.make_class(\"C\", [\"a\", \"b\"])\n >>> C(\"foo\", \"bar\")\n C(a='foo', b='bar')\n\n\nAfter *declaring* your attributes ``attrs`` gives you:\n\n- a concise and explicit overview of the class's attributes,\n- a nice human-readable ``__repr__``,\n- a complete set of comparison methods (equality and ordering),\n- an initializer,\n- and much more,\n\n*without* writing dull boilerplate code again and again and *without* runtime performance penalties.\n\nOn Python 3.6 and later, you can often even drop the calls to ``attr.ib()`` by using `type annotations `_.\n\nThis gives you the power to use actual classes with actual types in your code instead of confusing ``tuple``\\ s or `confusingly behaving `_ ``namedtuple``\\ s.\nWhich in turn encourages you to write *small classes* that do `one thing well `_.\nNever again violate the `single responsibility principle `_ just because implementing ``__init__`` et al is a painful drag.\n\n\n.. -getting-help-\n\nGetting Help\n============\n\nPlease use the ``python-attrs`` tag on `StackOverflow `_ to get help.\n\nAnswering questions of your fellow developers is also a great way to help the project!\n\n\n.. -project-information-\n\nProject Information\n===================\n\n``attrs`` is released under the `MIT `_ license,\nits documentation lives at `Read the Docs `_,\nthe code on `GitHub `_,\nand the latest release on `PyPI `_.\nIt’s rigorously tested on Python 2.7, 3.5+, and PyPy.\n\nWe collect information on **third-party extensions** in our `wiki `_.\nFeel free to browse and add your own!\n\nIf you'd like to contribute to ``attrs`` you're most welcome and we've written `a little guide `_ to get you started!\n\n\n``attrs`` for Enterprise\n------------------------\n\nAvailable as part of the Tidelift Subscription.\n\nThe maintainers of ``attrs`` and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications.\nSave time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use.\n`Learn more. `_\n\n\nRelease Information\n===================\n\n21.2.0 (2021-05-07)\n-------------------\n\nBackward-incompatible Changes\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n- We had to revert the recursive feature for ``attr.evolve()`` because it broke some use-cases -- sorry!\n `#806 `_\n- Python 3.4 is now blocked using packaging metadata because ``attrs`` can't be imported on it anymore.\n To ensure that 3.4 users can keep installing ``attrs`` easily, we will `yank `_ 21.1.0 from PyPI.\n This has **no** consequences if you pin ``attrs`` to 21.1.0.\n `#807 `_\n\n`Full changelog `_.\n\nCredits\n=======\n\n``attrs`` is written and maintained by `Hynek Schlawack `_.\n\nThe development is kindly supported by `Variomedia AG `_.\n\nA full list of contributors can be found in `GitHub's overview `_.\n\nIt’s the spiritual successor of `characteristic `_ and aspires to fix some of it clunkiness and unfortunate decisions.\nBoth were inspired by Twisted’s `FancyEqMixin `_ but both are implemented using class decorators because `subclassing is bad for you `_, m’kay?\n\n\n" + }, + "metadata_location": "/home/ayansinha/nexB/write_access/univers/venv/lib/python3.10/site-packages/attrs-21.2.0.dist-info", + "installer": "pip", + "requested": false + }, + { + "metadata": { + "metadata_version": "2.1", + "name": "packaging", + "version": "21.0", + "platform": [ + "UNKNOWN" + ], + "summary": "Core utilities for Python packages", + "description_content_type": "text/x-rst", + "home_page": "https://github.com/pypa/packaging", + "author": "Donald Stufft and individual contributors", + "author_email": "donald@stufft.io", + "license": "BSD-2-Clause or Apache-2.0", + "classifier": [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "License :: OSI Approved :: BSD License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy" + ], + "requires_dist": [ + "pyparsing (>=2.0.2)" + ], + "requires_python": ">=3.6", + "description": "packaging\n=========\n\n.. start-intro\n\nReusable core utilities for various Python Packaging\n`interoperability specifications `_.\n\nThis library provides utilities that implement the interoperability\nspecifications which have clearly one correct behaviour (eg: :pep:`440`)\nor benefit greatly from having a single shared implementation (eg: :pep:`425`).\n\n.. end-intro\n\nThe ``packaging`` project includes the following: version handling, specifiers,\nmarkers, requirements, tags, utilities.\n\nDocumentation\n-------------\n\nThe `documentation`_ provides information and the API for the following:\n\n- Version Handling\n- Specifiers\n- Markers\n- Requirements\n- Tags\n- Utilities\n\nInstallation\n------------\n\nUse ``pip`` to install these utilities::\n\n pip install packaging\n\nDiscussion\n----------\n\nIf you run into bugs, you can file them in our `issue tracker`_.\n\nYou can also join ``#pypa`` on Freenode to ask questions or get involved.\n\n\n.. _`documentation`: https://packaging.pypa.io/\n.. _`issue tracker`: https://github.com/pypa/packaging/issues\n\n\nCode of Conduct\n---------------\n\nEveryone interacting in the packaging project's codebases, issue trackers, chat\nrooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.\n\n.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md\n\nContributing\n------------\n\nThe ``CONTRIBUTING.rst`` file outlines how to contribute to this project as\nwell as how to report a potential security issue. The documentation for this\nproject also covers information about `project development`_ and `security`_.\n\n.. _`project development`: https://packaging.pypa.io/en/latest/development/\n.. _`security`: https://packaging.pypa.io/en/latest/security/\n\nProject History\n---------------\n\nPlease review the ``CHANGELOG.rst`` file or the `Changelog documentation`_ for\nrecent changes and project history.\n\n.. _`Changelog documentation`: https://packaging.pypa.io/en/latest/changelog/\n\nChangelog\n---------\n\n21.0 - 2021-07-03\n~~~~~~~~~~~~~~~~~\n\n* `packaging` is now only compatible with Python 3.6 and above.\n* Add support for zip files in ``parse_sdist_filename`` (`#429 `__)\n\n20.9 - 2021-01-29\n~~~~~~~~~~~~~~~~~\n\n* Run `isort `_ over the code base (`#377 `__)\n* Add support for the ``macosx_10_*_universal2`` platform tags (`#379 `__)\n* Introduce ``packaging.utils.parse_wheel_filename()`` and ``parse_sdist_filename()``\n (`#387 `__ and `#389 `__)\n\n20.8 - 2020-12-11\n~~~~~~~~~~~~~~~~~\n\n* Revert back to setuptools for compatibility purposes for some Linux distros (`#363 `__)\n* Do not insert an underscore in wheel tags when the interpreter version number\n is more than 2 digits (`#372 `__)\n\n20.7 - 2020-11-28\n~~~~~~~~~~~~~~~~~\n\nNo unreleased changes.\n\n20.6 - 2020-11-28\n~~~~~~~~~~~~~~~~~\n\n.. note:: This release was subsequently yanked, and these changes were included in 20.7.\n\n* Fix flit configuration, to include LICENSE files (`#357 `__)\n* Make `intel` a recognized CPU architecture for the `universal` macOS platform tag (`#361 `__)\n* Add some missing type hints to `packaging.requirements` (issue:`350`)\n\n20.5 - 2020-11-27\n~~~~~~~~~~~~~~~~~\n\n* Officially support Python 3.9 (`#343 `__)\n* Deprecate the ``LegacyVersion`` and ``LegacySpecifier`` classes (`#321 `__)\n* Handle ``OSError`` on non-dynamic executables when attempting to resolve\n the glibc version string.\n\n20.4 - 2020-05-19\n~~~~~~~~~~~~~~~~~\n\n* Canonicalize version before comparing specifiers. (`#282 `__)\n* Change type hint for ``canonicalize_name`` to return\n ``packaging.utils.NormalizedName``.\n This enables the use of static typing tools (like mypy) to detect mixing of\n normalized and un-normalized names.\n\n20.3 - 2020-03-05\n~~~~~~~~~~~~~~~~~\n\n* Fix changelog for 20.2.\n\n20.2 - 2020-03-05\n~~~~~~~~~~~~~~~~~\n\n* Fix a bug that caused a 32-bit OS that runs on a 64-bit ARM CPU (e.g. ARM-v8,\n aarch64), to report the wrong bitness.\n\n20.1 - 2020-01-24\n~~~~~~~~~~~~~~~~~~~\n\n* Fix a bug caused by reuse of an exhausted iterator. (`#257 `__)\n\n20.0 - 2020-01-06\n~~~~~~~~~~~~~~~~~\n\n* Add type hints (`#191 `__)\n\n* Add proper trove classifiers for PyPy support (`#198 `__)\n\n* Scale back depending on ``ctypes`` for manylinux support detection (`#171 `__)\n\n* Use ``sys.implementation.name`` where appropriate for ``packaging.tags`` (`#193 `__)\n\n* Expand upon the API provided by ``packaging.tags``: ``interpreter_name()``, ``mac_platforms()``, ``compatible_tags()``, ``cpython_tags()``, ``generic_tags()`` (`#187 `__)\n\n* Officially support Python 3.8 (`#232 `__)\n\n* Add ``major``, ``minor``, and ``micro`` aliases to ``packaging.version.Version`` (`#226 `__)\n\n* Properly mark ``packaging`` has being fully typed by adding a `py.typed` file (`#226 `__)\n\n19.2 - 2019-09-18\n~~~~~~~~~~~~~~~~~\n\n* Remove dependency on ``attrs`` (`#178 `__, `#179 `__)\n\n* Use appropriate fallbacks for CPython ABI tag (`#181 `__, `#185 `__)\n\n* Add manylinux2014 support (`#186 `__)\n\n* Improve ABI detection (`#181 `__)\n\n* Properly handle debug wheels for Python 3.8 (`#172 `__)\n\n* Improve detection of debug builds on Windows (`#194 `__)\n\n19.1 - 2019-07-30\n~~~~~~~~~~~~~~~~~\n\n* Add the ``packaging.tags`` module. (`#156 `__)\n\n* Correctly handle two-digit versions in ``python_version`` (`#119 `__)\n\n\n19.0 - 2019-01-20\n~~~~~~~~~~~~~~~~~\n\n* Fix string representation of PEP 508 direct URL requirements with markers.\n\n* Better handling of file URLs\n\n This allows for using ``file:///absolute/path``, which was previously\n prevented due to the missing ``netloc``.\n\n This allows for all file URLs that ``urlunparse`` turns back into the\n original URL to be valid.\n\n\n18.0 - 2018-09-26\n~~~~~~~~~~~~~~~~~\n\n* Improve error messages when invalid requirements are given. (`#129 `__)\n\n\n17.1 - 2017-02-28\n~~~~~~~~~~~~~~~~~\n\n* Fix ``utils.canonicalize_version`` when supplying non PEP 440 versions.\n\n\n17.0 - 2017-02-28\n~~~~~~~~~~~~~~~~~\n\n* Drop support for python 2.6, 3.2, and 3.3.\n\n* Define minimal pyparsing version to 2.0.2 (`#91 `__).\n\n* Add ``epoch``, ``release``, ``pre``, ``dev``, and ``post`` attributes to\n ``Version`` and ``LegacyVersion`` (`#34 `__).\n\n* Add ``Version().is_devrelease`` and ``LegacyVersion().is_devrelease`` to\n make it easy to determine if a release is a development release.\n\n* Add ``utils.canonicalize_version`` to canonicalize version strings or\n ``Version`` instances (`#121 `__).\n\n\n16.8 - 2016-10-29\n~~~~~~~~~~~~~~~~~\n\n* Fix markers that utilize ``in`` so that they render correctly.\n\n* Fix an erroneous test on Python RC releases.\n\n\n16.7 - 2016-04-23\n~~~~~~~~~~~~~~~~~\n\n* Add support for the deprecated ``python_implementation`` marker which was\n an undocumented setuptools marker in addition to the newer markers.\n\n\n16.6 - 2016-03-29\n~~~~~~~~~~~~~~~~~\n\n* Add support for the deprecated, PEP 345 environment markers in addition to\n the newer markers.\n\n\n16.5 - 2016-02-26\n~~~~~~~~~~~~~~~~~\n\n* Fix a regression in parsing requirements with whitespaces between the comma\n separators.\n\n\n16.4 - 2016-02-22\n~~~~~~~~~~~~~~~~~\n\n* Fix a regression in parsing requirements like ``foo (==4)``.\n\n\n16.3 - 2016-02-21\n~~~~~~~~~~~~~~~~~\n\n* Fix a bug where ``packaging.requirements:Requirement`` was overly strict when\n matching legacy requirements.\n\n\n16.2 - 2016-02-09\n~~~~~~~~~~~~~~~~~\n\n* Add a function that implements the name canonicalization from PEP 503.\n\n\n16.1 - 2016-02-07\n~~~~~~~~~~~~~~~~~\n\n* Implement requirement specifiers from PEP 508.\n\n\n16.0 - 2016-01-19\n~~~~~~~~~~~~~~~~~\n\n* Relicense so that packaging is available under *either* the Apache License,\n Version 2.0 or a 2 Clause BSD license.\n\n* Support installation of packaging when only distutils is available.\n\n* Fix ``==`` comparison when there is a prefix and a local version in play.\n (`#41 `__).\n\n* Implement environment markers from PEP 508.\n\n\n15.3 - 2015-08-01\n~~~~~~~~~~~~~~~~~\n\n* Normalize post-release spellings for rev/r prefixes. `#35 `__\n\n\n15.2 - 2015-05-13\n~~~~~~~~~~~~~~~~~\n\n* Fix an error where the arbitrary specifier (``===``) was not correctly\n allowing pre-releases when it was being used.\n\n* Expose the specifier and version parts through properties on the\n ``Specifier`` classes.\n\n* Allow iterating over the ``SpecifierSet`` to get access to all of the\n ``Specifier`` instances.\n\n* Allow testing if a version is contained within a specifier via the ``in``\n operator.\n\n\n15.1 - 2015-04-13\n~~~~~~~~~~~~~~~~~\n\n* Fix a logic error that was causing inconsistent answers about whether or not\n a pre-release was contained within a ``SpecifierSet`` or not.\n\n\n15.0 - 2015-01-02\n~~~~~~~~~~~~~~~~~\n\n* Add ``Version().is_postrelease`` and ``LegacyVersion().is_postrelease`` to\n make it easy to determine if a release is a post release.\n\n* Add ``Version().base_version`` and ``LegacyVersion().base_version`` to make\n it easy to get the public version without any pre or post release markers.\n\n* Support the update to PEP 440 which removed the implied ``!=V.*`` when using\n either ``>V`` or ``V`` or ````) operator.\n\n\n14.3 - 2014-11-19\n~~~~~~~~~~~~~~~~~\n\n* **BACKWARDS INCOMPATIBLE** Refactor specifier support so that it can sanely\n handle legacy specifiers as well as PEP 440 specifiers.\n\n* **BACKWARDS INCOMPATIBLE** Move the specifier support out of\n ``packaging.version`` into ``packaging.specifiers``.\n\n\n14.2 - 2014-09-10\n~~~~~~~~~~~~~~~~~\n\n* Add prerelease support to ``Specifier``.\n* Remove the ability to do ``item in Specifier()`` and replace it with\n ``Specifier().contains(item)`` in order to allow flags that signal if a\n prerelease should be accepted or not.\n* Add a method ``Specifier().filter()`` which will take an iterable and returns\n an iterable with items that do not match the specifier filtered out.\n\n\n14.1 - 2014-09-08\n~~~~~~~~~~~~~~~~~\n\n* Allow ``LegacyVersion`` and ``Version`` to be sorted together.\n* Add ``packaging.version.parse()`` to enable easily parsing a version string\n as either a ``Version`` or a ``LegacyVersion`` depending on it's PEP 440\n validity.\n\n\n14.0 - 2014-09-05\n~~~~~~~~~~~~~~~~~\n\n* Initial release.\n\n\n.. _`master`: https://github.com/pypa/packaging/\n\n\n" + }, + "metadata_location": "/home/ayansinha/nexB/write_access/univers/venv/lib/python3.10/site-packages/packaging-21.0.dist-info", + "installer": "pip", + "requested": false + }, + { + "metadata": { + "metadata_version": "2.1", + "name": "pip", + "version": "24.1", + "summary": "The PyPA recommended tool for installing Python packages.", + "description_content_type": "text/x-rst", + "author_email": "The pip developers ", + "license": "MIT", + "classifier": [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Topic :: Software Development :: Build Tools", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "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" + ], + "requires_python": ">=3.8", + "project_url": [ + "Homepage, https://pip.pypa.io/", + "Documentation, https://pip.pypa.io", + "Source, https://github.com/pypa/pip", + "Changelog, https://pip.pypa.io/en/stable/news/" + ], + "description": "pip - 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\n" + }, + "metadata_location": "/home/ayansinha/nexB/write_access/univers/venv/lib/python3.10/site-packages/pip-24.1.dist-info", + "installer": "pip", + "requested": true + }, + { + "metadata": { + "metadata_version": "2.1", + "name": "pyparsing", + "version": "2.4.7", + "platform": [ + "UNKNOWN" + ], + "summary": "Python parsing module", + "home_page": "https://github.com/pyparsing/pyparsing/", + "download_url": "https://pypi.org/project/pyparsing/", + "author": "Paul McGuire", + "author_email": "ptmcg@users.sourceforge.net", + "license": "MIT License", + "classifier": [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Intended Audience :: Information Technology", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.6", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8" + ], + "requires_python": ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*", + "description": "PyParsing -- A Python Parsing Module\n====================================\n\n|Build Status|\n\nIntroduction\n============\n\nThe pyparsing module is an alternative approach to creating and\nexecuting simple grammars, vs. the traditional lex/yacc approach, or the\nuse of regular expressions. The pyparsing module provides a library of\nclasses that client code uses to construct the grammar directly in\nPython code.\n\n*[Since first writing this description of pyparsing in late 2003, this\ntechnique for developing parsers has become more widespread, under the\nname Parsing Expression Grammars - PEGs. See more information on PEGs at*\nhttps://en.wikipedia.org/wiki/Parsing_expression_grammar *.]*\n\nHere is a program to parse ``\"Hello, World!\"`` (or any greeting of the form\n``\"salutation, addressee!\"``):\n\n.. code:: python\n\n from pyparsing import Word, alphas\n greet = Word(alphas) + \",\" + Word(alphas) + \"!\"\n hello = \"Hello, World!\"\n print(hello, \"->\", greet.parseString(hello))\n\nThe program outputs the following::\n\n Hello, World! -> ['Hello', ',', 'World', '!']\n\nThe Python representation of the grammar is quite readable, owing to the\nself-explanatory class names, and the use of '+', '|' and '^' operator\ndefinitions.\n\nThe parsed results returned from ``parseString()`` can be accessed as a\nnested list, a dictionary, or an object with named attributes.\n\nThe pyparsing module handles some of the problems that are typically\nvexing when writing text parsers:\n\n- extra or missing whitespace (the above program will also handle ``\"Hello,World!\"``, ``\"Hello , World !\"``, etc.)\n- quoted strings\n- embedded comments\n\nThe examples directory includes a simple SQL parser, simple CORBA IDL\nparser, a config file parser, a chemical formula parser, and a four-\nfunction algebraic notation parser, among many others.\n\nDocumentation\n=============\n\nThere are many examples in the online docstrings of the classes\nand methods in pyparsing. You can find them compiled into online docs\nat https://pyparsing-docs.readthedocs.io/en/latest/. Additional\ndocumentation resources and project info are listed in the online\nGitHub wiki, at https://github.com/pyparsing/pyparsing/wiki. An\nentire directory of examples is at\nhttps://github.com/pyparsing/pyparsing/tree/master/examples.\n\nLicense\n=======\n\nMIT License. See header of pyparsing.py\n\nHistory\n=======\n\nSee CHANGES file.\n\n.. |Build Status| image:: https://travis-ci.org/pyparsing/pyparsing.svg?branch=master\n :target: https://travis-ci.org/pyparsing/pyparsing\n\n\n" + }, + "metadata_location": "/home/ayansinha/nexB/write_access/univers/venv/lib/python3.10/site-packages/pyparsing-2.4.7.dist-info", + "installer": "pip", + "requested": false + }, + { + "metadata": { + "metadata_version": "2.1", + "name": "semantic-version", + "version": "2.8.5", + "platform": [ + "UNKNOWN" + ], + "summary": "A library implementing the 'SemVer' scheme.", + "keywords": [ + "semantic version", + "versioning", + "version" + ], + "home_page": "https://github.com/rbarrois/python-semanticversion", + "download_url": "http://pypi.python.org/pypi/semantic_version/", + "author": "Raphaël Barrois", + "author_email": "raphael.barrois+semver@polytechnique.org", + "license": "BSD", + "classifier": [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: BSD License", + "Topic :: Software Development :: Libraries :: Python Modules", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Topic :: Software Development :: Libraries :: Python Modules" + ], + "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*", + "description": "python-semanticversion\n======================\n\nThis small python library provides a few tools to handle `SemVer`_ in Python.\nIt follows strictly the 2.0.0 version of the SemVer scheme.\n\n.. image:: https://secure.travis-ci.org/rbarrois/python-semanticversion.png?branch=master\n :target: http://travis-ci.org/rbarrois/python-semanticversion/\n\n.. image:: https://img.shields.io/pypi/v/semantic_version.svg\n :target: https://python-semanticversion.readthedocs.io/en/latest/changelog.html\n :alt: Latest Version\n\n.. image:: https://img.shields.io/pypi/pyversions/semantic_version.svg\n :target: https://pypi.python.org/pypi/semantic_version/\n :alt: Supported Python versions\n\n.. image:: https://img.shields.io/pypi/wheel/semantic_version.svg\n :target: https://pypi.python.org/pypi/semantic_version/\n :alt: Wheel status\n\n.. image:: https://img.shields.io/pypi/l/semantic_version.svg\n :target: https://pypi.python.org/pypi/semantic_version/\n :alt: License\n\nLinks\n-----\n\n- Package on `PyPI`_: http://pypi.python.org/pypi/semantic_version/\n- Doc on `ReadTheDocs `_: https://python-semanticversion.readthedocs.io/\n- Source on `GitHub `_: http://github.com/rbarrois/python-semanticversion/\n- Build on `Travis CI `_: http://travis-ci.org/rbarrois/python-semanticversion/\n- Semantic Version specification: `SemVer`_\n\n\nGetting started\n===============\n\nInstall the package from `PyPI`_, using pip:\n\n.. code-block:: sh\n\n pip install semantic_version\n\nOr from GitHub:\n\n.. code-block:: sh\n\n $ git clone git://github.com/rbarrois/python-semanticversion.git\n\n\nImport it in your code:\n\n\n.. code-block:: python\n\n import semantic_version\n\n\n\nThis module provides classes to handle semantic versions:\n\n- ``Version`` represents a version number (``0.1.1-alpha+build.2012-05-15``)\n- ``BaseSpec``-derived classes represent requirement specifications (``>=0.1.1,<0.3.0``):\n\n - ``SimpleSpec`` describes a natural description syntax\n - ``NpmSpec`` is used for NPM-style range descriptions.\n\nVersions\n--------\n\nDefining a ``Version`` is quite simple:\n\n\n.. code-block:: pycon\n\n >>> import semantic_version\n >>> v = semantic_version.Version('0.1.1')\n >>> v.major\n 0\n >>> v.minor\n 1\n >>> v.patch\n 1\n >>> v.prerelease\n []\n >>> v.build\n []\n >>> list(v)\n [0, 1, 1, [], []]\n\nIf the provided version string is invalid, a ``ValueError`` will be raised:\n\n.. code-block:: pycon\n\n >>> semantic_version.Version('0.1')\n Traceback (most recent call last):\n File \"\", line 1, in \n File \"/Users/rbarrois/dev/semantic_version/src/semantic_version/base.py\", line 64, in __init__\n major, minor, patch, prerelease, build = self.parse(version_string, partial)\n File \"/Users/rbarrois/dev/semantic_version/src/semantic_version/base.py\", line 86, in parse\n raise ValueError('Invalid version string: %r' % version_string)\n ValueError: Invalid version string: '0.1'\n\n\nObviously, ``Versions`` can be compared:\n\n\n.. code-block:: pycon\n\n >>> semantic_version.Version('0.1.1') < semantic_version.Version('0.1.2')\n True\n >>> semantic_version.Version('0.1.1') > semantic_version.Version('0.1.1-alpha')\n True\n >>> semantic_version.Version('0.1.1') <= semantic_version.Version('0.1.1-alpha')\n False\n\nYou can also get a new version that represents a bump in one of the version levels:\n\n.. code-block:: pycon\n\n >>> v = semantic_version.Version('0.1.1+build')\n >>> new_v = v.next_major()\n >>> str(new_v)\n '1.0.0'\n >>> v = semantic_version.Version('1.1.1+build')\n >>> new_v = v.next_minor()\n >>> str(new_v)\n '1.2.0'\n >>> v = semantic_version.Version('1.1.1+build')\n >>> new_v = v.next_patch()\n >>> str(new_v)\n '1.1.2'\n\nIt is also possible to check whether a given string is a proper semantic version string:\n\n\n.. code-block:: pycon\n\n >>> semantic_version.validate('0.1.3')\n True\n >>> semantic_version.validate('0a2')\n False\n\n\nFinally, one may create a ``Version`` with named components instead:\n\n.. code-block:: pycon\n\n >>> semantic_version.Version(major=0, minor=1, patch=2)\n Version('0.1.2')\n\nIn that case, ``major``, ``minor`` and ``patch`` are mandatory, and must be integers.\n``prerelease`` and ``patch``, if provided, must be tuples of strings:\n\n.. code-block:: pycon\n\n >>> semantic_version.Version(major=0, minor=1, patch=2, prerelease=('alpha', '2'))\n Version('0.1.2-alpha.2')\n\n\nRequirement specification\n-------------------------\n\nThe ``SimpleSpec`` object describes a range of accepted versions:\n\n\n.. code-block:: pycon\n\n >>> s = SimpleSpec('>=0.1.1') # At least 0.1.1\n >>> s.match(Version('0.1.1'))\n True\n >>> s.match(Version('0.1.1-alpha1')) # pre-release doesn't satisfy version spec\n False\n >>> s.match(Version('0.1.0'))\n False\n\nSimpler test syntax is also available using the ``in`` keyword:\n\n.. code-block:: pycon\n\n >>> s = SimpleSpec('==0.1.1')\n >>> Version('0.1.1-alpha1') in s\n True\n >>> Version('0.1.2') in s\n False\n\n\nCombining specifications can be expressed as follows:\n\n .. code-block:: pycon\n\n >>> SimpleSpec('>=0.1.1,<0.3.0')\n\n\nUsing a specification\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\nThe ``SimpleSpec.filter`` method filters an iterable of ``Version``:\n\n.. code-block:: pycon\n\n >>> s = SimpleSpec('>=0.1.0,<0.4.0')\n >>> versions = (Version('0.%d.0' % i) for i in range(6))\n >>> for v in s.filter(versions):\n ... print v\n 0.1.0\n 0.2.0\n 0.3.0\n\nIt is also possible to select the 'best' version from such iterables:\n\n\n.. code-block:: pycon\n\n >>> s = SimpleSpec('>=0.1.0,<0.4.0')\n >>> versions = (Version('0.%d.0' % i) for i in range(6))\n >>> s.select(versions)\n Version('0.3.0')\n\n\nCoercing an arbitrary version string\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\nSome user-supplied input might not match the semantic version scheme.\nFor such cases, the ``Version.coerce`` method will try to convert any\nversion-like string into a valid semver version:\n\n.. code-block:: pycon\n\n >>> Version.coerce('0')\n Version('0.0.0')\n >>> Version.coerce('0.1.2.3.4')\n Version('0.1.2+3.4')\n >>> Version.coerce('0.1.2a3')\n Version('0.1.2-a3')\n\n\nIncluding pre-release identifiers in specifications\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\nWhen testing a ``Version`` against a ``SimpleSpec``, comparisons are\nadjusted for common user expectations; thus, a pre-release version (``1.0.0-alpha``)\nwill not satisfy the ``==1.0.0`` ``SimpleSpec``.\n\nPre-release identifiers will only be compared if included in the ``BaseSpec``\ndefinition or (for the empty pre-release number) if a single dash is appended\n(``1.0.0-``):\n\n\n.. code-block:: pycon\n\n >>> Version('0.1.0-alpha') in SimpleSpec('<0.1.0') # No pre-release identifier\n False\n >>> Version('0.1.0-alpha') in SimpleSpec('<0.1.0-') # Include pre-release in checks\n True\n\n\nIncluding build metadata in specifications\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\nBuild metadata has no ordering; thus, the only meaningful comparison including\nbuild metadata is equality.\n\n\n.. code-block:: pycon\n\n >>> Version('1.0.0+build2') in SimpleSpec('<=1.0.0') # Build metadata ignored\n True\n >>> Version('1.0.0+build1') in SimpleSpec('==1.0.0+build2') # Include build in checks\n False\n\n\nNPM-based ranges\n----------------\n\nThe ``NpmSpec`` class handles NPM-style ranges:\n\n.. code-block:: pycon\n\n >>> Version('1.2.3') in NpmSpec('1.2.2 - 1.4')\n True\n >>> Version('1.2.3') in NpmSpec('<1.x || >=1.2.3')\n True\n\nRefer to https://docs.npmjs.com/misc/semver.html for a detailed description of NPM\nrange syntax.\n\n\nUsing with Django\n=================\n\nThe ``semantic_version.django_fields`` module provides django fields to\nstore ``Version`` or ``BaseSpec`` objects.\n\nMore documentation is available in the ``django`` section.\n\n\nContributing\n============\n\nIn order to contribute to the source code:\n\n- Open an issue on `GitHub`_: https://github.com/rbarrois/python-semanticversion/issues\n- Fork the `repository `_\n and submit a pull request on `GitHub`_\n- Or send me a patch (mailto:raphael.barrois+semver@polytechnique.org)\n\nWhen submitting patches or pull requests, you should respect the following rules:\n\n- Coding conventions are based on ``8``\n- The whole test suite must pass after adding the changes\n- The test coverage for a new feature must be 100%\n- New features and methods should be documented in the ``reference`` section\n and included in the ``changelog``\n- Include your name in the ``contributors`` section\n\n.. note:: All files should contain the following header::\n\n # -*- encoding: utf-8 -*-\n # Copyright (c) The python-semanticversion project\n\n\nContents\n========\n\n :maxdepth: 2\n\n reference\n django\n changelog\n credits\n\n\n.. _SemVer: http://semver.org/\n.. _PyPI: http://pypi.python.org/\n\nIndices and tables\n==================\n\n* ``genindex``\n* ``modindex``\n* ``search``\n\n\n\n" + }, + "metadata_location": "/home/ayansinha/nexB/write_access/univers/venv/lib/python3.10/site-packages/semantic_version-2.8.5.dist-info", + "installer": "pip", + "requested": false + }, + { + "metadata": { + "metadata_version": "2.1", + "name": "semver", + "version": "2.13.0", + "platform": [ + "UNKNOWN" + ], + "summary": "Python helper for Semantic Versioning (http://semver.org/)", + "description_content_type": "text/x-rst", + "home_page": "https://github.com/python-semver/python-semver", + "download_url": "https://github.com/python-semver/python-semver/downloads", + "author": "Kostiantyn Rybnikov", + "author_email": "k-bx@k-bx.com", + "license": "BSD", + "classifier": [ + "Environment :: Web Environment", + "Intended Audience :: Developers", + "License :: OSI Approved :: BSD License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Topic :: Software Development :: Libraries :: Python Modules" + ], + "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*", + "project_url": [ + "Documentation, https://python-semver.rtfd.io", + "Releases, https://github.com/python-semver/python-semver/releases", + "Bug Tracker, https://github.com/python-semver/python-semver/issues" + ], + "description": "Quickstart\n==========\n\n.. teaser-begin\n\nA Python module for `semantic versioning`_. Simplifies comparing versions.\n\n|build-status| |python-support| |downloads| |license| |docs| |black|\n\n.. teaser-end\n\n.. warning::\n\n As anything comes to an end, this project will focus on Python 3.x only.\n New features and bugfixes will be integrated into the 3.x.y branch only.\n\n Major version 3 of semver will contain some incompatible changes:\n\n * removes support for Python 2.7 and 3.3\n * removes deprecated functions.\n\n The last version of semver which supports Python 2.7 and 3.4 will be\n 2.10.x. However, keep in mind, version 2.10.x is frozen: no new\n features nor backports will be integrated.\n\n We recommend to upgrade your workflow to Python 3.x to gain support,\n bugfixes, and new features.\n\nThe module follows the ``MAJOR.MINOR.PATCH`` style:\n\n* ``MAJOR`` version when you make incompatible API changes,\n* ``MINOR`` version when you add functionality in a backwards compatible manner, and\n* ``PATCH`` version when you make backwards compatible bug fixes.\n\nAdditional labels for pre-release and build metadata are supported.\n\nTo import this library, use:\n\n.. code-block:: python\n\n >>> import semver\n\nWorking with the library is quite straightforward. To turn a version string into the\ndifferent parts, use the ``semver.VersionInfo.parse`` function:\n\n.. code-block:: python\n\n >>> ver = semver.VersionInfo.parse('1.2.3-pre.2+build.4')\n >>> ver.major\n 1\n >>> ver.minor\n 2\n >>> ver.patch\n 3\n >>> ver.prerelease\n 'pre.2'\n >>> ver.build\n 'build.4'\n\nTo raise parts of a version, there are a couple of functions available for\nyou. The function ``semver.VersionInfo.bump_major`` leaves the original object untouched, but\nreturns a new ``semver.VersionInfo`` instance with the raised major part:\n\n.. code-block:: python\n\n >>> ver = semver.VersionInfo.parse(\"3.4.5\")\n >>> ver.bump_major()\n VersionInfo(major=4, minor=0, patch=0, prerelease=None, build=None)\n\nIt is allowed to concatenate different \"bump functions\":\n\n.. code-block:: python\n\n >>> ver.bump_major().bump_minor()\n VersionInfo(major=4, minor=1, patch=0, prerelease=None, build=None)\n\nTo compare two versions, semver provides the ``semver.compare`` function.\nThe return value indicates the relationship between the first and second\nversion:\n\n.. code-block:: python\n\n >>> semver.compare(\"1.0.0\", \"2.0.0\")\n -1\n >>> semver.compare(\"2.0.0\", \"1.0.0\")\n 1\n >>> semver.compare(\"2.0.0\", \"2.0.0\")\n 0\n\n\nThere are other functions to discover. Read on!\n\n\n.. |latest-version| image:: https://img.shields.io/pypi/v/semver.svg\n :alt: Latest version on PyPI\n :target: https://pypi.org/project/semver\n.. |build-status| image:: https://travis-ci.com/python-semver/python-semver.svg?branch=master\n :alt: Build status\n :target: https://travis-ci.com/python-semver/python-semver\n.. |python-support| image:: https://img.shields.io/pypi/pyversions/semver.svg\n :target: https://pypi.org/project/semver\n :alt: Python versions\n.. |downloads| image:: https://img.shields.io/pypi/dm/semver.svg\n :alt: Monthly downloads from PyPI\n :target: https://pypi.org/project/semver\n.. |license| image:: https://img.shields.io/pypi/l/semver.svg\n :alt: Software license\n :target: https://github.com/python-semver/python-semver/blob/master/LICENSE.txt\n.. |docs| image:: https://readthedocs.org/projects/python-semver/badge/?version=latest\n :target: http://python-semver.readthedocs.io/en/latest/?badge=latest\n :alt: Documentation Status\n.. _semantic versioning: http://semver.org/\n.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n :alt: Black Formatter\n\n\n" + }, + "metadata_location": "/home/ayansinha/nexB/write_access/univers/venv/lib/python3.10/site-packages/semver-2.13.0.dist-info", + "installer": "pip", + "requested": false + }, + { + "metadata": { + "metadata_version": "2.1", + "name": "setuptools", + "version": "70.1.0", + "summary": "Easily download, build, install, upgrade, and uninstall Python packages", + "description_content_type": "text/x-rst", + "keywords": [ + "CPAN", + "PyPI", + "distutils", + "eggs", + "package", + "management" + ], + "author_email": "Python Packaging Authority ", + "classifier": [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: System :: Archiving :: Packaging", + "Topic :: System :: Systems Administration", + "Topic :: Utilities" + ], + "requires_dist": [ + "sphinx >=3.5 ; extra == 'docs'", + "jaraco.packaging >=9.3 ; extra == 'docs'", + "rst.linker >=1.9 ; extra == 'docs'", + "furo ; extra == 'docs'", + "sphinx-lint ; extra == 'docs'", + "jaraco.tidelift >=1.4 ; extra == 'docs'", + "pygments-github-lexers ==0.0.5 ; extra == 'docs'", + "sphinx-favicon ; extra == 'docs'", + "sphinx-inline-tabs ; extra == 'docs'", + "sphinx-reredirects ; extra == 'docs'", + "sphinxcontrib-towncrier ; extra == 'docs'", + "sphinx-notfound-page <2,>=1 ; extra == 'docs'", + "pyproject-hooks !=1.1 ; extra == 'docs'", + "pytest !=8.1.1,>=6 ; extra == 'testing'", + "pytest-checkdocs >=2.4 ; extra == 'testing'", + "pytest-mypy ; extra == 'testing'", + "pytest-enabler >=2.2 ; extra == 'testing'", + "virtualenv >=13.0.0 ; extra == 'testing'", + "wheel ; extra == 'testing'", + "pip >=19.1 ; extra == 'testing'", + "packaging >=23.2 ; extra == 'testing'", + "jaraco.envs >=2.2 ; extra == 'testing'", + "pytest-xdist >=3 ; extra == 'testing'", + "jaraco.path >=3.2.0 ; extra == 'testing'", + "build[virtualenv] >=1.0.3 ; extra == 'testing'", + "filelock >=3.4.0 ; extra == 'testing'", + "ini2toml[lite] >=0.14 ; extra == 'testing'", + "tomli-w >=1.0.0 ; extra == 'testing'", + "pytest-timeout ; extra == 'testing'", + "pytest-home >=0.5 ; extra == 'testing'", + "mypy ==1.10.0 ; extra == 'testing'", + "tomli ; extra == 'testing'", + "importlib-metadata ; extra == 'testing'", + "pytest-subprocess ; extra == 'testing'", + "pyproject-hooks !=1.1 ; extra == 'testing'", + "jaraco.test ; extra == 'testing'", + "pytest-cov ; (platform_python_implementation != \"PyPy\") and extra == 'testing'", + "jaraco.develop >=7.21 ; (python_version >= \"3.9\" and sys_platform != \"cygwin\") and extra == 'testing'", + "pytest-ruff >=0.3.2 ; (sys_platform != \"cygwin\") and extra == 'testing'", + "pytest-perf ; (sys_platform != \"cygwin\") and extra == 'testing'" + ], + "requires_python": ">=3.8", + "project_url": [ + "Homepage, https://github.com/pypa/setuptools", + "Documentation, https://setuptools.pypa.io/", + "Changelog, https://setuptools.pypa.io/en/stable/history.html" + ], + "provides_extra": [ + "certs", + "docs", + "ssl", + "testing" + ], + "description": ".. |pypi-version| image:: https://img.shields.io/pypi/v/setuptools.svg\n :target: https://pypi.org/project/setuptools\n\n.. |py-version| image:: https://img.shields.io/pypi/pyversions/setuptools.svg\n\n.. |test-badge| image:: https://github.com/pypa/setuptools/actions/workflows/main.yml/badge.svg\n :target: https://github.com/pypa/setuptools/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. |ruff-badge| image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json\n :target: https://github.com/astral-sh/ruff\n :alt: Ruff\n\n.. |docs-badge| image:: https://img.shields.io/readthedocs/setuptools/latest.svg\n :target: https://setuptools.pypa.io\n\n.. |skeleton-badge| image:: https://img.shields.io/badge/skeleton-2024-informational\n :target: https://blog.jaraco.com/skeleton\n\n.. |codecov-badge| image:: https://img.shields.io/codecov/c/github/pypa/setuptools/master.svg?logo=codecov&logoColor=white\n :target: https://codecov.io/gh/pypa/setuptools\n\n.. |tidelift-badge| image:: https://tidelift.com/badges/github/pypa/setuptools?style=flat\n :target: https://tidelift.com/subscription/pkg/pypi-setuptools?utm_source=pypi-setuptools&utm_medium=readme\n\n.. |discord-badge| image:: https://img.shields.io/discord/803025117553754132\n :target: https://discord.com/channels/803025117553754132/815945031150993468\n :alt: Discord\n\n|pypi-version| |py-version| |test-badge| |ruff-badge| |docs-badge| |skeleton-badge| |codecov-badge| |discord-badge|\n\nSee the `Quickstart `_\nand the `User's Guide `_ for\ninstructions on how to use Setuptools.\n\nQuestions and comments should be directed to `GitHub Discussions\n`_.\nBug reports and especially tested patches may be\nsubmitted directly to the `bug tracker\n`_.\n\n\nCode of Conduct\n===============\n\nEveryone interacting in the setuptools project's codebases, issue trackers,\nchat rooms, and fora is expected to follow the\n`PSF Code of Conduct `_.\n\n\nFor Enterprise\n==============\n\nAvailable as part of the Tidelift Subscription.\n\nSetuptools and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.\n\n`Learn more `_.\n" + }, + "metadata_location": "/home/ayansinha/nexB/write_access/univers/venv/lib/python3.10/site-packages/setuptools-70.1.0.dist-info", + "installer": "pip", + "requested": true + }, + { + "metadata": { + "metadata_version": "2.1", + "name": "univers", + "version": "0.0.0", + "summary": "A mostly universal library to parse and compare software package versions and version ranges. A companion to Package URLs.", + "description_content_type": "text/x-rst", + "keywords": [ + "semver", + "utilities", + "version", + "release", + "version range", + "package URL", + "purl", + "arch", + "pacman", + "pypi", + "rpm", + "gentoo", + "ebuild", + "maven", + "debian", + "rubygems" + ], + "home_page": "https://github.com/nexB/univers", + "author": "Shivam Sandbhor, nexB. Inc. and others", + "author_email": "info@aboutcode.org", + "license": "Apache-2.0 AND BSD-3-Clause AND MIT", + "classifier": [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Topic :: Software Development", + "Topic :: Utilities" + ], + "requires_dist": [ + "attrs", + "packaging", + "semantic-version", + "semver", + "Sphinx >=5.0.2 ; extra == 'docs'", + "sphinx-rtd-theme >=1.0.0 ; extra == 'docs'", + "sphinx-reredirects >=0.1.2 ; extra == 'docs'", + "doc8 >=0.11.2 ; extra == 'docs'", + "pytest !=7.0.0,>=6 ; extra == 'testing'", + "pytest-xdist >=2 ; extra == 'testing'", + "aboutcode-toolkit >=7.0.2 ; extra == 'testing'", + "pycodestyle >=2.8.0 ; extra == 'testing'", + "twine ; extra == 'testing'", + "black ; extra == 'testing'", + "commoncode ; extra == 'testing'", + "isort >=5.10.1 ; extra == 'testing'" + ], + "requires_python": ">=3.7", + "provides_extra": [ + "docs", + "testing" + ], + "description": "univers: mostly universal version and version ranges comparison and conversion\n===============================================================================\n\n|Build Status| |License| |Python 3.6+|\n\n.. |Build Status| image:: https://api.travis-ci.com/sbs2001/univers.svg?branch=main&status=passed\n.. |License| image:: https://img.shields.io/badge/License-Apache%202.0-blue.svg\n :target: https://scancode-licensedb.aboutcode.org/apache-2.0.html\n.. |Python 3.6+| image:: https://img.shields.io/badge/python-3.6+-blue.svg\n :target: https://www.python.org/downloads/release/python-380/\n\n\n**univers** was born out of the need for a mostly universal way to store version\nranges and to compare two software package versions in VulnerableCode.\n\nPackage version ranges and version constraints are useful and essential:\n\n- When relating a known vulnerability or bug to a range of affected package\n versions. For instance a statement such as \"vulnerability 123 affects \n package bar, version 3.1 and version 4.2 but not version 5\" defines a\n range of bar versions affected by a vulnerability.\n\n- When resolving the dependencies of a package to express which subset of the\n versions are supported. For instance a dependency requirement statement such\n as \"I require package foo, version 2.0 and later versions\" defines a range of\n acceptable foo versions.\n\nVersion syntaxes and range notations are quite different across ecosystems,\nmaking it is difficult to process versions and version ranges across ecosystems\nin a consistent way.\n\nExisting tools and libraries typically support a single algorithms to parse and\ncompare versions with a single version range notation for a single package\necosystem.\n\n\n**univers** is different:\n\n- It tracks each ecosystem versioning scheme and how two versions are compared.\n\n- It support a growing number of package ecosystems versioning in a single\n library.\n\n- It can parse version range strings using their native notation (such as an npm\n range) into the common \"vers\" notation and internal object model and can\n return back a native version range string rebuilt from a \"vers\" range.\n\n- It is designed to work with `Package URLs (purl) `_.\n\n\nHow does **univers** work ?\n============================\n\n**univers** wraps, embeds and implements multiple version comparison libraries,\neach focused on a specific ecosystem versioning scheme.\n\nFor each scheme, **univers** provides an implementation for:\n\n- the version comparison procedure e.g, how to compare two versions,\n- parsing and converting from a native version range notation to the\n **univers** normalized and unified internal model,\n- converting a range back to its scheme-native range syntax and to the\n ``vers`` syntax.\n\n**univers** implements ``vers``, an experimental unified and mostly universal\nversion range syntax. It can parse and convert an existing native version range\nstrings to this unified syntax. For example, this means:\n\n- converting \">=1.2.3\" as used in a Python package into ``vers:pypi/>=1.2.3``,\n\n- or converting \"^1.0.2\" as used in an npm package dependency declaration into\n ``vers:npm/>=1.0.2|<2.0.0``\n\nThe supported package ecosystems versioning schemes and underlying libraries\ninclude:\n\n- npm that use the \"node-semver\" ranges notation and the semver versions syntax\n This is supported in part by the `semantic_version\n `_ library.\n\n- pypi: handled by Python's packaging library and the standard \n ``packaging.version`` module.\n\n- Rubygems which use a semver-like but not-quite-semver scheme and there can be\n commonly more than three version segments.\n Gems also use a slightly different range notation from node-semver with\n different operators and slightly different semantics: for instance it uses \"~>\"\n as a pessimistic operator and supports exclusion with != and does not support\n \"OR\" between constraints (that it call requirements).\n Gem are handled by Python port of the Rubygems requirements and version\n handling code from the `puppeteer tool\n `_\n\n- debian: handled by the `debian-inspector library\n `_.\n\n- maven: handled by the embedded `pymaven library\n `_.\n\n- rpm: handled by the embedded `rpm_vercmp library\n `_.\n\n- golang (using semver)\n\n- PHP composer\n\n- ebuild/gentoo: handled by the embedded `gentoo_vercmp module\n `_.\n\n- arch linux: handled by the embedded `arch utility module borrowed from msys2\n `_.\n\n- Alpine linux: handled using the base Gentoo version support and extras\n specific to Alpine.\n\n\nThe level of support for each ecosystem may not be even for now and new schemes\nand support for more package types are implemented on a continuous basis.\n\n\nAlternative\n============\n\nRather than using ecosystem-specific version schemes and code, another approach\nis to use a single procedure for all the versions as implemented in `libversion\n`_. ``libversion`` works in the most\ncommon case but may not work correctly when a task that demand precise version\ncomparisons such as for dependency resolution and vulnerability lookup where\na \"good enough\" comparison accuracy is not acceptable. ``libversion`` does not\nhandle version range notations.\n\n\nInstallation\n============\n\n $ pip install univers\n\n\nExamples\n========\n\nCompare two native Python versions:\n\n.. code:: python\n\n from univers.versions import PypiVersion\n assert PypiVersion(\"1.2.3\") < PypiVersion(\"1.2.4\")\n\n\nNormalize a version range from an npm:\n\n.. code:: python\n\n from univers.version_range import NpmVersionRange\n range = NpmVersionRange.from_native(\"^1.0.2\")\n assert str(range) == \"vers:npm/>=1.0.2|<2.0.0\"\n\n\nTest if a version is within or outside a version range:\n\n.. code:: python\n\n from univers.versions import PypiVersion\n from univers.version_range import VersionRange\n\n range = VersionRange.from_string(\"vers:pypi/>=1.2.4\")\n\n assert PypiVersion(\"1.2.4\") in range\n assert PypiVersion(\"1.2.3\") not in range\n\n\nDevelopment\n============\n\nRun these commands, starting from a git clone of https://github.com/nexB/univers ::\n\n $ ./configure --dev\n $ source venv/bin/active\n $ pytest -vvs\n\n\nWe use the same development process as other AboutCode projects.\n\nVisit https://github.com/nexB/univers and\nhttps://gitter.im/aboutcode-org/vulnerablecode and\nhttps://gitter.im/aboutcode-org/aboutcode for support and chat.\n\n\nPrimary license: Apache-2.0\nSPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause AND MIT\n" + }, + "metadata_location": "/home/ayansinha/nexB/write_access/univers/venv/lib/python3.10/site-packages/univers-0.0.0.dist-info", + "direct_url": { + "url": "file:///home/ayansinha/nexB/write_access/univers", + "dir_info": { + "editable": true + } + }, + "installer": "pip", + "requested": true + }, + { + "metadata": { + "metadata_version": "2.1", + "name": "wheel", + "version": "0.43.0", + "summary": "A built-package format for Python", + "description_content_type": "text/x-rst", + "keywords": [ + "wheel", + "packaging" + ], + "author_email": "Daniel Holth ", + "maintainer_email": "Alex Grönholm ", + "classifier": [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Topic :: System :: Archiving :: Packaging", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python", + "Programming Language :: Python :: 3 :: Only", + "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" + ], + "requires_dist": [ + "pytest >= 6.0.0 ; extra == \"test\"", + "setuptools >= 65 ; extra == \"test\"" + ], + "requires_python": ">=3.8", + "project_url": [ + "Changelog, https://wheel.readthedocs.io/en/stable/news.html", + "Documentation, https://wheel.readthedocs.io/", + "Issue Tracker, https://github.com/pypa/wheel/issues", + "Source, https://github.com/pypa/wheel" + ], + "provides_extra": [ + "test" + ], + "description": "wheel\n=====\n\nThis library is the reference implementation of the Python wheel packaging\nstandard, as defined in `PEP 427`_.\n\nIt has two different roles:\n\n#. A setuptools_ extension for building wheels that provides the\n ``bdist_wheel`` setuptools command\n#. A command line tool for working with wheel files\n\nIt should be noted that wheel is **not** intended to be used as a library, and\nas such there is no stable, public API.\n\n.. _PEP 427: https://www.python.org/dev/peps/pep-0427/\n.. _setuptools: https://pypi.org/project/setuptools/\n\nDocumentation\n-------------\n\nThe documentation_ can be found on Read The Docs.\n\n.. _documentation: https://wheel.readthedocs.io/\n\nCode of Conduct\n---------------\n\nEveryone interacting in the wheel project's codebases, issue trackers, chat\nrooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.\n\n.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md\n\n" + }, + "metadata_location": "/home/ayansinha/nexB/write_access/univers/venv/lib/python3.10/site-packages/wheel-0.43.0.dist-info", + "installer": "pip", + "requested": true + } + ], + "environment": { + "implementation_name": "cpython", + "implementation_version": "3.10.12", + "os_name": "posix", + "platform_machine": "x86_64", + "platform_release": "5.15.0-112-generic", + "platform_system": "Linux", + "platform_version": "#122-Ubuntu SMP Thu May 23 07:48:21 UTC 2024", + "python_full_version": "3.10.12", + "platform_python_implementation": "CPython", + "python_version": "3.10", + "sys_platform": "linux" + } +} diff --git a/tests/packagedcode/data/pypi/deplock/univers/pip-inspect.deplock-expected.json b/tests/packagedcode/data/pypi/deplock/univers/pip-inspect.deplock-expected.json new file mode 100644 index 00000000000..24e4a613f73 --- /dev/null +++ b/tests/packagedcode/data/pypi/deplock/univers/pip-inspect.deplock-expected.json @@ -0,0 +1,1628 @@ +[ + { + "type": "pypi", + "namespace": null, + "name": "univers", + "version": "0.0.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "univers: mostly universal version and version ranges comparison and conversion\n===============================================================================\n\n|Build Status| |License| |Python 3.6+|\n\n.. |Build Status| image:: https://api.travis-ci.com/sbs2001/univers.svg?branch=main&status=passed\n.. |License| image:: https://img.shields.io/badge/License-Apache%202.0-blue.svg\n :target: https://scancode-licensedb.aboutcode.org/apache-2.0.html\n.. |Python 3.6+| image:: https://img.shields.io/badge/python-3.6+-blue.svg\n :target: https://www.python.org/downloads/release/python-380/\n\n\n**univers** was born out of the need for a mostly universal way to store version\nranges and to compare two software package versions in VulnerableCode.\n\nPackage version ranges and version constraints are useful and essential:\n\n- When relating a known vulnerability or bug to a range of affected package\n versions. For instance a statement such as \"vulnerability 123 affects \n package bar, version 3.1 and version 4.2 but not version 5\" defines a\n range of bar versions affected by a vulnerability.\n\n- When resolving the dependencies of a package to express which subset of the\n versions are supported. For instance a dependency requirement statement such\n as \"I require package foo, version 2.0 and later versions\" defines a range of\n acceptable foo versions.\n\nVersion syntaxes and range notations are quite different across ecosystems,\nmaking it is difficult to process versions and version ranges across ecosystems\nin a consistent way.\n\nExisting tools and libraries typically support a single algorithms to parse and\ncompare versions with a single version range notation for a single package\necosystem.\n\n\n**univers** is different:\n\n- It tracks each ecosystem versioning scheme and how two versions are compared.\n\n- It support a growing number of package ecosystems versioning in a single\n library.\n\n- It can parse version range strings using their native notation (such as an npm\n range) into the common \"vers\" notation and internal object model and can\n return back a native version range string rebuilt from a \"vers\" range.\n\n- It is designed to work with `Package URLs (purl) `_.\n\n\nHow does **univers** work ?\n============================\n\n**univers** wraps, embeds and implements multiple version comparison libraries,\neach focused on a specific ecosystem versioning scheme.\n\nFor each scheme, **univers** provides an implementation for:\n\n- the version comparison procedure e.g, how to compare two versions,\n- parsing and converting from a native version range notation to the\n **univers** normalized and unified internal model,\n- converting a range back to its scheme-native range syntax and to the\n ``vers`` syntax.\n\n**univers** implements ``vers``, an experimental unified and mostly universal\nversion range syntax. It can parse and convert an existing native version range\nstrings to this unified syntax. For example, this means:\n\n- converting \">=1.2.3\" as used in a Python package into ``vers:pypi/>=1.2.3``,\n\n- or converting \"^1.0.2\" as used in an npm package dependency declaration into\n ``vers:npm/>=1.0.2|<2.0.0``\n\nThe supported package ecosystems versioning schemes and underlying libraries\ninclude:\n\n- npm that use the \"node-semver\" ranges notation and the semver versions syntax\n This is supported in part by the `semantic_version\n `_ library.\n\n- pypi: handled by Python's packaging library and the standard \n ``packaging.version`` module.\n\n- Rubygems which use a semver-like but not-quite-semver scheme and there can be\n commonly more than three version segments.\n Gems also use a slightly different range notation from node-semver with\n different operators and slightly different semantics: for instance it uses \"~>\"\n as a pessimistic operator and supports exclusion with != and does not support\n \"OR\" between constraints (that it call requirements).\n Gem are handled by Python port of the Rubygems requirements and version\n handling code from the `puppeteer tool\n `_\n\n- debian: handled by the `debian-inspector library\n `_.\n\n- maven: handled by the embedded `pymaven library\n `_.\n\n- rpm: handled by the embedded `rpm_vercmp library\n `_.\n\n- golang (using semver)\n\n- PHP composer\n\n- ebuild/gentoo: handled by the embedded `gentoo_vercmp module\n `_.\n\n- arch linux: handled by the embedded `arch utility module borrowed from msys2\n `_.\n\n- Alpine linux: handled using the base Gentoo version support and extras\n specific to Alpine.\n\n\nThe level of support for each ecosystem may not be even for now and new schemes\nand support for more package types are implemented on a continuous basis.\n\n\nAlternative\n============\n\nRather than using ecosystem-specific version schemes and code, another approach\nis to use a single procedure for all the versions as implemented in `libversion\n`_. ``libversion`` works in the most\ncommon case but may not work correctly when a task that demand precise version\ncomparisons such as for dependency resolution and vulnerability lookup where\na \"good enough\" comparison accuracy is not acceptable. ``libversion`` does not\nhandle version range notations.\n\n\nInstallation\n============\n\n $ pip install univers\n\n\nExamples\n========\n\nCompare two native Python versions:\n\n.. code:: python\n\n from univers.versions import PypiVersion\n assert PypiVersion(\"1.2.3\") < PypiVersion(\"1.2.4\")\n\n\nNormalize a version range from an npm:\n\n.. code:: python\n\n from univers.version_range import NpmVersionRange\n range = NpmVersionRange.from_native(\"^1.0.2\")\n assert str(range) == \"vers:npm/>=1.0.2|<2.0.0\"\n\n\nTest if a version is within or outside a version range:\n\n.. code:: python\n\n from univers.versions import PypiVersion\n from univers.version_range import VersionRange\n\n range = VersionRange.from_string(\"vers:pypi/>=1.2.4\")\n\n assert PypiVersion(\"1.2.4\") in range\n assert PypiVersion(\"1.2.3\") not in range\n\n\nDevelopment\n============\n\nRun these commands, starting from a git clone of https://github.com/nexB/univers ::\n\n $ ./configure --dev\n $ source venv/bin/active\n $ pytest -vvs\n\n\nWe use the same development process as other AboutCode projects.\n\nVisit https://github.com/nexB/univers and\nhttps://gitter.im/aboutcode-org/vulnerablecode and\nhttps://gitter.im/aboutcode-org/aboutcode for support and chat.\n\n\nPrimary license: Apache-2.0\nSPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause AND MIT\n", + "release_date": null, + "parties": [], + "keywords": [ + "semver", + "utilities", + "version", + "release", + "version range", + "package URL", + "purl", + "arch", + "pacman", + "pypi", + "rpm", + "gentoo", + "ebuild", + "maven", + "debian", + "rubygems" + ], + "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": "apache-2.0 AND bsd-new AND mit", + "declared_license_expression_spdx": "Apache-2.0 AND BSD-3-Clause AND MIT", + "license_detections": [ + { + "license_expression": "apache-2.0 AND bsd-new AND mit", + "license_expression_spdx": "Apache-2.0 AND BSD-3-Clause AND MIT", + "matches": [ + { + "license_expression": "apache-2.0 AND bsd-new AND mit", + "spdx_license_expression": "Apache-2.0 AND BSD-3-Clause AND MIT", + "from_file": null, + "start_line": 1, + "end_line": 1, + "matcher": "1-spdx-id", + "score": 100.0, + "matched_length": 9, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "spdx-license-identifier-apache_2_0_and_bsd_new_and_mit-5a0e0d1daea60cb9191d19fe5324c57e89cbcbf8", + "rule_url": null, + "matched_text": "Apache-2.0 AND BSD-3-Clause AND MIT" + } + ], + "identifier": "apache_2_0_and_bsd_new_and_mit-4d4f1034-453c-8cde-3ab0-bd35ddc243e6" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "Apache-2.0 AND BSD-3-Clause AND MIT", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": { + "pip_version": "24.1", + "inspect_version": "1" + }, + "dependencies": [ + { + "purl": "pkg:pypi/attrs@21.2.0", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": false, + "is_resolved": true, + "is_direct": true, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "attrs", + "version": "21.2.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "======================================\n``attrs``: Classes Without Boilerplate\n======================================\n\n\n``attrs`` is the Python package that will bring back the **joy** of **writing classes** by relieving you from the drudgery of implementing object protocols (aka `dunder `_ methods).\n`Trusted by NASA `_ for Mars missions since 2020!\n\nIts main goal is to help you to write **concise** and **correct** software without slowing down your code.\n\n.. teaser-end\n\nFor that, it gives you a class decorator and a way to declaratively define the attributes on that class:\n\n.. -code-begin-\n\n.. code-block:: pycon\n\n >>> import attr\n\n >>> @attr.s\n ... class SomeClass(object):\n ... a_number = attr.ib(default=42)\n ... list_of_numbers = attr.ib(factory=list)\n ...\n ... def hard_math(self, another_number):\n ... return self.a_number + sum(self.list_of_numbers) * another_number\n\n\n >>> sc = SomeClass(1, [1, 2, 3])\n >>> sc\n SomeClass(a_number=1, list_of_numbers=[1, 2, 3])\n\n >>> sc.hard_math(3)\n 19\n >>> sc == SomeClass(1, [1, 2, 3])\n True\n >>> sc != SomeClass(2, [3, 2, 1])\n True\n\n >>> attr.asdict(sc)\n {'a_number': 1, 'list_of_numbers': [1, 2, 3]}\n\n >>> SomeClass()\n SomeClass(a_number=42, list_of_numbers=[])\n\n >>> C = attr.make_class(\"C\", [\"a\", \"b\"])\n >>> C(\"foo\", \"bar\")\n C(a='foo', b='bar')\n\n\nAfter *declaring* your attributes ``attrs`` gives you:\n\n- a concise and explicit overview of the class's attributes,\n- a nice human-readable ``__repr__``,\n- a complete set of comparison methods (equality and ordering),\n- an initializer,\n- and much more,\n\n*without* writing dull boilerplate code again and again and *without* runtime performance penalties.\n\nOn Python 3.6 and later, you can often even drop the calls to ``attr.ib()`` by using `type annotations `_.\n\nThis gives you the power to use actual classes with actual types in your code instead of confusing ``tuple``\\ s or `confusingly behaving `_ ``namedtuple``\\ s.\nWhich in turn encourages you to write *small classes* that do `one thing well `_.\nNever again violate the `single responsibility principle `_ just because implementing ``__init__`` et al is a painful drag.\n\n\n.. -getting-help-\n\nGetting Help\n============\n\nPlease use the ``python-attrs`` tag on `StackOverflow `_ to get help.\n\nAnswering questions of your fellow developers is also a great way to help the project!\n\n\n.. -project-information-\n\nProject Information\n===================\n\n``attrs`` is released under the `MIT `_ license,\nits documentation lives at `Read the Docs `_,\nthe code on `GitHub `_,\nand the latest release on `PyPI `_.\nIt\u2019s rigorously tested on Python 2.7, 3.5+, and PyPy.\n\nWe collect information on **third-party extensions** in our `wiki `_.\nFeel free to browse and add your own!\n\nIf you'd like to contribute to ``attrs`` you're most welcome and we've written `a little guide `_ to get you started!\n\n\n``attrs`` for Enterprise\n------------------------\n\nAvailable as part of the Tidelift Subscription.\n\nThe maintainers of ``attrs`` and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications.\nSave time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use.\n`Learn more. `_\n\n\nRelease Information\n===================\n\n21.2.0 (2021-05-07)\n-------------------\n\nBackward-incompatible Changes\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n- We had to revert the recursive feature for ``attr.evolve()`` because it broke some use-cases -- sorry!\n `#806 `_\n- Python 3.4 is now blocked using packaging metadata because ``attrs`` can't be imported on it anymore.\n To ensure that 3.4 users can keep installing ``attrs`` easily, we will `yank `_ 21.1.0 from PyPI.\n This has **no** consequences if you pin ``attrs`` to 21.1.0.\n `#807 `_\n\n`Full changelog `_.\n\nCredits\n=======\n\n``attrs`` is written and maintained by `Hynek Schlawack `_.\n\nThe development is kindly supported by `Variomedia AG `_.\n\nA full list of contributors can be found in `GitHub's overview `_.\n\nIt\u2019s the spiritual successor of `characteristic `_ and aspires to fix some of it clunkiness and unfortunate decisions.\nBoth were inspired by Twisted\u2019s `FancyEqMixin `_ but both are implemented using class decorators because `subclassing is bad for you `_, m\u2019kay?\n\n\n", + "release_date": null, + "parties": [], + "keywords": [ + "class", + "attribute", + "boilerplate" + ], + "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", + "spdx_license_expression": "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": "MIT", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [ + { + "purl": "pkg:pypi/coverage", + "extracted_requirement": "coverage[toml]>=5.0.2; extra == \"dev\"", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/hypothesis", + "extracted_requirement": "hypothesis; extra == \"dev\"", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pympler", + "extracted_requirement": "pympler; extra == \"dev\"", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": "pytest>=4.3.0; extra == \"dev\"", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/six", + "extracted_requirement": "six; extra == \"dev\"", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/mypy", + "extracted_requirement": "mypy; extra == \"dev\"", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-mypy-plugins", + "extracted_requirement": "pytest-mypy-plugins; extra == \"dev\"", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/zope-interface", + "extracted_requirement": "zope.interface; extra == \"dev\"", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/furo", + "extracted_requirement": "furo; extra == \"dev\"", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx", + "extracted_requirement": "sphinx; extra == \"dev\"", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-notfound-page", + "extracted_requirement": "sphinx-notfound-page; extra == \"dev\"", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pre-commit", + "extracted_requirement": "pre-commit; extra == \"dev\"", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/furo", + "extracted_requirement": "furo; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx", + "extracted_requirement": "sphinx; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/zope-interface", + "extracted_requirement": "zope.interface; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-notfound-page", + "extracted_requirement": "sphinx-notfound-page; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/coverage", + "extracted_requirement": "coverage[toml]>=5.0.2; extra == \"tests\"", + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/hypothesis", + "extracted_requirement": "hypothesis; extra == \"tests\"", + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pympler", + "extracted_requirement": "pympler; extra == \"tests\"", + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": "pytest>=4.3.0; extra == \"tests\"", + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/six", + "extracted_requirement": "six; extra == \"tests\"", + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/mypy", + "extracted_requirement": "mypy; extra == \"tests\"", + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-mypy-plugins", + "extracted_requirement": "pytest-mypy-plugins; extra == \"tests\"", + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/zope-interface", + "extracted_requirement": "zope.interface; extra == \"tests\"", + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/coverage", + "extracted_requirement": "coverage[toml]>=5.0.2; extra == \"tests_no_zope\"", + "scope": "tests_no_zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/hypothesis", + "extracted_requirement": "hypothesis; extra == \"tests_no_zope\"", + "scope": "tests_no_zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pympler", + "extracted_requirement": "pympler; extra == \"tests_no_zope\"", + "scope": "tests_no_zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": "pytest>=4.3.0; extra == \"tests_no_zope\"", + "scope": "tests_no_zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/six", + "extracted_requirement": "six; extra == \"tests_no_zope\"", + "scope": "tests_no_zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/mypy", + "extracted_requirement": "mypy; extra == \"tests_no_zope\"", + "scope": "tests_no_zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-mypy-plugins", + "extracted_requirement": "pytest-mypy-plugins; extra == \"tests_no_zope\"", + "scope": "tests_no_zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null, + "datasource_id": "pypi_inspect_deplock", + "purl": "pkg:pypi/attrs@21.2.0" + }, + "extra_data": {} + }, + { + "purl": "pkg:pypi/packaging@21.0", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": false, + "is_resolved": true, + "is_direct": true, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "packaging", + "version": "21.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "packaging\n=========\n\n.. start-intro\n\nReusable core utilities for various Python Packaging\n`interoperability specifications `_.\n\nThis library provides utilities that implement the interoperability\nspecifications which have clearly one correct behaviour (eg: :pep:`440`)\nor benefit greatly from having a single shared implementation (eg: :pep:`425`).\n\n.. end-intro\n\nThe ``packaging`` project includes the following: version handling, specifiers,\nmarkers, requirements, tags, utilities.\n\nDocumentation\n-------------\n\nThe `documentation`_ provides information and the API for the following:\n\n- Version Handling\n- Specifiers\n- Markers\n- Requirements\n- Tags\n- Utilities\n\nInstallation\n------------\n\nUse ``pip`` to install these utilities::\n\n pip install packaging\n\nDiscussion\n----------\n\nIf you run into bugs, you can file them in our `issue tracker`_.\n\nYou can also join ``#pypa`` on Freenode to ask questions or get involved.\n\n\n.. _`documentation`: https://packaging.pypa.io/\n.. _`issue tracker`: https://github.com/pypa/packaging/issues\n\n\nCode of Conduct\n---------------\n\nEveryone interacting in the packaging project's codebases, issue trackers, chat\nrooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.\n\n.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md\n\nContributing\n------------\n\nThe ``CONTRIBUTING.rst`` file outlines how to contribute to this project as\nwell as how to report a potential security issue. The documentation for this\nproject also covers information about `project development`_ and `security`_.\n\n.. _`project development`: https://packaging.pypa.io/en/latest/development/\n.. _`security`: https://packaging.pypa.io/en/latest/security/\n\nProject History\n---------------\n\nPlease review the ``CHANGELOG.rst`` file or the `Changelog documentation`_ for\nrecent changes and project history.\n\n.. _`Changelog documentation`: https://packaging.pypa.io/en/latest/changelog/\n\nChangelog\n---------\n\n21.0 - 2021-07-03\n~~~~~~~~~~~~~~~~~\n\n* `packaging` is now only compatible with Python 3.6 and above.\n* Add support for zip files in ``parse_sdist_filename`` (`#429 `__)\n\n20.9 - 2021-01-29\n~~~~~~~~~~~~~~~~~\n\n* Run `isort `_ over the code base (`#377 `__)\n* Add support for the ``macosx_10_*_universal2`` platform tags (`#379 `__)\n* Introduce ``packaging.utils.parse_wheel_filename()`` and ``parse_sdist_filename()``\n (`#387 `__ and `#389 `__)\n\n20.8 - 2020-12-11\n~~~~~~~~~~~~~~~~~\n\n* Revert back to setuptools for compatibility purposes for some Linux distros (`#363 `__)\n* Do not insert an underscore in wheel tags when the interpreter version number\n is more than 2 digits (`#372 `__)\n\n20.7 - 2020-11-28\n~~~~~~~~~~~~~~~~~\n\nNo unreleased changes.\n\n20.6 - 2020-11-28\n~~~~~~~~~~~~~~~~~\n\n.. note:: This release was subsequently yanked, and these changes were included in 20.7.\n\n* Fix flit configuration, to include LICENSE files (`#357 `__)\n* Make `intel` a recognized CPU architecture for the `universal` macOS platform tag (`#361 `__)\n* Add some missing type hints to `packaging.requirements` (issue:`350`)\n\n20.5 - 2020-11-27\n~~~~~~~~~~~~~~~~~\n\n* Officially support Python 3.9 (`#343 `__)\n* Deprecate the ``LegacyVersion`` and ``LegacySpecifier`` classes (`#321 `__)\n* Handle ``OSError`` on non-dynamic executables when attempting to resolve\n the glibc version string.\n\n20.4 - 2020-05-19\n~~~~~~~~~~~~~~~~~\n\n* Canonicalize version before comparing specifiers. (`#282 `__)\n* Change type hint for ``canonicalize_name`` to return\n ``packaging.utils.NormalizedName``.\n This enables the use of static typing tools (like mypy) to detect mixing of\n normalized and un-normalized names.\n\n20.3 - 2020-03-05\n~~~~~~~~~~~~~~~~~\n\n* Fix changelog for 20.2.\n\n20.2 - 2020-03-05\n~~~~~~~~~~~~~~~~~\n\n* Fix a bug that caused a 32-bit OS that runs on a 64-bit ARM CPU (e.g. ARM-v8,\n aarch64), to report the wrong bitness.\n\n20.1 - 2020-01-24\n~~~~~~~~~~~~~~~~~~~\n\n* Fix a bug caused by reuse of an exhausted iterator. (`#257 `__)\n\n20.0 - 2020-01-06\n~~~~~~~~~~~~~~~~~\n\n* Add type hints (`#191 `__)\n\n* Add proper trove classifiers for PyPy support (`#198 `__)\n\n* Scale back depending on ``ctypes`` for manylinux support detection (`#171 `__)\n\n* Use ``sys.implementation.name`` where appropriate for ``packaging.tags`` (`#193 `__)\n\n* Expand upon the API provided by ``packaging.tags``: ``interpreter_name()``, ``mac_platforms()``, ``compatible_tags()``, ``cpython_tags()``, ``generic_tags()`` (`#187 `__)\n\n* Officially support Python 3.8 (`#232 `__)\n\n* Add ``major``, ``minor``, and ``micro`` aliases to ``packaging.version.Version`` (`#226 `__)\n\n* Properly mark ``packaging`` has being fully typed by adding a `py.typed` file (`#226 `__)\n\n19.2 - 2019-09-18\n~~~~~~~~~~~~~~~~~\n\n* Remove dependency on ``attrs`` (`#178 `__, `#179 `__)\n\n* Use appropriate fallbacks for CPython ABI tag (`#181 `__, `#185 `__)\n\n* Add manylinux2014 support (`#186 `__)\n\n* Improve ABI detection (`#181 `__)\n\n* Properly handle debug wheels for Python 3.8 (`#172 `__)\n\n* Improve detection of debug builds on Windows (`#194 `__)\n\n19.1 - 2019-07-30\n~~~~~~~~~~~~~~~~~\n\n* Add the ``packaging.tags`` module. (`#156 `__)\n\n* Correctly handle two-digit versions in ``python_version`` (`#119 `__)\n\n\n19.0 - 2019-01-20\n~~~~~~~~~~~~~~~~~\n\n* Fix string representation of PEP 508 direct URL requirements with markers.\n\n* Better handling of file URLs\n\n This allows for using ``file:///absolute/path``, which was previously\n prevented due to the missing ``netloc``.\n\n This allows for all file URLs that ``urlunparse`` turns back into the\n original URL to be valid.\n\n\n18.0 - 2018-09-26\n~~~~~~~~~~~~~~~~~\n\n* Improve error messages when invalid requirements are given. (`#129 `__)\n\n\n17.1 - 2017-02-28\n~~~~~~~~~~~~~~~~~\n\n* Fix ``utils.canonicalize_version`` when supplying non PEP 440 versions.\n\n\n17.0 - 2017-02-28\n~~~~~~~~~~~~~~~~~\n\n* Drop support for python 2.6, 3.2, and 3.3.\n\n* Define minimal pyparsing version to 2.0.2 (`#91 `__).\n\n* Add ``epoch``, ``release``, ``pre``, ``dev``, and ``post`` attributes to\n ``Version`` and ``LegacyVersion`` (`#34 `__).\n\n* Add ``Version().is_devrelease`` and ``LegacyVersion().is_devrelease`` to\n make it easy to determine if a release is a development release.\n\n* Add ``utils.canonicalize_version`` to canonicalize version strings or\n ``Version`` instances (`#121 `__).\n\n\n16.8 - 2016-10-29\n~~~~~~~~~~~~~~~~~\n\n* Fix markers that utilize ``in`` so that they render correctly.\n\n* Fix an erroneous test on Python RC releases.\n\n\n16.7 - 2016-04-23\n~~~~~~~~~~~~~~~~~\n\n* Add support for the deprecated ``python_implementation`` marker which was\n an undocumented setuptools marker in addition to the newer markers.\n\n\n16.6 - 2016-03-29\n~~~~~~~~~~~~~~~~~\n\n* Add support for the deprecated, PEP 345 environment markers in addition to\n the newer markers.\n\n\n16.5 - 2016-02-26\n~~~~~~~~~~~~~~~~~\n\n* Fix a regression in parsing requirements with whitespaces between the comma\n separators.\n\n\n16.4 - 2016-02-22\n~~~~~~~~~~~~~~~~~\n\n* Fix a regression in parsing requirements like ``foo (==4)``.\n\n\n16.3 - 2016-02-21\n~~~~~~~~~~~~~~~~~\n\n* Fix a bug where ``packaging.requirements:Requirement`` was overly strict when\n matching legacy requirements.\n\n\n16.2 - 2016-02-09\n~~~~~~~~~~~~~~~~~\n\n* Add a function that implements the name canonicalization from PEP 503.\n\n\n16.1 - 2016-02-07\n~~~~~~~~~~~~~~~~~\n\n* Implement requirement specifiers from PEP 508.\n\n\n16.0 - 2016-01-19\n~~~~~~~~~~~~~~~~~\n\n* Relicense so that packaging is available under *either* the Apache License,\n Version 2.0 or a 2 Clause BSD license.\n\n* Support installation of packaging when only distutils is available.\n\n* Fix ``==`` comparison when there is a prefix and a local version in play.\n (`#41 `__).\n\n* Implement environment markers from PEP 508.\n\n\n15.3 - 2015-08-01\n~~~~~~~~~~~~~~~~~\n\n* Normalize post-release spellings for rev/r prefixes. `#35 `__\n\n\n15.2 - 2015-05-13\n~~~~~~~~~~~~~~~~~\n\n* Fix an error where the arbitrary specifier (``===``) was not correctly\n allowing pre-releases when it was being used.\n\n* Expose the specifier and version parts through properties on the\n ``Specifier`` classes.\n\n* Allow iterating over the ``SpecifierSet`` to get access to all of the\n ``Specifier`` instances.\n\n* Allow testing if a version is contained within a specifier via the ``in``\n operator.\n\n\n15.1 - 2015-04-13\n~~~~~~~~~~~~~~~~~\n\n* Fix a logic error that was causing inconsistent answers about whether or not\n a pre-release was contained within a ``SpecifierSet`` or not.\n\n\n15.0 - 2015-01-02\n~~~~~~~~~~~~~~~~~\n\n* Add ``Version().is_postrelease`` and ``LegacyVersion().is_postrelease`` to\n make it easy to determine if a release is a post release.\n\n* Add ``Version().base_version`` and ``LegacyVersion().base_version`` to make\n it easy to get the public version without any pre or post release markers.\n\n* Support the update to PEP 440 which removed the implied ``!=V.*`` when using\n either ``>V`` or ``V`` or ````) operator.\n\n\n14.3 - 2014-11-19\n~~~~~~~~~~~~~~~~~\n\n* **BACKWARDS INCOMPATIBLE** Refactor specifier support so that it can sanely\n handle legacy specifiers as well as PEP 440 specifiers.\n\n* **BACKWARDS INCOMPATIBLE** Move the specifier support out of\n ``packaging.version`` into ``packaging.specifiers``.\n\n\n14.2 - 2014-09-10\n~~~~~~~~~~~~~~~~~\n\n* Add prerelease support to ``Specifier``.\n* Remove the ability to do ``item in Specifier()`` and replace it with\n ``Specifier().contains(item)`` in order to allow flags that signal if a\n prerelease should be accepted or not.\n* Add a method ``Specifier().filter()`` which will take an iterable and returns\n an iterable with items that do not match the specifier filtered out.\n\n\n14.1 - 2014-09-08\n~~~~~~~~~~~~~~~~~\n\n* Allow ``LegacyVersion`` and ``Version`` to be sorted together.\n* Add ``packaging.version.parse()`` to enable easily parsing a version string\n as either a ``Version`` or a ``LegacyVersion`` depending on it's PEP 440\n validity.\n\n\n14.0 - 2014-09-05\n~~~~~~~~~~~~~~~~~\n\n* Initial release.\n\n\n.. _`master`: https://github.com/pypa/packaging/\n\n\n", + "release_date": null, + "parties": [], + "keywords": null, + "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": "bsd-simplified OR apache-2.0", + "declared_license_expression_spdx": "BSD-2-Clause OR Apache-2.0", + "license_detections": [ + { + "license_expression": "bsd-simplified OR apache-2.0", + "license_expression_spdx": "BSD-2-Clause OR Apache-2.0", + "matches": [ + { + "license_expression": "bsd-simplified OR apache-2.0", + "spdx_license_expression": "BSD-2-Clause OR Apache-2.0", + "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-bsd_simplified_or_apache_2_0-4e6ba7864502b4956354d47c70173db3283d1005", + "rule_url": null, + "matched_text": "BSD-2-Clause or Apache-2.0" + } + ], + "identifier": "bsd_simplified_or_apache_2_0-dd30dee1-b8d2-187f-c9f9-69fd2ff5e39a" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "BSD-2-Clause or Apache-2.0", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [ + { + "purl": "pkg:pypi/pyparsing", + "extracted_requirement": "pyparsing>=2.0.2", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null, + "datasource_id": "pypi_inspect_deplock", + "purl": "pkg:pypi/packaging@21.0" + }, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pip@24.1", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": false, + "is_resolved": true, + "is_direct": false, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "pip", + "version": "24.1", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "pip - 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\n", + "release_date": null, + "parties": [], + "keywords": null, + "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", + "spdx_license_expression": "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": "MIT", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [], + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null, + "datasource_id": "pypi_inspect_deplock", + "purl": "pkg:pypi/pip@24.1" + }, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pyparsing@2.4.7", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": false, + "is_resolved": true, + "is_direct": false, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "pyparsing", + "version": "2.4.7", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "PyParsing -- A Python Parsing Module\n====================================\n\n|Build Status|\n\nIntroduction\n============\n\nThe pyparsing module is an alternative approach to creating and\nexecuting simple grammars, vs. the traditional lex/yacc approach, or the\nuse of regular expressions. The pyparsing module provides a library of\nclasses that client code uses to construct the grammar directly in\nPython code.\n\n*[Since first writing this description of pyparsing in late 2003, this\ntechnique for developing parsers has become more widespread, under the\nname Parsing Expression Grammars - PEGs. See more information on PEGs at*\nhttps://en.wikipedia.org/wiki/Parsing_expression_grammar *.]*\n\nHere is a program to parse ``\"Hello, World!\"`` (or any greeting of the form\n``\"salutation, addressee!\"``):\n\n.. code:: python\n\n from pyparsing import Word, alphas\n greet = Word(alphas) + \",\" + Word(alphas) + \"!\"\n hello = \"Hello, World!\"\n print(hello, \"->\", greet.parseString(hello))\n\nThe program outputs the following::\n\n Hello, World! -> ['Hello', ',', 'World', '!']\n\nThe Python representation of the grammar is quite readable, owing to the\nself-explanatory class names, and the use of '+', '|' and '^' operator\ndefinitions.\n\nThe parsed results returned from ``parseString()`` can be accessed as a\nnested list, a dictionary, or an object with named attributes.\n\nThe pyparsing module handles some of the problems that are typically\nvexing when writing text parsers:\n\n- extra or missing whitespace (the above program will also handle ``\"Hello,World!\"``, ``\"Hello , World !\"``, etc.)\n- quoted strings\n- embedded comments\n\nThe examples directory includes a simple SQL parser, simple CORBA IDL\nparser, a config file parser, a chemical formula parser, and a four-\nfunction algebraic notation parser, among many others.\n\nDocumentation\n=============\n\nThere are many examples in the online docstrings of the classes\nand methods in pyparsing. You can find them compiled into online docs\nat https://pyparsing-docs.readthedocs.io/en/latest/. Additional\ndocumentation resources and project info are listed in the online\nGitHub wiki, at https://github.com/pyparsing/pyparsing/wiki. An\nentire directory of examples is at\nhttps://github.com/pyparsing/pyparsing/tree/master/examples.\n\nLicense\n=======\n\nMIT License. See header of pyparsing.py\n\nHistory\n=======\n\nSee CHANGES file.\n\n.. |Build Status| image:: https://travis-ci.org/pyparsing/pyparsing.svg?branch=master\n :target: https://travis-ci.org/pyparsing/pyparsing\n\n\n", + "release_date": null, + "parties": [], + "keywords": null, + "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", + "spdx_license_expression": "MIT", + "from_file": null, + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "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" + } + ], + "identifier": "mit-9967e727-165e-9bb5-f090-7de5e47a3929" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "MIT License", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [], + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null, + "datasource_id": "pypi_inspect_deplock", + "purl": "pkg:pypi/pyparsing@2.4.7" + }, + "extra_data": {} + }, + { + "purl": "pkg:pypi/semantic-version@2.8.5", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": false, + "is_resolved": true, + "is_direct": true, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "semantic-version", + "version": "2.8.5", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "python-semanticversion\n======================\n\nThis small python library provides a few tools to handle `SemVer`_ in Python.\nIt follows strictly the 2.0.0 version of the SemVer scheme.\n\n.. image:: https://secure.travis-ci.org/rbarrois/python-semanticversion.png?branch=master\n :target: http://travis-ci.org/rbarrois/python-semanticversion/\n\n.. image:: https://img.shields.io/pypi/v/semantic_version.svg\n :target: https://python-semanticversion.readthedocs.io/en/latest/changelog.html\n :alt: Latest Version\n\n.. image:: https://img.shields.io/pypi/pyversions/semantic_version.svg\n :target: https://pypi.python.org/pypi/semantic_version/\n :alt: Supported Python versions\n\n.. image:: https://img.shields.io/pypi/wheel/semantic_version.svg\n :target: https://pypi.python.org/pypi/semantic_version/\n :alt: Wheel status\n\n.. image:: https://img.shields.io/pypi/l/semantic_version.svg\n :target: https://pypi.python.org/pypi/semantic_version/\n :alt: License\n\nLinks\n-----\n\n- Package on `PyPI`_: http://pypi.python.org/pypi/semantic_version/\n- Doc on `ReadTheDocs `_: https://python-semanticversion.readthedocs.io/\n- Source on `GitHub `_: http://github.com/rbarrois/python-semanticversion/\n- Build on `Travis CI `_: http://travis-ci.org/rbarrois/python-semanticversion/\n- Semantic Version specification: `SemVer`_\n\n\nGetting started\n===============\n\nInstall the package from `PyPI`_, using pip:\n\n.. code-block:: sh\n\n pip install semantic_version\n\nOr from GitHub:\n\n.. code-block:: sh\n\n $ git clone git://github.com/rbarrois/python-semanticversion.git\n\n\nImport it in your code:\n\n\n.. code-block:: python\n\n import semantic_version\n\n\n\nThis module provides classes to handle semantic versions:\n\n- ``Version`` represents a version number (``0.1.1-alpha+build.2012-05-15``)\n- ``BaseSpec``-derived classes represent requirement specifications (``>=0.1.1,<0.3.0``):\n\n - ``SimpleSpec`` describes a natural description syntax\n - ``NpmSpec`` is used for NPM-style range descriptions.\n\nVersions\n--------\n\nDefining a ``Version`` is quite simple:\n\n\n.. code-block:: pycon\n\n >>> import semantic_version\n >>> v = semantic_version.Version('0.1.1')\n >>> v.major\n 0\n >>> v.minor\n 1\n >>> v.patch\n 1\n >>> v.prerelease\n []\n >>> v.build\n []\n >>> list(v)\n [0, 1, 1, [], []]\n\nIf the provided version string is invalid, a ``ValueError`` will be raised:\n\n.. code-block:: pycon\n\n >>> semantic_version.Version('0.1')\n Traceback (most recent call last):\n File \"\", line 1, in \n File \"/Users/rbarrois/dev/semantic_version/src/semantic_version/base.py\", line 64, in __init__\n major, minor, patch, prerelease, build = self.parse(version_string, partial)\n File \"/Users/rbarrois/dev/semantic_version/src/semantic_version/base.py\", line 86, in parse\n raise ValueError('Invalid version string: %r' % version_string)\n ValueError: Invalid version string: '0.1'\n\n\nObviously, ``Versions`` can be compared:\n\n\n.. code-block:: pycon\n\n >>> semantic_version.Version('0.1.1') < semantic_version.Version('0.1.2')\n True\n >>> semantic_version.Version('0.1.1') > semantic_version.Version('0.1.1-alpha')\n True\n >>> semantic_version.Version('0.1.1') <= semantic_version.Version('0.1.1-alpha')\n False\n\nYou can also get a new version that represents a bump in one of the version levels:\n\n.. code-block:: pycon\n\n >>> v = semantic_version.Version('0.1.1+build')\n >>> new_v = v.next_major()\n >>> str(new_v)\n '1.0.0'\n >>> v = semantic_version.Version('1.1.1+build')\n >>> new_v = v.next_minor()\n >>> str(new_v)\n '1.2.0'\n >>> v = semantic_version.Version('1.1.1+build')\n >>> new_v = v.next_patch()\n >>> str(new_v)\n '1.1.2'\n\nIt is also possible to check whether a given string is a proper semantic version string:\n\n\n.. code-block:: pycon\n\n >>> semantic_version.validate('0.1.3')\n True\n >>> semantic_version.validate('0a2')\n False\n\n\nFinally, one may create a ``Version`` with named components instead:\n\n.. code-block:: pycon\n\n >>> semantic_version.Version(major=0, minor=1, patch=2)\n Version('0.1.2')\n\nIn that case, ``major``, ``minor`` and ``patch`` are mandatory, and must be integers.\n``prerelease`` and ``patch``, if provided, must be tuples of strings:\n\n.. code-block:: pycon\n\n >>> semantic_version.Version(major=0, minor=1, patch=2, prerelease=('alpha', '2'))\n Version('0.1.2-alpha.2')\n\n\nRequirement specification\n-------------------------\n\nThe ``SimpleSpec`` object describes a range of accepted versions:\n\n\n.. code-block:: pycon\n\n >>> s = SimpleSpec('>=0.1.1') # At least 0.1.1\n >>> s.match(Version('0.1.1'))\n True\n >>> s.match(Version('0.1.1-alpha1')) # pre-release doesn't satisfy version spec\n False\n >>> s.match(Version('0.1.0'))\n False\n\nSimpler test syntax is also available using the ``in`` keyword:\n\n.. code-block:: pycon\n\n >>> s = SimpleSpec('==0.1.1')\n >>> Version('0.1.1-alpha1') in s\n True\n >>> Version('0.1.2') in s\n False\n\n\nCombining specifications can be expressed as follows:\n\n .. code-block:: pycon\n\n >>> SimpleSpec('>=0.1.1,<0.3.0')\n\n\nUsing a specification\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\nThe ``SimpleSpec.filter`` method filters an iterable of ``Version``:\n\n.. code-block:: pycon\n\n >>> s = SimpleSpec('>=0.1.0,<0.4.0')\n >>> versions = (Version('0.%d.0' % i) for i in range(6))\n >>> for v in s.filter(versions):\n ... print v\n 0.1.0\n 0.2.0\n 0.3.0\n\nIt is also possible to select the 'best' version from such iterables:\n\n\n.. code-block:: pycon\n\n >>> s = SimpleSpec('>=0.1.0,<0.4.0')\n >>> versions = (Version('0.%d.0' % i) for i in range(6))\n >>> s.select(versions)\n Version('0.3.0')\n\n\nCoercing an arbitrary version string\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\nSome user-supplied input might not match the semantic version scheme.\nFor such cases, the ``Version.coerce`` method will try to convert any\nversion-like string into a valid semver version:\n\n.. code-block:: pycon\n\n >>> Version.coerce('0')\n Version('0.0.0')\n >>> Version.coerce('0.1.2.3.4')\n Version('0.1.2+3.4')\n >>> Version.coerce('0.1.2a3')\n Version('0.1.2-a3')\n\n\nIncluding pre-release identifiers in specifications\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\nWhen testing a ``Version`` against a ``SimpleSpec``, comparisons are\nadjusted for common user expectations; thus, a pre-release version (``1.0.0-alpha``)\nwill not satisfy the ``==1.0.0`` ``SimpleSpec``.\n\nPre-release identifiers will only be compared if included in the ``BaseSpec``\ndefinition or (for the empty pre-release number) if a single dash is appended\n(``1.0.0-``):\n\n\n.. code-block:: pycon\n\n >>> Version('0.1.0-alpha') in SimpleSpec('<0.1.0') # No pre-release identifier\n False\n >>> Version('0.1.0-alpha') in SimpleSpec('<0.1.0-') # Include pre-release in checks\n True\n\n\nIncluding build metadata in specifications\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\nBuild metadata has no ordering; thus, the only meaningful comparison including\nbuild metadata is equality.\n\n\n.. code-block:: pycon\n\n >>> Version('1.0.0+build2') in SimpleSpec('<=1.0.0') # Build metadata ignored\n True\n >>> Version('1.0.0+build1') in SimpleSpec('==1.0.0+build2') # Include build in checks\n False\n\n\nNPM-based ranges\n----------------\n\nThe ``NpmSpec`` class handles NPM-style ranges:\n\n.. code-block:: pycon\n\n >>> Version('1.2.3') in NpmSpec('1.2.2 - 1.4')\n True\n >>> Version('1.2.3') in NpmSpec('<1.x || >=1.2.3')\n True\n\nRefer to https://docs.npmjs.com/misc/semver.html for a detailed description of NPM\nrange syntax.\n\n\nUsing with Django\n=================\n\nThe ``semantic_version.django_fields`` module provides django fields to\nstore ``Version`` or ``BaseSpec`` objects.\n\nMore documentation is available in the ``django`` section.\n\n\nContributing\n============\n\nIn order to contribute to the source code:\n\n- Open an issue on `GitHub`_: https://github.com/rbarrois/python-semanticversion/issues\n- Fork the `repository `_\n and submit a pull request on `GitHub`_\n- Or send me a patch (mailto:raphael.barrois+semver@polytechnique.org)\n\nWhen submitting patches or pull requests, you should respect the following rules:\n\n- Coding conventions are based on ``8``\n- The whole test suite must pass after adding the changes\n- The test coverage for a new feature must be 100%\n- New features and methods should be documented in the ``reference`` section\n and included in the ``changelog``\n- Include your name in the ``contributors`` section\n\n.. note:: All files should contain the following header::\n\n # -*- encoding: utf-8 -*-\n # Copyright (c) The python-semanticversion project\n\n\nContents\n========\n\n :maxdepth: 2\n\n reference\n django\n changelog\n credits\n\n\n.. _SemVer: http://semver.org/\n.. _PyPI: http://pypi.python.org/\n\nIndices and tables\n==================\n\n* ``genindex``\n* ``modindex``\n* ``search``\n\n\n\n", + "release_date": null, + "parties": [], + "keywords": [ + "semantic version", + "versioning", + "version" + ], + "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": "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", + "spdx_license_expression": "BSD-3-Clause", + "from_file": null, + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 99.0, + "matched_length": 2, + "match_coverage": 100.0, + "rule_relevance": 99, + "rule_identifier": "bsd-new_89.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/bsd-new_89.RULE", + "matched_text": "license BSD" + } + ], + "identifier": "bsd_new-261898a0-0118-87c4-7092-14e4ff134882" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "BSD", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [], + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null, + "datasource_id": "pypi_inspect_deplock", + "purl": "pkg:pypi/semantic-version@2.8.5" + }, + "extra_data": {} + }, + { + "purl": "pkg:pypi/semver@2.13.0", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": false, + "is_resolved": true, + "is_direct": true, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "semver", + "version": "2.13.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "Quickstart\n==========\n\n.. teaser-begin\n\nA Python module for `semantic versioning`_. Simplifies comparing versions.\n\n|build-status| |python-support| |downloads| |license| |docs| |black|\n\n.. teaser-end\n\n.. warning::\n\n As anything comes to an end, this project will focus on Python 3.x only.\n New features and bugfixes will be integrated into the 3.x.y branch only.\n\n Major version 3 of semver will contain some incompatible changes:\n\n * removes support for Python 2.7 and 3.3\n * removes deprecated functions.\n\n The last version of semver which supports Python 2.7 and 3.4 will be\n 2.10.x. However, keep in mind, version 2.10.x is frozen: no new\n features nor backports will be integrated.\n\n We recommend to upgrade your workflow to Python 3.x to gain support,\n bugfixes, and new features.\n\nThe module follows the ``MAJOR.MINOR.PATCH`` style:\n\n* ``MAJOR`` version when you make incompatible API changes,\n* ``MINOR`` version when you add functionality in a backwards compatible manner, and\n* ``PATCH`` version when you make backwards compatible bug fixes.\n\nAdditional labels for pre-release and build metadata are supported.\n\nTo import this library, use:\n\n.. code-block:: python\n\n >>> import semver\n\nWorking with the library is quite straightforward. To turn a version string into the\ndifferent parts, use the ``semver.VersionInfo.parse`` function:\n\n.. code-block:: python\n\n >>> ver = semver.VersionInfo.parse('1.2.3-pre.2+build.4')\n >>> ver.major\n 1\n >>> ver.minor\n 2\n >>> ver.patch\n 3\n >>> ver.prerelease\n 'pre.2'\n >>> ver.build\n 'build.4'\n\nTo raise parts of a version, there are a couple of functions available for\nyou. The function ``semver.VersionInfo.bump_major`` leaves the original object untouched, but\nreturns a new ``semver.VersionInfo`` instance with the raised major part:\n\n.. code-block:: python\n\n >>> ver = semver.VersionInfo.parse(\"3.4.5\")\n >>> ver.bump_major()\n VersionInfo(major=4, minor=0, patch=0, prerelease=None, build=None)\n\nIt is allowed to concatenate different \"bump functions\":\n\n.. code-block:: python\n\n >>> ver.bump_major().bump_minor()\n VersionInfo(major=4, minor=1, patch=0, prerelease=None, build=None)\n\nTo compare two versions, semver provides the ``semver.compare`` function.\nThe return value indicates the relationship between the first and second\nversion:\n\n.. code-block:: python\n\n >>> semver.compare(\"1.0.0\", \"2.0.0\")\n -1\n >>> semver.compare(\"2.0.0\", \"1.0.0\")\n 1\n >>> semver.compare(\"2.0.0\", \"2.0.0\")\n 0\n\n\nThere are other functions to discover. Read on!\n\n\n.. |latest-version| image:: https://img.shields.io/pypi/v/semver.svg\n :alt: Latest version on PyPI\n :target: https://pypi.org/project/semver\n.. |build-status| image:: https://travis-ci.com/python-semver/python-semver.svg?branch=master\n :alt: Build status\n :target: https://travis-ci.com/python-semver/python-semver\n.. |python-support| image:: https://img.shields.io/pypi/pyversions/semver.svg\n :target: https://pypi.org/project/semver\n :alt: Python versions\n.. |downloads| image:: https://img.shields.io/pypi/dm/semver.svg\n :alt: Monthly downloads from PyPI\n :target: https://pypi.org/project/semver\n.. |license| image:: https://img.shields.io/pypi/l/semver.svg\n :alt: Software license\n :target: https://github.com/python-semver/python-semver/blob/master/LICENSE.txt\n.. |docs| image:: https://readthedocs.org/projects/python-semver/badge/?version=latest\n :target: http://python-semver.readthedocs.io/en/latest/?badge=latest\n :alt: Documentation Status\n.. _semantic versioning: http://semver.org/\n.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/psf/black\n :alt: Black Formatter\n\n\n", + "release_date": null, + "parties": [], + "keywords": null, + "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": "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", + "spdx_license_expression": "BSD-3-Clause", + "from_file": null, + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 99.0, + "matched_length": 2, + "match_coverage": 100.0, + "rule_relevance": 99, + "rule_identifier": "bsd-new_89.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/bsd-new_89.RULE", + "matched_text": "license BSD" + } + ], + "identifier": "bsd_new-261898a0-0118-87c4-7092-14e4ff134882" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "BSD", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [], + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null, + "datasource_id": "pypi_inspect_deplock", + "purl": "pkg:pypi/semver@2.13.0" + }, + "extra_data": {} + }, + { + "purl": "pkg:pypi/setuptools@70.1.0", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": false, + "is_resolved": true, + "is_direct": false, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "setuptools", + "version": "70.1.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": ".. |pypi-version| image:: https://img.shields.io/pypi/v/setuptools.svg\n :target: https://pypi.org/project/setuptools\n\n.. |py-version| image:: https://img.shields.io/pypi/pyversions/setuptools.svg\n\n.. |test-badge| image:: https://github.com/pypa/setuptools/actions/workflows/main.yml/badge.svg\n :target: https://github.com/pypa/setuptools/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. |ruff-badge| image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json\n :target: https://github.com/astral-sh/ruff\n :alt: Ruff\n\n.. |docs-badge| image:: https://img.shields.io/readthedocs/setuptools/latest.svg\n :target: https://setuptools.pypa.io\n\n.. |skeleton-badge| image:: https://img.shields.io/badge/skeleton-2024-informational\n :target: https://blog.jaraco.com/skeleton\n\n.. |codecov-badge| image:: https://img.shields.io/codecov/c/github/pypa/setuptools/master.svg?logo=codecov&logoColor=white\n :target: https://codecov.io/gh/pypa/setuptools\n\n.. |tidelift-badge| image:: https://tidelift.com/badges/github/pypa/setuptools?style=flat\n :target: https://tidelift.com/subscription/pkg/pypi-setuptools?utm_source=pypi-setuptools&utm_medium=readme\n\n.. |discord-badge| image:: https://img.shields.io/discord/803025117553754132\n :target: https://discord.com/channels/803025117553754132/815945031150993468\n :alt: Discord\n\n|pypi-version| |py-version| |test-badge| |ruff-badge| |docs-badge| |skeleton-badge| |codecov-badge| |discord-badge|\n\nSee the `Quickstart `_\nand the `User's Guide `_ for\ninstructions on how to use Setuptools.\n\nQuestions and comments should be directed to `GitHub Discussions\n`_.\nBug reports and especially tested patches may be\nsubmitted directly to the `bug tracker\n`_.\n\n\nCode of Conduct\n===============\n\nEveryone interacting in the setuptools project's codebases, issue trackers,\nchat rooms, and fora is expected to follow the\n`PSF Code of Conduct `_.\n\n\nFor Enterprise\n==============\n\nAvailable as part of the Tidelift Subscription.\n\nSetuptools and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.\n\n`Learn more `_.\n", + "release_date": null, + "parties": [], + "keywords": [ + "CPAN", + "PyPI", + "distutils", + "eggs", + "package", + "management" + ], + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [ + { + "purl": "pkg:pypi/sphinx", + "extracted_requirement": "sphinx>=3.5; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/jaraco-packaging", + "extracted_requirement": "jaraco.packaging>=9.3; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/rst-linker", + "extracted_requirement": "rst.linker>=1.9; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/furo", + "extracted_requirement": "furo; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-lint", + "extracted_requirement": "sphinx-lint; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/jaraco-tidelift", + "extracted_requirement": "jaraco.tidelift>=1.4; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pygments-github-lexers@0.0.5", + "extracted_requirement": "pygments-github-lexers==0.0.5; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": true, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-favicon", + "extracted_requirement": "sphinx-favicon; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-inline-tabs", + "extracted_requirement": "sphinx-inline-tabs; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-reredirects", + "extracted_requirement": "sphinx-reredirects; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinxcontrib-towncrier", + "extracted_requirement": "sphinxcontrib-towncrier; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-notfound-page", + "extracted_requirement": "sphinx-notfound-page<2,>=1; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pyproject-hooks", + "extracted_requirement": "pyproject-hooks!=1.1; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": "pytest!=8.1.1,>=6; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-checkdocs", + "extracted_requirement": "pytest-checkdocs>=2.4; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-mypy", + "extracted_requirement": "pytest-mypy; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-enabler", + "extracted_requirement": "pytest-enabler>=2.2; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/virtualenv", + "extracted_requirement": "virtualenv>=13.0.0; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/wheel", + "extracted_requirement": "wheel; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pip", + "extracted_requirement": "pip>=19.1; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/packaging", + "extracted_requirement": "packaging>=23.2; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/jaraco-envs", + "extracted_requirement": "jaraco.envs>=2.2; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-xdist", + "extracted_requirement": "pytest-xdist>=3; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/jaraco-path", + "extracted_requirement": "jaraco.path>=3.2.0; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/build", + "extracted_requirement": "build[virtualenv]>=1.0.3; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/filelock", + "extracted_requirement": "filelock>=3.4.0; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/ini2toml", + "extracted_requirement": "ini2toml[lite]>=0.14; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/tomli-w", + "extracted_requirement": "tomli-w>=1.0.0; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-timeout", + "extracted_requirement": "pytest-timeout; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-home", + "extracted_requirement": "pytest-home>=0.5; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/mypy@1.10.0", + "extracted_requirement": "mypy==1.10.0; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": true, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/tomli", + "extracted_requirement": "tomli; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/importlib-metadata", + "extracted_requirement": "importlib-metadata; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-subprocess", + "extracted_requirement": "pytest-subprocess; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pyproject-hooks", + "extracted_requirement": "pyproject-hooks!=1.1; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/jaraco-test", + "extracted_requirement": "jaraco.test; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-cov", + "extracted_requirement": "pytest-cov; platform_python_implementation != \"PyPy\" and extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/jaraco-develop", + "extracted_requirement": "jaraco.develop>=7.21; (python_version >= \"3.9\" and sys_platform != \"cygwin\") and extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-ruff", + "extracted_requirement": "pytest-ruff>=0.3.2; sys_platform != \"cygwin\" and extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-perf", + "extracted_requirement": "pytest-perf; sys_platform != \"cygwin\" and extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null, + "datasource_id": "pypi_inspect_deplock", + "purl": "pkg:pypi/setuptools@70.1.0" + }, + "extra_data": {} + }, + { + "purl": "pkg:pypi/wheel@0.43.0", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": false, + "is_resolved": true, + "is_direct": false, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "wheel", + "version": "0.43.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "wheel\n=====\n\nThis library is the reference implementation of the Python wheel packaging\nstandard, as defined in `PEP 427`_.\n\nIt has two different roles:\n\n#. A setuptools_ extension for building wheels that provides the\n ``bdist_wheel`` setuptools command\n#. A command line tool for working with wheel files\n\nIt should be noted that wheel is **not** intended to be used as a library, and\nas such there is no stable, public API.\n\n.. _PEP 427: https://www.python.org/dev/peps/pep-0427/\n.. _setuptools: https://pypi.org/project/setuptools/\n\nDocumentation\n-------------\n\nThe documentation_ can be found on Read The Docs.\n\n.. _documentation: https://wheel.readthedocs.io/\n\nCode of Conduct\n---------------\n\nEveryone interacting in the wheel project's codebases, issue trackers, chat\nrooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.\n\n.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md\n\n", + "release_date": null, + "parties": [], + "keywords": [ + "wheel", + "packaging" + ], + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [ + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": "pytest>=6.0.0; extra == \"test\"", + "scope": "test", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/setuptools", + "extracted_requirement": "setuptools>=65; extra == \"test\"", + "scope": "test", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null, + "datasource_id": "pypi_inspect_deplock", + "purl": "pkg:pypi/wheel@0.43.0" + }, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx", + "extracted_requirement": "Sphinx>=5.0.2; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-rtd-theme", + "extracted_requirement": "sphinx-rtd-theme>=1.0.0; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-reredirects", + "extracted_requirement": "sphinx-reredirects>=0.1.2; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/doc8", + "extracted_requirement": "doc8>=0.11.2; extra == \"docs\"", + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": "pytest!=7.0.0,>=6; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-xdist", + "extracted_requirement": "pytest-xdist>=2; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/aboutcode-toolkit", + "extracted_requirement": "aboutcode-toolkit>=7.0.2; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pycodestyle", + "extracted_requirement": "pycodestyle>=2.8.0; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/twine", + "extracted_requirement": "twine; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/black", + "extracted_requirement": "black; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/commoncode", + "extracted_requirement": "commoncode; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/isort", + "extracted_requirement": "isort>=5.10.1; extra == \"testing\"", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null, + "datasource_id": "pypi_inspect_deplock", + "purl": "pkg:pypi/univers@0.0.0" + } +] \ No newline at end of file diff --git a/tests/packagedcode/test_pypi.py b/tests/packagedcode/test_pypi.py index 1bf786b11fc..a315dd19e1d 100644 --- a/tests/packagedcode/test_pypi.py +++ b/tests/packagedcode/test_pypi.py @@ -349,6 +349,20 @@ def test_parse_pyproject_toml_poetry_gino(self): self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) +class TestPipInspectDeplockHandler(PackageTester): + test_data_dir = os.path.join(os.path.dirname(__file__), 'data') + + def test_is_pip_inspect_deplock(self): + test_file = self.get_test_loc('pypi/deplock/univers/pip-inspect.deplock') + assert pypi.PipInspectDeplockHandler.is_datafile(test_file) + + def test_parse_pip_inspect_deplock_univers(self): + test_file = self.get_test_loc('pypi/deplock/univers/pip-inspect.deplock') + package = pypi.PipInspectDeplockHandler.parse(test_file) + expected_loc = self.get_test_loc('pypi/deplock/univers/pip-inspect.deplock-expected.json') + self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) + + class TestPipRequirementsFileHandler(PackageTester): test_data_dir = os.path.join(os.path.dirname(__file__), 'data') From e6edbc25d7b7f7cd45a6bfed7940c61b6f0519b6 Mon Sep 17 00:00:00 2001 From: Ayan Sinha Mahapatra Date: Fri, 28 Jun 2024 19:02:16 +0530 Subject: [PATCH 03/10] Only contain version ranges in extracted_requirement Signed-off-by: Ayan Sinha Mahapatra --- src/packagedcode/pypi.py | 58 +++- .../data/common/manifests-expected.json | 22 +- .../data/common/manifests-expected.jsonlines | 26 +- .../data/common/manifests-expected.yaml | 26 +- ...n-package-instance-expected-with-uuid.json | 16 +- .../python-package-instance-expected.json | 16 +- ...ackage-instance-with-license-expected.json | 16 +- .../paddlenlp.expected.json | 8 +- ...commoncode-21.5.12-py3.9.egg-expected.json | 30 +- .../pypi/deplock/simple/pip-inspect.deplock | 99 +++++++ .../simple/pip-inspect.deplock-expected.json | 270 ++++++++++++++++++ .../univers/pip-inspect.deplock-expected.json | 178 ++++++------ .../scancode_toolkit.egg-info-expected.json | 112 ++++---- .../pypi/metadata/v20/PKG-INFO-expected.json | 6 +- ...s_require_with_vars_setup.py-expected.json | 2 +- .../flask_setup.py-expected.json | 28 +- .../pendulum_setup.py-expected.json | 6 +- .../requests_setup.py-expected.json | 18 +- .../sqlalchemy_setup.py-expected.json | 16 +- .../unpack_kwargs_setup.py-expected.json | 4 +- .../setup.py-expected.json | 10 +- .../flask-2.2.0.dev0/setup.py-expected.json | 18 +- .../flit-2.3.0/setup.py-expected.json | 26 +- .../paho-mqtt-1.5.0/setup.py-expected.json | 2 +- .../pexpect-4.6.0/setup.py-expected.json | 2 +- .../requests-2.24.0/setup.py-expected.json | 16 +- .../setupreader-0.0.3/setup.py-expected.json | 4 +- .../urllib3-1.25.9/setup.py-expected.json | 18 +- .../setup.py/bluepyopt_setup.py-expected.json | 22 +- .../setup.py/complex_setup.py-expected.json | 20 +- .../pypi/setup.py/ntfs_setup.py-expected.json | 2 +- .../setup.py/nvchecker_setup.py-expected.json | 4 +- ..._agents_common_code_setup.py-expected.json | 4 +- .../pipdeptree_setup.py-expected.json | 4 +- .../setup.py/pydep_setup.py-expected.json | 2 +- .../setup.py/saneyaml_setup.py-expected.json | 2 +- .../setuppycheck_setup.py-expected.json | 2 +- .../setup.py/simple-setup.py-expected.json | 62 ++-- .../setup.py/url_py_setup.py-expected.json | 2 +- .../whatsapp-play-setup.py-expected.json | 48 ++-- .../site-packages/site-packages-expected.json | 24 +- .../data/pypi/solo-setup/expected.json | 10 +- .../PyJPString-0.0.3-subdir-expected.json | 8 +- .../celery-expected.json | 176 ++++++------ .../daglib_wheel_extracted-expected.json | 16 +- .../Jinja2-2.10.dist-info-expected.json | 4 +- .../urllib3-1.26.4.dist-info-expected.json | 18 +- .../haruka_bot-1.2.3.dist-info-expected.json | 24 +- ...plugincode-21.1.21.dist-info-expected.json | 16 +- .../anonapi-0.0.19.dist-info-expected.json | 2 +- tests/packagedcode/test_pypi.py | 6 + ...holder_from_package_resource.expected.json | 4 +- 52 files changed, 997 insertions(+), 538 deletions(-) create mode 100644 tests/packagedcode/data/pypi/deplock/simple/pip-inspect.deplock create mode 100644 tests/packagedcode/data/pypi/deplock/simple/pip-inspect.deplock-expected.json diff --git a/src/packagedcode/pypi.py b/src/packagedcode/pypi.py index 9268a44694e..6c2c0924326 100644 --- a/src/packagedcode/pypi.py +++ b/src/packagedcode/pypi.py @@ -615,10 +615,11 @@ def parse(cls, location, package_only=False): for package_metadata in installed_packages: package_metadata_dep = package_metadata.get('metadata') + is_requested = package_metadata.get('requested') # `direct_url` is only present for root package # `requested` is true for root package and direct dependencies only - if package_metadata.get('requested') and 'direct_url' in package_metadata: + if is_requested and 'direct_url' in package_metadata: main_package_metadata = package_metadata_dep main_package_requires = main_package_metadata.get('requires_dist') dependencies_for_main = get_requires_dependencies( @@ -645,6 +646,8 @@ def parse(cls, location, package_only=False): is_resolved=True, resolved_package=package_data_dep.to_dict() ) + if is_requested: + dependency.is_direct = True dependencies.append(dependency) dependency_mappings = [] @@ -1650,6 +1653,15 @@ def get_requires_dependencies(requires, default_scope='install', is_direct=True) extra = get_extra(req.marker) scope = extra or default_scope + extra_data = {} + if req.marker: + platform = get_python_version_os(req.marker) + if platform: + extra_data = platform + + extracted_requirement = None + if requirement: + extracted_requirement = requirement dependent_packages.append( models.DependentPackage( purl=purl.to_string(), @@ -1658,7 +1670,8 @@ def get_requires_dependencies(requires, default_scope='install', is_direct=True) is_optional=True if bool(extra) else False, is_resolved=is_resolved, is_direct=is_direct, - extracted_requirement=str(req), + extracted_requirement=extracted_requirement, + extra_data=extra_data, )) return dependent_packages @@ -1690,6 +1703,47 @@ def get_extra(marker): return value.value +def get_python_version_os(marker): + """ + Return the "python_version" or "os related values of a ``marker`` + requirement Marker or None. + """ + platform_data = {} + python_version_operators = ['<', '>=', '==', '<=', '<'] + + if not marker or not isinstance(marker, markers.Marker): + return platform_data + + marks = getattr(marker, '_markers', []) + + for mark in marks: + # filter for variable(extra) == value tuples of (Variable, Op, Value) + if not isinstance(mark, tuple) and not len(mark) == 3: + continue + + variable, operator, value = mark + + if ( + isinstance(variable, markers.Variable) + and variable.value == 'python_version' + and isinstance(operator, markers.Op) + and operator.value in python_version_operators + and isinstance(value, markers.Value) + ): + platform_data["python_version"] = f"{operator.value} {value.value}" + + if ( + isinstance(variable, markers.Variable) + and variable.value == 'sys_platform' + and isinstance(operator, markers.Op) + and operator.value == '==' + and isinstance(value, markers.Value) + ): + platform_data["sys_platform"] = f"{operator.value} {value.value}" + + return platform_data + + def get_dparse2_supported_file_name(file_name): """ Return the file_name if this is supported or None given a `file_name` diff --git a/tests/formattedcode/data/common/manifests-expected.json b/tests/formattedcode/data/common/manifests-expected.json index 4e1abbd413e..730bafeb8ae 100644 --- a/tests/formattedcode/data/common/manifests-expected.json +++ b/tests/formattedcode/data/common/manifests-expected.json @@ -1695,7 +1695,7 @@ "dependencies": [ { "purl": "pkg:pypi/numpy", - "extracted_requirement": "numpy>=1.6", + "extracted_requirement": ">=1.6", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1706,7 +1706,7 @@ }, { "purl": "pkg:pypi/pandas", - "extracted_requirement": "pandas>=0.18", + "extracted_requirement": ">=0.18", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1717,7 +1717,7 @@ }, { "purl": "pkg:pypi/deap", - "extracted_requirement": "deap", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -1728,7 +1728,7 @@ }, { "purl": "pkg:pypi/efel", - "extracted_requirement": "efel>=2.13", + "extracted_requirement": ">=2.13", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1739,7 +1739,7 @@ }, { "purl": "pkg:pypi/ipyparallel", - "extracted_requirement": "ipyparallel", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -1750,7 +1750,7 @@ }, { "purl": "pkg:pypi/pickleshare", - "extracted_requirement": "pickleshare>=0.7.3", + "extracted_requirement": ">=0.7.3", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1761,7 +1761,7 @@ }, { "purl": "pkg:pypi/jinja2", - "extracted_requirement": "Jinja2>=2.8", + "extracted_requirement": ">=2.8", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1772,7 +1772,7 @@ }, { "purl": "pkg:pypi/future", - "extracted_requirement": "future", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -1783,7 +1783,7 @@ }, { "purl": "pkg:pypi/pebble", - "extracted_requirement": "Pebble>=4.3.10", + "extracted_requirement": ">=4.3.10", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1794,7 +1794,7 @@ }, { "purl": "pkg:pypi/scoop", - "extracted_requirement": "scoop>=0.7", + "extracted_requirement": ">=0.7", "scope": "all", "is_runtime": true, "is_optional": false, @@ -1805,7 +1805,7 @@ }, { "purl": "pkg:pypi/scoop", - "extracted_requirement": "scoop>=0.7", + "extracted_requirement": ">=0.7", "scope": "scoop", "is_runtime": true, "is_optional": false, diff --git a/tests/formattedcode/data/common/manifests-expected.jsonlines b/tests/formattedcode/data/common/manifests-expected.jsonlines index 84b171f519a..960021483b9 100644 --- a/tests/formattedcode/data/common/manifests-expected.jsonlines +++ b/tests/formattedcode/data/common/manifests-expected.jsonlines @@ -12,7 +12,7 @@ "--package": 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.", - "output_format_version": "3.1.0", + "output_format_version": "3.2.0", "message": null, "errors": [], "warnings": [], @@ -24,7 +24,7 @@ "platform_version": "#122-Ubuntu SMP Thu May 23 07:48:21 UTC 2024", "python_version": "3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]" }, - "spdx_license_list_version": "3.23", + "spdx_license_list_version": "3.24", "files_count": 4 } } @@ -1765,7 +1765,7 @@ "dependencies": [ { "purl": "pkg:pypi/numpy", - "extracted_requirement": "numpy>=1.6", + "extracted_requirement": ">=1.6", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1776,7 +1776,7 @@ }, { "purl": "pkg:pypi/pandas", - "extracted_requirement": "pandas>=0.18", + "extracted_requirement": ">=0.18", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1787,7 +1787,7 @@ }, { "purl": "pkg:pypi/deap", - "extracted_requirement": "deap", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -1798,7 +1798,7 @@ }, { "purl": "pkg:pypi/efel", - "extracted_requirement": "efel>=2.13", + "extracted_requirement": ">=2.13", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1809,7 +1809,7 @@ }, { "purl": "pkg:pypi/ipyparallel", - "extracted_requirement": "ipyparallel", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -1820,7 +1820,7 @@ }, { "purl": "pkg:pypi/pickleshare", - "extracted_requirement": "pickleshare>=0.7.3", + "extracted_requirement": ">=0.7.3", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1831,7 +1831,7 @@ }, { "purl": "pkg:pypi/jinja2", - "extracted_requirement": "Jinja2>=2.8", + "extracted_requirement": ">=2.8", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1842,7 +1842,7 @@ }, { "purl": "pkg:pypi/future", - "extracted_requirement": "future", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -1853,7 +1853,7 @@ }, { "purl": "pkg:pypi/pebble", - "extracted_requirement": "Pebble>=4.3.10", + "extracted_requirement": ">=4.3.10", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1864,7 +1864,7 @@ }, { "purl": "pkg:pypi/scoop", - "extracted_requirement": "scoop>=0.7", + "extracted_requirement": ">=0.7", "scope": "all", "is_runtime": true, "is_optional": false, @@ -1875,7 +1875,7 @@ }, { "purl": "pkg:pypi/scoop", - "extracted_requirement": "scoop>=0.7", + "extracted_requirement": ">=0.7", "scope": "scoop", "is_runtime": true, "is_optional": false, diff --git a/tests/formattedcode/data/common/manifests-expected.yaml b/tests/formattedcode/data/common/manifests-expected.yaml index 1a2bdc5b5ff..5b74788a162 100644 --- a/tests/formattedcode/data/common/manifests-expected.yaml +++ b/tests/formattedcode/data/common/manifests-expected.yaml @@ -21,7 +21,7 @@ headers: for any legal advice. ScanCode is a free software code scanning tool from nexB Inc. and others. Visit https://github.com/nexB/scancode-toolkit/ for support and download. - output_format_version: 3.1.0 + output_format_version: 3.2.0 message: errors: [] warnings: [] @@ -32,7 +32,7 @@ headers: platform: Linux-5.15.0-112-generic-x86_64-with-glibc2.35 platform_version: '#122-Ubuntu SMP Thu May 23 07:48:21 UTC 2024' python_version: 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] - spdx_license_list_version: '3.23' + spdx_license_list_version: '3.24' files_count: 4 summary: declared_license_expression: apache-2.0 AND cddl-1.0 AND mit @@ -2563,7 +2563,7 @@ files: extra_data: {} dependencies: - purl: pkg:pypi/numpy - extracted_requirement: numpy>=1.6 + extracted_requirement: '>=1.6' scope: install is_runtime: yes is_optional: no @@ -2572,7 +2572,7 @@ files: resolved_package: {} extra_data: {} - purl: pkg:pypi/pandas - extracted_requirement: pandas>=0.18 + extracted_requirement: '>=0.18' scope: install is_runtime: yes is_optional: no @@ -2581,7 +2581,7 @@ files: resolved_package: {} extra_data: {} - purl: pkg:pypi/deap - extracted_requirement: deap + extracted_requirement: scope: install is_runtime: yes is_optional: no @@ -2590,7 +2590,7 @@ files: resolved_package: {} extra_data: {} - purl: pkg:pypi/efel - extracted_requirement: efel>=2.13 + extracted_requirement: '>=2.13' scope: install is_runtime: yes is_optional: no @@ -2599,7 +2599,7 @@ files: resolved_package: {} extra_data: {} - purl: pkg:pypi/ipyparallel - extracted_requirement: ipyparallel + extracted_requirement: scope: install is_runtime: yes is_optional: no @@ -2608,7 +2608,7 @@ files: resolved_package: {} extra_data: {} - purl: pkg:pypi/pickleshare - extracted_requirement: pickleshare>=0.7.3 + extracted_requirement: '>=0.7.3' scope: install is_runtime: yes is_optional: no @@ -2617,7 +2617,7 @@ files: resolved_package: {} extra_data: {} - purl: pkg:pypi/jinja2 - extracted_requirement: Jinja2>=2.8 + extracted_requirement: '>=2.8' scope: install is_runtime: yes is_optional: no @@ -2626,7 +2626,7 @@ files: resolved_package: {} extra_data: {} - purl: pkg:pypi/future - extracted_requirement: future + extracted_requirement: scope: install is_runtime: yes is_optional: no @@ -2635,7 +2635,7 @@ files: resolved_package: {} extra_data: {} - purl: pkg:pypi/pebble - extracted_requirement: Pebble>=4.3.10 + extracted_requirement: '>=4.3.10' scope: install is_runtime: yes is_optional: no @@ -2644,7 +2644,7 @@ files: resolved_package: {} extra_data: {} - purl: pkg:pypi/scoop - extracted_requirement: scoop>=0.7 + extracted_requirement: '>=0.7' scope: all is_runtime: yes is_optional: no @@ -2653,7 +2653,7 @@ files: resolved_package: {} extra_data: {} - purl: pkg:pypi/scoop - extracted_requirement: scoop>=0.7 + extracted_requirement: '>=0.7' scope: scoop is_runtime: yes is_optional: no diff --git a/tests/packagedcode/data/instance/python-package-instance-expected-with-uuid.json b/tests/packagedcode/data/instance/python-package-instance-expected-with-uuid.json index 9ade7ee6563..6b7c95f57c9 100644 --- a/tests/packagedcode/data/instance/python-package-instance-expected-with-uuid.json +++ b/tests/packagedcode/data/instance/python-package-instance-expected-with-uuid.json @@ -98,7 +98,7 @@ }, { "purl": "pkg:pypi/colorama", - "extracted_requirement": "colorama; platform_system == \"Windows\"", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -113,14 +113,16 @@ }, { "purl": "pkg:pypi/importlib-metadata", - "extracted_requirement": "importlib-metadata; python_version < \"3.8\"", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, - "extra_data": {}, + "extra_data": { + "python_version": "< 3.8" + }, "dependency_uid": "pkg:pypi/importlib-metadata?uuid=fixed-uid-done-for-testing-5642512d1758", "for_package_uid": "pkg:pypi/click@attr:%20click.__version__?uuid=fixed-uid-done-for-testing-5642512d1758", "datafile_path": "setup.py", @@ -287,7 +289,7 @@ "dependencies": [ { "purl": "pkg:pypi/colorama", - "extracted_requirement": "colorama; platform_system == \"Windows\"", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -298,14 +300,16 @@ }, { "purl": "pkg:pypi/importlib-metadata", - "extracted_requirement": "importlib-metadata; python_version < \"3.8\"", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, - "extra_data": {} + "extra_data": { + "python_version": "< 3.8" + } } ], "repository_homepage_url": "https://pypi.org/project/click", diff --git a/tests/packagedcode/data/instance/python-package-instance-expected.json b/tests/packagedcode/data/instance/python-package-instance-expected.json index 9ade7ee6563..6b7c95f57c9 100644 --- a/tests/packagedcode/data/instance/python-package-instance-expected.json +++ b/tests/packagedcode/data/instance/python-package-instance-expected.json @@ -98,7 +98,7 @@ }, { "purl": "pkg:pypi/colorama", - "extracted_requirement": "colorama; platform_system == \"Windows\"", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -113,14 +113,16 @@ }, { "purl": "pkg:pypi/importlib-metadata", - "extracted_requirement": "importlib-metadata; python_version < \"3.8\"", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, - "extra_data": {}, + "extra_data": { + "python_version": "< 3.8" + }, "dependency_uid": "pkg:pypi/importlib-metadata?uuid=fixed-uid-done-for-testing-5642512d1758", "for_package_uid": "pkg:pypi/click@attr:%20click.__version__?uuid=fixed-uid-done-for-testing-5642512d1758", "datafile_path": "setup.py", @@ -287,7 +289,7 @@ "dependencies": [ { "purl": "pkg:pypi/colorama", - "extracted_requirement": "colorama; platform_system == \"Windows\"", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -298,14 +300,16 @@ }, { "purl": "pkg:pypi/importlib-metadata", - "extracted_requirement": "importlib-metadata; python_version < \"3.8\"", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, - "extra_data": {} + "extra_data": { + "python_version": "< 3.8" + } } ], "repository_homepage_url": "https://pypi.org/project/click", diff --git a/tests/packagedcode/data/instance/python-package-instance-with-license-expected.json b/tests/packagedcode/data/instance/python-package-instance-with-license-expected.json index ebeb0ffe2b5..573c9c12da8 100644 --- a/tests/packagedcode/data/instance/python-package-instance-with-license-expected.json +++ b/tests/packagedcode/data/instance/python-package-instance-with-license-expected.json @@ -115,7 +115,7 @@ }, { "purl": "pkg:pypi/colorama", - "extracted_requirement": "colorama; platform_system == \"Windows\"", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -130,14 +130,16 @@ }, { "purl": "pkg:pypi/importlib-metadata", - "extracted_requirement": "importlib-metadata; python_version < \"3.8\"", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, - "extra_data": {}, + "extra_data": { + "python_version": "< 3.8" + }, "dependency_uid": "pkg:pypi/importlib-metadata?uuid=fixed-uid-done-for-testing-5642512d1758", "for_package_uid": "pkg:pypi/click@attr:%20click.__version__?uuid=fixed-uid-done-for-testing-5642512d1758", "datafile_path": "setup.py", @@ -569,7 +571,7 @@ "dependencies": [ { "purl": "pkg:pypi/colorama", - "extracted_requirement": "colorama; platform_system == \"Windows\"", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -580,14 +582,16 @@ }, { "purl": "pkg:pypi/importlib-metadata", - "extracted_requirement": "importlib-metadata; python_version < \"3.8\"", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, - "extra_data": {} + "extra_data": { + "python_version": "< 3.8" + } } ], "repository_homepage_url": "https://pypi.org/project/click", diff --git a/tests/packagedcode/data/license_detection/reference-to-package/paddlenlp.expected.json b/tests/packagedcode/data/license_detection/reference-to-package/paddlenlp.expected.json index e70de33ab2d..6489f14f0f8 100644 --- a/tests/packagedcode/data/license_detection/reference-to-package/paddlenlp.expected.json +++ b/tests/packagedcode/data/license_detection/reference-to-package/paddlenlp.expected.json @@ -373,7 +373,7 @@ }, { "purl": "pkg:pypi/cython", - "extracted_requirement": "cython", + "extracted_requirement": null, "scope": "setup", "is_runtime": true, "is_optional": false, @@ -388,7 +388,7 @@ }, { "purl": "pkg:pypi/numpy", - "extracted_requirement": "numpy", + "extracted_requirement": null, "scope": "setup", "is_runtime": true, "is_optional": false, @@ -1723,7 +1723,7 @@ "dependencies": [ { "purl": "pkg:pypi/cython", - "extracted_requirement": "cython", + "extracted_requirement": null, "scope": "setup", "is_runtime": true, "is_optional": false, @@ -1734,7 +1734,7 @@ }, { "purl": "pkg:pypi/numpy", - "extracted_requirement": "numpy", + "extracted_requirement": null, "scope": "setup", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/archive/commoncode-21.5.12-py3.9.egg-expected.json b/tests/packagedcode/data/pypi/archive/commoncode-21.5.12-py3.9.egg-expected.json index 21197d4dc0b..d533c15044d 100644 --- a/tests/packagedcode/data/pypi/archive/commoncode-21.5.12-py3.9.egg-expected.json +++ b/tests/packagedcode/data/pypi/archive/commoncode-21.5.12-py3.9.egg-expected.json @@ -98,7 +98,7 @@ "dependencies": [ { "purl": "pkg:pypi/attrs", - "extracted_requirement": "attrs!=20.1.0,>=18.1", + "extracted_requirement": "!=20.1.0,>=18.1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -109,7 +109,7 @@ }, { "purl": "pkg:pypi/click", - "extracted_requirement": "click>=6.0.0", + "extracted_requirement": ">=6.0.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -120,7 +120,7 @@ }, { "purl": "pkg:pypi/text-unidecode", - "extracted_requirement": "text_unidecode>=1.0", + "extracted_requirement": ">=1.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -131,7 +131,7 @@ }, { "purl": "pkg:pypi/beautifulsoup4", - "extracted_requirement": "Beautifulsoup4<5.0.0,>=4.0.0", + "extracted_requirement": "<5.0.0,>=4.0.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -142,7 +142,7 @@ }, { "purl": "pkg:pypi/requests", - "extracted_requirement": "requests<3.0.0,>=2.7.0", + "extracted_requirement": "<3.0.0,>=2.7.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -153,7 +153,7 @@ }, { "purl": "pkg:pypi/intbitset", - "extracted_requirement": "intbitset<3.0,>=2.3.0", + "extracted_requirement": "<3.0,>=2.3.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -164,7 +164,7 @@ }, { "purl": "pkg:pypi/saneyaml", - "extracted_requirement": "saneyaml", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -175,18 +175,20 @@ }, { "purl": "pkg:pypi/typing", - "extracted_requirement": "typing<3.7,>=3.6; python_version < \"3.7\"", + "extracted_requirement": "<3.7,>=3.6", "scope": "install", "is_runtime": true, "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, - "extra_data": {} + "extra_data": { + "python_version": "< 3.7" + } }, { "purl": "pkg:pypi/sphinx", - "extracted_requirement": "Sphinx>=3.3.1; extra == \"docs\"", + "extracted_requirement": ">=3.3.1", "scope": "docs", "is_runtime": true, "is_optional": true, @@ -197,7 +199,7 @@ }, { "purl": "pkg:pypi/sphinx-rtd-theme", - "extracted_requirement": "sphinx-rtd-theme>=0.5.0; extra == \"docs\"", + "extracted_requirement": ">=0.5.0", "scope": "docs", "is_runtime": true, "is_optional": true, @@ -208,7 +210,7 @@ }, { "purl": "pkg:pypi/doc8", - "extracted_requirement": "doc8>=0.8.1; extra == \"docs\"", + "extracted_requirement": ">=0.8.1", "scope": "docs", "is_runtime": true, "is_optional": true, @@ -219,7 +221,7 @@ }, { "purl": "pkg:pypi/pytest", - "extracted_requirement": "pytest>=6; extra == \"testing\"", + "extracted_requirement": ">=6", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -230,7 +232,7 @@ }, { "purl": "pkg:pypi/pytest-xdist", - "extracted_requirement": "pytest-xdist>=2; extra == \"testing\"", + "extracted_requirement": ">=2", "scope": "testing", "is_runtime": true, "is_optional": true, diff --git a/tests/packagedcode/data/pypi/deplock/simple/pip-inspect.deplock b/tests/packagedcode/data/pypi/deplock/simple/pip-inspect.deplock new file mode 100644 index 00000000000..f5ec82701bd --- /dev/null +++ b/tests/packagedcode/data/pypi/deplock/simple/pip-inspect.deplock @@ -0,0 +1,99 @@ +{ + "version": "1", + "pip_version": "24.1", + "installed": [ + { + "metadata": { + "metadata_version": "2.1", + "name": "packaging", + "version": "21.0", + "platform": [ + "UNKNOWN" + ], + "summary": "Core utilities for Python packages", + "description_content_type": "text/x-rst", + "home_page": "https://github.com/pypa/packaging", + "author": "Donald Stufft and individual contributors", + "author_email": "donald@stufft.io", + "license": "BSD-2-Clause or Apache-2.0", + "requires_dist": [ + "pyparsing (>=2.0.2)" + ], + "requires_python": ">=3.6" + }, + "metadata_location": "/home/ayansinha/nexB/write_access/univers/venv/lib/python3.10/site-packages/packaging-21.0.dist-info", + "installer": "pip", + "requested": false + }, + { + "metadata": { + "metadata_version": "2.1", + "name": "univers", + "version": "0.0.0", + "summary": "A mostly universal library to parse and compare software package versions and version ranges. A companion to Package URLs.", + "description_content_type": "text/x-rst", + "home_page": "https://github.com/nexB/univers", + "author": "Shivam Sandbhor, nexB. Inc. and others", + "author_email": "info@aboutcode.org", + "license": "Apache-2.0 AND BSD-3-Clause AND MIT", + "requires_dist": [ + "attrs", + "packaging", + "semantic-version", + "semver; python_version < \"3.8\"" + ], + "requires_python": ">=3.7", + "provides_extra": [ + "docs", + "testing" + ] + }, + "metadata_location": "/home/ayansinha/nexB/write_access/univers/venv/lib/python3.10/site-packages/univers-0.0.0.dist-info", + "direct_url": { + "url": "file:///home/ayansinha/nexB/write_access/univers", + "dir_info": { + "editable": true + } + }, + "installer": "pip", + "requested": true + }, + { + "metadata": { + "metadata_version": "2.1", + "name": "setuptools", + "version": "70.1.0", + "summary": "Easily download, build, install, upgrade, and uninstall Python packages", + "description_content_type": "text/x-rst", + "keywords": [ + "CPAN", + "PyPI", + "distutils", + "eggs", + "package", + "management" + ], + "author_email": "Python Packaging Authority ", + "requires_dist": [ + "packaging >=23.2 ; extra == 'testing'" + ], + "requires_python": ">=3.8", + "project_url": [ + "Homepage, https://github.com/pypa/setuptools", + "Documentation, https://setuptools.pypa.io/", + "Changelog, https://setuptools.pypa.io/en/stable/history.html" + ], + "provides_extra": [ + "certs", + "docs", + "ssl", + "testing" + ], + "description": ".. |pypi-version| image:: https://img.shields.io/pypi/v/setuptools.svg\n :target: https://pypi.org/project/setuptools\n\n.. |py-version| image:: https://img.shields.io/pypi/pyversions/setuptools.svg\n\n.. |test-badge| image:: https://github.com/pypa/setuptools/actions/workflows/main.yml/badge.svg\n :target: https://github.com/pypa/setuptools/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. |ruff-badge| image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json\n :target: https://github.com/astral-sh/ruff\n :alt: Ruff\n\n.. |docs-badge| image:: https://img.shields.io/readthedocs/setuptools/latest.svg\n :target: https://setuptools.pypa.io\n\n.. |skeleton-badge| image:: https://img.shields.io/badge/skeleton-2024-informational\n :target: https://blog.jaraco.com/skeleton\n\n.. |codecov-badge| image:: https://img.shields.io/codecov/c/github/pypa/setuptools/master.svg?logo=codecov&logoColor=white\n :target: https://codecov.io/gh/pypa/setuptools\n\n.. |tidelift-badge| image:: https://tidelift.com/badges/github/pypa/setuptools?style=flat\n :target: https://tidelift.com/subscription/pkg/pypi-setuptools?utm_source=pypi-setuptools&utm_medium=readme\n\n.. |discord-badge| image:: https://img.shields.io/discord/803025117553754132\n :target: https://discord.com/channels/803025117553754132/815945031150993468\n :alt: Discord\n\n|pypi-version| |py-version| |test-badge| |ruff-badge| |docs-badge| |skeleton-badge| |codecov-badge| |discord-badge|\n\nSee the `Quickstart `_\nand the `User's Guide `_ for\ninstructions on how to use Setuptools.\n\nQuestions and comments should be directed to `GitHub Discussions\n`_.\nBug reports and especially tested patches may be\nsubmitted directly to the `bug tracker\n`_.\n\n\nCode of Conduct\n===============\n\nEveryone interacting in the setuptools project's codebases, issue trackers,\nchat rooms, and fora is expected to follow the\n`PSF Code of Conduct `_.\n\n\nFor Enterprise\n==============\n\nAvailable as part of the Tidelift Subscription.\n\nSetuptools and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.\n\n`Learn more `_.\n" + }, + "metadata_location": "/home/ayansinha/nexB/write_access/univers/venv/lib/python3.10/site-packages/setuptools-70.1.0.dist-info", + "installer": "pip", + "requested": true + } + ] +} diff --git a/tests/packagedcode/data/pypi/deplock/simple/pip-inspect.deplock-expected.json b/tests/packagedcode/data/pypi/deplock/simple/pip-inspect.deplock-expected.json new file mode 100644 index 00000000000..f1e09e1faf2 --- /dev/null +++ b/tests/packagedcode/data/pypi/deplock/simple/pip-inspect.deplock-expected.json @@ -0,0 +1,270 @@ +[ + { + "type": "pypi", + "namespace": null, + "name": "univers", + "version": "0.0.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "release_date": null, + "parties": [], + "keywords": null, + "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": "apache-2.0 AND bsd-new AND mit", + "declared_license_expression_spdx": "Apache-2.0 AND BSD-3-Clause AND MIT", + "license_detections": [ + { + "license_expression": "apache-2.0 AND bsd-new AND mit", + "license_expression_spdx": "Apache-2.0 AND BSD-3-Clause AND MIT", + "matches": [ + { + "license_expression": "apache-2.0 AND bsd-new AND mit", + "spdx_license_expression": "Apache-2.0 AND BSD-3-Clause AND MIT", + "from_file": null, + "start_line": 1, + "end_line": 1, + "matcher": "1-spdx-id", + "score": 100.0, + "matched_length": 9, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "spdx-license-identifier-apache_2_0_and_bsd_new_and_mit-5a0e0d1daea60cb9191d19fe5324c57e89cbcbf8", + "rule_url": null, + "matched_text": "Apache-2.0 AND BSD-3-Clause AND MIT" + } + ], + "identifier": "apache_2_0_and_bsd_new_and_mit-4d4f1034-453c-8cde-3ab0-bd35ddc243e6" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "Apache-2.0 AND BSD-3-Clause AND MIT", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": { + "pip_version": "24.1", + "inspect_version": "1" + }, + "dependencies": [ + { + "purl": "pkg:pypi/packaging@21.0", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": false, + "is_resolved": true, + "is_direct": true, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "packaging", + "version": "21.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "release_date": null, + "parties": [], + "keywords": null, + "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": "bsd-simplified OR apache-2.0", + "declared_license_expression_spdx": "BSD-2-Clause OR Apache-2.0", + "license_detections": [ + { + "license_expression": "bsd-simplified OR apache-2.0", + "license_expression_spdx": "BSD-2-Clause OR Apache-2.0", + "matches": [ + { + "license_expression": "bsd-simplified OR apache-2.0", + "spdx_license_expression": "BSD-2-Clause OR Apache-2.0", + "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-bsd_simplified_or_apache_2_0-4e6ba7864502b4956354d47c70173db3283d1005", + "rule_url": null, + "matched_text": "BSD-2-Clause or Apache-2.0" + } + ], + "identifier": "bsd_simplified_or_apache_2_0-dd30dee1-b8d2-187f-c9f9-69fd2ff5e39a" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "BSD-2-Clause or Apache-2.0", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [ + { + "purl": "pkg:pypi/pyparsing", + "extracted_requirement": ">=2.0.2", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null, + "datasource_id": "pypi_inspect_deplock", + "purl": "pkg:pypi/packaging@21.0" + }, + "extra_data": {} + }, + { + "purl": "pkg:pypi/setuptools@70.1.0", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": false, + "is_resolved": true, + "is_direct": true, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "setuptools", + "version": "70.1.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": ".. |pypi-version| image:: https://img.shields.io/pypi/v/setuptools.svg\n :target: https://pypi.org/project/setuptools\n\n.. |py-version| image:: https://img.shields.io/pypi/pyversions/setuptools.svg\n\n.. |test-badge| image:: https://github.com/pypa/setuptools/actions/workflows/main.yml/badge.svg\n :target: https://github.com/pypa/setuptools/actions?query=workflow%3A%22tests%22\n :alt: tests\n\n.. |ruff-badge| image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json\n :target: https://github.com/astral-sh/ruff\n :alt: Ruff\n\n.. |docs-badge| image:: https://img.shields.io/readthedocs/setuptools/latest.svg\n :target: https://setuptools.pypa.io\n\n.. |skeleton-badge| image:: https://img.shields.io/badge/skeleton-2024-informational\n :target: https://blog.jaraco.com/skeleton\n\n.. |codecov-badge| image:: https://img.shields.io/codecov/c/github/pypa/setuptools/master.svg?logo=codecov&logoColor=white\n :target: https://codecov.io/gh/pypa/setuptools\n\n.. |tidelift-badge| image:: https://tidelift.com/badges/github/pypa/setuptools?style=flat\n :target: https://tidelift.com/subscription/pkg/pypi-setuptools?utm_source=pypi-setuptools&utm_medium=readme\n\n.. |discord-badge| image:: https://img.shields.io/discord/803025117553754132\n :target: https://discord.com/channels/803025117553754132/815945031150993468\n :alt: Discord\n\n|pypi-version| |py-version| |test-badge| |ruff-badge| |docs-badge| |skeleton-badge| |codecov-badge| |discord-badge|\n\nSee the `Quickstart `_\nand the `User's Guide `_ for\ninstructions on how to use Setuptools.\n\nQuestions and comments should be directed to `GitHub Discussions\n`_.\nBug reports and especially tested patches may be\nsubmitted directly to the `bug tracker\n`_.\n\n\nCode of Conduct\n===============\n\nEveryone interacting in the setuptools project's codebases, issue trackers,\nchat rooms, and fora is expected to follow the\n`PSF Code of Conduct `_.\n\n\nFor Enterprise\n==============\n\nAvailable as part of the Tidelift Subscription.\n\nSetuptools and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.\n\n`Learn more `_.\n", + "release_date": null, + "parties": [], + "keywords": [ + "CPAN", + "PyPI", + "distutils", + "eggs", + "package", + "management" + ], + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [ + { + "purl": "pkg:pypi/packaging", + "extracted_requirement": ">=23.2", + "scope": "testing", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null, + "datasource_id": "pypi_inspect_deplock", + "purl": "pkg:pypi/setuptools@70.1.0" + }, + "extra_data": {} + }, + { + "purl": "pkg:pypi/attrs", + "extracted_requirement": null, + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/semantic-version", + "extracted_requirement": null, + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/semver", + "extracted_requirement": null, + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": { + "python_version": "< 3.8" + } + } + ], + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null, + "datasource_id": "pypi_inspect_deplock", + "purl": "pkg:pypi/univers@0.0.0" + } +] \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/deplock/univers/pip-inspect.deplock-expected.json b/tests/packagedcode/data/pypi/deplock/univers/pip-inspect.deplock-expected.json index 24e4a613f73..c3b45d68554 100644 --- a/tests/packagedcode/data/pypi/deplock/univers/pip-inspect.deplock-expected.json +++ b/tests/packagedcode/data/pypi/deplock/univers/pip-inspect.deplock-expected.json @@ -155,7 +155,7 @@ "dependencies": [ { "purl": "pkg:pypi/coverage", - "extracted_requirement": "coverage[toml]>=5.0.2; extra == \"dev\"", + "extracted_requirement": ">=5.0.2", "scope": "dev", "is_runtime": true, "is_optional": true, @@ -166,7 +166,7 @@ }, { "purl": "pkg:pypi/hypothesis", - "extracted_requirement": "hypothesis; extra == \"dev\"", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": true, @@ -177,7 +177,7 @@ }, { "purl": "pkg:pypi/pympler", - "extracted_requirement": "pympler; extra == \"dev\"", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": true, @@ -188,7 +188,7 @@ }, { "purl": "pkg:pypi/pytest", - "extracted_requirement": "pytest>=4.3.0; extra == \"dev\"", + "extracted_requirement": ">=4.3.0", "scope": "dev", "is_runtime": true, "is_optional": true, @@ -199,7 +199,7 @@ }, { "purl": "pkg:pypi/six", - "extracted_requirement": "six; extra == \"dev\"", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": true, @@ -210,7 +210,7 @@ }, { "purl": "pkg:pypi/mypy", - "extracted_requirement": "mypy; extra == \"dev\"", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": true, @@ -221,7 +221,7 @@ }, { "purl": "pkg:pypi/pytest-mypy-plugins", - "extracted_requirement": "pytest-mypy-plugins; extra == \"dev\"", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": true, @@ -232,7 +232,7 @@ }, { "purl": "pkg:pypi/zope-interface", - "extracted_requirement": "zope.interface; extra == \"dev\"", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": true, @@ -243,7 +243,7 @@ }, { "purl": "pkg:pypi/furo", - "extracted_requirement": "furo; extra == \"dev\"", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": true, @@ -254,7 +254,7 @@ }, { "purl": "pkg:pypi/sphinx", - "extracted_requirement": "sphinx; extra == \"dev\"", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": true, @@ -265,7 +265,7 @@ }, { "purl": "pkg:pypi/sphinx-notfound-page", - "extracted_requirement": "sphinx-notfound-page; extra == \"dev\"", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": true, @@ -276,7 +276,7 @@ }, { "purl": "pkg:pypi/pre-commit", - "extracted_requirement": "pre-commit; extra == \"dev\"", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": true, @@ -287,7 +287,7 @@ }, { "purl": "pkg:pypi/furo", - "extracted_requirement": "furo; extra == \"docs\"", + "extracted_requirement": null, "scope": "docs", "is_runtime": true, "is_optional": true, @@ -298,7 +298,7 @@ }, { "purl": "pkg:pypi/sphinx", - "extracted_requirement": "sphinx; extra == \"docs\"", + "extracted_requirement": null, "scope": "docs", "is_runtime": true, "is_optional": true, @@ -309,7 +309,7 @@ }, { "purl": "pkg:pypi/zope-interface", - "extracted_requirement": "zope.interface; extra == \"docs\"", + "extracted_requirement": null, "scope": "docs", "is_runtime": true, "is_optional": true, @@ -320,7 +320,7 @@ }, { "purl": "pkg:pypi/sphinx-notfound-page", - "extracted_requirement": "sphinx-notfound-page; extra == \"docs\"", + "extracted_requirement": null, "scope": "docs", "is_runtime": true, "is_optional": true, @@ -331,7 +331,7 @@ }, { "purl": "pkg:pypi/coverage", - "extracted_requirement": "coverage[toml]>=5.0.2; extra == \"tests\"", + "extracted_requirement": ">=5.0.2", "scope": "tests", "is_runtime": true, "is_optional": true, @@ -342,7 +342,7 @@ }, { "purl": "pkg:pypi/hypothesis", - "extracted_requirement": "hypothesis; extra == \"tests\"", + "extracted_requirement": null, "scope": "tests", "is_runtime": true, "is_optional": true, @@ -353,7 +353,7 @@ }, { "purl": "pkg:pypi/pympler", - "extracted_requirement": "pympler; extra == \"tests\"", + "extracted_requirement": null, "scope": "tests", "is_runtime": true, "is_optional": true, @@ -364,7 +364,7 @@ }, { "purl": "pkg:pypi/pytest", - "extracted_requirement": "pytest>=4.3.0; extra == \"tests\"", + "extracted_requirement": ">=4.3.0", "scope": "tests", "is_runtime": true, "is_optional": true, @@ -375,7 +375,7 @@ }, { "purl": "pkg:pypi/six", - "extracted_requirement": "six; extra == \"tests\"", + "extracted_requirement": null, "scope": "tests", "is_runtime": true, "is_optional": true, @@ -386,7 +386,7 @@ }, { "purl": "pkg:pypi/mypy", - "extracted_requirement": "mypy; extra == \"tests\"", + "extracted_requirement": null, "scope": "tests", "is_runtime": true, "is_optional": true, @@ -397,7 +397,7 @@ }, { "purl": "pkg:pypi/pytest-mypy-plugins", - "extracted_requirement": "pytest-mypy-plugins; extra == \"tests\"", + "extracted_requirement": null, "scope": "tests", "is_runtime": true, "is_optional": true, @@ -408,7 +408,7 @@ }, { "purl": "pkg:pypi/zope-interface", - "extracted_requirement": "zope.interface; extra == \"tests\"", + "extracted_requirement": null, "scope": "tests", "is_runtime": true, "is_optional": true, @@ -419,7 +419,7 @@ }, { "purl": "pkg:pypi/coverage", - "extracted_requirement": "coverage[toml]>=5.0.2; extra == \"tests_no_zope\"", + "extracted_requirement": ">=5.0.2", "scope": "tests_no_zope", "is_runtime": true, "is_optional": true, @@ -430,7 +430,7 @@ }, { "purl": "pkg:pypi/hypothesis", - "extracted_requirement": "hypothesis; extra == \"tests_no_zope\"", + "extracted_requirement": null, "scope": "tests_no_zope", "is_runtime": true, "is_optional": true, @@ -441,7 +441,7 @@ }, { "purl": "pkg:pypi/pympler", - "extracted_requirement": "pympler; extra == \"tests_no_zope\"", + "extracted_requirement": null, "scope": "tests_no_zope", "is_runtime": true, "is_optional": true, @@ -452,7 +452,7 @@ }, { "purl": "pkg:pypi/pytest", - "extracted_requirement": "pytest>=4.3.0; extra == \"tests_no_zope\"", + "extracted_requirement": ">=4.3.0", "scope": "tests_no_zope", "is_runtime": true, "is_optional": true, @@ -463,7 +463,7 @@ }, { "purl": "pkg:pypi/six", - "extracted_requirement": "six; extra == \"tests_no_zope\"", + "extracted_requirement": null, "scope": "tests_no_zope", "is_runtime": true, "is_optional": true, @@ -474,7 +474,7 @@ }, { "purl": "pkg:pypi/mypy", - "extracted_requirement": "mypy; extra == \"tests_no_zope\"", + "extracted_requirement": null, "scope": "tests_no_zope", "is_runtime": true, "is_optional": true, @@ -485,7 +485,7 @@ }, { "purl": "pkg:pypi/pytest-mypy-plugins", - "extracted_requirement": "pytest-mypy-plugins; extra == \"tests_no_zope\"", + "extracted_requirement": null, "scope": "tests_no_zope", "is_runtime": true, "is_optional": true, @@ -574,7 +574,7 @@ "dependencies": [ { "purl": "pkg:pypi/pyparsing", - "extracted_requirement": "pyparsing>=2.0.2", + "extracted_requirement": ">=2.0.2", "scope": "install", "is_runtime": true, "is_optional": false, @@ -599,7 +599,7 @@ "is_runtime": true, "is_optional": false, "is_resolved": true, - "is_direct": false, + "is_direct": true, "resolved_package": { "type": "pypi", "namespace": null, @@ -911,7 +911,7 @@ "is_runtime": true, "is_optional": false, "is_resolved": true, - "is_direct": false, + "is_direct": true, "resolved_package": { "type": "pypi", "namespace": null, @@ -959,7 +959,7 @@ "dependencies": [ { "purl": "pkg:pypi/sphinx", - "extracted_requirement": "sphinx>=3.5; extra == \"docs\"", + "extracted_requirement": ">=3.5", "scope": "docs", "is_runtime": true, "is_optional": true, @@ -970,7 +970,7 @@ }, { "purl": "pkg:pypi/jaraco-packaging", - "extracted_requirement": "jaraco.packaging>=9.3; extra == \"docs\"", + "extracted_requirement": ">=9.3", "scope": "docs", "is_runtime": true, "is_optional": true, @@ -981,7 +981,7 @@ }, { "purl": "pkg:pypi/rst-linker", - "extracted_requirement": "rst.linker>=1.9; extra == \"docs\"", + "extracted_requirement": ">=1.9", "scope": "docs", "is_runtime": true, "is_optional": true, @@ -992,7 +992,7 @@ }, { "purl": "pkg:pypi/furo", - "extracted_requirement": "furo; extra == \"docs\"", + "extracted_requirement": null, "scope": "docs", "is_runtime": true, "is_optional": true, @@ -1003,7 +1003,7 @@ }, { "purl": "pkg:pypi/sphinx-lint", - "extracted_requirement": "sphinx-lint; extra == \"docs\"", + "extracted_requirement": null, "scope": "docs", "is_runtime": true, "is_optional": true, @@ -1014,7 +1014,7 @@ }, { "purl": "pkg:pypi/jaraco-tidelift", - "extracted_requirement": "jaraco.tidelift>=1.4; extra == \"docs\"", + "extracted_requirement": ">=1.4", "scope": "docs", "is_runtime": true, "is_optional": true, @@ -1025,7 +1025,7 @@ }, { "purl": "pkg:pypi/pygments-github-lexers@0.0.5", - "extracted_requirement": "pygments-github-lexers==0.0.5; extra == \"docs\"", + "extracted_requirement": "==0.0.5", "scope": "docs", "is_runtime": true, "is_optional": true, @@ -1036,7 +1036,7 @@ }, { "purl": "pkg:pypi/sphinx-favicon", - "extracted_requirement": "sphinx-favicon; extra == \"docs\"", + "extracted_requirement": null, "scope": "docs", "is_runtime": true, "is_optional": true, @@ -1047,7 +1047,7 @@ }, { "purl": "pkg:pypi/sphinx-inline-tabs", - "extracted_requirement": "sphinx-inline-tabs; extra == \"docs\"", + "extracted_requirement": null, "scope": "docs", "is_runtime": true, "is_optional": true, @@ -1058,7 +1058,7 @@ }, { "purl": "pkg:pypi/sphinx-reredirects", - "extracted_requirement": "sphinx-reredirects; extra == \"docs\"", + "extracted_requirement": null, "scope": "docs", "is_runtime": true, "is_optional": true, @@ -1069,7 +1069,7 @@ }, { "purl": "pkg:pypi/sphinxcontrib-towncrier", - "extracted_requirement": "sphinxcontrib-towncrier; extra == \"docs\"", + "extracted_requirement": null, "scope": "docs", "is_runtime": true, "is_optional": true, @@ -1080,7 +1080,7 @@ }, { "purl": "pkg:pypi/sphinx-notfound-page", - "extracted_requirement": "sphinx-notfound-page<2,>=1; extra == \"docs\"", + "extracted_requirement": "<2,>=1", "scope": "docs", "is_runtime": true, "is_optional": true, @@ -1091,7 +1091,7 @@ }, { "purl": "pkg:pypi/pyproject-hooks", - "extracted_requirement": "pyproject-hooks!=1.1; extra == \"docs\"", + "extracted_requirement": "!=1.1", "scope": "docs", "is_runtime": true, "is_optional": true, @@ -1102,7 +1102,7 @@ }, { "purl": "pkg:pypi/pytest", - "extracted_requirement": "pytest!=8.1.1,>=6; extra == \"testing\"", + "extracted_requirement": "!=8.1.1,>=6", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1113,7 +1113,7 @@ }, { "purl": "pkg:pypi/pytest-checkdocs", - "extracted_requirement": "pytest-checkdocs>=2.4; extra == \"testing\"", + "extracted_requirement": ">=2.4", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1124,7 +1124,7 @@ }, { "purl": "pkg:pypi/pytest-mypy", - "extracted_requirement": "pytest-mypy; extra == \"testing\"", + "extracted_requirement": null, "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1135,7 +1135,7 @@ }, { "purl": "pkg:pypi/pytest-enabler", - "extracted_requirement": "pytest-enabler>=2.2; extra == \"testing\"", + "extracted_requirement": ">=2.2", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1146,7 +1146,7 @@ }, { "purl": "pkg:pypi/virtualenv", - "extracted_requirement": "virtualenv>=13.0.0; extra == \"testing\"", + "extracted_requirement": ">=13.0.0", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1157,7 +1157,7 @@ }, { "purl": "pkg:pypi/wheel", - "extracted_requirement": "wheel; extra == \"testing\"", + "extracted_requirement": null, "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1168,7 +1168,7 @@ }, { "purl": "pkg:pypi/pip", - "extracted_requirement": "pip>=19.1; extra == \"testing\"", + "extracted_requirement": ">=19.1", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1179,7 +1179,7 @@ }, { "purl": "pkg:pypi/packaging", - "extracted_requirement": "packaging>=23.2; extra == \"testing\"", + "extracted_requirement": ">=23.2", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1190,7 +1190,7 @@ }, { "purl": "pkg:pypi/jaraco-envs", - "extracted_requirement": "jaraco.envs>=2.2; extra == \"testing\"", + "extracted_requirement": ">=2.2", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1201,7 +1201,7 @@ }, { "purl": "pkg:pypi/pytest-xdist", - "extracted_requirement": "pytest-xdist>=3; extra == \"testing\"", + "extracted_requirement": ">=3", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1212,7 +1212,7 @@ }, { "purl": "pkg:pypi/jaraco-path", - "extracted_requirement": "jaraco.path>=3.2.0; extra == \"testing\"", + "extracted_requirement": ">=3.2.0", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1223,7 +1223,7 @@ }, { "purl": "pkg:pypi/build", - "extracted_requirement": "build[virtualenv]>=1.0.3; extra == \"testing\"", + "extracted_requirement": ">=1.0.3", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1234,7 +1234,7 @@ }, { "purl": "pkg:pypi/filelock", - "extracted_requirement": "filelock>=3.4.0; extra == \"testing\"", + "extracted_requirement": ">=3.4.0", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1245,7 +1245,7 @@ }, { "purl": "pkg:pypi/ini2toml", - "extracted_requirement": "ini2toml[lite]>=0.14; extra == \"testing\"", + "extracted_requirement": ">=0.14", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1256,7 +1256,7 @@ }, { "purl": "pkg:pypi/tomli-w", - "extracted_requirement": "tomli-w>=1.0.0; extra == \"testing\"", + "extracted_requirement": ">=1.0.0", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1267,7 +1267,7 @@ }, { "purl": "pkg:pypi/pytest-timeout", - "extracted_requirement": "pytest-timeout; extra == \"testing\"", + "extracted_requirement": null, "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1278,7 +1278,7 @@ }, { "purl": "pkg:pypi/pytest-home", - "extracted_requirement": "pytest-home>=0.5; extra == \"testing\"", + "extracted_requirement": ">=0.5", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1289,7 +1289,7 @@ }, { "purl": "pkg:pypi/mypy@1.10.0", - "extracted_requirement": "mypy==1.10.0; extra == \"testing\"", + "extracted_requirement": "==1.10.0", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1300,7 +1300,7 @@ }, { "purl": "pkg:pypi/tomli", - "extracted_requirement": "tomli; extra == \"testing\"", + "extracted_requirement": null, "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1311,7 +1311,7 @@ }, { "purl": "pkg:pypi/importlib-metadata", - "extracted_requirement": "importlib-metadata; extra == \"testing\"", + "extracted_requirement": null, "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1322,7 +1322,7 @@ }, { "purl": "pkg:pypi/pytest-subprocess", - "extracted_requirement": "pytest-subprocess; extra == \"testing\"", + "extracted_requirement": null, "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1333,7 +1333,7 @@ }, { "purl": "pkg:pypi/pyproject-hooks", - "extracted_requirement": "pyproject-hooks!=1.1; extra == \"testing\"", + "extracted_requirement": "!=1.1", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1344,7 +1344,7 @@ }, { "purl": "pkg:pypi/jaraco-test", - "extracted_requirement": "jaraco.test; extra == \"testing\"", + "extracted_requirement": null, "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1355,7 +1355,7 @@ }, { "purl": "pkg:pypi/pytest-cov", - "extracted_requirement": "pytest-cov; platform_python_implementation != \"PyPy\" and extra == \"testing\"", + "extracted_requirement": null, "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1366,7 +1366,7 @@ }, { "purl": "pkg:pypi/jaraco-develop", - "extracted_requirement": "jaraco.develop>=7.21; (python_version >= \"3.9\" and sys_platform != \"cygwin\") and extra == \"testing\"", + "extracted_requirement": ">=7.21", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1377,7 +1377,7 @@ }, { "purl": "pkg:pypi/pytest-ruff", - "extracted_requirement": "pytest-ruff>=0.3.2; sys_platform != \"cygwin\" and extra == \"testing\"", + "extracted_requirement": ">=0.3.2", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1388,7 +1388,7 @@ }, { "purl": "pkg:pypi/pytest-perf", - "extracted_requirement": "pytest-perf; sys_platform != \"cygwin\" and extra == \"testing\"", + "extracted_requirement": null, "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1413,7 +1413,7 @@ "is_runtime": true, "is_optional": false, "is_resolved": true, - "is_direct": false, + "is_direct": true, "resolved_package": { "type": "pypi", "namespace": null, @@ -1457,7 +1457,7 @@ "dependencies": [ { "purl": "pkg:pypi/pytest", - "extracted_requirement": "pytest>=6.0.0; extra == \"test\"", + "extracted_requirement": ">=6.0.0", "scope": "test", "is_runtime": true, "is_optional": true, @@ -1468,7 +1468,7 @@ }, { "purl": "pkg:pypi/setuptools", - "extracted_requirement": "setuptools>=65; extra == \"test\"", + "extracted_requirement": ">=65", "scope": "test", "is_runtime": true, "is_optional": true, @@ -1488,7 +1488,7 @@ }, { "purl": "pkg:pypi/sphinx", - "extracted_requirement": "Sphinx>=5.0.2; extra == \"docs\"", + "extracted_requirement": ">=5.0.2", "scope": "docs", "is_runtime": true, "is_optional": true, @@ -1499,7 +1499,7 @@ }, { "purl": "pkg:pypi/sphinx-rtd-theme", - "extracted_requirement": "sphinx-rtd-theme>=1.0.0; extra == \"docs\"", + "extracted_requirement": ">=1.0.0", "scope": "docs", "is_runtime": true, "is_optional": true, @@ -1510,7 +1510,7 @@ }, { "purl": "pkg:pypi/sphinx-reredirects", - "extracted_requirement": "sphinx-reredirects>=0.1.2; extra == \"docs\"", + "extracted_requirement": ">=0.1.2", "scope": "docs", "is_runtime": true, "is_optional": true, @@ -1521,7 +1521,7 @@ }, { "purl": "pkg:pypi/doc8", - "extracted_requirement": "doc8>=0.11.2; extra == \"docs\"", + "extracted_requirement": ">=0.11.2", "scope": "docs", "is_runtime": true, "is_optional": true, @@ -1532,7 +1532,7 @@ }, { "purl": "pkg:pypi/pytest", - "extracted_requirement": "pytest!=7.0.0,>=6; extra == \"testing\"", + "extracted_requirement": "!=7.0.0,>=6", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1543,7 +1543,7 @@ }, { "purl": "pkg:pypi/pytest-xdist", - "extracted_requirement": "pytest-xdist>=2; extra == \"testing\"", + "extracted_requirement": ">=2", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1554,7 +1554,7 @@ }, { "purl": "pkg:pypi/aboutcode-toolkit", - "extracted_requirement": "aboutcode-toolkit>=7.0.2; extra == \"testing\"", + "extracted_requirement": ">=7.0.2", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1565,7 +1565,7 @@ }, { "purl": "pkg:pypi/pycodestyle", - "extracted_requirement": "pycodestyle>=2.8.0; extra == \"testing\"", + "extracted_requirement": ">=2.8.0", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1576,7 +1576,7 @@ }, { "purl": "pkg:pypi/twine", - "extracted_requirement": "twine; extra == \"testing\"", + "extracted_requirement": null, "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1587,7 +1587,7 @@ }, { "purl": "pkg:pypi/black", - "extracted_requirement": "black; extra == \"testing\"", + "extracted_requirement": null, "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1598,7 +1598,7 @@ }, { "purl": "pkg:pypi/commoncode", - "extracted_requirement": "commoncode; extra == \"testing\"", + "extracted_requirement": null, "scope": "testing", "is_runtime": true, "is_optional": true, @@ -1609,7 +1609,7 @@ }, { "purl": "pkg:pypi/isort", - "extracted_requirement": "isort>=5.10.1; extra == \"testing\"", + "extracted_requirement": ">=5.10.1", "scope": "testing", "is_runtime": true, "is_optional": true, diff --git a/tests/packagedcode/data/pypi/develop/scancode_toolkit.egg-info-expected.json b/tests/packagedcode/data/pypi/develop/scancode_toolkit.egg-info-expected.json index 871740c6179..c3eee696694 100644 --- a/tests/packagedcode/data/pypi/develop/scancode_toolkit.egg-info-expected.json +++ b/tests/packagedcode/data/pypi/develop/scancode_toolkit.egg-info-expected.json @@ -1108,7 +1108,7 @@ "dependencies": [ { "purl": "pkg:pypi/attrs", - "extracted_requirement": "attrs!=20.1.0,>=18.1", + "extracted_requirement": "!=20.1.0,>=18.1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1119,7 +1119,7 @@ }, { "purl": "pkg:pypi/beautifulsoup4", - "extracted_requirement": "Beautifulsoup4<5.0.0,>=4.0.0", + "extracted_requirement": "<5.0.0,>=4.0.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1130,7 +1130,7 @@ }, { "purl": "pkg:pypi/bitarray", - "extracted_requirement": "bitarray<1.0.0,>=0.8.1", + "extracted_requirement": "<1.0.0,>=0.8.1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1141,7 +1141,7 @@ }, { "purl": "pkg:pypi/boolean-py", - "extracted_requirement": "boolean.py<4.0,>=3.5", + "extracted_requirement": "<4.0,>=3.5", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1152,7 +1152,7 @@ }, { "purl": "pkg:pypi/chardet", - "extracted_requirement": "chardet>=3.0.0", + "extracted_requirement": ">=3.0.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1163,7 +1163,7 @@ }, { "purl": "pkg:pypi/click", - "extracted_requirement": "click!=7.0,>=6.7", + "extracted_requirement": "!=7.0,>=6.7", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1174,7 +1174,7 @@ }, { "purl": "pkg:pypi/colorama", - "extracted_requirement": "colorama>=0.3.9", + "extracted_requirement": ">=0.3.9", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1185,7 +1185,7 @@ }, { "purl": "pkg:pypi/commoncode", - "extracted_requirement": "commoncode>=21.1.21", + "extracted_requirement": ">=21.1.21", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1196,7 +1196,7 @@ }, { "purl": "pkg:pypi/debian-inspector", - "extracted_requirement": "debian-inspector>=0.9.10", + "extracted_requirement": ">=0.9.10", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1207,7 +1207,7 @@ }, { "purl": "pkg:pypi/dparse", - "extracted_requirement": "dparse>=0.5.1", + "extracted_requirement": ">=0.5.1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1218,7 +1218,7 @@ }, { "purl": "pkg:pypi/fasteners", - "extracted_requirement": "fasteners", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -1229,7 +1229,7 @@ }, { "purl": "pkg:pypi/fingerprints", - "extracted_requirement": "fingerprints>=0.6.0", + "extracted_requirement": ">=0.6.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1240,7 +1240,7 @@ }, { "purl": "pkg:pypi/ftfy", - "extracted_requirement": "ftfy<5.0.0", + "extracted_requirement": "<5.0.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1251,7 +1251,7 @@ }, { "purl": "pkg:pypi/gemfileparser", - "extracted_requirement": "gemfileparser>=0.7.0", + "extracted_requirement": ">=0.7.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1262,7 +1262,7 @@ }, { "purl": "pkg:pypi/html5lib", - "extracted_requirement": "html5lib", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -1273,7 +1273,7 @@ }, { "purl": "pkg:pypi/intbitset", - "extracted_requirement": "intbitset<3.0,>=2.3.0", + "extracted_requirement": "<3.0,>=2.3.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1284,7 +1284,7 @@ }, { "purl": "pkg:pypi/jaraco-functools", - "extracted_requirement": "jaraco.functools", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -1295,7 +1295,7 @@ }, { "purl": "pkg:pypi/javaproperties", - "extracted_requirement": "javaproperties>=0.5", + "extracted_requirement": ">=0.5", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1306,7 +1306,7 @@ }, { "purl": "pkg:pypi/jinja2", - "extracted_requirement": "jinja2<3.0.0,>=2.7.0", + "extracted_requirement": "<3.0.0,>=2.7.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1317,7 +1317,7 @@ }, { "purl": "pkg:pypi/jsonstreams", - "extracted_requirement": "jsonstreams>=0.5.0", + "extracted_requirement": ">=0.5.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1328,7 +1328,7 @@ }, { "purl": "pkg:pypi/license-expression", - "extracted_requirement": "license_expression>=0.99", + "extracted_requirement": ">=0.99", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1339,7 +1339,7 @@ }, { "purl": "pkg:pypi/lxml", - "extracted_requirement": "lxml<5.0.0,>=4.0.0", + "extracted_requirement": "<5.0.0,>=4.0.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1350,7 +1350,7 @@ }, { "purl": "pkg:pypi/markupsafe", - "extracted_requirement": "MarkupSafe>=0.23", + "extracted_requirement": ">=0.23", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1361,7 +1361,7 @@ }, { "purl": "pkg:pypi/nltk", - "extracted_requirement": "nltk!=3.6,<4.0,>=3.2", + "extracted_requirement": "!=3.6,<4.0,>=3.2", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1372,7 +1372,7 @@ }, { "purl": "pkg:pypi/packageurl-python", - "extracted_requirement": "packageurl_python>=0.7.0", + "extracted_requirement": ">=0.7.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1383,7 +1383,7 @@ }, { "purl": "pkg:pypi/pdfminer-six", - "extracted_requirement": "pdfminer.six>=20170720", + "extracted_requirement": ">=20170720", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1394,7 +1394,7 @@ }, { "purl": "pkg:pypi/pefile", - "extracted_requirement": "pefile>=2018.8.8", + "extracted_requirement": ">=2018.8.8", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1405,7 +1405,7 @@ }, { "purl": "pkg:pypi/pkginfo", - "extracted_requirement": "pkginfo>=1.5.0.1", + "extracted_requirement": ">=1.5.0.1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1416,7 +1416,7 @@ }, { "purl": "pkg:pypi/pluggy", - "extracted_requirement": "pluggy<1.0,>=0.4.0", + "extracted_requirement": "<1.0,>=0.4.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1427,7 +1427,7 @@ }, { "purl": "pkg:pypi/plugincode", - "extracted_requirement": "plugincode>=21.1.21", + "extracted_requirement": ">=21.1.21", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1438,7 +1438,7 @@ }, { "purl": "pkg:pypi/publicsuffix2", - "extracted_requirement": "publicsuffix2", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -1449,7 +1449,7 @@ }, { "purl": "pkg:pypi/pyahocorasick", - "extracted_requirement": "pyahocorasick<1.5,>=1.4", + "extracted_requirement": "<1.5,>=1.4", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1460,7 +1460,7 @@ }, { "purl": "pkg:pypi/pycryptodome", - "extracted_requirement": "pycryptodome>=3.4", + "extracted_requirement": ">=3.4", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1471,7 +1471,7 @@ }, { "purl": "pkg:pypi/pygments", - "extracted_requirement": "pygments", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -1482,7 +1482,7 @@ }, { "purl": "pkg:pypi/pymaven-patch", - "extracted_requirement": "pymaven_patch>=0.2.8", + "extracted_requirement": ">=0.2.8", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1493,7 +1493,7 @@ }, { "purl": "pkg:pypi/requests", - "extracted_requirement": "requests<3.0.0,>=2.7.0", + "extracted_requirement": "<3.0.0,>=2.7.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1504,7 +1504,7 @@ }, { "purl": "pkg:pypi/saneyaml", - "extracted_requirement": "saneyaml>=0.5.2", + "extracted_requirement": ">=0.5.2", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1515,7 +1515,7 @@ }, { "purl": "pkg:pypi/spdx-tools", - "extracted_requirement": "spdx_tools>=0.6.0", + "extracted_requirement": ">=0.6.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1526,7 +1526,7 @@ }, { "purl": "pkg:pypi/text-unidecode", - "extracted_requirement": "text_unidecode<2.0,>=1.0", + "extracted_requirement": "<2.0,>=1.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1537,7 +1537,7 @@ }, { "purl": "pkg:pypi/toml", - "extracted_requirement": "toml>=0.10.0", + "extracted_requirement": ">=0.10.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1548,7 +1548,7 @@ }, { "purl": "pkg:pypi/urlpy", - "extracted_requirement": "urlpy", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -1559,7 +1559,7 @@ }, { "purl": "pkg:pypi/xmltodict", - "extracted_requirement": "xmltodict>=0.11.0", + "extracted_requirement": ">=0.11.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1570,7 +1570,7 @@ }, { "purl": "pkg:pypi/extractcode", - "extracted_requirement": "extractcode[full]>=21.2.24", + "extracted_requirement": ">=21.2.24", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1581,7 +1581,7 @@ }, { "purl": "pkg:pypi/typecode", - "extracted_requirement": "typecode[full]>=21.2.24", + "extracted_requirement": ">=21.2.24", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1592,18 +1592,20 @@ }, { "purl": "pkg:pypi/typing", - "extracted_requirement": "typing<3.7,>=3.6; python_version < \"3.7\"", + "extracted_requirement": "<3.7,>=3.6", "scope": "install", "is_runtime": true, "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, - "extra_data": {} + "extra_data": { + "python_version": "< 3.7" + } }, { "purl": "pkg:pypi/pytest", - "extracted_requirement": "pytest; extra == \"dev\"", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": true, @@ -1614,7 +1616,7 @@ }, { "purl": "pkg:pypi/pytest-cov", - "extracted_requirement": "pytest-cov; extra == \"dev\"", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": true, @@ -1625,7 +1627,7 @@ }, { "purl": "pkg:pypi/pytest-xdist", - "extracted_requirement": "pytest-xdist; extra == \"dev\"", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": true, @@ -1636,7 +1638,7 @@ }, { "purl": "pkg:pypi/pytest-rerunfailures", - "extracted_requirement": "pytest-rerunfailures; extra == \"dev\"", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": true, @@ -1647,7 +1649,7 @@ }, { "purl": "pkg:pypi/aboutcode-toolkit", - "extracted_requirement": "aboutcode-toolkit>=6.0.0; extra == \"dev\"", + "extracted_requirement": ">=6.0.0", "scope": "dev", "is_runtime": true, "is_optional": true, @@ -1658,7 +1660,7 @@ }, { "purl": "pkg:pypi/bump2version", - "extracted_requirement": "bump2version; extra == \"dev\"", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": true, @@ -1669,7 +1671,7 @@ }, { "purl": "pkg:pypi/codecov", - "extracted_requirement": "codecov; extra == \"dev\"", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": true, @@ -1680,7 +1682,7 @@ }, { "purl": "pkg:pypi/coverage", - "extracted_requirement": "coverage; extra == \"dev\"", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": true, @@ -1691,7 +1693,7 @@ }, { "purl": "pkg:pypi/rpm-inspector-rpm", - "extracted_requirement": "rpm_inspector_rpm>=4.16.1.3; platform_system == \"Linux\" and extra == \"packages\"", + "extracted_requirement": ">=4.16.1.3", "scope": "packages", "is_runtime": true, "is_optional": true, diff --git a/tests/packagedcode/data/pypi/metadata/v20/PKG-INFO-expected.json b/tests/packagedcode/data/pypi/metadata/v20/PKG-INFO-expected.json index 6d231ba0105..21b3b1d4f26 100644 --- a/tests/packagedcode/data/pypi/metadata/v20/PKG-INFO-expected.json +++ b/tests/packagedcode/data/pypi/metadata/v20/PKG-INFO-expected.json @@ -113,7 +113,7 @@ "dependencies": [ { "purl": "pkg:pypi/pykerberos", - "extracted_requirement": "pykerberos; extra == \"gssapi\"", + "extracted_requirement": null, "scope": "gssapi", "is_runtime": true, "is_optional": true, @@ -124,7 +124,7 @@ }, { "purl": "pkg:pypi/dnspython", - "extracted_requirement": "dnspython<2.0.0,>=1.8.0; extra == \"srv\"", + "extracted_requirement": "<2.0.0,>=1.8.0", "scope": "srv", "is_runtime": true, "is_optional": true, @@ -135,7 +135,7 @@ }, { "purl": "pkg:pypi/ipaddress", - "extracted_requirement": "ipaddress; extra == \"tls\"", + "extracted_requirement": null, "scope": "tls", "is_runtime": true, "is_optional": true, diff --git a/tests/packagedcode/data/pypi/more_setup.py/extras_require_with_vars_setup.py-expected.json b/tests/packagedcode/data/pypi/more_setup.py/extras_require_with_vars_setup.py-expected.json index e039ccf909a..6051b6e5ed1 100644 --- a/tests/packagedcode/data/pypi/more_setup.py/extras_require_with_vars_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/more_setup.py/extras_require_with_vars_setup.py-expected.json @@ -39,7 +39,7 @@ "dependencies": [ { "purl": "pkg:pypi/pytest", - "extracted_requirement": "pytest", + "extracted_requirement": null, "scope": "test", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/more_setup.py/flask_setup.py-expected.json b/tests/packagedcode/data/pypi/more_setup.py/flask_setup.py-expected.json index 268768f5c8b..59cfe8a0209 100644 --- a/tests/packagedcode/data/pypi/more_setup.py/flask_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/more_setup.py/flask_setup.py-expected.json @@ -118,7 +118,7 @@ "dependencies": [ { "purl": "pkg:pypi/werkzeug", - "extracted_requirement": "Werkzeug>=0.14", + "extracted_requirement": ">=0.14", "scope": "install", "is_runtime": true, "is_optional": false, @@ -129,7 +129,7 @@ }, { "purl": "pkg:pypi/jinja2", - "extracted_requirement": "Jinja2>=2.10", + "extracted_requirement": ">=2.10", "scope": "install", "is_runtime": true, "is_optional": false, @@ -140,7 +140,7 @@ }, { "purl": "pkg:pypi/itsdangerous", - "extracted_requirement": "itsdangerous>=0.24", + "extracted_requirement": ">=0.24", "scope": "install", "is_runtime": true, "is_optional": false, @@ -151,7 +151,7 @@ }, { "purl": "pkg:pypi/click", - "extracted_requirement": "click>=5.1", + "extracted_requirement": ">=5.1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -162,7 +162,7 @@ }, { "purl": "pkg:pypi/python-dotenv", - "extracted_requirement": "python-dotenv", + "extracted_requirement": null, "scope": "dotenv", "is_runtime": true, "is_optional": false, @@ -173,7 +173,7 @@ }, { "purl": "pkg:pypi/pytest", - "extracted_requirement": "pytest>=3", + "extracted_requirement": ">=3", "scope": "dev", "is_runtime": true, "is_optional": false, @@ -184,7 +184,7 @@ }, { "purl": "pkg:pypi/coverage", - "extracted_requirement": "coverage", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": false, @@ -195,7 +195,7 @@ }, { "purl": "pkg:pypi/tox", - "extracted_requirement": "tox", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": false, @@ -206,7 +206,7 @@ }, { "purl": "pkg:pypi/sphinx", - "extracted_requirement": "sphinx", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": false, @@ -217,7 +217,7 @@ }, { "purl": "pkg:pypi/pallets-sphinx-themes", - "extracted_requirement": "pallets-sphinx-themes", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": false, @@ -228,7 +228,7 @@ }, { "purl": "pkg:pypi/sphinxcontrib-log-cabinet", - "extracted_requirement": "sphinxcontrib-log-cabinet", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": false, @@ -239,7 +239,7 @@ }, { "purl": "pkg:pypi/sphinx", - "extracted_requirement": "sphinx", + "extracted_requirement": null, "scope": "docs", "is_runtime": true, "is_optional": false, @@ -250,7 +250,7 @@ }, { "purl": "pkg:pypi/pallets-sphinx-themes", - "extracted_requirement": "pallets-sphinx-themes", + "extracted_requirement": null, "scope": "docs", "is_runtime": true, "is_optional": false, @@ -261,7 +261,7 @@ }, { "purl": "pkg:pypi/sphinxcontrib-log-cabinet", - "extracted_requirement": "sphinxcontrib-log-cabinet", + "extracted_requirement": null, "scope": "docs", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/more_setup.py/pendulum_setup.py-expected.json b/tests/packagedcode/data/pypi/more_setup.py/pendulum_setup.py-expected.json index 97631f2c1f7..1ccadfe740d 100644 --- a/tests/packagedcode/data/pypi/more_setup.py/pendulum_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/more_setup.py/pendulum_setup.py-expected.json @@ -49,7 +49,7 @@ "dependencies": [ { "purl": "pkg:pypi/python-dateutil", - "extracted_requirement": "python-dateutil<3.0,>=2.6", + "extracted_requirement": "<3.0,>=2.6", "scope": "install", "is_runtime": true, "is_optional": false, @@ -60,7 +60,7 @@ }, { "purl": "pkg:pypi/pytzdata", - "extracted_requirement": "pytzdata>=2018.3", + "extracted_requirement": ">=2018.3", "scope": "install", "is_runtime": true, "is_optional": false, @@ -71,7 +71,7 @@ }, { "purl": "pkg:pypi/typing", - "extracted_requirement": "typing<4.0,>=3.6", + "extracted_requirement": "<4.0,>=3.6", "scope": ":python_version < \"3.5\"", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/more_setup.py/requests_setup.py-expected.json b/tests/packagedcode/data/pypi/more_setup.py/requests_setup.py-expected.json index 49fd970c871..d36f4cdad57 100644 --- a/tests/packagedcode/data/pypi/more_setup.py/requests_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/more_setup.py/requests_setup.py-expected.json @@ -78,7 +78,7 @@ "dependencies": [ { "purl": "pkg:pypi/chardet", - "extracted_requirement": "chardet<3.1.0,>=3.0.2", + "extracted_requirement": "<3.1.0,>=3.0.2", "scope": "install", "is_runtime": true, "is_optional": false, @@ -89,7 +89,7 @@ }, { "purl": "pkg:pypi/idna", - "extracted_requirement": "idna<2.8,>=2.5", + "extracted_requirement": "<2.8,>=2.5", "scope": "install", "is_runtime": true, "is_optional": false, @@ -100,7 +100,7 @@ }, { "purl": "pkg:pypi/urllib3", - "extracted_requirement": "urllib3<1.25,>=1.21.1", + "extracted_requirement": "<1.25,>=1.21.1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -111,7 +111,7 @@ }, { "purl": "pkg:pypi/certifi", - "extracted_requirement": "certifi>=2017.4.17", + "extracted_requirement": ">=2017.4.17", "scope": "install", "is_runtime": true, "is_optional": false, @@ -122,7 +122,7 @@ }, { "purl": "pkg:pypi/pyopenssl", - "extracted_requirement": "pyOpenSSL>=0.14", + "extracted_requirement": ">=0.14", "scope": "security", "is_runtime": true, "is_optional": false, @@ -133,7 +133,7 @@ }, { "purl": "pkg:pypi/cryptography", - "extracted_requirement": "cryptography>=1.3.4", + "extracted_requirement": ">=1.3.4", "scope": "security", "is_runtime": true, "is_optional": false, @@ -144,7 +144,7 @@ }, { "purl": "pkg:pypi/idna", - "extracted_requirement": "idna>=2.0.0", + "extracted_requirement": ">=2.0.0", "scope": "security", "is_runtime": true, "is_optional": false, @@ -155,7 +155,7 @@ }, { "purl": "pkg:pypi/pysocks", - "extracted_requirement": "PySocks!=1.5.7,>=1.5.6", + "extracted_requirement": "!=1.5.7,>=1.5.6", "scope": "socks", "is_runtime": true, "is_optional": false, @@ -166,7 +166,7 @@ }, { "purl": "pkg:pypi/win-inet-pton", - "extracted_requirement": "win_inet_pton", + "extracted_requirement": null, "scope": "socks:sys_platform == \"win32\" and python_version == \"2.7\"", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/more_setup.py/sqlalchemy_setup.py-expected.json b/tests/packagedcode/data/pypi/more_setup.py/sqlalchemy_setup.py-expected.json index 2d29c94a486..01238a35c81 100644 --- a/tests/packagedcode/data/pypi/more_setup.py/sqlalchemy_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/more_setup.py/sqlalchemy_setup.py-expected.json @@ -101,7 +101,7 @@ "dependencies": [ { "purl": "pkg:pypi/mysqlclient", - "extracted_requirement": "mysqlclient", + "extracted_requirement": null, "scope": "mysql", "is_runtime": true, "is_optional": false, @@ -112,7 +112,7 @@ }, { "purl": "pkg:pypi/pymysql", - "extracted_requirement": "pymysql", + "extracted_requirement": null, "scope": "pymysql", "is_runtime": true, "is_optional": false, @@ -123,7 +123,7 @@ }, { "purl": "pkg:pypi/psycopg2", - "extracted_requirement": "psycopg2", + "extracted_requirement": null, "scope": "postgresql", "is_runtime": true, "is_optional": false, @@ -134,7 +134,7 @@ }, { "purl": "pkg:pypi/pg8000", - "extracted_requirement": "pg8000", + "extracted_requirement": null, "scope": "postgresql_pg8000", "is_runtime": true, "is_optional": false, @@ -145,7 +145,7 @@ }, { "purl": "pkg:pypi/psycopg2cffi", - "extracted_requirement": "psycopg2cffi", + "extracted_requirement": null, "scope": "postgresql_psycopg2cffi", "is_runtime": true, "is_optional": false, @@ -156,7 +156,7 @@ }, { "purl": "pkg:pypi/cx-oracle", - "extracted_requirement": "cx_oracle", + "extracted_requirement": null, "scope": "oracle", "is_runtime": true, "is_optional": false, @@ -167,7 +167,7 @@ }, { "purl": "pkg:pypi/pyodbc", - "extracted_requirement": "pyodbc", + "extracted_requirement": null, "scope": "mssql_pyodbc", "is_runtime": true, "is_optional": false, @@ -178,7 +178,7 @@ }, { "purl": "pkg:pypi/pymssql", - "extracted_requirement": "pymssql", + "extracted_requirement": null, "scope": "mssql_pymssql", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/more_setup.py/unpack_kwargs_setup.py-expected.json b/tests/packagedcode/data/pypi/more_setup.py/unpack_kwargs_setup.py-expected.json index 0ab40c862e0..ecfa737eeb4 100644 --- a/tests/packagedcode/data/pypi/more_setup.py/unpack_kwargs_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/more_setup.py/unpack_kwargs_setup.py-expected.json @@ -70,7 +70,7 @@ "dependencies": [ { "purl": "pkg:pypi/pendulum", - "extracted_requirement": "pendulum>=1.4.4", + "extracted_requirement": ">=1.4.4", "scope": "install", "is_runtime": true, "is_optional": false, @@ -81,7 +81,7 @@ }, { "purl": "pkg:pypi/cachy", - "extracted_requirement": "cachy[msgpack]>=0.2.0", + "extracted_requirement": ">=0.2.0", "scope": "install", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/setup.py-versions/cdp-seattle-backend-1.0.0/setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py-versions/cdp-seattle-backend-1.0.0/setup.py-expected.json index 65dcece23ee..ed83fd5acc2 100644 --- a/tests/packagedcode/data/pypi/setup.py-versions/cdp-seattle-backend-1.0.0/setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py-versions/cdp-seattle-backend-1.0.0/setup.py-expected.json @@ -101,7 +101,7 @@ "dependencies": [ { "purl": "pkg:pypi/cdp-backend@3.0.16", - "extracted_requirement": "cdp-backend[pipeline]==3.0.16", + "extracted_requirement": "==3.0.16", "scope": "install", "is_runtime": true, "is_optional": false, @@ -112,7 +112,7 @@ }, { "purl": "pkg:pypi/cdp-scrapers", - "extracted_requirement": "cdp-scrapers>=0.4.0", + "extracted_requirement": ">=0.4.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -123,7 +123,7 @@ }, { "purl": "pkg:pypi/black", - "extracted_requirement": "black>=19.10b0", + "extracted_requirement": ">=19.10b0", "scope": "test", "is_runtime": true, "is_optional": false, @@ -134,7 +134,7 @@ }, { "purl": "pkg:pypi/flake8", - "extracted_requirement": "flake8>=3.8.3", + "extracted_requirement": ">=3.8.3", "scope": "test", "is_runtime": true, "is_optional": false, @@ -145,7 +145,7 @@ }, { "purl": "pkg:pypi/flake8-debugger", - "extracted_requirement": "flake8-debugger>=3.2.1", + "extracted_requirement": ">=3.2.1", "scope": "test", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/setup.py-versions/flask-2.2.0.dev0/setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py-versions/flask-2.2.0.dev0/setup.py-expected.json index 359ec7553a1..2434c2ab29a 100644 --- a/tests/packagedcode/data/pypi/setup.py-versions/flask-2.2.0.dev0/setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py-versions/flask-2.2.0.dev0/setup.py-expected.json @@ -39,7 +39,7 @@ "dependencies": [ { "purl": "pkg:pypi/werkzeug", - "extracted_requirement": "Werkzeug>=2.0", + "extracted_requirement": ">=2.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -50,7 +50,7 @@ }, { "purl": "pkg:pypi/jinja2", - "extracted_requirement": "Jinja2>=3.0", + "extracted_requirement": ">=3.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -61,7 +61,7 @@ }, { "purl": "pkg:pypi/itsdangerous", - "extracted_requirement": "itsdangerous>=2.0", + "extracted_requirement": ">=2.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -72,7 +72,7 @@ }, { "purl": "pkg:pypi/click", - "extracted_requirement": "click>=8.0", + "extracted_requirement": ">=8.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -83,18 +83,20 @@ }, { "purl": "pkg:pypi/importlib-metadata", - "extracted_requirement": "importlib-metadata>=3.6.0; python_version < \"3.10\"", + "extracted_requirement": ">=3.6.0", "scope": "install", "is_runtime": true, "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, - "extra_data": {} + "extra_data": { + "python_version": "< 3.10" + } }, { "purl": "pkg:pypi/asgiref", - "extracted_requirement": "asgiref>=3.2", + "extracted_requirement": ">=3.2", "scope": "async", "is_runtime": true, "is_optional": false, @@ -105,7 +107,7 @@ }, { "purl": "pkg:pypi/python-dotenv", - "extracted_requirement": "python-dotenv", + "extracted_requirement": null, "scope": "dotenv", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/setup.py-versions/flit-2.3.0/setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py-versions/flit-2.3.0/setup.py-expected.json index b2f449b8583..d7cf57efae6 100644 --- a/tests/packagedcode/data/pypi/setup.py-versions/flit-2.3.0/setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py-versions/flit-2.3.0/setup.py-expected.json @@ -49,7 +49,7 @@ "dependencies": [ { "purl": "pkg:pypi/flit-core", - "extracted_requirement": "flit_core>=2.3.0", + "extracted_requirement": ">=2.3.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -60,7 +60,7 @@ }, { "purl": "pkg:pypi/requests", - "extracted_requirement": "requests", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -71,7 +71,7 @@ }, { "purl": "pkg:pypi/docutils", - "extracted_requirement": "docutils", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -82,7 +82,7 @@ }, { "purl": "pkg:pypi/pytoml", - "extracted_requirement": "pytoml", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -93,7 +93,7 @@ }, { "purl": "pkg:pypi/zipfile36", - "extracted_requirement": "zipfile36", + "extracted_requirement": null, "scope": ":python_version in '3.3 3.4 3.5'", "is_runtime": true, "is_optional": false, @@ -104,7 +104,7 @@ }, { "purl": "pkg:pypi/sphinx", - "extracted_requirement": "sphinx", + "extracted_requirement": null, "scope": "doc", "is_runtime": true, "is_optional": false, @@ -115,7 +115,7 @@ }, { "purl": "pkg:pypi/sphinxcontrib-github-alt", - "extracted_requirement": "sphinxcontrib_github_alt", + "extracted_requirement": null, "scope": "doc", "is_runtime": true, "is_optional": false, @@ -126,7 +126,7 @@ }, { "purl": "pkg:pypi/pygments-github-lexers", - "extracted_requirement": "pygments-github-lexers", + "extracted_requirement": null, "scope": "doc", "is_runtime": true, "is_optional": false, @@ -137,7 +137,7 @@ }, { "purl": "pkg:pypi/requests-download", - "extracted_requirement": "requests_download", + "extracted_requirement": null, "scope": "installfrom", "is_runtime": true, "is_optional": false, @@ -148,7 +148,7 @@ }, { "purl": "pkg:pypi/testpath", - "extracted_requirement": "testpath", + "extracted_requirement": null, "scope": "test", "is_runtime": true, "is_optional": false, @@ -159,7 +159,7 @@ }, { "purl": "pkg:pypi/responses", - "extracted_requirement": "responses", + "extracted_requirement": null, "scope": "test", "is_runtime": true, "is_optional": false, @@ -170,7 +170,7 @@ }, { "purl": "pkg:pypi/pytest", - "extracted_requirement": "pytest>=2.7.3", + "extracted_requirement": ">=2.7.3", "scope": "test", "is_runtime": true, "is_optional": false, @@ -181,7 +181,7 @@ }, { "purl": "pkg:pypi/pytest-cov", - "extracted_requirement": "pytest-cov", + "extracted_requirement": null, "scope": "test", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/setup.py-versions/paho-mqtt-1.5.0/setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py-versions/paho-mqtt-1.5.0/setup.py-expected.json index 24dee15a0ff..c428c1b3121 100644 --- a/tests/packagedcode/data/pypi/setup.py-versions/paho-mqtt-1.5.0/setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py-versions/paho-mqtt-1.5.0/setup.py-expected.json @@ -124,7 +124,7 @@ "dependencies": [ { "purl": "pkg:pypi/pysocks", - "extracted_requirement": "PySocks", + "extracted_requirement": null, "scope": "proxy", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/setup.py-versions/pexpect-4.6.0/setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py-versions/pexpect-4.6.0/setup.py-expected.json index b3e1966cbf3..9ec66d2a96f 100644 --- a/tests/packagedcode/data/pypi/setup.py-versions/pexpect-4.6.0/setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py-versions/pexpect-4.6.0/setup.py-expected.json @@ -112,7 +112,7 @@ "dependencies": [ { "purl": "pkg:pypi/ptyprocess", - "extracted_requirement": "ptyprocess>=0.5", + "extracted_requirement": ">=0.5", "scope": "install", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/setup.py-versions/requests-2.24.0/setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py-versions/requests-2.24.0/setup.py-expected.json index 3963bea95ca..2c1c5bb9ed8 100644 --- a/tests/packagedcode/data/pypi/setup.py-versions/requests-2.24.0/setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py-versions/requests-2.24.0/setup.py-expected.json @@ -79,7 +79,7 @@ "dependencies": [ { "purl": "pkg:pypi/chardet", - "extracted_requirement": "chardet<4,>=3.0.2", + "extracted_requirement": "<4,>=3.0.2", "scope": "install", "is_runtime": true, "is_optional": false, @@ -90,7 +90,7 @@ }, { "purl": "pkg:pypi/idna", - "extracted_requirement": "idna<3,>=2.5", + "extracted_requirement": "<3,>=2.5", "scope": "install", "is_runtime": true, "is_optional": false, @@ -101,7 +101,7 @@ }, { "purl": "pkg:pypi/urllib3", - "extracted_requirement": "urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1", + "extracted_requirement": "!=1.25.0,!=1.25.1,<1.26,>=1.21.1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -112,7 +112,7 @@ }, { "purl": "pkg:pypi/certifi", - "extracted_requirement": "certifi>=2017.4.17", + "extracted_requirement": ">=2017.4.17", "scope": "install", "is_runtime": true, "is_optional": false, @@ -123,7 +123,7 @@ }, { "purl": "pkg:pypi/pyopenssl", - "extracted_requirement": "pyOpenSSL>=0.14", + "extracted_requirement": ">=0.14", "scope": "security", "is_runtime": true, "is_optional": false, @@ -134,7 +134,7 @@ }, { "purl": "pkg:pypi/cryptography", - "extracted_requirement": "cryptography>=1.3.4", + "extracted_requirement": ">=1.3.4", "scope": "security", "is_runtime": true, "is_optional": false, @@ -145,7 +145,7 @@ }, { "purl": "pkg:pypi/pysocks", - "extracted_requirement": "PySocks!=1.5.7,>=1.5.6", + "extracted_requirement": "!=1.5.7,>=1.5.6", "scope": "socks", "is_runtime": true, "is_optional": false, @@ -156,7 +156,7 @@ }, { "purl": "pkg:pypi/win-inet-pton", - "extracted_requirement": "win_inet_pton", + "extracted_requirement": null, "scope": "socks:sys_platform == \"win32\" and python_version == \"2.7\"", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/setup.py-versions/setupreader-0.0.3/setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py-versions/setupreader-0.0.3/setup.py-expected.json index d83d40e1892..d5685b86655 100644 --- a/tests/packagedcode/data/pypi/setup.py-versions/setupreader-0.0.3/setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py-versions/setupreader-0.0.3/setup.py-expected.json @@ -70,7 +70,7 @@ "dependencies": [ { "purl": "pkg:pypi/setuptools", - "extracted_requirement": "setuptools", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -81,7 +81,7 @@ }, { "purl": "pkg:pypi/mock", - "extracted_requirement": "mock", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/setup.py-versions/urllib3-1.25.9/setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py-versions/urllib3-1.25.9/setup.py-expected.json index 355ae4d9443..9e415ac548f 100644 --- a/tests/packagedcode/data/pypi/setup.py-versions/urllib3-1.25.9/setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py-versions/urllib3-1.25.9/setup.py-expected.json @@ -120,7 +120,7 @@ "dependencies": [ { "purl": "pkg:pypi/brotlipy", - "extracted_requirement": "brotlipy>=0.6.0", + "extracted_requirement": ">=0.6.0", "scope": "brotli", "is_runtime": true, "is_optional": false, @@ -131,7 +131,7 @@ }, { "purl": "pkg:pypi/pyopenssl", - "extracted_requirement": "pyOpenSSL>=0.14", + "extracted_requirement": ">=0.14", "scope": "secure", "is_runtime": true, "is_optional": false, @@ -142,7 +142,7 @@ }, { "purl": "pkg:pypi/cryptography", - "extracted_requirement": "cryptography>=1.3.4", + "extracted_requirement": ">=1.3.4", "scope": "secure", "is_runtime": true, "is_optional": false, @@ -153,7 +153,7 @@ }, { "purl": "pkg:pypi/idna", - "extracted_requirement": "idna>=2.0.0", + "extracted_requirement": ">=2.0.0", "scope": "secure", "is_runtime": true, "is_optional": false, @@ -164,7 +164,7 @@ }, { "purl": "pkg:pypi/certifi", - "extracted_requirement": "certifi", + "extracted_requirement": null, "scope": "secure", "is_runtime": true, "is_optional": false, @@ -175,18 +175,20 @@ }, { "purl": "pkg:pypi/ipaddress", - "extracted_requirement": "ipaddress; python_version == \"2.7\"", + "extracted_requirement": null, "scope": "secure", "is_runtime": true, "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, - "extra_data": {} + "extra_data": { + "python_version": "== 2.7" + } }, { "purl": "pkg:pypi/pysocks", - "extracted_requirement": "PySocks!=1.5.7,<2.0,>=1.5.6", + "extracted_requirement": "!=1.5.7,<2.0,>=1.5.6", "scope": "socks", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/setup.py/bluepyopt_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/bluepyopt_setup.py-expected.json index 196603fca61..6242b2a3e57 100644 --- a/tests/packagedcode/data/pypi/setup.py/bluepyopt_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/bluepyopt_setup.py-expected.json @@ -102,7 +102,7 @@ "dependencies": [ { "purl": "pkg:pypi/numpy", - "extracted_requirement": "numpy>=1.6", + "extracted_requirement": ">=1.6", "scope": "install", "is_runtime": true, "is_optional": false, @@ -113,7 +113,7 @@ }, { "purl": "pkg:pypi/pandas", - "extracted_requirement": "pandas>=0.18", + "extracted_requirement": ">=0.18", "scope": "install", "is_runtime": true, "is_optional": false, @@ -124,7 +124,7 @@ }, { "purl": "pkg:pypi/deap", - "extracted_requirement": "deap", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -135,7 +135,7 @@ }, { "purl": "pkg:pypi/efel", - "extracted_requirement": "efel>=2.13", + "extracted_requirement": ">=2.13", "scope": "install", "is_runtime": true, "is_optional": false, @@ -146,7 +146,7 @@ }, { "purl": "pkg:pypi/ipyparallel", - "extracted_requirement": "ipyparallel", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -157,7 +157,7 @@ }, { "purl": "pkg:pypi/pickleshare", - "extracted_requirement": "pickleshare>=0.7.3", + "extracted_requirement": ">=0.7.3", "scope": "install", "is_runtime": true, "is_optional": false, @@ -168,7 +168,7 @@ }, { "purl": "pkg:pypi/jinja2", - "extracted_requirement": "Jinja2>=2.8", + "extracted_requirement": ">=2.8", "scope": "install", "is_runtime": true, "is_optional": false, @@ -179,7 +179,7 @@ }, { "purl": "pkg:pypi/future", - "extracted_requirement": "future", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -190,7 +190,7 @@ }, { "purl": "pkg:pypi/pebble", - "extracted_requirement": "Pebble>=4.3.10", + "extracted_requirement": ">=4.3.10", "scope": "install", "is_runtime": true, "is_optional": false, @@ -201,7 +201,7 @@ }, { "purl": "pkg:pypi/scoop", - "extracted_requirement": "scoop>=0.7", + "extracted_requirement": ">=0.7", "scope": "all", "is_runtime": true, "is_optional": false, @@ -212,7 +212,7 @@ }, { "purl": "pkg:pypi/scoop", - "extracted_requirement": "scoop>=0.7", + "extracted_requirement": ">=0.7", "scope": "scoop", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/setup.py/complex_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/complex_setup.py-expected.json index 46e6f9ee451..186debedf0d 100644 --- a/tests/packagedcode/data/pypi/setup.py/complex_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/complex_setup.py-expected.json @@ -70,7 +70,7 @@ "dependencies": [ { "purl": "pkg:pypi/psutil", - "extracted_requirement": "psutil", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -81,7 +81,7 @@ }, { "purl": "pkg:pypi/colorama", - "extracted_requirement": "colorama", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -92,7 +92,7 @@ }, { "purl": "pkg:pypi/six", - "extracted_requirement": "six", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -103,7 +103,7 @@ }, { "purl": "pkg:pypi/pathlib2", - "extracted_requirement": "pathlib2", + "extracted_requirement": null, "scope": ":python_version<\"3.4\"", "is_runtime": true, "is_optional": false, @@ -114,7 +114,7 @@ }, { "purl": "pkg:pypi/backports-shutil-get-terminal-size", - "extracted_requirement": "backports.shutil_get_terminal_size", + "extracted_requirement": null, "scope": ":python_version<\"3.3\"", "is_runtime": true, "is_optional": false, @@ -125,7 +125,7 @@ }, { "purl": "pkg:pypi/decorator", - "extracted_requirement": "decorator<5", + "extracted_requirement": "<5", "scope": ":python_version<=\"2.7\"", "is_runtime": true, "is_optional": false, @@ -136,7 +136,7 @@ }, { "purl": "pkg:pypi/pyte", - "extracted_requirement": "pyte<0.8.1", + "extracted_requirement": "<0.8.1", "scope": ":python_version<=\"2.7\"", "is_runtime": true, "is_optional": false, @@ -147,7 +147,7 @@ }, { "purl": "pkg:pypi/decorator", - "extracted_requirement": "decorator", + "extracted_requirement": null, "scope": ":python_version>\"2.7\"", "is_runtime": true, "is_optional": false, @@ -158,7 +158,7 @@ }, { "purl": "pkg:pypi/pyte", - "extracted_requirement": "pyte", + "extracted_requirement": null, "scope": ":python_version>\"2.7\"", "is_runtime": true, "is_optional": false, @@ -169,7 +169,7 @@ }, { "purl": "pkg:pypi/win-unicode-console", - "extracted_requirement": "win_unicode_console", + "extracted_requirement": null, "scope": ":sys_platform=='win32'", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/setup.py/ntfs_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/ntfs_setup.py-expected.json index 11a3c48144d..c4115c8ed09 100644 --- a/tests/packagedcode/data/pypi/setup.py/ntfs_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/ntfs_setup.py-expected.json @@ -103,7 +103,7 @@ "dependencies": [ { "purl": "pkg:pypi/setuptools", - "extracted_requirement": "setuptools", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/setup.py/nvchecker_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/nvchecker_setup.py-expected.json index 01b8fc46835..566554085a0 100644 --- a/tests/packagedcode/data/pypi/setup.py/nvchecker_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/nvchecker_setup.py-expected.json @@ -113,7 +113,7 @@ "dependencies": [ { "purl": "pkg:pypi/tornado", - "extracted_requirement": "tornado>=4.1", + "extracted_requirement": ">=4.1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -124,7 +124,7 @@ }, { "purl": "pkg:pypi/setuptools", - "extracted_requirement": "setuptools", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/setup.py/oi_agents_common_code_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/oi_agents_common_code_setup.py-expected.json index 3dfda0e31ff..12b77ddad26 100644 --- a/tests/packagedcode/data/pypi/setup.py/oi_agents_common_code_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/oi_agents_common_code_setup.py-expected.json @@ -119,7 +119,7 @@ "dependencies": [ { "purl": "pkg:pypi/ipython", - "extracted_requirement": "ipython", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": false, @@ -130,7 +130,7 @@ }, { "purl": "pkg:pypi/coverage", - "extracted_requirement": "coverage", + "extracted_requirement": null, "scope": "test", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/setup.py/pipdeptree_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/pipdeptree_setup.py-expected.json index 27446ba3183..e6878287ed7 100644 --- a/tests/packagedcode/data/pypi/setup.py/pipdeptree_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/pipdeptree_setup.py-expected.json @@ -104,7 +104,7 @@ "dependencies": [ { "purl": "pkg:pypi/pip", - "extracted_requirement": "pip>=6.0.0", + "extracted_requirement": ">=6.0.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -115,7 +115,7 @@ }, { "purl": "pkg:pypi/graphviz", - "extracted_requirement": "graphviz", + "extracted_requirement": null, "scope": "graphviz", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/setup.py/pydep_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/pydep_setup.py-expected.json index fea8cb6190a..1609f0cf05e 100644 --- a/tests/packagedcode/data/pypi/setup.py/pydep_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/pydep_setup.py-expected.json @@ -47,7 +47,7 @@ "dependencies": [ { "purl": "pkg:pypi/pip@7.1.2", - "extracted_requirement": "pip==7.1.2", + "extracted_requirement": "==7.1.2", "scope": "install", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/setup.py/saneyaml_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/saneyaml_setup.py-expected.json index 12c08505903..e66a53e267f 100644 --- a/tests/packagedcode/data/pypi/setup.py/saneyaml_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/saneyaml_setup.py-expected.json @@ -107,7 +107,7 @@ "dependencies": [ { "purl": "pkg:pypi/pyyaml", - "extracted_requirement": "PyYAML<=3.13,>=3.11", + "extracted_requirement": "<=3.13,>=3.11", "scope": "install", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/setup.py/setuppycheck_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/setuppycheck_setup.py-expected.json index 6430051765d..ee7d720f7e8 100644 --- a/tests/packagedcode/data/pypi/setup.py/setuppycheck_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/setuppycheck_setup.py-expected.json @@ -74,7 +74,7 @@ "dependencies": [ { "purl": "pkg:pypi/mock", - "extracted_requirement": "mock", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/setup.py/simple-setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/simple-setup.py-expected.json index 6e1188c014f..d3017cf9668 100644 --- a/tests/packagedcode/data/pypi/setup.py/simple-setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/simple-setup.py-expected.json @@ -140,7 +140,7 @@ "dependencies": [ { "purl": "pkg:pypi/py2-ipaddress", - "extracted_requirement": "py2-ipaddress<3.0,>=2.0", + "extracted_requirement": "<3.0,>=2.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -151,7 +151,7 @@ }, { "purl": "pkg:pypi/url", - "extracted_requirement": "url>=0.1.4", + "extracted_requirement": ">=0.1.4", "scope": "install", "is_runtime": true, "is_optional": false, @@ -162,7 +162,7 @@ }, { "purl": "pkg:pypi/publicsuffix2", - "extracted_requirement": "publicsuffix2", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -173,7 +173,7 @@ }, { "purl": "pkg:pypi/nltk", - "extracted_requirement": "nltk<3.0.0,>=2.0b4", + "extracted_requirement": "<3.0.0,>=2.0b4", "scope": "install", "is_runtime": true, "is_optional": false, @@ -184,7 +184,7 @@ }, { "purl": "pkg:pypi/patch", - "extracted_requirement": "patch<1.15,>=1.14.2", + "extracted_requirement": "<1.15,>=1.14.2", "scope": "install", "is_runtime": true, "is_optional": false, @@ -195,7 +195,7 @@ }, { "purl": "pkg:pypi/bz2file", - "extracted_requirement": "bz2file>=0.98", + "extracted_requirement": ">=0.98", "scope": "install", "is_runtime": true, "is_optional": false, @@ -206,7 +206,7 @@ }, { "purl": "pkg:pypi/pyyaml", - "extracted_requirement": "PyYAML<4.0,>=3.0", + "extracted_requirement": "<4.0,>=3.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -217,7 +217,7 @@ }, { "purl": "pkg:pypi/beautifulsoup", - "extracted_requirement": "Beautifulsoup<4.0.0,>=3.2.0", + "extracted_requirement": "<4.0.0,>=3.2.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -228,7 +228,7 @@ }, { "purl": "pkg:pypi/beautifulsoup4", - "extracted_requirement": "Beautifulsoup4<5.0.0,>=4.3.0", + "extracted_requirement": "<5.0.0,>=4.3.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -239,7 +239,7 @@ }, { "purl": "pkg:pypi/html5lib", - "extracted_requirement": "html5lib", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -250,7 +250,7 @@ }, { "purl": "pkg:pypi/six", - "extracted_requirement": "six", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -261,7 +261,7 @@ }, { "purl": "pkg:pypi/pygments", - "extracted_requirement": "pygments<3.0.0,>=2.0.0", + "extracted_requirement": "<3.0.0,>=2.0.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -272,7 +272,7 @@ }, { "purl": "pkg:pypi/pdfminer", - "extracted_requirement": "pdfminer>=20140328", + "extracted_requirement": ">=20140328", "scope": "install", "is_runtime": true, "is_optional": false, @@ -283,7 +283,7 @@ }, { "purl": "pkg:pypi/chardet", - "extracted_requirement": "chardet<3.0.0,>=2.1.1", + "extracted_requirement": "<3.0.0,>=2.1.1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -294,7 +294,7 @@ }, { "purl": "pkg:pypi/binaryornot", - "extracted_requirement": "binaryornot>=0.4.0", + "extracted_requirement": ">=0.4.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -305,7 +305,7 @@ }, { "purl": "pkg:pypi/click", - "extracted_requirement": "click<5.0.0,>=4.0.0", + "extracted_requirement": "<5.0.0,>=4.0.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -316,7 +316,7 @@ }, { "purl": "pkg:pypi/jinja2", - "extracted_requirement": "jinja2<3.0.0,>=2.7.0", + "extracted_requirement": "<3.0.0,>=2.7.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -327,7 +327,7 @@ }, { "purl": "pkg:pypi/markupsafe", - "extracted_requirement": "MarkupSafe>=0.23", + "extracted_requirement": ">=0.23", "scope": "install", "is_runtime": true, "is_optional": false, @@ -338,7 +338,7 @@ }, { "purl": "pkg:pypi/colorama", - "extracted_requirement": "colorama", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -349,7 +349,7 @@ }, { "purl": "pkg:pypi/about-code-tool", - "extracted_requirement": "about-code-tool>=0.9.0", + "extracted_requirement": ">=0.9.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -360,7 +360,7 @@ }, { "purl": "pkg:pypi/requests", - "extracted_requirement": "requests<3.0.0,>=2.7.0", + "extracted_requirement": "<3.0.0,>=2.7.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -371,7 +371,7 @@ }, { "purl": "pkg:pypi/certifi", - "extracted_requirement": "certifi", + "extracted_requirement": null, "scope": "base", "is_runtime": true, "is_optional": false, @@ -382,7 +382,7 @@ }, { "purl": "pkg:pypi/setuptools", - "extracted_requirement": "setuptools", + "extracted_requirement": null, "scope": "base", "is_runtime": true, "is_optional": false, @@ -393,7 +393,7 @@ }, { "purl": "pkg:pypi/wheel", - "extracted_requirement": "wheel", + "extracted_requirement": null, "scope": "base", "is_runtime": true, "is_optional": false, @@ -404,7 +404,7 @@ }, { "purl": "pkg:pypi/pip", - "extracted_requirement": "pip", + "extracted_requirement": null, "scope": "base", "is_runtime": true, "is_optional": false, @@ -415,7 +415,7 @@ }, { "purl": "pkg:pypi/wincertstore", - "extracted_requirement": "wincertstore", + "extracted_requirement": null, "scope": "base", "is_runtime": true, "is_optional": false, @@ -426,7 +426,7 @@ }, { "purl": "pkg:pypi/pytest", - "extracted_requirement": "pytest", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": false, @@ -437,7 +437,7 @@ }, { "purl": "pkg:pypi/execnet", - "extracted_requirement": "execnet", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": false, @@ -448,7 +448,7 @@ }, { "purl": "pkg:pypi/py", - "extracted_requirement": "py", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": false, @@ -459,7 +459,7 @@ }, { "purl": "pkg:pypi/pytest-xdist", - "extracted_requirement": "pytest-xdist", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": false, @@ -470,7 +470,7 @@ }, { "purl": "pkg:pypi/bumpversion", - "extracted_requirement": "bumpversion", + "extracted_requirement": null, "scope": "dev", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/setup.py/url_py_setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/url_py_setup.py-expected.json index c2a71a44f2a..9dec1d5ba9f 100644 --- a/tests/packagedcode/data/pypi/setup.py/url_py_setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/url_py_setup.py-expected.json @@ -97,7 +97,7 @@ "dependencies": [ { "purl": "pkg:pypi/publicsuffix2", - "extracted_requirement": "publicsuffix2", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/setup.py/whatsapp-play-setup.py-expected.json b/tests/packagedcode/data/pypi/setup.py/whatsapp-play-setup.py-expected.json index c4760caf374..82120d7cefe 100644 --- a/tests/packagedcode/data/pypi/setup.py/whatsapp-play-setup.py-expected.json +++ b/tests/packagedcode/data/pypi/setup.py/whatsapp-play-setup.py-expected.json @@ -115,7 +115,7 @@ "dependencies": [ { "purl": "pkg:pypi/argparse", - "extracted_requirement": "argparse>=1.4.0", + "extracted_requirement": ">=1.4.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -126,7 +126,7 @@ }, { "purl": "pkg:pypi/beautifulsoup4", - "extracted_requirement": "beautifulsoup4>=4.8.1", + "extracted_requirement": ">=4.8.1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -137,7 +137,7 @@ }, { "purl": "pkg:pypi/colorama", - "extracted_requirement": "colorama>=0.4.3", + "extracted_requirement": ">=0.4.3", "scope": "install", "is_runtime": true, "is_optional": false, @@ -148,7 +148,7 @@ }, { "purl": "pkg:pypi/datetime", - "extracted_requirement": "dateTime>=4.3", + "extracted_requirement": ">=4.3", "scope": "install", "is_runtime": true, "is_optional": false, @@ -159,7 +159,7 @@ }, { "purl": "pkg:pypi/decorator", - "extracted_requirement": "decorator>=4.4.2", + "extracted_requirement": ">=4.4.2", "scope": "install", "is_runtime": true, "is_optional": false, @@ -170,7 +170,7 @@ }, { "purl": "pkg:pypi/flake8", - "extracted_requirement": "flake8>=3.7.9", + "extracted_requirement": ">=3.7.9", "scope": "install", "is_runtime": true, "is_optional": false, @@ -181,7 +181,7 @@ }, { "purl": "pkg:pypi/google", - "extracted_requirement": "google>=2.0.3", + "extracted_requirement": ">=2.0.3", "scope": "install", "is_runtime": true, "is_optional": false, @@ -192,7 +192,7 @@ }, { "purl": "pkg:pypi/gtts@2.1.1", - "extracted_requirement": "gTTS==2.1.1", + "extracted_requirement": "==2.1.1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -203,7 +203,7 @@ }, { "purl": "pkg:pypi/newsapi-python", - "extracted_requirement": "newsapi-python>=0.2.6", + "extracted_requirement": ">=0.2.6", "scope": "install", "is_runtime": true, "is_optional": false, @@ -214,7 +214,7 @@ }, { "purl": "pkg:pypi/phonenumbers@8.10.2", - "extracted_requirement": "phonenumbers==8.10.2", + "extracted_requirement": "==8.10.2", "scope": "install", "is_runtime": true, "is_optional": false, @@ -225,7 +225,7 @@ }, { "purl": "pkg:pypi/playsound", - "extracted_requirement": "playsound>=1.2.2", + "extracted_requirement": ">=1.2.2", "scope": "install", "is_runtime": true, "is_optional": false, @@ -236,7 +236,7 @@ }, { "purl": "pkg:pypi/prompt-toolkit@1.0.14", - "extracted_requirement": "prompt_toolkit==1.0.14", + "extracted_requirement": "==1.0.14", "scope": "install", "is_runtime": true, "is_optional": false, @@ -247,7 +247,7 @@ }, { "purl": "pkg:pypi/psutil", - "extracted_requirement": "psutil>=5.7.0", + "extracted_requirement": ">=5.7.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -258,7 +258,7 @@ }, { "purl": "pkg:pypi/pyfiglet", - "extracted_requirement": "pyfiglet>=0.8.post1", + "extracted_requirement": ">=0.8.post1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -269,7 +269,7 @@ }, { "purl": "pkg:pypi/pyflakes", - "extracted_requirement": "pyflakes>=2.2.0", + "extracted_requirement": ">=2.2.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -280,7 +280,7 @@ }, { "purl": "pkg:pypi/pygments", - "extracted_requirement": "Pygments>=2.6.1", + "extracted_requirement": ">=2.6.1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -291,7 +291,7 @@ }, { "purl": "pkg:pypi/pyppeteer", - "extracted_requirement": "pyppeteer>=0.0.25", + "extracted_requirement": ">=0.0.25", "scope": "install", "is_runtime": true, "is_optional": false, @@ -302,7 +302,7 @@ }, { "purl": "pkg:pypi/python-dotenv@0.12.0", - "extracted_requirement": "python-dotenv==0.12.0", + "extracted_requirement": "==0.12.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -313,7 +313,7 @@ }, { "purl": "pkg:pypi/python-telegram-bot", - "extracted_requirement": "python-telegram-bot>=11.1.0", + "extracted_requirement": ">=11.1.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -324,7 +324,7 @@ }, { "purl": "pkg:pypi/requests", - "extracted_requirement": "requests>=2.22.0", + "extracted_requirement": ">=2.22.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -335,7 +335,7 @@ }, { "purl": "pkg:pypi/transitions", - "extracted_requirement": "transitions>=0.7.2", + "extracted_requirement": ">=0.7.2", "scope": "install", "is_runtime": true, "is_optional": false, @@ -346,7 +346,7 @@ }, { "purl": "pkg:pypi/urllib3", - "extracted_requirement": "urllib3>=1.25.8", + "extracted_requirement": ">=1.25.8", "scope": "install", "is_runtime": true, "is_optional": false, @@ -357,7 +357,7 @@ }, { "purl": "pkg:pypi/websockets", - "extracted_requirement": "websockets>=8.1", + "extracted_requirement": ">=8.1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -368,7 +368,7 @@ }, { "purl": "pkg:pypi/whaaaaat", - "extracted_requirement": "whaaaaat>=0.5.2", + "extracted_requirement": ">=0.5.2", "scope": "install", "is_runtime": true, "is_optional": false, 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 c6098ab4524..42a2e6c6cc6 100644 --- a/tests/packagedcode/data/pypi/site-packages/site-packages-expected.json +++ b/tests/packagedcode/data/pypi/site-packages/site-packages-expected.json @@ -205,7 +205,7 @@ "dependencies": [ { "purl": "pkg:pypi/colorama", - "extracted_requirement": "colorama; platform_system == \"Windows\"", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -220,14 +220,16 @@ }, { "purl": "pkg:pypi/importlib-metadata", - "extracted_requirement": "importlib-metadata; python_version < \"3.8\"", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, - "extra_data": {}, + "extra_data": { + "python_version": "< 3.8" + }, "dependency_uid": "pkg:pypi/importlib-metadata?uuid=fixed-uid-done-for-testing-5642512d1758", "for_package_uid": "pkg:pypi/click@8.0.4?uuid=fixed-uid-done-for-testing-5642512d1758", "datafile_path": "lib/python3.9/site-packages/click-8.0.4.dist-info/METADATA", @@ -861,7 +863,7 @@ "dependencies": [ { "purl": "pkg:pypi/colorama", - "extracted_requirement": "colorama; platform_system == \"Windows\"", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -872,14 +874,16 @@ }, { "purl": "pkg:pypi/importlib-metadata", - "extracted_requirement": "importlib-metadata; python_version < \"3.8\"", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, - "extra_data": {} + "extra_data": { + "python_version": "< 3.8" + } } ], "repository_homepage_url": "https://pypi.org/project/click", @@ -1062,7 +1066,7 @@ "dependencies": [ { "purl": "pkg:pypi/six", - "extracted_requirement": "six>=1.10.0", + "extracted_requirement": ">=1.10.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1073,7 +1077,7 @@ }, { "purl": "pkg:pypi/zenhan", - "extracted_requirement": "zenhan>=0.5.2", + "extracted_requirement": ">=0.5.2", "scope": "install", "is_runtime": true, "is_optional": false, @@ -1084,7 +1088,7 @@ }, { "purl": "pkg:pypi/django", - "extracted_requirement": "django", + "extracted_requirement": null, "scope": "test", "is_runtime": true, "is_optional": false, @@ -1095,7 +1099,7 @@ }, { "purl": "pkg:pypi/pytest@2.9.1", - "extracted_requirement": "pytest==2.9.1", + "extracted_requirement": "==2.9.1", "scope": "test", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/solo-setup/expected.json b/tests/packagedcode/data/pypi/solo-setup/expected.json index fd8264aa6ea..53722beadde 100644 --- a/tests/packagedcode/data/pypi/solo-setup/expected.json +++ b/tests/packagedcode/data/pypi/solo-setup/expected.json @@ -108,7 +108,7 @@ "dependencies": [ { "purl": "pkg:pypi/cdp-backend@3.0.16", - "extracted_requirement": "cdp-backend[pipeline]==3.0.16", + "extracted_requirement": "==3.0.16", "scope": "install", "is_runtime": true, "is_optional": false, @@ -119,7 +119,7 @@ }, { "purl": "pkg:pypi/cdp-scrapers", - "extracted_requirement": "cdp-scrapers>=0.4.0", + "extracted_requirement": ">=0.4.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -130,7 +130,7 @@ }, { "purl": "pkg:pypi/black", - "extracted_requirement": "black>=19.10b0", + "extracted_requirement": ">=19.10b0", "scope": "test", "is_runtime": true, "is_optional": false, @@ -141,7 +141,7 @@ }, { "purl": "pkg:pypi/flake8", - "extracted_requirement": "flake8>=3.8.3", + "extracted_requirement": ">=3.8.3", "scope": "test", "is_runtime": true, "is_optional": false, @@ -152,7 +152,7 @@ }, { "purl": "pkg:pypi/flake8-debugger", - "extracted_requirement": "flake8-debugger>=3.2.1", + "extracted_requirement": ">=3.2.1", "scope": "test", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/data/pypi/unpacked_sdist/metadata-1.0/PyJPString-0.0.3-subdir-expected.json b/tests/packagedcode/data/pypi/unpacked_sdist/metadata-1.0/PyJPString-0.0.3-subdir-expected.json index df2af8a6a31..1c3feed700b 100644 --- a/tests/packagedcode/data/pypi/unpacked_sdist/metadata-1.0/PyJPString-0.0.3-subdir-expected.json +++ b/tests/packagedcode/data/pypi/unpacked_sdist/metadata-1.0/PyJPString-0.0.3-subdir-expected.json @@ -200,7 +200,7 @@ "dependencies": [ { "purl": "pkg:pypi/six", - "extracted_requirement": "six>=1.10.0", + "extracted_requirement": ">=1.10.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -211,7 +211,7 @@ }, { "purl": "pkg:pypi/zenhan", - "extracted_requirement": "zenhan>=0.5.2", + "extracted_requirement": ">=0.5.2", "scope": "install", "is_runtime": true, "is_optional": false, @@ -222,7 +222,7 @@ }, { "purl": "pkg:pypi/django", - "extracted_requirement": "django; extra == \"test\"", + "extracted_requirement": null, "scope": "test", "is_runtime": true, "is_optional": true, @@ -233,7 +233,7 @@ }, { "purl": "pkg:pypi/pytest@2.9.1", - "extracted_requirement": "pytest==2.9.1; extra == \"test\"", + "extracted_requirement": "==2.9.1", "scope": "test", "is_runtime": true, "is_optional": true, diff --git a/tests/packagedcode/data/pypi/unpacked_sdist/prefer-egg-info-pkg-info/celery-expected.json b/tests/packagedcode/data/pypi/unpacked_sdist/prefer-egg-info-pkg-info/celery-expected.json index 73d93cf8158..dcf38dcda11 100644 --- a/tests/packagedcode/data/pypi/unpacked_sdist/prefer-egg-info-pkg-info/celery-expected.json +++ b/tests/packagedcode/data/pypi/unpacked_sdist/prefer-egg-info-pkg-info/celery-expected.json @@ -125,7 +125,7 @@ "dependencies": [ { "purl": "pkg:pypi/pytz", - "extracted_requirement": "pytz>=2021.3", + "extracted_requirement": ">=2021.3", "scope": "install", "is_runtime": true, "is_optional": false, @@ -140,7 +140,7 @@ }, { "purl": "pkg:pypi/billiard", - "extracted_requirement": "billiard<4.0,>=3.6.4.0", + "extracted_requirement": "<4.0,>=3.6.4.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -155,7 +155,7 @@ }, { "purl": "pkg:pypi/kombu", - "extracted_requirement": "kombu<6.0,>=5.2.3", + "extracted_requirement": "<6.0,>=5.2.3", "scope": "install", "is_runtime": true, "is_optional": false, @@ -170,7 +170,7 @@ }, { "purl": "pkg:pypi/vine", - "extracted_requirement": "vine<6.0,>=5.0.0", + "extracted_requirement": "<6.0,>=5.0.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -185,7 +185,7 @@ }, { "purl": "pkg:pypi/click", - "extracted_requirement": "click<9.0,>=8.0.3", + "extracted_requirement": "<9.0,>=8.0.3", "scope": "install", "is_runtime": true, "is_optional": false, @@ -200,7 +200,7 @@ }, { "purl": "pkg:pypi/click-didyoumean", - "extracted_requirement": "click-didyoumean>=0.0.3", + "extracted_requirement": ">=0.0.3", "scope": "install", "is_runtime": true, "is_optional": false, @@ -215,7 +215,7 @@ }, { "purl": "pkg:pypi/click-repl", - "extracted_requirement": "click-repl>=0.2.0", + "extracted_requirement": ">=0.2.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -230,7 +230,7 @@ }, { "purl": "pkg:pypi/click-plugins", - "extracted_requirement": "click-plugins>=1.1.1", + "extracted_requirement": ">=1.1.1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -245,14 +245,16 @@ }, { "purl": "pkg:pypi/importlib-metadata", - "extracted_requirement": "importlib-metadata>=1.4.0; python_version < \"3.8\"", + "extracted_requirement": ">=1.4.0", "scope": "install", "is_runtime": true, "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, - "extra_data": {}, + "extra_data": { + "python_version": "< 3.8" + }, "dependency_uid": "pkg:pypi/importlib-metadata?uuid=fixed-uid-done-for-testing-5642512d1758", "for_package_uid": "pkg:pypi/celery@5.2.7?uuid=fixed-uid-done-for-testing-5642512d1758", "datafile_path": "celery/celery.egg-info/PKG-INFO", @@ -260,7 +262,7 @@ }, { "purl": "pkg:pypi/pyarango", - "extracted_requirement": "pyArango>=1.3.2; extra == \"arangodb\"", + "extracted_requirement": ">=1.3.2", "scope": "arangodb", "is_runtime": true, "is_optional": true, @@ -275,7 +277,7 @@ }, { "purl": "pkg:pypi/cryptography", - "extracted_requirement": "cryptography; extra == \"auth\"", + "extracted_requirement": null, "scope": "auth", "is_runtime": true, "is_optional": true, @@ -290,7 +292,7 @@ }, { "purl": "pkg:pypi/azure-storage-blob@12.9.0", - "extracted_requirement": "azure-storage-blob==12.9.0; extra == \"azureblockblob\"", + "extracted_requirement": "==12.9.0", "scope": "azureblockblob", "is_runtime": true, "is_optional": true, @@ -305,7 +307,7 @@ }, { "purl": "pkg:pypi/brotli", - "extracted_requirement": "brotli>=1.0.0; platform_python_implementation == \"CPython\" and extra == \"brotli\"", + "extracted_requirement": ">=1.0.0", "scope": "brotli", "is_runtime": true, "is_optional": true, @@ -320,7 +322,7 @@ }, { "purl": "pkg:pypi/brotlipy", - "extracted_requirement": "brotlipy>=0.7.0; platform_python_implementation == \"PyPy\" and extra == \"brotli\"", + "extracted_requirement": ">=0.7.0", "scope": "brotli", "is_runtime": true, "is_optional": true, @@ -335,7 +337,7 @@ }, { "purl": "pkg:pypi/cassandra-driver", - "extracted_requirement": "cassandra-driver<3.21.0; extra == \"cassandra\"", + "extracted_requirement": "<3.21.0", "scope": "cassandra", "is_runtime": true, "is_optional": true, @@ -350,7 +352,7 @@ }, { "purl": "pkg:pypi/python-consul2", - "extracted_requirement": "python-consul2; extra == \"consul\"", + "extracted_requirement": null, "scope": "consul", "is_runtime": true, "is_optional": true, @@ -365,7 +367,7 @@ }, { "purl": "pkg:pypi/pydocumentdb@2.3.2", - "extracted_requirement": "pydocumentdb==2.3.2; extra == \"cosmosdbsql\"", + "extracted_requirement": "==2.3.2", "scope": "cosmosdbsql", "is_runtime": true, "is_optional": true, @@ -380,7 +382,7 @@ }, { "purl": "pkg:pypi/couchbase", - "extracted_requirement": "couchbase>=3.0.0; (platform_python_implementation != \"PyPy\" and (platform_system != \"Windows\" or python_version < \"3.10\")) and extra == \"couchbase\"", + "extracted_requirement": ">=3.0.0", "scope": "couchbase", "is_runtime": true, "is_optional": true, @@ -395,7 +397,7 @@ }, { "purl": "pkg:pypi/pycouchdb", - "extracted_requirement": "pycouchdb; extra == \"couchdb\"", + "extracted_requirement": null, "scope": "couchdb", "is_runtime": true, "is_optional": true, @@ -410,7 +412,7 @@ }, { "purl": "pkg:pypi/django", - "extracted_requirement": "Django>=1.11; extra == \"django\"", + "extracted_requirement": ">=1.11", "scope": "django", "is_runtime": true, "is_optional": true, @@ -425,7 +427,7 @@ }, { "purl": "pkg:pypi/boto3", - "extracted_requirement": "boto3>=1.9.178; extra == \"dynamodb\"", + "extracted_requirement": ">=1.9.178", "scope": "dynamodb", "is_runtime": true, "is_optional": true, @@ -440,7 +442,7 @@ }, { "purl": "pkg:pypi/elasticsearch", - "extracted_requirement": "elasticsearch; extra == \"elasticsearch\"", + "extracted_requirement": null, "scope": "elasticsearch", "is_runtime": true, "is_optional": true, @@ -455,7 +457,7 @@ }, { "purl": "pkg:pypi/eventlet", - "extracted_requirement": "eventlet>=0.32.0; python_version < \"3.10\" and extra == \"eventlet\"", + "extracted_requirement": ">=0.32.0", "scope": "eventlet", "is_runtime": true, "is_optional": true, @@ -470,7 +472,7 @@ }, { "purl": "pkg:pypi/gevent", - "extracted_requirement": "gevent>=1.5.0; extra == \"gevent\"", + "extracted_requirement": ">=1.5.0", "scope": "gevent", "is_runtime": true, "is_optional": true, @@ -485,7 +487,7 @@ }, { "purl": "pkg:pypi/librabbitmq", - "extracted_requirement": "librabbitmq>=1.5.0; extra == \"librabbitmq\"", + "extracted_requirement": ">=1.5.0", "scope": "librabbitmq", "is_runtime": true, "is_optional": true, @@ -500,7 +502,7 @@ }, { "purl": "pkg:pypi/pylibmc", - "extracted_requirement": "pylibmc; platform_system != \"Windows\" and extra == \"memcache\"", + "extracted_requirement": null, "scope": "memcache", "is_runtime": true, "is_optional": true, @@ -515,7 +517,7 @@ }, { "purl": "pkg:pypi/pymongo", - "extracted_requirement": "pymongo[srv]>=3.11.1; extra == \"mongodb\"", + "extracted_requirement": ">=3.11.1", "scope": "mongodb", "is_runtime": true, "is_optional": true, @@ -530,7 +532,7 @@ }, { "purl": "pkg:pypi/msgpack", - "extracted_requirement": "msgpack; extra == \"msgpack\"", + "extracted_requirement": null, "scope": "msgpack", "is_runtime": true, "is_optional": true, @@ -545,7 +547,7 @@ }, { "purl": "pkg:pypi/python-memcached", - "extracted_requirement": "python-memcached; extra == \"pymemcache\"", + "extracted_requirement": null, "scope": "pymemcache", "is_runtime": true, "is_optional": true, @@ -560,7 +562,7 @@ }, { "purl": "pkg:pypi/pyro4", - "extracted_requirement": "pyro4; extra == \"pyro\"", + "extracted_requirement": null, "scope": "pyro", "is_runtime": true, "is_optional": true, @@ -575,7 +577,7 @@ }, { "purl": "pkg:pypi/pytest-celery", - "extracted_requirement": "pytest-celery; extra == \"pytest\"", + "extracted_requirement": null, "scope": "pytest", "is_runtime": true, "is_optional": true, @@ -590,7 +592,7 @@ }, { "purl": "pkg:pypi/redis", - "extracted_requirement": "redis!=4.0.0,!=4.0.1,>=3.4.1; extra == \"redis\"", + "extracted_requirement": "!=4.0.0,!=4.0.1,>=3.4.1", "scope": "redis", "is_runtime": true, "is_optional": true, @@ -605,7 +607,7 @@ }, { "purl": "pkg:pypi/boto3", - "extracted_requirement": "boto3>=1.9.125; extra == \"s3\"", + "extracted_requirement": ">=1.9.125", "scope": "s3", "is_runtime": true, "is_optional": true, @@ -620,7 +622,7 @@ }, { "purl": "pkg:pypi/softlayer-messaging", - "extracted_requirement": "softlayer_messaging>=1.0.3; extra == \"slmq\"", + "extracted_requirement": ">=1.0.3", "scope": "slmq", "is_runtime": true, "is_optional": true, @@ -635,7 +637,7 @@ }, { "purl": "pkg:pypi/ephem", - "extracted_requirement": "ephem; platform_python_implementation != \"PyPy\" and extra == \"solar\"", + "extracted_requirement": null, "scope": "solar", "is_runtime": true, "is_optional": true, @@ -650,7 +652,7 @@ }, { "purl": "pkg:pypi/sqlalchemy", - "extracted_requirement": "sqlalchemy; extra == \"sqlalchemy\"", + "extracted_requirement": null, "scope": "sqlalchemy", "is_runtime": true, "is_optional": true, @@ -665,7 +667,7 @@ }, { "purl": "pkg:pypi/kombu", - "extracted_requirement": "kombu[sqs]; extra == \"sqs\"", + "extracted_requirement": null, "scope": "sqs", "is_runtime": true, "is_optional": true, @@ -680,7 +682,7 @@ }, { "purl": "pkg:pypi/tblib", - "extracted_requirement": "tblib>=1.3.0; python_version < \"3.8.0\" and extra == \"tblib\"", + "extracted_requirement": ">=1.3.0", "scope": "tblib", "is_runtime": true, "is_optional": true, @@ -695,7 +697,7 @@ }, { "purl": "pkg:pypi/tblib", - "extracted_requirement": "tblib>=1.5.0; python_version >= \"3.8.0\" and extra == \"tblib\"", + "extracted_requirement": ">=1.5.0", "scope": "tblib", "is_runtime": true, "is_optional": true, @@ -710,7 +712,7 @@ }, { "purl": "pkg:pypi/pyyaml", - "extracted_requirement": "PyYAML>=3.10; extra == \"yaml\"", + "extracted_requirement": ">=3.10", "scope": "yaml", "is_runtime": true, "is_optional": true, @@ -725,7 +727,7 @@ }, { "purl": "pkg:pypi/kazoo", - "extracted_requirement": "kazoo>=1.3.1; extra == \"zookeeper\"", + "extracted_requirement": ">=1.3.1", "scope": "zookeeper", "is_runtime": true, "is_optional": true, @@ -740,7 +742,7 @@ }, { "purl": "pkg:pypi/zstandard", - "extracted_requirement": "zstandard; extra == \"zstd\"", + "extracted_requirement": null, "scope": "zstd", "is_runtime": true, "is_optional": true, @@ -6882,7 +6884,7 @@ "dependencies": [ { "purl": "pkg:pypi/pytz", - "extracted_requirement": "pytz>=2021.3", + "extracted_requirement": ">=2021.3", "scope": "install", "is_runtime": true, "is_optional": false, @@ -6893,7 +6895,7 @@ }, { "purl": "pkg:pypi/billiard", - "extracted_requirement": "billiard<4.0,>=3.6.4.0", + "extracted_requirement": "<4.0,>=3.6.4.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -6904,7 +6906,7 @@ }, { "purl": "pkg:pypi/kombu", - "extracted_requirement": "kombu<6.0,>=5.2.3", + "extracted_requirement": "<6.0,>=5.2.3", "scope": "install", "is_runtime": true, "is_optional": false, @@ -6915,7 +6917,7 @@ }, { "purl": "pkg:pypi/vine", - "extracted_requirement": "vine<6.0,>=5.0.0", + "extracted_requirement": "<6.0,>=5.0.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -6926,7 +6928,7 @@ }, { "purl": "pkg:pypi/click", - "extracted_requirement": "click<9.0,>=8.0.3", + "extracted_requirement": "<9.0,>=8.0.3", "scope": "install", "is_runtime": true, "is_optional": false, @@ -6937,7 +6939,7 @@ }, { "purl": "pkg:pypi/click-didyoumean", - "extracted_requirement": "click-didyoumean>=0.0.3", + "extracted_requirement": ">=0.0.3", "scope": "install", "is_runtime": true, "is_optional": false, @@ -6948,7 +6950,7 @@ }, { "purl": "pkg:pypi/click-repl", - "extracted_requirement": "click-repl>=0.2.0", + "extracted_requirement": ">=0.2.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -6959,7 +6961,7 @@ }, { "purl": "pkg:pypi/click-plugins", - "extracted_requirement": "click-plugins>=1.1.1", + "extracted_requirement": ">=1.1.1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -6970,18 +6972,20 @@ }, { "purl": "pkg:pypi/importlib-metadata", - "extracted_requirement": "importlib-metadata>=1.4.0; python_version < \"3.8\"", + "extracted_requirement": ">=1.4.0", "scope": "install", "is_runtime": true, "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, - "extra_data": {} + "extra_data": { + "python_version": "< 3.8" + } }, { "purl": "pkg:pypi/pyarango", - "extracted_requirement": "pyArango>=1.3.2; extra == \"arangodb\"", + "extracted_requirement": ">=1.3.2", "scope": "arangodb", "is_runtime": true, "is_optional": true, @@ -6992,7 +6996,7 @@ }, { "purl": "pkg:pypi/cryptography", - "extracted_requirement": "cryptography; extra == \"auth\"", + "extracted_requirement": null, "scope": "auth", "is_runtime": true, "is_optional": true, @@ -7003,7 +7007,7 @@ }, { "purl": "pkg:pypi/azure-storage-blob@12.9.0", - "extracted_requirement": "azure-storage-blob==12.9.0; extra == \"azureblockblob\"", + "extracted_requirement": "==12.9.0", "scope": "azureblockblob", "is_runtime": true, "is_optional": true, @@ -7014,7 +7018,7 @@ }, { "purl": "pkg:pypi/brotli", - "extracted_requirement": "brotli>=1.0.0; platform_python_implementation == \"CPython\" and extra == \"brotli\"", + "extracted_requirement": ">=1.0.0", "scope": "brotli", "is_runtime": true, "is_optional": true, @@ -7025,7 +7029,7 @@ }, { "purl": "pkg:pypi/brotlipy", - "extracted_requirement": "brotlipy>=0.7.0; platform_python_implementation == \"PyPy\" and extra == \"brotli\"", + "extracted_requirement": ">=0.7.0", "scope": "brotli", "is_runtime": true, "is_optional": true, @@ -7036,7 +7040,7 @@ }, { "purl": "pkg:pypi/cassandra-driver", - "extracted_requirement": "cassandra-driver<3.21.0; extra == \"cassandra\"", + "extracted_requirement": "<3.21.0", "scope": "cassandra", "is_runtime": true, "is_optional": true, @@ -7047,7 +7051,7 @@ }, { "purl": "pkg:pypi/python-consul2", - "extracted_requirement": "python-consul2; extra == \"consul\"", + "extracted_requirement": null, "scope": "consul", "is_runtime": true, "is_optional": true, @@ -7058,7 +7062,7 @@ }, { "purl": "pkg:pypi/pydocumentdb@2.3.2", - "extracted_requirement": "pydocumentdb==2.3.2; extra == \"cosmosdbsql\"", + "extracted_requirement": "==2.3.2", "scope": "cosmosdbsql", "is_runtime": true, "is_optional": true, @@ -7069,7 +7073,7 @@ }, { "purl": "pkg:pypi/couchbase", - "extracted_requirement": "couchbase>=3.0.0; (platform_python_implementation != \"PyPy\" and (platform_system != \"Windows\" or python_version < \"3.10\")) and extra == \"couchbase\"", + "extracted_requirement": ">=3.0.0", "scope": "couchbase", "is_runtime": true, "is_optional": true, @@ -7080,7 +7084,7 @@ }, { "purl": "pkg:pypi/pycouchdb", - "extracted_requirement": "pycouchdb; extra == \"couchdb\"", + "extracted_requirement": null, "scope": "couchdb", "is_runtime": true, "is_optional": true, @@ -7091,7 +7095,7 @@ }, { "purl": "pkg:pypi/django", - "extracted_requirement": "Django>=1.11; extra == \"django\"", + "extracted_requirement": ">=1.11", "scope": "django", "is_runtime": true, "is_optional": true, @@ -7102,7 +7106,7 @@ }, { "purl": "pkg:pypi/boto3", - "extracted_requirement": "boto3>=1.9.178; extra == \"dynamodb\"", + "extracted_requirement": ">=1.9.178", "scope": "dynamodb", "is_runtime": true, "is_optional": true, @@ -7113,7 +7117,7 @@ }, { "purl": "pkg:pypi/elasticsearch", - "extracted_requirement": "elasticsearch; extra == \"elasticsearch\"", + "extracted_requirement": null, "scope": "elasticsearch", "is_runtime": true, "is_optional": true, @@ -7124,7 +7128,7 @@ }, { "purl": "pkg:pypi/eventlet", - "extracted_requirement": "eventlet>=0.32.0; python_version < \"3.10\" and extra == \"eventlet\"", + "extracted_requirement": ">=0.32.0", "scope": "eventlet", "is_runtime": true, "is_optional": true, @@ -7135,7 +7139,7 @@ }, { "purl": "pkg:pypi/gevent", - "extracted_requirement": "gevent>=1.5.0; extra == \"gevent\"", + "extracted_requirement": ">=1.5.0", "scope": "gevent", "is_runtime": true, "is_optional": true, @@ -7146,7 +7150,7 @@ }, { "purl": "pkg:pypi/librabbitmq", - "extracted_requirement": "librabbitmq>=1.5.0; extra == \"librabbitmq\"", + "extracted_requirement": ">=1.5.0", "scope": "librabbitmq", "is_runtime": true, "is_optional": true, @@ -7157,7 +7161,7 @@ }, { "purl": "pkg:pypi/pylibmc", - "extracted_requirement": "pylibmc; platform_system != \"Windows\" and extra == \"memcache\"", + "extracted_requirement": null, "scope": "memcache", "is_runtime": true, "is_optional": true, @@ -7168,7 +7172,7 @@ }, { "purl": "pkg:pypi/pymongo", - "extracted_requirement": "pymongo[srv]>=3.11.1; extra == \"mongodb\"", + "extracted_requirement": ">=3.11.1", "scope": "mongodb", "is_runtime": true, "is_optional": true, @@ -7179,7 +7183,7 @@ }, { "purl": "pkg:pypi/msgpack", - "extracted_requirement": "msgpack; extra == \"msgpack\"", + "extracted_requirement": null, "scope": "msgpack", "is_runtime": true, "is_optional": true, @@ -7190,7 +7194,7 @@ }, { "purl": "pkg:pypi/python-memcached", - "extracted_requirement": "python-memcached; extra == \"pymemcache\"", + "extracted_requirement": null, "scope": "pymemcache", "is_runtime": true, "is_optional": true, @@ -7201,7 +7205,7 @@ }, { "purl": "pkg:pypi/pyro4", - "extracted_requirement": "pyro4; extra == \"pyro\"", + "extracted_requirement": null, "scope": "pyro", "is_runtime": true, "is_optional": true, @@ -7212,7 +7216,7 @@ }, { "purl": "pkg:pypi/pytest-celery", - "extracted_requirement": "pytest-celery; extra == \"pytest\"", + "extracted_requirement": null, "scope": "pytest", "is_runtime": true, "is_optional": true, @@ -7223,7 +7227,7 @@ }, { "purl": "pkg:pypi/redis", - "extracted_requirement": "redis!=4.0.0,!=4.0.1,>=3.4.1; extra == \"redis\"", + "extracted_requirement": "!=4.0.0,!=4.0.1,>=3.4.1", "scope": "redis", "is_runtime": true, "is_optional": true, @@ -7234,7 +7238,7 @@ }, { "purl": "pkg:pypi/boto3", - "extracted_requirement": "boto3>=1.9.125; extra == \"s3\"", + "extracted_requirement": ">=1.9.125", "scope": "s3", "is_runtime": true, "is_optional": true, @@ -7245,7 +7249,7 @@ }, { "purl": "pkg:pypi/softlayer-messaging", - "extracted_requirement": "softlayer_messaging>=1.0.3; extra == \"slmq\"", + "extracted_requirement": ">=1.0.3", "scope": "slmq", "is_runtime": true, "is_optional": true, @@ -7256,7 +7260,7 @@ }, { "purl": "pkg:pypi/ephem", - "extracted_requirement": "ephem; platform_python_implementation != \"PyPy\" and extra == \"solar\"", + "extracted_requirement": null, "scope": "solar", "is_runtime": true, "is_optional": true, @@ -7267,7 +7271,7 @@ }, { "purl": "pkg:pypi/sqlalchemy", - "extracted_requirement": "sqlalchemy; extra == \"sqlalchemy\"", + "extracted_requirement": null, "scope": "sqlalchemy", "is_runtime": true, "is_optional": true, @@ -7278,7 +7282,7 @@ }, { "purl": "pkg:pypi/kombu", - "extracted_requirement": "kombu[sqs]; extra == \"sqs\"", + "extracted_requirement": null, "scope": "sqs", "is_runtime": true, "is_optional": true, @@ -7289,7 +7293,7 @@ }, { "purl": "pkg:pypi/tblib", - "extracted_requirement": "tblib>=1.3.0; python_version < \"3.8.0\" and extra == \"tblib\"", + "extracted_requirement": ">=1.3.0", "scope": "tblib", "is_runtime": true, "is_optional": true, @@ -7300,7 +7304,7 @@ }, { "purl": "pkg:pypi/tblib", - "extracted_requirement": "tblib>=1.5.0; python_version >= \"3.8.0\" and extra == \"tblib\"", + "extracted_requirement": ">=1.5.0", "scope": "tblib", "is_runtime": true, "is_optional": true, @@ -7311,7 +7315,7 @@ }, { "purl": "pkg:pypi/pyyaml", - "extracted_requirement": "PyYAML>=3.10; extra == \"yaml\"", + "extracted_requirement": ">=3.10", "scope": "yaml", "is_runtime": true, "is_optional": true, @@ -7322,7 +7326,7 @@ }, { "purl": "pkg:pypi/kazoo", - "extracted_requirement": "kazoo>=1.3.1; extra == \"zookeeper\"", + "extracted_requirement": ">=1.3.1", "scope": "zookeeper", "is_runtime": true, "is_optional": true, @@ -7333,7 +7337,7 @@ }, { "purl": "pkg:pypi/zstandard", - "extracted_requirement": "zstandard; extra == \"zstd\"", + "extracted_requirement": null, "scope": "zstd", "is_runtime": true, "is_optional": true, 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 be181169dd8..9ecfc125423 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 @@ -111,7 +111,7 @@ "dependencies": [ { "purl": "pkg:pypi/dask", - "extracted_requirement": "dask[delayed]<2023.0.0,>=2022.7.1", + "extracted_requirement": "<2023.0.0,>=2022.7.1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -126,7 +126,7 @@ }, { "purl": "pkg:pypi/graphviz", - "extracted_requirement": "graphviz<0.21,>=0.20; extra == \"graphviz\"", + "extracted_requirement": "<0.21,>=0.20", "scope": "graphviz", "is_runtime": true, "is_optional": true, @@ -141,7 +141,7 @@ }, { "purl": "pkg:pypi/ipycytoscape", - "extracted_requirement": "ipycytoscape<2.0.0,>=1.3.3; extra == \"ipycytoscape\"", + "extracted_requirement": "<2.0.0,>=1.3.3", "scope": "ipycytoscape", "is_runtime": true, "is_optional": true, @@ -156,7 +156,7 @@ }, { "purl": "pkg:pypi/networkx", - "extracted_requirement": "networkx<3.0.0,>=2.8.5", + "extracted_requirement": "<3.0.0,>=2.8.5", "scope": "install", "is_runtime": true, "is_optional": false, @@ -368,7 +368,7 @@ "dependencies": [ { "purl": "pkg:pypi/dask", - "extracted_requirement": "dask[delayed]<2023.0.0,>=2022.7.1", + "extracted_requirement": "<2023.0.0,>=2022.7.1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -379,7 +379,7 @@ }, { "purl": "pkg:pypi/graphviz", - "extracted_requirement": "graphviz<0.21,>=0.20; extra == \"graphviz\"", + "extracted_requirement": "<0.21,>=0.20", "scope": "graphviz", "is_runtime": true, "is_optional": true, @@ -390,7 +390,7 @@ }, { "purl": "pkg:pypi/ipycytoscape", - "extracted_requirement": "ipycytoscape<2.0.0,>=1.3.3; extra == \"ipycytoscape\"", + "extracted_requirement": "<2.0.0,>=1.3.3", "scope": "ipycytoscape", "is_runtime": true, "is_optional": true, @@ -401,7 +401,7 @@ }, { "purl": "pkg:pypi/networkx", - "extracted_requirement": "networkx<3.0.0,>=2.8.5", + "extracted_requirement": "<3.0.0,>=2.8.5", "scope": "install", "is_runtime": true, "is_optional": false, 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 66756736502..bfaf6b1015e 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 @@ -677,7 +677,7 @@ "dependencies": [ { "purl": "pkg:pypi/markupsafe", - "extracted_requirement": "MarkupSafe>=0.23", + "extracted_requirement": ">=0.23", "scope": "install", "is_runtime": true, "is_optional": false, @@ -688,7 +688,7 @@ }, { "purl": "pkg:pypi/babel", - "extracted_requirement": "Babel>=0.8; extra == \"i18n\"", + "extracted_requirement": ">=0.8", "scope": "i18n", "is_runtime": true, "is_optional": true, 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 7c8679fd9a9..cc0a84635d2 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 @@ -887,7 +887,7 @@ "dependencies": [ { "purl": "pkg:pypi/pyopenssl", - "extracted_requirement": "pyOpenSSL>=0.14; extra == \"secure\"", + "extracted_requirement": ">=0.14", "scope": "secure", "is_runtime": true, "is_optional": true, @@ -898,7 +898,7 @@ }, { "purl": "pkg:pypi/cryptography", - "extracted_requirement": "cryptography>=1.3.4; extra == \"secure\"", + "extracted_requirement": ">=1.3.4", "scope": "secure", "is_runtime": true, "is_optional": true, @@ -909,7 +909,7 @@ }, { "purl": "pkg:pypi/idna", - "extracted_requirement": "idna>=2.0.0; extra == \"secure\"", + "extracted_requirement": ">=2.0.0", "scope": "secure", "is_runtime": true, "is_optional": true, @@ -920,7 +920,7 @@ }, { "purl": "pkg:pypi/certifi", - "extracted_requirement": "certifi; extra == \"secure\"", + "extracted_requirement": null, "scope": "secure", "is_runtime": true, "is_optional": true, @@ -931,18 +931,20 @@ }, { "purl": "pkg:pypi/ipaddress", - "extracted_requirement": "ipaddress; python_version == \"2.7\" and extra == \"secure\"", + "extracted_requirement": null, "scope": "secure", "is_runtime": true, "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, - "extra_data": {} + "extra_data": { + "python_version": "== 2.7" + } }, { "purl": "pkg:pypi/pysocks", - "extracted_requirement": "PySocks!=1.5.7,<2.0,>=1.5.6; extra == \"socks\"", + "extracted_requirement": "!=1.5.7,<2.0,>=1.5.6", "scope": "socks", "is_runtime": true, "is_optional": true, @@ -953,7 +955,7 @@ }, { "purl": "pkg:pypi/brotlipy", - "extracted_requirement": "brotlipy>=0.6.0; extra == \"brotli\"", + "extracted_requirement": ">=0.6.0", "scope": "brotli", "is_runtime": true, "is_optional": true, 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 c8f0d0a9621..5bd15d717ef 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 @@ -284,7 +284,7 @@ "dependencies": [ { "purl": "pkg:pypi/click", - "extracted_requirement": "click<8.0.0,>=7.1.2", + "extracted_requirement": "<8.0.0,>=7.1.2", "scope": "install", "is_runtime": true, "is_optional": false, @@ -295,7 +295,7 @@ }, { "purl": "pkg:pypi/httpx", - "extracted_requirement": "httpx<0.18.0,>=0.17.0", + "extracted_requirement": "<0.18.0,>=0.17.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -306,7 +306,7 @@ }, { "purl": "pkg:pypi/nonebot-adapter-cqhttp", - "extracted_requirement": "nonebot-adapter-cqhttp<3.0.0,>=2.0.0-alpha.11", + "extracted_requirement": "<3.0.0,>=2.0.0-alpha.11", "scope": "install", "is_runtime": true, "is_optional": false, @@ -317,7 +317,7 @@ }, { "purl": "pkg:pypi/nonebot-plugin-apscheduler", - "extracted_requirement": "nonebot-plugin-apscheduler<0.2.0,>=0.1.2", + "extracted_requirement": "<0.2.0,>=0.1.2", "scope": "install", "is_runtime": true, "is_optional": false, @@ -328,7 +328,7 @@ }, { "purl": "pkg:pypi/nonebot2", - "extracted_requirement": "nonebot2<3.0.0,>=2.0.0-alpha.11", + "extracted_requirement": "<3.0.0,>=2.0.0-alpha.11", "scope": "install", "is_runtime": true, "is_optional": false, @@ -339,7 +339,7 @@ }, { "purl": "pkg:pypi/packaging", - "extracted_requirement": "packaging<21.0,>=20.9", + "extracted_requirement": "<21.0,>=20.9", "scope": "install", "is_runtime": true, "is_optional": false, @@ -350,7 +350,7 @@ }, { "purl": "pkg:pypi/pydantic", - "extracted_requirement": "pydantic<2.0.0,>=1.8.1", + "extracted_requirement": "<2.0.0,>=1.8.1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -361,7 +361,7 @@ }, { "purl": "pkg:pypi/pyppeteer", - "extracted_requirement": "pyppeteer<0.3.0,>=0.2.5", + "extracted_requirement": "<0.3.0,>=0.2.5", "scope": "install", "is_runtime": true, "is_optional": false, @@ -372,7 +372,7 @@ }, { "purl": "pkg:pypi/python-dotenv", - "extracted_requirement": "python-dotenv<0.16.0,>=0.15.0", + "extracted_requirement": "<0.16.0,>=0.15.0", "scope": "install", "is_runtime": true, "is_optional": false, @@ -383,7 +383,7 @@ }, { "purl": "pkg:pypi/qrcode", - "extracted_requirement": "qrcode[pil]<7.0,>=6.1", + "extracted_requirement": "<7.0,>=6.1", "scope": "install", "is_runtime": true, "is_optional": false, @@ -394,7 +394,7 @@ }, { "purl": "pkg:pypi/rsa", - "extracted_requirement": "rsa<5.0,>=4.7", + "extracted_requirement": "<5.0,>=4.7", "scope": "install", "is_runtime": true, "is_optional": false, @@ -405,7 +405,7 @@ }, { "purl": "pkg:pypi/tinydb", - "extracted_requirement": "tinydb<5.0.0,>=4.3.0", + "extracted_requirement": "<5.0.0,>=4.3.0", "scope": "install", "is_runtime": true, "is_optional": false, 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 bad341294df..602855ab8db 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 @@ -290,7 +290,7 @@ "dependencies": [ { "purl": "pkg:pypi/click", - "extracted_requirement": "click>=6", + "extracted_requirement": ">=6", "scope": "install", "is_runtime": true, "is_optional": false, @@ -301,7 +301,7 @@ }, { "purl": "pkg:pypi/commoncode", - "extracted_requirement": "commoncode>=21.1.21", + "extracted_requirement": ">=21.1.21", "scope": "install", "is_runtime": true, "is_optional": false, @@ -312,7 +312,7 @@ }, { "purl": "pkg:pypi/pluggy", - "extracted_requirement": "pluggy", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, @@ -323,7 +323,7 @@ }, { "purl": "pkg:pypi/sphinx", - "extracted_requirement": "Sphinx>=3.3.1; extra == \"docs\"", + "extracted_requirement": ">=3.3.1", "scope": "docs", "is_runtime": true, "is_optional": true, @@ -334,7 +334,7 @@ }, { "purl": "pkg:pypi/sphinx-rtd-theme", - "extracted_requirement": "sphinx-rtd-theme>=0.5.0; extra == \"docs\"", + "extracted_requirement": ">=0.5.0", "scope": "docs", "is_runtime": true, "is_optional": true, @@ -345,7 +345,7 @@ }, { "purl": "pkg:pypi/doc8", - "extracted_requirement": "doc8>=0.8.1; extra == \"docs\"", + "extracted_requirement": ">=0.8.1", "scope": "docs", "is_runtime": true, "is_optional": true, @@ -356,7 +356,7 @@ }, { "purl": "pkg:pypi/pytest", - "extracted_requirement": "pytest>=6; extra == \"testing\"", + "extracted_requirement": ">=6", "scope": "testing", "is_runtime": true, "is_optional": true, @@ -367,7 +367,7 @@ }, { "purl": "pkg:pypi/pytest-xdist", - "extracted_requirement": "pytest-xdist>=2; extra == \"testing\"", + "extracted_requirement": ">=2", "scope": "testing", "is_runtime": true, "is_optional": true, 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 0bd15f9e322..866bd8a17de 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 @@ -208,7 +208,7 @@ "dependencies": [ { "purl": "pkg:pypi/pyyaml", - "extracted_requirement": "pyyaml", + "extracted_requirement": null, "scope": "install", "is_runtime": true, "is_optional": false, diff --git a/tests/packagedcode/test_pypi.py b/tests/packagedcode/test_pypi.py index a315dd19e1d..4af155f38f2 100644 --- a/tests/packagedcode/test_pypi.py +++ b/tests/packagedcode/test_pypi.py @@ -356,6 +356,12 @@ def test_is_pip_inspect_deplock(self): test_file = self.get_test_loc('pypi/deplock/univers/pip-inspect.deplock') assert pypi.PipInspectDeplockHandler.is_datafile(test_file) + def test_parse_pip_inspect_deplock_simple(self): + test_file = self.get_test_loc('pypi/deplock/simple/pip-inspect.deplock') + package = pypi.PipInspectDeplockHandler.parse(test_file) + expected_loc = self.get_test_loc('pypi/deplock/simple/pip-inspect.deplock-expected.json') + self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) + def test_parse_pip_inspect_deplock_univers(self): test_file = self.get_test_loc('pypi/deplock/univers/pip-inspect.deplock') package = pypi.PipInspectDeplockHandler.parse(test_file) diff --git a/tests/summarycode/data/summary/use_holder_from_package_resource/use_holder_from_package_resource.expected.json b/tests/summarycode/data/summary/use_holder_from_package_resource/use_holder_from_package_resource.expected.json index 96000831cc1..fec55837a6e 100644 --- a/tests/summarycode/data/summary/use_holder_from_package_resource/use_holder_from_package_resource.expected.json +++ b/tests/summarycode/data/summary/use_holder_from_package_resource/use_holder_from_package_resource.expected.json @@ -109,7 +109,7 @@ "dependencies": [ { "purl": "pkg:pypi/pybind11", - "extracted_requirement": "pybind11>=2.5.0", + "extracted_requirement": ">=2.5.0", "scope": "setup", "is_runtime": true, "is_optional": false, @@ -330,7 +330,7 @@ "dependencies": [ { "purl": "pkg:pypi/pybind11", - "extracted_requirement": "pybind11>=2.5.0", + "extracted_requirement": ">=2.5.0", "scope": "setup", "is_runtime": true, "is_optional": false, From bc22ee99f8cf22f378900b8cd1c5b47c0a73e507 Mon Sep 17 00:00:00 2001 From: Ayan Sinha Mahapatra Date: Mon, 1 Jul 2024 13:18:06 +0530 Subject: [PATCH 04/10] Add poetry and pyproject.toml support * Add poetry.lock support * Add pyproject.toml dependencies support for poetry * Add pyproject.toml dependencies support for standard python projects * Add poetry package assembly Reference: https://github.com/nexB/scancode-toolkit/issues/3753 Reference: https://github.com/nexB/scancode-toolkit/issues/2109 Signed-off-by: Ayan Sinha Mahapatra --- src/packagedcode/__init__.py | 1 + src/packagedcode/pypi.py | 260 ++- tests/packagedcode/data/plugin/help.txt | 7 + .../univers-package-assembly-expected.json | 1988 +++++++++++++++++ .../poetry/univers-poetry.lock-expected.json | 863 +++++++ .../univers-pyproject.toml-expected.json | 122 + .../data/pypi/poetry/univers/poetry.lock | 77 + .../data/pypi/poetry/univers/pyproject.toml | 18 + .../connexion-pyproject.toml-expected.json | 439 ++++ .../poetry/connexion/pyproject.toml | 111 + .../gerapy-pyproject.toml-expected.json | 234 +- .../poetry/gino-pyproject.toml-expected.json | 272 ++- ...flow-pyclient-pyproject.toml-expected.json | 25 +- .../attrs-pyproject.toml-expected.json | 218 +- .../flask-pyproject.toml-expected.json | 93 +- tests/packagedcode/test_pypi.py | 36 +- 16 files changed, 4755 insertions(+), 9 deletions(-) create mode 100644 tests/packagedcode/data/pypi/poetry/univers-package-assembly-expected.json create mode 100644 tests/packagedcode/data/pypi/poetry/univers-poetry.lock-expected.json create mode 100644 tests/packagedcode/data/pypi/poetry/univers-pyproject.toml-expected.json create mode 100644 tests/packagedcode/data/pypi/poetry/univers/poetry.lock create mode 100644 tests/packagedcode/data/pypi/poetry/univers/pyproject.toml create mode 100644 tests/packagedcode/data/pypi/pyproject-toml/poetry/connexion-pyproject.toml-expected.json create mode 100644 tests/packagedcode/data/pypi/pyproject-toml/poetry/connexion/pyproject.toml diff --git a/src/packagedcode/__init__.py b/src/packagedcode/__init__.py index 554fbd0e8b6..629a1655de2 100644 --- a/src/packagedcode/__init__.py +++ b/src/packagedcode/__init__.py @@ -174,6 +174,7 @@ pypi.PypiWheelHandler, pypi.PyprojectTomlHandler, pypi.PoetryPyprojectTomlHandler, + pypi.PoetryLockHandler, pypi.PythonEditableInstallationPkgInfoFile, pypi.PythonEggPkgInfoFile, pypi.PythonInstalledWheelMetadataFile, diff --git a/src/packagedcode/pypi.py b/src/packagedcode/pypi.py index 6c2c0924326..deba7631d0f 100644 --- a/src/packagedcode/pypi.py +++ b/src/packagedcode/pypi.py @@ -484,6 +484,19 @@ def parse(cls, location, package_only=False): if license_file: extra_data['license_file'] = license_file + dependencies = [] + parsed_dependencies = get_requires_dependencies( + requires=project_data.get("dependencies", []), + ) + dependencies.extend(parsed_dependencies) + + for dep_type, deps in project_data.get("optional-dependencies", {}).items(): + parsed_dependencies = get_requires_dependencies( + requires=deps, + default_scope=dep_type, + ) + dependencies.extend(parsed_dependencies) + package_data = dict( datasource_id=cls.datasource_id, type=cls.default_package_type, @@ -494,6 +507,7 @@ def parse(cls, location, package_only=False): description=description, keywords=get_keywords(project_data), parties=get_pyproject_toml_parties(project_data), + dependencies=dependencies, extra_data=extra_data, **urls, ) @@ -510,7 +524,75 @@ def is_poetry_pyproject_toml(location): return False -class PoetryPyprojectTomlHandler(BaseExtractedPythonLayout): +class BasePoetryPythonLayout(BaseExtractedPythonLayout): + """ + Base class for poetry python projects. + """ + + @classmethod + def assemble(cls, package_data, resource, codebase, package_adder): + + package_resource = None + if resource.name == 'pyproject.toml': + package_resource = resource + elif resource.name == 'poetry.lock': + if resource.has_parent(): + siblings = resource.siblings(codebase) + package_resource = [r for r in siblings if r.name == 'pyproject.toml'] + if package_resource: + package_resource = package_resource[0] + + if not package_resource: + # we do not have a pyproject.toml + yield from yield_dependencies_from_package_resource(resource) + return + + if codebase.has_single_resource: + yield from models.DatafileHandler.assemble(package_data, resource, codebase, package_adder) + return + + assert len(package_resource.package_data) == 1, f'Invalid pyproject.toml for {package_resource.path}' + pkg_data = package_resource.package_data[0] + pkg_data = models.PackageData.from_dict(pkg_data) + + if pkg_data.purl: + package = models.Package.from_package_data( + package_data=pkg_data, + datafile_path=package_resource.path, + ) + package_uid = package.package_uid + package.populate_license_fields() + yield package + + root = package_resource.parent(codebase) + if root: + for pypi_res in cls.walk_pypi(resource=root, codebase=codebase): + if package_uid and package_uid not in pypi_res.for_packages: + package_adder(package_uid, pypi_res, codebase) + yield pypi_res + + yield package_resource + + else: + # we have no package, so deps are not for a specific package uid + package_uid = None + + # in all cases yield possible dependencies + yield from yield_dependencies_from_package_data(pkg_data, package_resource.path, package_uid) + + # we yield this as we do not want this further processed + yield package_resource + + for lock_file in package_resource.siblings(codebase): + if lock_file.name == 'poetry.lock': + yield from yield_dependencies_from_package_resource(lock_file, package_uid) + + if package_uid and package_uid not in lock_file.for_packages: + package_adder(package_uid, lock_file, codebase) + yield lock_file + + +class PoetryPyprojectTomlHandler(BasePoetryPythonLayout): datasource_id = 'pypi_poetry_pyproject_toml' path_patterns = ('*pyproject.toml',) default_package_type = 'pypi' @@ -525,6 +607,45 @@ def is_datafile(cls, location, filetypes=tuple()): and is_poetry_pyproject_toml(location) ) + @classmethod + def parse_non_group_dependencies(cls, dependencies, dev=False): + dependency_mappings = [] + for dep_name, requirement in dependencies.items(): + if not dev and dep_name == "python": + continue + + purl = PackageURL( + type=cls.default_package_type, + name=dep_name, + ) + is_optional = False + if dev: + is_optional = True + + extra_data = {} + if isinstance(requirement, str): + extracted_requirement = requirement + elif isinstance(requirement, dict): + extracted_requirement = requirement.get("version") + is_optional = requirement.get("optional", is_optional) + python_version = requirement.get("python") + if python_version: + extra_data["python_version"] = python_version + + dependency = models.DependentPackage( + purl=purl.to_string(), + extracted_requirement=extracted_requirement, + scope="install", + is_runtime=True, + is_optional=is_optional, + is_direct=True, + is_resolved=False, + extra_data=extra_data, + ) + dependency_mappings.append(dependency.to_dict()) + + return dependency_mappings + @classmethod def parse(cls, location, package_only=False): toml_data = toml.load(location, _dict=dict) @@ -532,7 +653,7 @@ def parse(cls, location, package_only=False): tool_data = toml_data.get('tool') if not tool_data: return - + poetry_data = tool_data.get('poetry') if not poetry_data: return @@ -548,6 +669,34 @@ def parse(cls, location, package_only=False): if license_file: extra_data['license_file'] = license_file + dependencies = [] + parsed_deps = cls.parse_non_group_dependencies( + dependencies=poetry_data.get("dependencies", {}), + ) + dependencies.extend(parsed_deps) + parsed_deps = cls.parse_non_group_dependencies( + dependencies=poetry_data.get("dev-dependencies", {}), + dev=True, + ) + dependencies.extend(parsed_deps) + + for group_name, group_deps in poetry_data.get("group", {}).items(): + for name, requirement in group_deps.get("dependencies", {}).items(): + purl = PackageURL( + type=cls.default_package_type, + name=name, + ) + dependency = models.DependentPackage( + purl=purl.to_string(), + extracted_requirement=requirement, + scope=group_name, + is_runtime=True, + is_optional=False, + is_direct=True, + is_resolved=False, + ) + dependencies.append(dependency.to_dict()) + package_data = dict( datasource_id=cls.datasource_id, type=cls.default_package_type, @@ -559,11 +708,118 @@ def parse(cls, location, package_only=False): keywords=get_keywords(poetry_data), parties=get_pyproject_toml_parties(poetry_data), extra_data=extra_data, + dependencies=dependencies, **urls, ) yield models.PackageData.from_data(package_data, package_only) +class PoetryLockHandler(BasePoetryPythonLayout): + datasource_id = 'pypi_poetry_lock' + path_patterns = ('*poetry.lock',) + default_package_type = 'pypi' + default_primary_language = 'Python' + description = 'Python poetry lockfile' + documentation_url = 'https://python-poetry.org/docs/basic-usage/#installing-with-poetrylock' + + @classmethod + def parse(cls, location, package_only=False): + toml_data = toml.load(location, _dict=dict) + + packages = toml_data.get('package') + if not packages: + return + + metadata = toml_data.get('metadata') + + dependencies = [] + for package in packages: + dependencies_for_resolved = [] + + deps = package.get("dependencies") or {} + for name, requirement in deps.items(): + purl = PackageURL( + type=cls.default_package_type, + name=name, + ) + dependency = models.DependentPackage( + purl=purl.to_string(), + extracted_requirement=requirement, + scope="install", + is_runtime=True, + is_optional=False, + is_direct=True, + is_resolved=False, + ) + dependencies_for_resolved.append(dependency.to_dict()) + + extra_deps = package.get("extras") or {} + for group_name, group_deps in extra_deps.items(): + for dep in group_deps: + if " (" in dep and ")" in dep: + name, requirement = dep.split(" (") + requirement = requirement.rstrip(")") + else: + requirement = None + name = dep + purl = PackageURL( + type=cls.default_package_type, + name=name, + ) + dependency = models.DependentPackage( + purl=purl.to_string(), + extracted_requirement=requirement, + scope=group_name, + is_runtime=True, + is_optional=True, + is_direct=True, + is_resolved=False, + ) + dependencies_for_resolved.append(dependency.to_dict()) + + name = package.get('name') + version = package.get('version') + urls = get_pypi_urls(name, version) + package_data = dict( + datasource_id=cls.datasource_id, + type=cls.default_package_type, + primary_language='Python', + name=name, + version=version, + description=metadata.get('description'), + is_virtual=True, + dependencies=dependencies_for_resolved, + **urls, + ) + resolved_package = models.PackageData.from_data(package_data, package_only) + + is_optional = package.get("is_optional") or True + dependency = models.DependentPackage( + purl=resolved_package.purl, + extracted_requirement=None, + scope=None, + is_runtime=True, + is_optional=is_optional, + is_direct=False, + is_resolved=True, + resolved_package=resolved_package.to_dict() + ) + dependencies.append(dependency.to_dict()) + + extra_data = {} + extra_data['python_version'] = metadata.get("python-versions") + extra_data['lock_version'] = metadata.get("lock-version") + + package_data = dict( + datasource_id=cls.datasource_id, + type=cls.default_package_type, + primary_language='Python', + extra_data=extra_data, + dependencies=dependencies, + ) + yield models.PackageData.from_data(package_data, package_only) + + class PipInspectDeplockHandler(models.DatafileHandler): datasource_id = 'pypi_inspect_deplock' path_patterns = ('*pip-inspect.deplock',) diff --git a/tests/packagedcode/data/plugin/help.txt b/tests/packagedcode/data/plugin/help.txt index 62a5cad63ce..7128425a969 100755 --- a/tests/packagedcode/data/plugin/help.txt +++ b/tests/packagedcode/data/plugin/help.txt @@ -727,6 +727,13 @@ Package type: pypi description: Python poetry pyproject.toml path_patterns: '*pip-inspect.deplock' -------------------------------------------- +Package type: pypi + datasource_id: pypi_poetry_lock + documentation URL: https://python-poetry.org/docs/basic-usage/#installing-with-poetrylock + primary language: Python + description: Python poetry lockfile + path_patterns: '*poetry.lock' +-------------------------------------------- Package type: pypi datasource_id: pypi_poetry_pyproject_toml documentation URL: https://packaging.python.org/en/latest/specifications/pyproject-toml/ diff --git a/tests/packagedcode/data/pypi/poetry/univers-package-assembly-expected.json b/tests/packagedcode/data/pypi/poetry/univers-package-assembly-expected.json new file mode 100644 index 00000000000..b20a29ed09c --- /dev/null +++ b/tests/packagedcode/data/pypi/poetry/univers-package-assembly-expected.json @@ -0,0 +1,1988 @@ +{ + "packages": [ + { + "type": "pypi", + "namespace": null, + "name": "univers", + "version": "0.1.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "A mostly universal library to parse and compare software package versions and version ranges. A companion to Package URLs.", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "nexB. Inc.", + "email": "info@aboutcode.org", + "url": null + } + ], + "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": "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", + "spdx_license_expression": "Apache-2.0", + "from_file": "univers/pyproject.toml", + "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": [], + "is_private": false, + "is_virtual": false, + "extra_data": {}, + "repository_homepage_url": "https://pypi.org/project/univers", + "repository_download_url": "https://pypi.org/packages/source/u/univers/univers-0.1.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/univers/0.1.0/json", + "package_uid": "pkg:pypi/univers@0.1.0?uuid=fixed-uid-done-for-testing-5642512d1758", + "datafile_paths": [ + "univers/pyproject.toml" + ], + "datasource_ids": [ + "pypi_poetry_pyproject_toml" + ], + "purl": "pkg:pypi/univers@0.1.0" + } + ], + "dependencies": [ + { + "purl": "pkg:pypi/attrs", + "extracted_requirement": "^21.2.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {}, + "dependency_uid": "pkg:pypi/attrs?uuid=fixed-uid-done-for-testing-5642512d1758", + "for_package_uid": "pkg:pypi/univers@0.1.0?uuid=fixed-uid-done-for-testing-5642512d1758", + "datafile_path": "univers/pyproject.toml", + "datasource_id": "pypi_poetry_pyproject_toml" + }, + { + "purl": "pkg:pypi/packaging", + "extracted_requirement": "21.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {}, + "dependency_uid": "pkg:pypi/packaging?uuid=fixed-uid-done-for-testing-5642512d1758", + "for_package_uid": "pkg:pypi/univers@0.1.0?uuid=fixed-uid-done-for-testing-5642512d1758", + "datafile_path": "univers/pyproject.toml", + "datasource_id": "pypi_poetry_pyproject_toml" + }, + { + "purl": "pkg:pypi/semantic-version", + "extracted_requirement": "^2.8.5", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {}, + "dependency_uid": "pkg:pypi/semantic-version?uuid=fixed-uid-done-for-testing-5642512d1758", + "for_package_uid": "pkg:pypi/univers@0.1.0?uuid=fixed-uid-done-for-testing-5642512d1758", + "datafile_path": "univers/pyproject.toml", + "datasource_id": "pypi_poetry_pyproject_toml" + }, + { + "purl": "pkg:pypi/semver", + "extracted_requirement": "^2.13.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {}, + "dependency_uid": "pkg:pypi/semver?uuid=fixed-uid-done-for-testing-5642512d1758", + "for_package_uid": "pkg:pypi/univers@0.1.0?uuid=fixed-uid-done-for-testing-5642512d1758", + "datafile_path": "univers/pyproject.toml", + "datasource_id": "pypi_poetry_pyproject_toml" + }, + { + "purl": "pkg:pypi/attrs@21.4.0", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": true, + "is_resolved": true, + "is_direct": false, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "attrs", + "version": "21.4.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [ + { + "purl": "pkg:pypi/cloudpickle", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/coverage%5btoml%5d", + "extracted_requirement": ">=5.0.2", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/furo", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/hypothesis", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/mypy", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": 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_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pympler", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": ">=4.3.0", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-mypy-plugins", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/six", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-notfound-page", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/zope.interface", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/furo", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-notfound-page", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/zope.interface", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/cloudpickle", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/coverage%5btoml%5d", + "extracted_requirement": ">=5.0.2", + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/hypothesis", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/mypy", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pympler", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": ">=4.3.0", + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-mypy-plugins", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/six", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/zope.interface", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/cloudpickle", + "extracted_requirement": null, + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/coverage%5btoml%5d", + "extracted_requirement": ">=5.0.2", + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/hypothesis", + "extracted_requirement": null, + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/mypy", + "extracted_requirement": null, + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pympler", + "extracted_requirement": null, + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": ">=4.3.0", + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-mypy-plugins", + "extracted_requirement": null, + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/six", + "extracted_requirement": null, + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": "https://pypi.org/project/attrs", + "repository_download_url": "https://pypi.org/packages/source/a/attrs/attrs-21.4.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/attrs/21.4.0/json", + "datasource_id": "pypi_poetry_lock", + "purl": "pkg:pypi/attrs@21.4.0" + }, + "extra_data": {}, + "dependency_uid": "pkg:pypi/attrs@21.4.0?uuid=fixed-uid-done-for-testing-5642512d1758", + "for_package_uid": "pkg:pypi/univers@0.1.0?uuid=fixed-uid-done-for-testing-5642512d1758", + "datafile_path": "univers/poetry.lock", + "datasource_id": "pypi_poetry_lock" + }, + { + "purl": "pkg:pypi/packaging@21.0", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": true, + "is_resolved": true, + "is_direct": false, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "packaging", + "version": "21.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [ + { + "purl": "pkg:pypi/pyparsing", + "extracted_requirement": ">=2.0.2", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": "https://pypi.org/project/packaging", + "repository_download_url": "https://pypi.org/packages/source/p/packaging/packaging-21.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/packaging/21.0/json", + "datasource_id": "pypi_poetry_lock", + "purl": "pkg:pypi/packaging@21.0" + }, + "extra_data": {}, + "dependency_uid": "pkg:pypi/packaging@21.0?uuid=fixed-uid-done-for-testing-5642512d1758", + "for_package_uid": "pkg:pypi/univers@0.1.0?uuid=fixed-uid-done-for-testing-5642512d1758", + "datafile_path": "univers/poetry.lock", + "datasource_id": "pypi_poetry_lock" + }, + { + "purl": "pkg:pypi/pyparsing@3.1.2", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": true, + "is_resolved": true, + "is_direct": false, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "pyparsing", + "version": "3.1.2", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [ + { + "purl": "pkg:pypi/jinja2", + "extracted_requirement": null, + "scope": "diagrams", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/railroad-diagrams", + "extracted_requirement": null, + "scope": "diagrams", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": "https://pypi.org/project/pyparsing", + "repository_download_url": "https://pypi.org/packages/source/p/pyparsing/pyparsing-3.1.2.tar.gz", + "api_data_url": "https://pypi.org/pypi/pyparsing/3.1.2/json", + "datasource_id": "pypi_poetry_lock", + "purl": "pkg:pypi/pyparsing@3.1.2" + }, + "extra_data": {}, + "dependency_uid": "pkg:pypi/pyparsing@3.1.2?uuid=fixed-uid-done-for-testing-5642512d1758", + "for_package_uid": "pkg:pypi/univers@0.1.0?uuid=fixed-uid-done-for-testing-5642512d1758", + "datafile_path": "univers/poetry.lock", + "datasource_id": "pypi_poetry_lock" + }, + { + "purl": "pkg:pypi/semantic-version@2.10.0", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": true, + "is_resolved": true, + "is_direct": false, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "semantic-version", + "version": "2.10.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [ + { + "purl": "pkg:pypi/django", + "extracted_requirement": ">=1.11", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/check-manifest", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/colorama", + "extracted_requirement": "<=0.4.1", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/coverage", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/flake8", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/nose2", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/readme-renderer", + "extracted_requirement": "<25.0", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/tox", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/wheel", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/zest.releaser%5brecommended%5d", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx", + "extracted_requirement": null, + "scope": "doc", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-rtd-theme", + "extracted_requirement": null, + "scope": "doc", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": "https://pypi.org/project/semantic-version", + "repository_download_url": "https://pypi.org/packages/source/s/semantic-version/semantic-version-2.10.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/semantic-version/2.10.0/json", + "datasource_id": "pypi_poetry_lock", + "purl": "pkg:pypi/semantic-version@2.10.0" + }, + "extra_data": {}, + "dependency_uid": "pkg:pypi/semantic-version@2.10.0?uuid=fixed-uid-done-for-testing-5642512d1758", + "for_package_uid": "pkg:pypi/univers@0.1.0?uuid=fixed-uid-done-for-testing-5642512d1758", + "datafile_path": "univers/poetry.lock", + "datasource_id": "pypi_poetry_lock" + }, + { + "purl": "pkg:pypi/semver@2.13.0", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": true, + "is_resolved": true, + "is_direct": false, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "semver", + "version": "2.13.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [], + "repository_homepage_url": "https://pypi.org/project/semver", + "repository_download_url": "https://pypi.org/packages/source/s/semver/semver-2.13.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/semver/2.13.0/json", + "datasource_id": "pypi_poetry_lock", + "purl": "pkg:pypi/semver@2.13.0" + }, + "extra_data": {}, + "dependency_uid": "pkg:pypi/semver@2.13.0?uuid=fixed-uid-done-for-testing-5642512d1758", + "for_package_uid": "pkg:pypi/univers@0.1.0?uuid=fixed-uid-done-for-testing-5642512d1758", + "datafile_path": "univers/poetry.lock", + "datasource_id": "pypi_poetry_lock" + } + ], + "files": [ + { + "path": "univers", + "type": "directory", + "package_data": [], + "for_packages": [], + "scan_errors": [] + }, + { + "path": "univers/poetry.lock", + "type": "file", + "package_data": [ + { + "type": "pypi", + "namespace": null, + "name": null, + "version": null, + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": false, + "extra_data": { + "python_version": "^3.8", + "lock_version": "2.0" + }, + "dependencies": [ + { + "purl": "pkg:pypi/attrs@21.4.0", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": true, + "is_resolved": true, + "is_direct": false, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "attrs", + "version": "21.4.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [ + { + "purl": "pkg:pypi/cloudpickle", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/coverage%5btoml%5d", + "extracted_requirement": ">=5.0.2", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/furo", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/hypothesis", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/mypy", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": 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_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pympler", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": ">=4.3.0", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-mypy-plugins", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/six", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-notfound-page", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/zope.interface", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/furo", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-notfound-page", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/zope.interface", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/cloudpickle", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/coverage%5btoml%5d", + "extracted_requirement": ">=5.0.2", + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/hypothesis", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/mypy", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pympler", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": ">=4.3.0", + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-mypy-plugins", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/six", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/zope.interface", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/cloudpickle", + "extracted_requirement": null, + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/coverage%5btoml%5d", + "extracted_requirement": ">=5.0.2", + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/hypothesis", + "extracted_requirement": null, + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/mypy", + "extracted_requirement": null, + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pympler", + "extracted_requirement": null, + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": ">=4.3.0", + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-mypy-plugins", + "extracted_requirement": null, + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/six", + "extracted_requirement": null, + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": "https://pypi.org/project/attrs", + "repository_download_url": "https://pypi.org/packages/source/a/attrs/attrs-21.4.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/attrs/21.4.0/json", + "datasource_id": "pypi_poetry_lock", + "purl": "pkg:pypi/attrs@21.4.0" + }, + "extra_data": {} + }, + { + "purl": "pkg:pypi/packaging@21.0", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": true, + "is_resolved": true, + "is_direct": false, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "packaging", + "version": "21.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [ + { + "purl": "pkg:pypi/pyparsing", + "extracted_requirement": ">=2.0.2", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": "https://pypi.org/project/packaging", + "repository_download_url": "https://pypi.org/packages/source/p/packaging/packaging-21.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/packaging/21.0/json", + "datasource_id": "pypi_poetry_lock", + "purl": "pkg:pypi/packaging@21.0" + }, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pyparsing@3.1.2", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": true, + "is_resolved": true, + "is_direct": false, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "pyparsing", + "version": "3.1.2", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [ + { + "purl": "pkg:pypi/jinja2", + "extracted_requirement": null, + "scope": "diagrams", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/railroad-diagrams", + "extracted_requirement": null, + "scope": "diagrams", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": "https://pypi.org/project/pyparsing", + "repository_download_url": "https://pypi.org/packages/source/p/pyparsing/pyparsing-3.1.2.tar.gz", + "api_data_url": "https://pypi.org/pypi/pyparsing/3.1.2/json", + "datasource_id": "pypi_poetry_lock", + "purl": "pkg:pypi/pyparsing@3.1.2" + }, + "extra_data": {} + }, + { + "purl": "pkg:pypi/semantic-version@2.10.0", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": true, + "is_resolved": true, + "is_direct": false, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "semantic-version", + "version": "2.10.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [ + { + "purl": "pkg:pypi/django", + "extracted_requirement": ">=1.11", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/check-manifest", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/colorama", + "extracted_requirement": "<=0.4.1", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/coverage", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/flake8", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/nose2", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/readme-renderer", + "extracted_requirement": "<25.0", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/tox", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/wheel", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/zest.releaser%5brecommended%5d", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx", + "extracted_requirement": null, + "scope": "doc", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-rtd-theme", + "extracted_requirement": null, + "scope": "doc", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": "https://pypi.org/project/semantic-version", + "repository_download_url": "https://pypi.org/packages/source/s/semantic-version/semantic-version-2.10.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/semantic-version/2.10.0/json", + "datasource_id": "pypi_poetry_lock", + "purl": "pkg:pypi/semantic-version@2.10.0" + }, + "extra_data": {} + }, + { + "purl": "pkg:pypi/semver@2.13.0", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": true, + "is_resolved": true, + "is_direct": false, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "semver", + "version": "2.13.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [], + "repository_homepage_url": "https://pypi.org/project/semver", + "repository_download_url": "https://pypi.org/packages/source/s/semver/semver-2.13.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/semver/2.13.0/json", + "datasource_id": "pypi_poetry_lock", + "purl": "pkg:pypi/semver@2.13.0" + }, + "extra_data": {} + } + ], + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null, + "datasource_id": "pypi_poetry_lock", + "purl": null + } + ], + "for_packages": [ + "pkg:pypi/univers@0.1.0?uuid=fixed-uid-done-for-testing-5642512d1758" + ], + "scan_errors": [] + }, + { + "path": "univers/pyproject.toml", + "type": "file", + "package_data": [ + { + "type": "pypi", + "namespace": null, + "name": "univers", + "version": "0.1.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "A mostly universal library to parse and compare software package versions and version ranges. A companion to Package URLs.", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "nexB. Inc.", + "email": "info@aboutcode.org", + "url": null + } + ], + "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": "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", + "spdx_license_expression": "Apache-2.0", + "from_file": "univers/pyproject.toml", + "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": {}, + "dependencies": [ + { + "purl": "pkg:pypi/attrs", + "extracted_requirement": "^21.2.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/packaging", + "extracted_requirement": "21.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/semantic-version", + "extracted_requirement": "^2.8.5", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/semver", + "extracted_requirement": "^2.13.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": "https://pypi.org/project/univers", + "repository_download_url": "https://pypi.org/packages/source/u/univers/univers-0.1.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/univers/0.1.0/json", + "datasource_id": "pypi_poetry_pyproject_toml", + "purl": "pkg:pypi/univers@0.1.0" + } + ], + "for_packages": [ + "pkg:pypi/univers@0.1.0?uuid=fixed-uid-done-for-testing-5642512d1758" + ], + "scan_errors": [] + } + ] +} \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/poetry/univers-poetry.lock-expected.json b/tests/packagedcode/data/pypi/poetry/univers-poetry.lock-expected.json new file mode 100644 index 00000000000..3225ca4c54a --- /dev/null +++ b/tests/packagedcode/data/pypi/poetry/univers-poetry.lock-expected.json @@ -0,0 +1,863 @@ +[ + { + "type": "pypi", + "namespace": null, + "name": null, + "version": null, + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": false, + "extra_data": { + "python_version": "^3.8", + "lock_version": "2.0" + }, + "dependencies": [ + { + "purl": "pkg:pypi/attrs@21.4.0", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": true, + "is_resolved": true, + "is_direct": false, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "attrs", + "version": "21.4.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [ + { + "purl": "pkg:pypi/cloudpickle", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/coverage%5btoml%5d", + "extracted_requirement": ">=5.0.2", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/furo", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/hypothesis", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/mypy", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": 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_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pympler", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": ">=4.3.0", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-mypy-plugins", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/six", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-notfound-page", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/zope.interface", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/furo", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-notfound-page", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/zope.interface", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/cloudpickle", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/coverage%5btoml%5d", + "extracted_requirement": ">=5.0.2", + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/hypothesis", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/mypy", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pympler", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": ">=4.3.0", + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-mypy-plugins", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/six", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/zope.interface", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/cloudpickle", + "extracted_requirement": null, + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/coverage%5btoml%5d", + "extracted_requirement": ">=5.0.2", + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/hypothesis", + "extracted_requirement": null, + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/mypy", + "extracted_requirement": null, + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pympler", + "extracted_requirement": null, + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": ">=4.3.0", + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-mypy-plugins", + "extracted_requirement": null, + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/six", + "extracted_requirement": null, + "scope": "tests-no-zope", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": "https://pypi.org/project/attrs", + "repository_download_url": "https://pypi.org/packages/source/a/attrs/attrs-21.4.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/attrs/21.4.0/json", + "datasource_id": "pypi_poetry_lock", + "purl": "pkg:pypi/attrs@21.4.0" + }, + "extra_data": {} + }, + { + "purl": "pkg:pypi/packaging@21.0", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": true, + "is_resolved": true, + "is_direct": false, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "packaging", + "version": "21.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [ + { + "purl": "pkg:pypi/pyparsing", + "extracted_requirement": ">=2.0.2", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": "https://pypi.org/project/packaging", + "repository_download_url": "https://pypi.org/packages/source/p/packaging/packaging-21.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/packaging/21.0/json", + "datasource_id": "pypi_poetry_lock", + "purl": "pkg:pypi/packaging@21.0" + }, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pyparsing@3.1.2", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": true, + "is_resolved": true, + "is_direct": false, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "pyparsing", + "version": "3.1.2", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [ + { + "purl": "pkg:pypi/jinja2", + "extracted_requirement": null, + "scope": "diagrams", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/railroad-diagrams", + "extracted_requirement": null, + "scope": "diagrams", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": "https://pypi.org/project/pyparsing", + "repository_download_url": "https://pypi.org/packages/source/p/pyparsing/pyparsing-3.1.2.tar.gz", + "api_data_url": "https://pypi.org/pypi/pyparsing/3.1.2/json", + "datasource_id": "pypi_poetry_lock", + "purl": "pkg:pypi/pyparsing@3.1.2" + }, + "extra_data": {} + }, + { + "purl": "pkg:pypi/semantic-version@2.10.0", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": true, + "is_resolved": true, + "is_direct": false, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "semantic-version", + "version": "2.10.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [ + { + "purl": "pkg:pypi/django", + "extracted_requirement": ">=1.11", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/check-manifest", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/colorama", + "extracted_requirement": "<=0.4.1", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/coverage", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/flake8", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/nose2", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/readme-renderer", + "extracted_requirement": "<25.0", + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/tox", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/wheel", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/zest.releaser%5brecommended%5d", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx", + "extracted_requirement": null, + "scope": "doc", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-rtd-theme", + "extracted_requirement": null, + "scope": "doc", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": "https://pypi.org/project/semantic-version", + "repository_download_url": "https://pypi.org/packages/source/s/semantic-version/semantic-version-2.10.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/semantic-version/2.10.0/json", + "datasource_id": "pypi_poetry_lock", + "purl": "pkg:pypi/semantic-version@2.10.0" + }, + "extra_data": {} + }, + { + "purl": "pkg:pypi/semver@2.13.0", + "extracted_requirement": null, + "scope": null, + "is_runtime": true, + "is_optional": true, + "is_resolved": true, + "is_direct": false, + "resolved_package": { + "type": "pypi", + "namespace": null, + "name": "semver", + "version": "2.13.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": null, + "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": null, + "declared_license_expression_spdx": null, + "license_detections": [], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": null, + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": true, + "extra_data": {}, + "dependencies": [], + "repository_homepage_url": "https://pypi.org/project/semver", + "repository_download_url": "https://pypi.org/packages/source/s/semver/semver-2.13.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/semver/2.13.0/json", + "datasource_id": "pypi_poetry_lock", + "purl": "pkg:pypi/semver@2.13.0" + }, + "extra_data": {} + } + ], + "repository_homepage_url": null, + "repository_download_url": null, + "api_data_url": null, + "datasource_id": "pypi_poetry_lock", + "purl": null + } +] \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/poetry/univers-pyproject.toml-expected.json b/tests/packagedcode/data/pypi/poetry/univers-pyproject.toml-expected.json new file mode 100644 index 00000000000..96389ae207f --- /dev/null +++ b/tests/packagedcode/data/pypi/poetry/univers-pyproject.toml-expected.json @@ -0,0 +1,122 @@ +[ + { + "type": "pypi", + "namespace": null, + "name": "univers", + "version": "0.1.0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "A mostly universal library to parse and compare software package versions and version ranges. A companion to Package URLs.", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "nexB. Inc.", + "email": "info@aboutcode.org", + "url": null + } + ], + "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": "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", + "spdx_license_expression": "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": {}, + "dependencies": [ + { + "purl": "pkg:pypi/attrs", + "extracted_requirement": "^21.2.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/packaging", + "extracted_requirement": "21.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/semantic-version", + "extracted_requirement": "^2.8.5", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/semver", + "extracted_requirement": "^2.13.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": "https://pypi.org/project/univers", + "repository_download_url": "https://pypi.org/packages/source/u/univers/univers-0.1.0.tar.gz", + "api_data_url": "https://pypi.org/pypi/univers/0.1.0/json", + "datasource_id": "pypi_poetry_pyproject_toml", + "purl": "pkg:pypi/univers@0.1.0" + } +] \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/poetry/univers/poetry.lock b/tests/packagedcode/data/pypi/poetry/univers/poetry.lock new file mode 100644 index 00000000000..8035d75e0e0 --- /dev/null +++ b/tests/packagedcode/data/pypi/poetry/univers/poetry.lock @@ -0,0 +1,77 @@ +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. + +[[package]] +name = "attrs" +version = "21.4.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, + {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, +] + +[package.extras] +dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "sphinx", "sphinx-notfound-page", "zope.interface"] +docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] +tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "zope.interface"] +tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six"] + +[[package]] +name = "packaging" +version = "21.0" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.6" +files = [ + {file = "packaging-21.0-py3-none-any.whl", hash = "sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14"}, + {file = "packaging-21.0.tar.gz", hash = "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7"}, +] + +[package.dependencies] +pyparsing = ">=2.0.2" + +[[package]] +name = "pyparsing" +version = "3.1.2" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +optional = false +python-versions = ">=3.6.8" +files = [ + {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, + {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "semantic-version" +version = "2.10.0" +description = "A library implementing the 'SemVer' scheme." +optional = false +python-versions = ">=2.7" +files = [ + {file = "semantic_version-2.10.0-py2.py3-none-any.whl", hash = "sha256:de78a3b8e0feda74cabc54aab2da702113e33ac9d9eb9d2389bcf1f58b7d9177"}, + {file = "semantic_version-2.10.0.tar.gz", hash = "sha256:bdabb6d336998cbb378d4b9db3a4b56a1e3235701dc05ea2690d9a997ed5041c"}, +] + +[package.extras] +dev = ["Django (>=1.11)", "check-manifest", "colorama (<=0.4.1)", "coverage", "flake8", "nose2", "readme-renderer (<25.0)", "tox", "wheel", "zest.releaser[recommended]"] +doc = ["Sphinx", "sphinx-rtd-theme"] + +[[package]] +name = "semver" +version = "2.13.0" +description = "Python helper for Semantic Versioning (http://semver.org/)" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "semver-2.13.0-py2.py3-none-any.whl", hash = "sha256:ced8b23dceb22134307c1b8abfa523da14198793d9787ac838e70e29e77458d4"}, + {file = "semver-2.13.0.tar.gz", hash = "sha256:fa0fe2722ee1c3f57eac478820c3a5ae2f624af8264cbdf9000c980ff7f75e3f"}, +] + +[metadata] +lock-version = "2.0" +python-versions = "^3.8" +content-hash = "e0b01835b389522de3d7719c282374c07b94cf44c55ff6a706176422b3d811ca" diff --git a/tests/packagedcode/data/pypi/poetry/univers/pyproject.toml b/tests/packagedcode/data/pypi/poetry/univers/pyproject.toml new file mode 100644 index 00000000000..48b47bfb8be --- /dev/null +++ b/tests/packagedcode/data/pypi/poetry/univers/pyproject.toml @@ -0,0 +1,18 @@ +[tool.poetry] +name = "univers" +version = "0.1.0" +description = "A mostly universal library to parse and compare software package versions and version ranges. A companion to Package URLs." +authors = ["nexB. Inc. "] +license = "apache-2.0" +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.8" +attrs = "^21.2.0" +packaging = "21.0" +semantic-version = "^2.8.5" +semver = "^2.13.0" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/tests/packagedcode/data/pypi/pyproject-toml/poetry/connexion-pyproject.toml-expected.json b/tests/packagedcode/data/pypi/pyproject-toml/poetry/connexion-pyproject.toml-expected.json new file mode 100644 index 00000000000..8d1f38600fb --- /dev/null +++ b/tests/packagedcode/data/pypi/pyproject-toml/poetry/connexion-pyproject.toml-expected.json @@ -0,0 +1,439 @@ +[ + { + "type": "pypi", + "namespace": null, + "name": "sphinxemoji", + "version": "3.0.dev0", + "qualifiers": {}, + "subpath": null, + "primary_language": "Python", + "description": "Connexion - API first applications with OpenAPI/Swagger", + "release_date": null, + "parties": [ + { + "type": "person", + "role": "author", + "name": "Robbe Sneyders", + "email": "robbe.sneyders@gmail.com", + "url": null + }, + { + "type": "person", + "role": "author", + "name": "Ruwan Lambrichts", + "email": "ruwan.lambrichts@ml6.eu", + "url": null + }, + { + "type": "person", + "role": "author", + "name": "Daniel Grossmann-Kavanagh", + "email": "me@danielgk.com", + "url": null + }, + { + "type": "person", + "role": "author", + "name": "Henning Jacobs", + "email": "henning.jacobs@zalando.de", + "url": null + }, + { + "type": "person", + "role": "author", + "name": "Jo\u00e3o Santos", + "email": "joao.santos@zalando.de", + "url": null + }, + { + "type": "person", + "role": "maintainer", + "name": "Robbe Sneyders", + "email": "robbe.sneyders@gmail.com", + "url": null + }, + { + "type": "person", + "role": "maintainer", + "name": "Ruwan Lambrichts", + "email": "ruwan.lambrichts@ml6.eu", + "url": null + } + ], + "keywords": [ + "api", + "swagger", + "openapi", + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "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", + "Topic :: Internet", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Internet :: WWW/HTTP :: HTTP Servers", + "Topic :: Software Development", + "Topic :: Software Development :: Libraries", + "Topic :: Software Development :: Libraries :: Python Modules", + "Typing :: Typed" + ], + "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": "https://github.com/spec-first/connexion", + "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", + "spdx_license_expression": "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" + }, + { + "license_expression": "apache-2.0", + "license_expression_spdx": "Apache-2.0", + "matches": [ + { + "license_expression": "apache-2.0", + "spdx_license_expression": "Apache-2.0", + "from_file": null, + "start_line": 1, + "end_line": 1, + "matcher": "1-hash", + "score": 95.0, + "matched_length": 6, + "match_coverage": 100.0, + "rule_relevance": 95, + "rule_identifier": "pypi_apache_no-version.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/pypi_apache_no-version.RULE", + "matched_text": "- 'License :: OSI Approved :: Apache Software License'" + } + ], + "identifier": "apache_2_0-e267f9d9-ae62-e9c9-9cc2-8cd0a1e4928f" + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "license: Apache-2.0\nclassifiers:\n - 'License :: OSI Approved :: Apache Software License'\n", + "notice_text": null, + "source_packages": [], + "file_references": [], + "is_private": false, + "is_virtual": false, + "extra_data": {}, + "dependencies": [ + { + "purl": "pkg:pypi/asgiref", + "extracted_requirement": ">= 3.4", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/httpx", + "extracted_requirement": ">= 0.23", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/inflection", + "extracted_requirement": ">= 0.3.1", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/jsonschema", + "extracted_requirement": ">=4.17.3", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/jinja2", + "extracted_requirement": ">= 3.0.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/python-multipart", + "extracted_requirement": ">= 0.0.5", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pyyaml", + "extracted_requirement": ">= 5.1", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/requests", + "extracted_requirement": ">= 2.27", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/starlette", + "extracted_requirement": ">= 0.35", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/typing-extensions", + "extracted_requirement": ">= 4.6.1", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/werkzeug", + "extracted_requirement": ">= 2.2.1", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/a2wsgi", + "extracted_requirement": ">= 1.7", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/flask", + "extracted_requirement": ">= 2.2", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/swagger-ui-bundle", + "extracted_requirement": ">= 1.1.0", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/uvicorn", + "extracted_requirement": ">= 0.17.6", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/jsf", + "extracted_requirement": ">=0.10.0", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pre-commit", + "extracted_requirement": "~2.21.0", + "scope": "tests", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": "7.2.1", + "scope": "tests", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-asyncio", + "extracted_requirement": "~0.18.3", + "scope": "tests", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-cov", + "extracted_requirement": "~2.12.1", + "scope": "tests", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx", + "extracted_requirement": "5.3.0", + "scope": "docs", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-copybutton", + "extracted_requirement": "0.5.2", + "scope": "docs", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-design", + "extracted_requirement": "0.4.1", + "scope": "docs", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-rtd-theme", + "extracted_requirement": "1.2.0", + "scope": "docs", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinxemoji", + "extracted_requirement": "0.2.0", + "scope": "docs", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": "https://pypi.org/project/connexion", + "repository_download_url": "https://pypi.org/packages/source/c/connexion/connexion-3.0.dev0.tar.gz", + "api_data_url": "https://pypi.org/pypi/connexion/3.0.dev0/json", + "datasource_id": "pypi_poetry_pyproject_toml", + "purl": "pkg:pypi/sphinxemoji@3.0.dev0" + } +] \ No newline at end of file diff --git a/tests/packagedcode/data/pypi/pyproject-toml/poetry/connexion/pyproject.toml b/tests/packagedcode/data/pypi/pyproject-toml/poetry/connexion/pyproject.toml new file mode 100644 index 00000000000..019796203f3 --- /dev/null +++ b/tests/packagedcode/data/pypi/pyproject-toml/poetry/connexion/pyproject.toml @@ -0,0 +1,111 @@ +[tool.poetry] +name = "connexion" +version = "3.0.dev0" +description = "Connexion - API first applications with OpenAPI/Swagger" +readme = "README.md" +keywords = ["api", "swagger", "openapi"] +license = "Apache-2.0" +authors = [ + "Robbe Sneyders ", + "Ruwan Lambrichts ", + "Daniel Grossmann-Kavanagh ", + "Henning Jacobs ", + "João Santos ", +] +maintainers = [ + "Robbe Sneyders ", + "Ruwan Lambrichts ", +] +repository = "https://github.com/spec-first/connexion" +include = ["*.txt", "*.rst"] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "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", + "Topic :: Internet", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Internet :: WWW/HTTP :: HTTP Servers", + "Topic :: Software Development", + "Topic :: Software Development :: Libraries", + "Topic :: Software Development :: Libraries :: Python Modules", + "Typing :: Typed", +] + +[tool.poetry.scripts] +connexion = 'connexion.cli:main' + +[tool.poetry.dependencies] +python = '^3.8' +asgiref = ">= 3.4" +httpx = ">= 0.23" +inflection = ">= 0.3.1" +jsonschema = ">=4.17.3" +Jinja2 = ">= 3.0.0" +python-multipart = ">= 0.0.5" +PyYAML = ">= 5.1" +requests = ">= 2.27" +starlette = ">= 0.35" +typing-extensions = ">= 4.6.1" +werkzeug = ">= 2.2.1" + +a2wsgi = { version = ">= 1.7", optional = true } +flask = { version = ">= 2.2", extras = ["async"], optional = true } +swagger-ui-bundle = { version = ">= 1.1.0", optional = true } +uvicorn = { version = ">= 0.17.6", extras = ["standard"], optional = true } +jsf = { version = ">=0.10.0", optional = true } + +[tool.poetry.extras] +flask = ["a2wsgi", "flask"] +swagger-ui = ["swagger-ui-bundle"] +uvicorn = ["uvicorn"] +mock = ["jsf"] + +[tool.poetry.group.tests.dependencies] +pre-commit = "~2.21.0" +pytest = "7.2.1" +pytest-asyncio = "~0.18.3" +pytest-cov = "~2.12.1" + +[tool.poetry.group.docs.dependencies] +sphinx = "5.3.0" +sphinx_copybutton = "0.5.2" +sphinx_design = "0.4.1" +sphinx-rtd-theme = "1.2.0" +sphinxemoji = "0.2.0" + +[build-system] +requires = ["poetry-core>=1.2.0"] +build-backend = "poetry.core.masonry.api" + +[tool.distutils.bdist_wheel] +universal = true + +[tool.pytest.ini_options] +filterwarnings = [ + "ignore::DeprecationWarning:connexion.*:", + "ignore::FutureWarning:connexion.*:", +] +asyncio_mode = "auto" + +[tool.isort] +profile = "black" + +[tool.coverage.report] +exclude_lines = [ + "pragma: no cover", + "if t.TYPE_CHECKING:", + "@t.overload", +] + +[[tool.mypy.overrides]] +module = "referencing.jsonschema.*" +follow_imports = "skip" diff --git a/tests/packagedcode/data/pypi/pyproject-toml/poetry/gerapy-pyproject.toml-expected.json b/tests/packagedcode/data/pypi/pyproject-toml/poetry/gerapy-pyproject.toml-expected.json index 261321ccadb..2df7935275c 100644 --- a/tests/packagedcode/data/pypi/pyproject-toml/poetry/gerapy-pyproject.toml-expected.json +++ b/tests/packagedcode/data/pypi/pyproject-toml/poetry/gerapy-pyproject.toml-expected.json @@ -95,7 +95,239 @@ "is_private": false, "is_virtual": false, "extra_data": {}, - "dependencies": [], + "dependencies": [ + { + "purl": "pkg:pypi/apscheduler", + "extracted_requirement": ">=3.5.1,<=3.7.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/cryptography", + "extracted_requirement": ">=2.8", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/django", + "extracted_requirement": ">=2.2,<3.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/django-cors-headers", + "extracted_requirement": ">=3.2.0,<=3.7.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/django-apscheduler", + "extracted_requirement": ">=0.3.0,<=0.6.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/furl", + "extracted_requirement": ">=2.1.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/jinja2", + "extracted_requirement": ">=2.11.3", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/scrapy", + "extracted_requirement": ">=2.7.1", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/scrapy-redis", + "extracted_requirement": ">=0.6.8", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/scrapy-splash", + "extracted_requirement": ">=0.7.2", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/python-scrapyd-api", + "extracted_requirement": ">=2.1.2", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/redis", + "extracted_requirement": ">=2.10.5", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/requests", + "extracted_requirement": ">=2.20.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pymongo", + "extracted_requirement": ">=3.9.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pymysql", + "extracted_requirement": ">=0.7.10", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pyquery", + "extracted_requirement": ">=1.2.17", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/beautifulsoup4", + "extracted_requirement": ">=4.7.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/djangorestframework", + "extracted_requirement": ">=3.11.2", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/websocket", + "extracted_requirement": ">=0.2.1", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pyppeteer", + "extracted_requirement": ">=0.0.25", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/uberegg", + "extracted_requirement": "^0.1.1", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], "repository_homepage_url": "https://pypi.org/project/gerapy", "repository_download_url": "https://pypi.org/packages/source/g/gerapy/gerapy-0.9.13.tar.gz", "api_data_url": "https://pypi.org/pypi/gerapy/0.9.13/json", diff --git a/tests/packagedcode/data/pypi/pyproject-toml/poetry/gino-pyproject.toml-expected.json b/tests/packagedcode/data/pypi/pyproject-toml/poetry/gino-pyproject.toml-expected.json index 5f709840ea8..141fe49b010 100644 --- a/tests/packagedcode/data/pypi/pyproject-toml/poetry/gino-pyproject.toml-expected.json +++ b/tests/packagedcode/data/pypi/pyproject-toml/poetry/gino-pyproject.toml-expected.json @@ -119,7 +119,277 @@ "extra_data": { "documentation": "https://python-gino.org/docs/" }, - "dependencies": [], + "dependencies": [ + { + "purl": "pkg:pypi/sqlalchemy", + "extracted_requirement": ">=1.3,<1.4", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/asyncpg", + "extracted_requirement": ">=0.18,<1.0", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/aiomysql", + "extracted_requirement": "^0.0.22", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/contextvars", + "extracted_requirement": "^2.4", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": { + "python_version": "<3.7" + } + }, + { + "purl": "pkg:pypi/importlib-metadata", + "extracted_requirement": "^2.0.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": { + "python_version": "<3.8" + } + }, + { + "purl": "pkg:pypi/gino-starlette", + "extracted_requirement": "^0.1.1", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": { + "python_version": "^3.6" + } + }, + { + "purl": "pkg:pypi/gino-aiohttp", + "extracted_requirement": "^0.2.0", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": { + "python_version": "^3.6" + } + }, + { + "purl": "pkg:pypi/gino-tornado", + "extracted_requirement": "^0.1.0", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": { + "python_version": "^3.5.2" + } + }, + { + "purl": "pkg:pypi/gino-sanic", + "extracted_requirement": "^0.1.0", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": { + "python_version": "^3.6" + } + }, + { + "purl": "pkg:pypi/gino-quart", + "extracted_requirement": "^0.1.0", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": { + "python_version": "^3.7" + } + }, + { + "purl": "pkg:pypi/psycopg2-binary", + "extracted_requirement": "^2.9.3", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/click", + "extracted_requirement": "^8.0.3", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": "^7.0.1", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-asyncio", + "extracted_requirement": "^0.16.0", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-mock", + "extracted_requirement": "^3.6.0", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-cov", + "extracted_requirement": "^3.0.0", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/black", + "extracted_requirement": "^22.1.0", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": { + "python_version": ">=3.6.2" + } + }, + { + "purl": "pkg:pypi/mypy", + "extracted_requirement": "^0.931", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx", + "extracted_requirement": "^4.3.0", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-rtd-theme", + "extracted_requirement": "^1.0.0", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinxcontrib-apidoc", + "extracted_requirement": "^0.3.0", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-autobuild", + "extracted_requirement": "^2021.3.14", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-intl", + "extracted_requirement": "^2.0.1", + "scope": "install", + "is_runtime": true, + "is_optional": true, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], "repository_homepage_url": "https://pypi.org/project/gino", "repository_download_url": "https://pypi.org/packages/source/g/gino/gino-1.1.0-rc.1.tar.gz", "api_data_url": "https://pypi.org/pypi/gino/1.1.0-rc.1/json", diff --git a/tests/packagedcode/data/pypi/pyproject-toml/standard/apache-airflow-pyclient-pyproject.toml-expected.json b/tests/packagedcode/data/pypi/pyproject-toml/standard/apache-airflow-pyclient-pyproject.toml-expected.json index 0daed6123a1..080f6cd1d2f 100644 --- a/tests/packagedcode/data/pypi/pyproject-toml/standard/apache-airflow-pyclient-pyproject.toml-expected.json +++ b/tests/packagedcode/data/pypi/pyproject-toml/standard/apache-airflow-pyclient-pyproject.toml-expected.json @@ -87,7 +87,30 @@ "Documentation": "https://airflow.apache.org/docs/apache-airflow/stable/stable-rest-api-ref.html", "Download": "https://archive.apache.org/dist/airflow/clients/python/" }, - "dependencies": [], + "dependencies": [ + { + "purl": "pkg:pypi/python-dateutil", + "extracted_requirement": null, + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/urllib3", + "extracted_requirement": ">=1.25.3", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], "repository_homepage_url": "https://pypi.org/project/apache-airflow-client", "repository_download_url": null, "api_data_url": "https://pypi.org/pypi/apache-airflow-client/json", diff --git a/tests/packagedcode/data/pypi/pyproject-toml/standard/attrs-pyproject.toml-expected.json b/tests/packagedcode/data/pypi/pyproject-toml/standard/attrs-pyproject.toml-expected.json index 54946740d86..5f48a55133d 100644 --- a/tests/packagedcode/data/pypi/pyproject-toml/standard/attrs-pyproject.toml-expected.json +++ b/tests/packagedcode/data/pypi/pyproject-toml/standard/attrs-pyproject.toml-expected.json @@ -109,7 +109,223 @@ "Funding": "https://github.com/sponsors/hynek", "Tidelift": "https://tidelift.com/subscription/pkg/pypi-attrs?utm_source=pypi-attrs&utm_medium=pypi" }, - "dependencies": [], + "dependencies": [ + { + "purl": "pkg:pypi/importlib-metadata", + "extracted_requirement": null, + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": { + "python_version": "< 3.8" + } + }, + { + "purl": "pkg:pypi/pytest-mypy-plugins", + "extracted_requirement": null, + "scope": "tests-mypy", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": { + "python_version": ">= 3.8" + } + }, + { + "purl": "pkg:pypi/mypy", + "extracted_requirement": "<1.10,>=1.6", + "scope": "tests-mypy", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": { + "python_version": ">= 3.8" + } + }, + { + "purl": "pkg:pypi/cloudpickle", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/hypothesis", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pympler", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest", + "extracted_requirement": ">=4.3.0", + "scope": "tests", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pytest-xdist", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/attrs", + "extracted_requirement": null, + "scope": "tests", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/attrs", + "extracted_requirement": null, + "scope": "cov", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/coverage", + "extracted_requirement": ">=5.3", + "scope": "cov", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/furo", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/myst-parser", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinx-notfound-page", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/sphinxcontrib-towncrier", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/towncrier", + "extracted_requirement": null, + "scope": "docs", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/attrs", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/pre-commit", + "extracted_requirement": null, + "scope": "dev", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], "repository_homepage_url": "https://pypi.org/project/attrs", "repository_download_url": null, "api_data_url": "https://pypi.org/pypi/attrs/json", diff --git a/tests/packagedcode/data/pypi/pyproject-toml/standard/flask-pyproject.toml-expected.json b/tests/packagedcode/data/pypi/pyproject-toml/standard/flask-pyproject.toml-expected.json index dab6479f9a9..07fe37e07d6 100644 --- a/tests/packagedcode/data/pypi/pyproject-toml/standard/flask-pyproject.toml-expected.json +++ b/tests/packagedcode/data/pypi/pyproject-toml/standard/flask-pyproject.toml-expected.json @@ -85,7 +85,98 @@ "Chat": "https://discord.gg/pallets", "license_file": "LICENSE.txt" }, - "dependencies": [], + "dependencies": [ + { + "purl": "pkg:pypi/werkzeug", + "extracted_requirement": ">=3.0.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/jinja2", + "extracted_requirement": ">=3.1.2", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/itsdangerous", + "extracted_requirement": ">=2.1.2", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/click", + "extracted_requirement": ">=8.1.3", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/blinker", + "extracted_requirement": ">=1.6.2", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/importlib-metadata", + "extracted_requirement": ">=3.6.0", + "scope": "install", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": { + "python_version": "< 3.10" + } + }, + { + "purl": "pkg:pypi/asgiref", + "extracted_requirement": ">=3.2", + "scope": "async", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:pypi/python-dotenv", + "extracted_requirement": null, + "scope": "dotenv", + "is_runtime": true, + "is_optional": false, + "is_resolved": false, + "is_direct": true, + "resolved_package": {}, + "extra_data": {} + } + ], "repository_homepage_url": "https://pypi.org/project/Flask", "repository_download_url": "https://pypi.org/packages/source/F/Flask/Flask-3.1.0.dev.tar.gz", "api_data_url": "https://pypi.org/pypi/Flask/3.1.0.dev/json", diff --git a/tests/packagedcode/test_pypi.py b/tests/packagedcode/test_pypi.py index 4af155f38f2..7164214dd95 100644 --- a/tests/packagedcode/test_pypi.py +++ b/tests/packagedcode/test_pypi.py @@ -79,6 +79,13 @@ def test_package_scan_pypi_end_to_end_extracted_wheel(self): run_scan_click(['--package', '--processes', '-1', test_dir, '--json-pp', result_file]) check_json_scan(expected_file, result_file, remove_uuid=True, regen=REGEN_TEST_FIXTURES) + def test_package_scan_poetry_end_to_end(self): + test_dir = self.get_test_loc('pypi/poetry/univers/') + result_file = self.get_temp_file('json') + expected_file = self.get_test_loc('pypi/poetry/univers-package-assembly-expected.json') + run_scan_click(['--package', '--processes', '-1', test_dir, '--json-pp', result_file]) + check_json_scan(expected_file, result_file, remove_uuid=True, regen=REGEN_TEST_FIXTURES) + class TestPyPiDevelopEggInfoPkgInfo(PackageTester): test_data_dir = os.path.join(os.path.dirname(__file__), 'data') @@ -332,22 +339,47 @@ def test_parse_pyproject_toml_standard_lc0(self): expected_loc = self.get_test_loc('pypi/pyproject-toml/standard/lc0-pyproject.toml-expected.json') self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) + +class TestPoetryHandler(PackageTester): + def test_is_pyproject_toml_poetry(self): test_file = self.get_test_loc('pypi/pyproject-toml/poetry/gerapy/pyproject.toml') assert pypi.PoetryPyprojectTomlHandler.is_datafile(test_file) - + def test_parse_pyproject_toml_poetry_gerapy(self): test_file = self.get_test_loc('pypi/pyproject-toml/poetry/gerapy/pyproject.toml') package = pypi.PoetryPyprojectTomlHandler.parse(test_file) expected_loc = self.get_test_loc('pypi/pyproject-toml/poetry/gerapy-pyproject.toml-expected.json') self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) - + def test_parse_pyproject_toml_poetry_gino(self): test_file = self.get_test_loc('pypi/pyproject-toml/poetry/gino/pyproject.toml') package = pypi.PoetryPyprojectTomlHandler.parse(test_file) expected_loc = self.get_test_loc('pypi/pyproject-toml/poetry/gino-pyproject.toml-expected.json') self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) + def test_parse_pyproject_toml_poetry_connexion(self): + test_file = self.get_test_loc('pypi/pyproject-toml/poetry/connexion/pyproject.toml') + package = pypi.PoetryPyprojectTomlHandler.parse(test_file) + expected_loc = self.get_test_loc('pypi/pyproject-toml/poetry/connexion-pyproject.toml-expected.json') + self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) + + def test_is_poetry_lock(self): + test_file = self.get_test_loc('pypi/poetry/univers/poetry.lock') + assert pypi.PoetryLockHandler.is_datafile(test_file) + + def test_parse_poetry_lock_univers(self): + test_file = self.get_test_loc('pypi/poetry/univers/poetry.lock') + package = pypi.PoetryLockHandler.parse(test_file) + expected_loc = self.get_test_loc('pypi/poetry/univers-poetry.lock-expected.json') + self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) + + def test_parse_pyproject_toml_poetry_univers(self): + test_file = self.get_test_loc('pypi/poetry/univers/pyproject.toml') + package = pypi.PoetryPyprojectTomlHandler.parse(test_file) + expected_loc = self.get_test_loc('pypi/poetry/univers-pyproject.toml-expected.json') + self.check_packages_data(package, expected_loc, regen=REGEN_TEST_FIXTURES) + class TestPipInspectDeplockHandler(PackageTester): test_data_dir = os.path.join(os.path.dirname(__file__), 'data') From 124da3dcef0d95a6f6aa76ed849f47ada25b83e2 Mon Sep 17 00:00:00 2001 From: Ayan Sinha Mahapatra Date: Mon, 1 Jul 2024 15:11:21 +0530 Subject: [PATCH 05/10] Replace deprecated macos CI runners Replace macos-11 runners with macos-14 runners. Reference: https://github.com/actions/runner-images?tab=readme-ov-file#available-images Reference: https://github.com/nexB/skeleton/issues/89 Signed-off-by: Ayan Sinha Mahapatra --- azure-pipelines.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 373b78cdd91..c2a3b522df2 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -25,24 +25,24 @@ jobs: - template: etc/ci/azure-posix.yml parameters: - job_name: macos11_cpython - image_name: macOS-11 + job_name: macos12_cpython + image_name: macOS-12 python_versions: ['3.8', '3.9', '3.10', '3.11', '3.12'] test_suites: all: venv/bin/pytest -n 2 -vvs - template: etc/ci/azure-posix.yml parameters: - job_name: macos12_cpython - image_name: macOS-12 + job_name: macos13_cpython + image_name: macOS-13 python_versions: ['3.8', '3.9', '3.10', '3.11', '3.12'] test_suites: all: venv/bin/pytest -n 2 -vvs - template: etc/ci/azure-posix.yml parameters: - job_name: macos13_cpython - image_name: macOS-13 + job_name: macos14_cpython_arm64 + image_name: macOS-14 python_versions: ['3.8', '3.9', '3.10', '3.11', '3.12'] test_suites: all: venv/bin/pytest -n 2 -vvs @@ -50,8 +50,8 @@ jobs: - template: etc/ci/azure-posix.yml parameters: job_name: macos14_cpython - image_name: macOS-14 - python_versions: ['3.8', '3.9', '3.10', '3.11', '3.12'] + image_name: macOS-14-large + python_versions: ['3.8', '3.8', '3.9', '3.10', '3.12'] test_suites: all: venv/bin/pytest -n 2 -vvs From be4e14d414cf4f7112b529dc71f7abccc9dcf24a Mon Sep 17 00:00:00 2001 From: Ayan Sinha Mahapatra Date: Mon, 1 Jul 2024 16:00:40 +0530 Subject: [PATCH 06/10] Update minimum required python version to 3.8 Signed-off-by: Ayan Sinha Mahapatra --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index bd0e58a705c..a8e20c5d427 100644 --- a/setup.cfg +++ b/setup.cfg @@ -38,7 +38,7 @@ zip_safe = false setup_requires = setuptools_scm[toml] >= 4 -python_requires = >=3.7 +python_requires = >=3.8 install_requires = From e2e9019f4dc30aff5899887b8052b836c9432ce1 Mon Sep 17 00:00:00 2001 From: Ayan Sinha Mahapatra Date: Mon, 1 Jul 2024 17:57:40 +0530 Subject: [PATCH 07/10] Update scope and runtime/optional attributes Signed-off-by: Ayan Sinha Mahapatra --- src/packagedcode/pypi.py | 48 ++- .../univers-package-assembly-expected.json | 404 +++++++++--------- .../poetry/univers-poetry.lock-expected.json | 194 ++++----- .../univers-pyproject.toml-expected.json | 8 +- .../connexion-pyproject.toml-expected.json | 50 +-- .../gerapy-pyproject.toml-expected.json | 42 +- .../poetry/gino-pyproject.toml-expected.json | 100 ++--- .../attrs-pyproject.toml-expected.json | 36 +- .../flask-pyproject.toml-expected.json | 4 +- .../daglib_wheel_extracted-expected.json | 4 +- 10 files changed, 453 insertions(+), 437 deletions(-) diff --git a/src/packagedcode/pypi.py b/src/packagedcode/pypi.py index deba7631d0f..dcfe261d946 100644 --- a/src/packagedcode/pypi.py +++ b/src/packagedcode/pypi.py @@ -494,6 +494,7 @@ def parse(cls, location, package_only=False): parsed_dependencies = get_requires_dependencies( requires=deps, default_scope=dep_type, + is_optional=True, ) dependencies.extend(parsed_dependencies) @@ -608,26 +609,29 @@ def is_datafile(cls, location, filetypes=tuple()): ) @classmethod - def parse_non_group_dependencies(cls, dependencies, dev=False): + def parse_non_group_dependencies( + cls, + dependencies, + scope="install", + is_optional=False, + is_runtime=True, + ): dependency_mappings = [] for dep_name, requirement in dependencies.items(): - if not dev and dep_name == "python": + if is_runtime and dep_name == "python": continue purl = PackageURL( type=cls.default_package_type, name=dep_name, ) - is_optional = False - if dev: - is_optional = True extra_data = {} if isinstance(requirement, str): extracted_requirement = requirement elif isinstance(requirement, dict): extracted_requirement = requirement.get("version") - is_optional = requirement.get("optional", is_optional) + is_optional = requirement.get("optional", False) python_version = requirement.get("python") if python_version: extra_data["python_version"] = python_version @@ -635,8 +639,8 @@ def parse_non_group_dependencies(cls, dependencies, dev=False): dependency = models.DependentPackage( purl=purl.to_string(), extracted_requirement=extracted_requirement, - scope="install", - is_runtime=True, + scope=scope, + is_runtime=is_runtime, is_optional=is_optional, is_direct=True, is_resolved=False, @@ -672,11 +676,13 @@ def parse(cls, location, package_only=False): dependencies = [] parsed_deps = cls.parse_non_group_dependencies( dependencies=poetry_data.get("dependencies", {}), + scope="dependencies", ) dependencies.extend(parsed_deps) parsed_deps = cls.parse_non_group_dependencies( dependencies=poetry_data.get("dev-dependencies", {}), - dev=True, + scope="dev-dependencies", + is_runtime=False, ) dependencies.extend(parsed_deps) @@ -690,7 +696,7 @@ def parse(cls, location, package_only=False): purl=purl.to_string(), extracted_requirement=requirement, scope=group_name, - is_runtime=True, + is_runtime=False, is_optional=False, is_direct=True, is_resolved=False, @@ -745,7 +751,7 @@ def parse(cls, location, package_only=False): dependency = models.DependentPackage( purl=purl.to_string(), extracted_requirement=requirement, - scope="install", + scope="dependencies", is_runtime=True, is_optional=False, is_direct=True, @@ -770,8 +776,8 @@ def parse(cls, location, package_only=False): purl=purl.to_string(), extracted_requirement=requirement, scope=group_name, - is_runtime=True, - is_optional=True, + is_runtime=False, + is_optional=False, is_direct=True, is_resolved=False, ) @@ -1871,7 +1877,13 @@ def get_dist_dependencies(dist): return get_requires_dependencies(requires=dist.requires) -def get_requires_dependencies(requires, default_scope='install', is_direct=True): +def get_requires_dependencies( + requires, + default_scope='install', + is_direct=True, + is_optional=False, + is_runtime=True, +): """ Return a list of DependentPackage found in a ``requires`` list of requirement strings or an empty list. @@ -1918,12 +1930,16 @@ def get_requires_dependencies(requires, default_scope='install', is_direct=True) extracted_requirement = None if requirement: extracted_requirement = requirement + + if is_optional or bool(extra): + is_optional = True + dependent_packages.append( models.DependentPackage( purl=purl.to_string(), scope=scope, - is_runtime=True, - is_optional=True if bool(extra) else False, + is_runtime=is_runtime, + is_optional=is_optional, is_resolved=is_resolved, is_direct=is_direct, extracted_requirement=extracted_requirement, diff --git a/tests/packagedcode/data/pypi/poetry/univers-package-assembly-expected.json b/tests/packagedcode/data/pypi/poetry/univers-package-assembly-expected.json index b20a29ed09c..af849e2758a 100644 --- a/tests/packagedcode/data/pypi/poetry/univers-package-assembly-expected.json +++ b/tests/packagedcode/data/pypi/poetry/univers-package-assembly-expected.json @@ -84,7 +84,7 @@ { "purl": "pkg:pypi/attrs", "extracted_requirement": "^21.2.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -99,7 +99,7 @@ { "purl": "pkg:pypi/packaging", "extracted_requirement": "21.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -114,7 +114,7 @@ { "purl": "pkg:pypi/semantic-version", "extracted_requirement": "^2.8.5", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -129,7 +129,7 @@ { "purl": "pkg:pypi/semver", "extracted_requirement": "^2.13.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -191,8 +191,8 @@ "purl": "pkg:pypi/cloudpickle", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -202,8 +202,8 @@ "purl": "pkg:pypi/coverage%5btoml%5d", "extracted_requirement": ">=5.0.2", "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -213,8 +213,8 @@ "purl": "pkg:pypi/furo", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -224,8 +224,8 @@ "purl": "pkg:pypi/hypothesis", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -235,8 +235,8 @@ "purl": "pkg:pypi/mypy", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -246,8 +246,8 @@ "purl": "pkg:pypi/pre-commit", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -257,8 +257,8 @@ "purl": "pkg:pypi/pympler", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -268,8 +268,8 @@ "purl": "pkg:pypi/pytest", "extracted_requirement": ">=4.3.0", "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -279,8 +279,8 @@ "purl": "pkg:pypi/pytest-mypy-plugins", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -290,8 +290,8 @@ "purl": "pkg:pypi/six", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -301,8 +301,8 @@ "purl": "pkg:pypi/sphinx", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -312,8 +312,8 @@ "purl": "pkg:pypi/sphinx-notfound-page", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -323,8 +323,8 @@ "purl": "pkg:pypi/zope.interface", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -334,8 +334,8 @@ "purl": "pkg:pypi/furo", "extracted_requirement": null, "scope": "docs", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -345,8 +345,8 @@ "purl": "pkg:pypi/sphinx", "extracted_requirement": null, "scope": "docs", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -356,8 +356,8 @@ "purl": "pkg:pypi/sphinx-notfound-page", "extracted_requirement": null, "scope": "docs", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -367,8 +367,8 @@ "purl": "pkg:pypi/zope.interface", "extracted_requirement": null, "scope": "docs", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -378,8 +378,8 @@ "purl": "pkg:pypi/cloudpickle", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -389,8 +389,8 @@ "purl": "pkg:pypi/coverage%5btoml%5d", "extracted_requirement": ">=5.0.2", "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -400,8 +400,8 @@ "purl": "pkg:pypi/hypothesis", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -411,8 +411,8 @@ "purl": "pkg:pypi/mypy", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -422,8 +422,8 @@ "purl": "pkg:pypi/pympler", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -433,8 +433,8 @@ "purl": "pkg:pypi/pytest", "extracted_requirement": ">=4.3.0", "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -444,8 +444,8 @@ "purl": "pkg:pypi/pytest-mypy-plugins", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -455,8 +455,8 @@ "purl": "pkg:pypi/six", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -466,8 +466,8 @@ "purl": "pkg:pypi/zope.interface", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -477,8 +477,8 @@ "purl": "pkg:pypi/cloudpickle", "extracted_requirement": null, "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -488,8 +488,8 @@ "purl": "pkg:pypi/coverage%5btoml%5d", "extracted_requirement": ">=5.0.2", "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -499,8 +499,8 @@ "purl": "pkg:pypi/hypothesis", "extracted_requirement": null, "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -510,8 +510,8 @@ "purl": "pkg:pypi/mypy", "extracted_requirement": null, "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -521,8 +521,8 @@ "purl": "pkg:pypi/pympler", "extracted_requirement": null, "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -532,8 +532,8 @@ "purl": "pkg:pypi/pytest", "extracted_requirement": ">=4.3.0", "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -543,8 +543,8 @@ "purl": "pkg:pypi/pytest-mypy-plugins", "extracted_requirement": null, "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -554,8 +554,8 @@ "purl": "pkg:pypi/six", "extracted_requirement": null, "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -623,7 +623,7 @@ { "purl": "pkg:pypi/pyparsing", "extracted_requirement": ">=2.0.2", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -694,8 +694,8 @@ "purl": "pkg:pypi/jinja2", "extracted_requirement": null, "scope": "diagrams", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -705,8 +705,8 @@ "purl": "pkg:pypi/railroad-diagrams", "extracted_requirement": null, "scope": "diagrams", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -775,8 +775,8 @@ "purl": "pkg:pypi/django", "extracted_requirement": ">=1.11", "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -786,8 +786,8 @@ "purl": "pkg:pypi/check-manifest", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -797,8 +797,8 @@ "purl": "pkg:pypi/colorama", "extracted_requirement": "<=0.4.1", "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -808,8 +808,8 @@ "purl": "pkg:pypi/coverage", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -819,8 +819,8 @@ "purl": "pkg:pypi/flake8", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -830,8 +830,8 @@ "purl": "pkg:pypi/nose2", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -841,8 +841,8 @@ "purl": "pkg:pypi/readme-renderer", "extracted_requirement": "<25.0", "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -852,8 +852,8 @@ "purl": "pkg:pypi/tox", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -863,8 +863,8 @@ "purl": "pkg:pypi/wheel", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -874,8 +874,8 @@ "purl": "pkg:pypi/zest.releaser%5brecommended%5d", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -885,8 +885,8 @@ "purl": "pkg:pypi/sphinx", "extracted_requirement": null, "scope": "doc", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -896,8 +896,8 @@ "purl": "pkg:pypi/sphinx-rtd-theme", "extracted_requirement": null, "scope": "doc", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1078,8 +1078,8 @@ "purl": "pkg:pypi/cloudpickle", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1089,8 +1089,8 @@ "purl": "pkg:pypi/coverage%5btoml%5d", "extracted_requirement": ">=5.0.2", "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1100,8 +1100,8 @@ "purl": "pkg:pypi/furo", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1111,8 +1111,8 @@ "purl": "pkg:pypi/hypothesis", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1122,8 +1122,8 @@ "purl": "pkg:pypi/mypy", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1133,8 +1133,8 @@ "purl": "pkg:pypi/pre-commit", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1144,8 +1144,8 @@ "purl": "pkg:pypi/pympler", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1155,8 +1155,8 @@ "purl": "pkg:pypi/pytest", "extracted_requirement": ">=4.3.0", "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1166,8 +1166,8 @@ "purl": "pkg:pypi/pytest-mypy-plugins", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1177,8 +1177,8 @@ "purl": "pkg:pypi/six", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1188,8 +1188,8 @@ "purl": "pkg:pypi/sphinx", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1199,8 +1199,8 @@ "purl": "pkg:pypi/sphinx-notfound-page", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1210,8 +1210,8 @@ "purl": "pkg:pypi/zope.interface", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1221,8 +1221,8 @@ "purl": "pkg:pypi/furo", "extracted_requirement": null, "scope": "docs", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1232,8 +1232,8 @@ "purl": "pkg:pypi/sphinx", "extracted_requirement": null, "scope": "docs", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1243,8 +1243,8 @@ "purl": "pkg:pypi/sphinx-notfound-page", "extracted_requirement": null, "scope": "docs", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1254,8 +1254,8 @@ "purl": "pkg:pypi/zope.interface", "extracted_requirement": null, "scope": "docs", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1265,8 +1265,8 @@ "purl": "pkg:pypi/cloudpickle", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1276,8 +1276,8 @@ "purl": "pkg:pypi/coverage%5btoml%5d", "extracted_requirement": ">=5.0.2", "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1287,8 +1287,8 @@ "purl": "pkg:pypi/hypothesis", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1298,8 +1298,8 @@ "purl": "pkg:pypi/mypy", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1309,8 +1309,8 @@ "purl": "pkg:pypi/pympler", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1320,8 +1320,8 @@ "purl": "pkg:pypi/pytest", "extracted_requirement": ">=4.3.0", "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1331,8 +1331,8 @@ "purl": "pkg:pypi/pytest-mypy-plugins", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1342,8 +1342,8 @@ "purl": "pkg:pypi/six", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1353,8 +1353,8 @@ "purl": "pkg:pypi/zope.interface", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1364,8 +1364,8 @@ "purl": "pkg:pypi/cloudpickle", "extracted_requirement": null, "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1375,8 +1375,8 @@ "purl": "pkg:pypi/coverage%5btoml%5d", "extracted_requirement": ">=5.0.2", "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1386,8 +1386,8 @@ "purl": "pkg:pypi/hypothesis", "extracted_requirement": null, "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1397,8 +1397,8 @@ "purl": "pkg:pypi/mypy", "extracted_requirement": null, "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1408,8 +1408,8 @@ "purl": "pkg:pypi/pympler", "extracted_requirement": null, "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1419,8 +1419,8 @@ "purl": "pkg:pypi/pytest", "extracted_requirement": ">=4.3.0", "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1430,8 +1430,8 @@ "purl": "pkg:pypi/pytest-mypy-plugins", "extracted_requirement": null, "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1441,8 +1441,8 @@ "purl": "pkg:pypi/six", "extracted_requirement": null, "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1506,7 +1506,7 @@ { "purl": "pkg:pypi/pyparsing", "extracted_requirement": ">=2.0.2", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -1573,8 +1573,8 @@ "purl": "pkg:pypi/jinja2", "extracted_requirement": null, "scope": "diagrams", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1584,8 +1584,8 @@ "purl": "pkg:pypi/railroad-diagrams", "extracted_requirement": null, "scope": "diagrams", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1650,8 +1650,8 @@ "purl": "pkg:pypi/django", "extracted_requirement": ">=1.11", "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1661,8 +1661,8 @@ "purl": "pkg:pypi/check-manifest", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1672,8 +1672,8 @@ "purl": "pkg:pypi/colorama", "extracted_requirement": "<=0.4.1", "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1683,8 +1683,8 @@ "purl": "pkg:pypi/coverage", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1694,8 +1694,8 @@ "purl": "pkg:pypi/flake8", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1705,8 +1705,8 @@ "purl": "pkg:pypi/nose2", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1716,8 +1716,8 @@ "purl": "pkg:pypi/readme-renderer", "extracted_requirement": "<25.0", "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1727,8 +1727,8 @@ "purl": "pkg:pypi/tox", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1738,8 +1738,8 @@ "purl": "pkg:pypi/wheel", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1749,8 +1749,8 @@ "purl": "pkg:pypi/zest.releaser%5brecommended%5d", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1760,8 +1760,8 @@ "purl": "pkg:pypi/sphinx", "extracted_requirement": null, "scope": "doc", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1771,8 +1771,8 @@ "purl": "pkg:pypi/sphinx-rtd-theme", "extracted_requirement": null, "scope": "doc", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -1930,7 +1930,7 @@ { "purl": "pkg:pypi/attrs", "extracted_requirement": "^21.2.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -1941,7 +1941,7 @@ { "purl": "pkg:pypi/packaging", "extracted_requirement": "21.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -1952,7 +1952,7 @@ { "purl": "pkg:pypi/semantic-version", "extracted_requirement": "^2.8.5", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -1963,7 +1963,7 @@ { "purl": "pkg:pypi/semver", "extracted_requirement": "^2.13.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, diff --git a/tests/packagedcode/data/pypi/poetry/univers-poetry.lock-expected.json b/tests/packagedcode/data/pypi/poetry/univers-poetry.lock-expected.json index 3225ca4c54a..b89dcdc35ef 100644 --- a/tests/packagedcode/data/pypi/poetry/univers-poetry.lock-expected.json +++ b/tests/packagedcode/data/pypi/poetry/univers-poetry.lock-expected.json @@ -90,8 +90,8 @@ "purl": "pkg:pypi/cloudpickle", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -101,8 +101,8 @@ "purl": "pkg:pypi/coverage%5btoml%5d", "extracted_requirement": ">=5.0.2", "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -112,8 +112,8 @@ "purl": "pkg:pypi/furo", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -123,8 +123,8 @@ "purl": "pkg:pypi/hypothesis", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -134,8 +134,8 @@ "purl": "pkg:pypi/mypy", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -145,8 +145,8 @@ "purl": "pkg:pypi/pre-commit", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -156,8 +156,8 @@ "purl": "pkg:pypi/pympler", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -167,8 +167,8 @@ "purl": "pkg:pypi/pytest", "extracted_requirement": ">=4.3.0", "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -178,8 +178,8 @@ "purl": "pkg:pypi/pytest-mypy-plugins", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -189,8 +189,8 @@ "purl": "pkg:pypi/six", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -200,8 +200,8 @@ "purl": "pkg:pypi/sphinx", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -211,8 +211,8 @@ "purl": "pkg:pypi/sphinx-notfound-page", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -222,8 +222,8 @@ "purl": "pkg:pypi/zope.interface", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -233,8 +233,8 @@ "purl": "pkg:pypi/furo", "extracted_requirement": null, "scope": "docs", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -244,8 +244,8 @@ "purl": "pkg:pypi/sphinx", "extracted_requirement": null, "scope": "docs", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -255,8 +255,8 @@ "purl": "pkg:pypi/sphinx-notfound-page", "extracted_requirement": null, "scope": "docs", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -266,8 +266,8 @@ "purl": "pkg:pypi/zope.interface", "extracted_requirement": null, "scope": "docs", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -277,8 +277,8 @@ "purl": "pkg:pypi/cloudpickle", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -288,8 +288,8 @@ "purl": "pkg:pypi/coverage%5btoml%5d", "extracted_requirement": ">=5.0.2", "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -299,8 +299,8 @@ "purl": "pkg:pypi/hypothesis", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -310,8 +310,8 @@ "purl": "pkg:pypi/mypy", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -321,8 +321,8 @@ "purl": "pkg:pypi/pympler", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -332,8 +332,8 @@ "purl": "pkg:pypi/pytest", "extracted_requirement": ">=4.3.0", "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -343,8 +343,8 @@ "purl": "pkg:pypi/pytest-mypy-plugins", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -354,8 +354,8 @@ "purl": "pkg:pypi/six", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -365,8 +365,8 @@ "purl": "pkg:pypi/zope.interface", "extracted_requirement": null, "scope": "tests", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -376,8 +376,8 @@ "purl": "pkg:pypi/cloudpickle", "extracted_requirement": null, "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -387,8 +387,8 @@ "purl": "pkg:pypi/coverage%5btoml%5d", "extracted_requirement": ">=5.0.2", "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -398,8 +398,8 @@ "purl": "pkg:pypi/hypothesis", "extracted_requirement": null, "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -409,8 +409,8 @@ "purl": "pkg:pypi/mypy", "extracted_requirement": null, "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -420,8 +420,8 @@ "purl": "pkg:pypi/pympler", "extracted_requirement": null, "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -431,8 +431,8 @@ "purl": "pkg:pypi/pytest", "extracted_requirement": ">=4.3.0", "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -442,8 +442,8 @@ "purl": "pkg:pypi/pytest-mypy-plugins", "extracted_requirement": null, "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -453,8 +453,8 @@ "purl": "pkg:pypi/six", "extracted_requirement": null, "scope": "tests-no-zope", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -518,7 +518,7 @@ { "purl": "pkg:pypi/pyparsing", "extracted_requirement": ">=2.0.2", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -585,8 +585,8 @@ "purl": "pkg:pypi/jinja2", "extracted_requirement": null, "scope": "diagrams", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -596,8 +596,8 @@ "purl": "pkg:pypi/railroad-diagrams", "extracted_requirement": null, "scope": "diagrams", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -662,8 +662,8 @@ "purl": "pkg:pypi/django", "extracted_requirement": ">=1.11", "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -673,8 +673,8 @@ "purl": "pkg:pypi/check-manifest", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -684,8 +684,8 @@ "purl": "pkg:pypi/colorama", "extracted_requirement": "<=0.4.1", "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -695,8 +695,8 @@ "purl": "pkg:pypi/coverage", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -706,8 +706,8 @@ "purl": "pkg:pypi/flake8", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -717,8 +717,8 @@ "purl": "pkg:pypi/nose2", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -728,8 +728,8 @@ "purl": "pkg:pypi/readme-renderer", "extracted_requirement": "<25.0", "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -739,8 +739,8 @@ "purl": "pkg:pypi/tox", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -750,8 +750,8 @@ "purl": "pkg:pypi/wheel", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -761,8 +761,8 @@ "purl": "pkg:pypi/zest.releaser%5brecommended%5d", "extracted_requirement": null, "scope": "dev", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -772,8 +772,8 @@ "purl": "pkg:pypi/sphinx", "extracted_requirement": null, "scope": "doc", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -783,8 +783,8 @@ "purl": "pkg:pypi/sphinx-rtd-theme", "extracted_requirement": null, "scope": "doc", - "is_runtime": true, - "is_optional": true, + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, diff --git a/tests/packagedcode/data/pypi/poetry/univers-pyproject.toml-expected.json b/tests/packagedcode/data/pypi/poetry/univers-pyproject.toml-expected.json index 96389ae207f..e48de46671b 100644 --- a/tests/packagedcode/data/pypi/poetry/univers-pyproject.toml-expected.json +++ b/tests/packagedcode/data/pypi/poetry/univers-pyproject.toml-expected.json @@ -71,7 +71,7 @@ { "purl": "pkg:pypi/attrs", "extracted_requirement": "^21.2.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -82,7 +82,7 @@ { "purl": "pkg:pypi/packaging", "extracted_requirement": "21.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -93,7 +93,7 @@ { "purl": "pkg:pypi/semantic-version", "extracted_requirement": "^2.8.5", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -104,7 +104,7 @@ { "purl": "pkg:pypi/semver", "extracted_requirement": "^2.13.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, diff --git a/tests/packagedcode/data/pypi/pyproject-toml/poetry/connexion-pyproject.toml-expected.json b/tests/packagedcode/data/pypi/pyproject-toml/poetry/connexion-pyproject.toml-expected.json index 8d1f38600fb..15116146533 100644 --- a/tests/packagedcode/data/pypi/pyproject-toml/poetry/connexion-pyproject.toml-expected.json +++ b/tests/packagedcode/data/pypi/pyproject-toml/poetry/connexion-pyproject.toml-expected.json @@ -157,7 +157,7 @@ { "purl": "pkg:pypi/asgiref", "extracted_requirement": ">= 3.4", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -168,7 +168,7 @@ { "purl": "pkg:pypi/httpx", "extracted_requirement": ">= 0.23", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -179,7 +179,7 @@ { "purl": "pkg:pypi/inflection", "extracted_requirement": ">= 0.3.1", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -190,7 +190,7 @@ { "purl": "pkg:pypi/jsonschema", "extracted_requirement": ">=4.17.3", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -201,7 +201,7 @@ { "purl": "pkg:pypi/jinja2", "extracted_requirement": ">= 3.0.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -212,7 +212,7 @@ { "purl": "pkg:pypi/python-multipart", "extracted_requirement": ">= 0.0.5", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -223,7 +223,7 @@ { "purl": "pkg:pypi/pyyaml", "extracted_requirement": ">= 5.1", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -234,7 +234,7 @@ { "purl": "pkg:pypi/requests", "extracted_requirement": ">= 2.27", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -245,7 +245,7 @@ { "purl": "pkg:pypi/starlette", "extracted_requirement": ">= 0.35", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -256,7 +256,7 @@ { "purl": "pkg:pypi/typing-extensions", "extracted_requirement": ">= 4.6.1", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -267,7 +267,7 @@ { "purl": "pkg:pypi/werkzeug", "extracted_requirement": ">= 2.2.1", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -278,7 +278,7 @@ { "purl": "pkg:pypi/a2wsgi", "extracted_requirement": ">= 1.7", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": true, "is_resolved": false, @@ -289,7 +289,7 @@ { "purl": "pkg:pypi/flask", "extracted_requirement": ">= 2.2", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": true, "is_resolved": false, @@ -300,7 +300,7 @@ { "purl": "pkg:pypi/swagger-ui-bundle", "extracted_requirement": ">= 1.1.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": true, "is_resolved": false, @@ -311,7 +311,7 @@ { "purl": "pkg:pypi/uvicorn", "extracted_requirement": ">= 0.17.6", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": true, "is_resolved": false, @@ -322,7 +322,7 @@ { "purl": "pkg:pypi/jsf", "extracted_requirement": ">=0.10.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": true, "is_resolved": false, @@ -334,7 +334,7 @@ "purl": "pkg:pypi/pre-commit", "extracted_requirement": "~2.21.0", "scope": "tests", - "is_runtime": true, + "is_runtime": false, "is_optional": false, "is_resolved": false, "is_direct": true, @@ -345,7 +345,7 @@ "purl": "pkg:pypi/pytest", "extracted_requirement": "7.2.1", "scope": "tests", - "is_runtime": true, + "is_runtime": false, "is_optional": false, "is_resolved": false, "is_direct": true, @@ -356,7 +356,7 @@ "purl": "pkg:pypi/pytest-asyncio", "extracted_requirement": "~0.18.3", "scope": "tests", - "is_runtime": true, + "is_runtime": false, "is_optional": false, "is_resolved": false, "is_direct": true, @@ -367,7 +367,7 @@ "purl": "pkg:pypi/pytest-cov", "extracted_requirement": "~2.12.1", "scope": "tests", - "is_runtime": true, + "is_runtime": false, "is_optional": false, "is_resolved": false, "is_direct": true, @@ -378,7 +378,7 @@ "purl": "pkg:pypi/sphinx", "extracted_requirement": "5.3.0", "scope": "docs", - "is_runtime": true, + "is_runtime": false, "is_optional": false, "is_resolved": false, "is_direct": true, @@ -389,7 +389,7 @@ "purl": "pkg:pypi/sphinx-copybutton", "extracted_requirement": "0.5.2", "scope": "docs", - "is_runtime": true, + "is_runtime": false, "is_optional": false, "is_resolved": false, "is_direct": true, @@ -400,7 +400,7 @@ "purl": "pkg:pypi/sphinx-design", "extracted_requirement": "0.4.1", "scope": "docs", - "is_runtime": true, + "is_runtime": false, "is_optional": false, "is_resolved": false, "is_direct": true, @@ -411,7 +411,7 @@ "purl": "pkg:pypi/sphinx-rtd-theme", "extracted_requirement": "1.2.0", "scope": "docs", - "is_runtime": true, + "is_runtime": false, "is_optional": false, "is_resolved": false, "is_direct": true, @@ -422,7 +422,7 @@ "purl": "pkg:pypi/sphinxemoji", "extracted_requirement": "0.2.0", "scope": "docs", - "is_runtime": true, + "is_runtime": false, "is_optional": false, "is_resolved": false, "is_direct": true, diff --git a/tests/packagedcode/data/pypi/pyproject-toml/poetry/gerapy-pyproject.toml-expected.json b/tests/packagedcode/data/pypi/pyproject-toml/poetry/gerapy-pyproject.toml-expected.json index 2df7935275c..9d072c1546d 100644 --- a/tests/packagedcode/data/pypi/pyproject-toml/poetry/gerapy-pyproject.toml-expected.json +++ b/tests/packagedcode/data/pypi/pyproject-toml/poetry/gerapy-pyproject.toml-expected.json @@ -99,7 +99,7 @@ { "purl": "pkg:pypi/apscheduler", "extracted_requirement": ">=3.5.1,<=3.7.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -110,7 +110,7 @@ { "purl": "pkg:pypi/cryptography", "extracted_requirement": ">=2.8", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -121,7 +121,7 @@ { "purl": "pkg:pypi/django", "extracted_requirement": ">=2.2,<3.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -132,7 +132,7 @@ { "purl": "pkg:pypi/django-cors-headers", "extracted_requirement": ">=3.2.0,<=3.7.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -143,7 +143,7 @@ { "purl": "pkg:pypi/django-apscheduler", "extracted_requirement": ">=0.3.0,<=0.6.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -154,7 +154,7 @@ { "purl": "pkg:pypi/furl", "extracted_requirement": ">=2.1.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -165,7 +165,7 @@ { "purl": "pkg:pypi/jinja2", "extracted_requirement": ">=2.11.3", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -176,7 +176,7 @@ { "purl": "pkg:pypi/scrapy", "extracted_requirement": ">=2.7.1", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -187,7 +187,7 @@ { "purl": "pkg:pypi/scrapy-redis", "extracted_requirement": ">=0.6.8", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -198,7 +198,7 @@ { "purl": "pkg:pypi/scrapy-splash", "extracted_requirement": ">=0.7.2", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -209,7 +209,7 @@ { "purl": "pkg:pypi/python-scrapyd-api", "extracted_requirement": ">=2.1.2", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -220,7 +220,7 @@ { "purl": "pkg:pypi/redis", "extracted_requirement": ">=2.10.5", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -231,7 +231,7 @@ { "purl": "pkg:pypi/requests", "extracted_requirement": ">=2.20.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -242,7 +242,7 @@ { "purl": "pkg:pypi/pymongo", "extracted_requirement": ">=3.9.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -253,7 +253,7 @@ { "purl": "pkg:pypi/pymysql", "extracted_requirement": ">=0.7.10", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -264,7 +264,7 @@ { "purl": "pkg:pypi/pyquery", "extracted_requirement": ">=1.2.17", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -275,7 +275,7 @@ { "purl": "pkg:pypi/beautifulsoup4", "extracted_requirement": ">=4.7.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -286,7 +286,7 @@ { "purl": "pkg:pypi/djangorestframework", "extracted_requirement": ">=3.11.2", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -297,7 +297,7 @@ { "purl": "pkg:pypi/websocket", "extracted_requirement": ">=0.2.1", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -308,7 +308,7 @@ { "purl": "pkg:pypi/pyppeteer", "extracted_requirement": ">=0.0.25", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -319,7 +319,7 @@ { "purl": "pkg:pypi/uberegg", "extracted_requirement": "^0.1.1", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, diff --git a/tests/packagedcode/data/pypi/pyproject-toml/poetry/gino-pyproject.toml-expected.json b/tests/packagedcode/data/pypi/pyproject-toml/poetry/gino-pyproject.toml-expected.json index 141fe49b010..0886b352c74 100644 --- a/tests/packagedcode/data/pypi/pyproject-toml/poetry/gino-pyproject.toml-expected.json +++ b/tests/packagedcode/data/pypi/pyproject-toml/poetry/gino-pyproject.toml-expected.json @@ -123,7 +123,7 @@ { "purl": "pkg:pypi/sqlalchemy", "extracted_requirement": ">=1.3,<1.4", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -134,7 +134,7 @@ { "purl": "pkg:pypi/asyncpg", "extracted_requirement": ">=0.18,<1.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": true, "is_resolved": false, @@ -145,9 +145,9 @@ { "purl": "pkg:pypi/aiomysql", "extracted_requirement": "^0.0.22", - "scope": "install", + "scope": "dependencies", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -156,7 +156,7 @@ { "purl": "pkg:pypi/contextvars", "extracted_requirement": "^2.4", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -169,7 +169,7 @@ { "purl": "pkg:pypi/importlib-metadata", "extracted_requirement": "^2.0.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": false, "is_resolved": false, @@ -182,7 +182,7 @@ { "purl": "pkg:pypi/gino-starlette", "extracted_requirement": "^0.1.1", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": true, "is_resolved": false, @@ -195,7 +195,7 @@ { "purl": "pkg:pypi/gino-aiohttp", "extracted_requirement": "^0.2.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": true, "is_resolved": false, @@ -208,7 +208,7 @@ { "purl": "pkg:pypi/gino-tornado", "extracted_requirement": "^0.1.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": true, "is_resolved": false, @@ -221,7 +221,7 @@ { "purl": "pkg:pypi/gino-sanic", "extracted_requirement": "^0.1.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": true, "is_resolved": false, @@ -234,7 +234,7 @@ { "purl": "pkg:pypi/gino-quart", "extracted_requirement": "^0.1.0", - "scope": "install", + "scope": "dependencies", "is_runtime": true, "is_optional": true, "is_resolved": false, @@ -247,9 +247,9 @@ { "purl": "pkg:pypi/psycopg2-binary", "extracted_requirement": "^2.9.3", - "scope": "install", - "is_runtime": true, - "is_optional": true, + "scope": "dev-dependencies", + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -258,9 +258,9 @@ { "purl": "pkg:pypi/click", "extracted_requirement": "^8.0.3", - "scope": "install", - "is_runtime": true, - "is_optional": true, + "scope": "dev-dependencies", + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -269,9 +269,9 @@ { "purl": "pkg:pypi/pytest", "extracted_requirement": "^7.0.1", - "scope": "install", - "is_runtime": true, - "is_optional": true, + "scope": "dev-dependencies", + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -280,9 +280,9 @@ { "purl": "pkg:pypi/pytest-asyncio", "extracted_requirement": "^0.16.0", - "scope": "install", - "is_runtime": true, - "is_optional": true, + "scope": "dev-dependencies", + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -291,9 +291,9 @@ { "purl": "pkg:pypi/pytest-mock", "extracted_requirement": "^3.6.0", - "scope": "install", - "is_runtime": true, - "is_optional": true, + "scope": "dev-dependencies", + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -302,9 +302,9 @@ { "purl": "pkg:pypi/pytest-cov", "extracted_requirement": "^3.0.0", - "scope": "install", - "is_runtime": true, - "is_optional": true, + "scope": "dev-dependencies", + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -313,9 +313,9 @@ { "purl": "pkg:pypi/black", "extracted_requirement": "^22.1.0", - "scope": "install", - "is_runtime": true, - "is_optional": true, + "scope": "dev-dependencies", + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -326,9 +326,9 @@ { "purl": "pkg:pypi/mypy", "extracted_requirement": "^0.931", - "scope": "install", - "is_runtime": true, - "is_optional": true, + "scope": "dev-dependencies", + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -337,9 +337,9 @@ { "purl": "pkg:pypi/sphinx", "extracted_requirement": "^4.3.0", - "scope": "install", - "is_runtime": true, - "is_optional": true, + "scope": "dev-dependencies", + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -348,9 +348,9 @@ { "purl": "pkg:pypi/sphinx-rtd-theme", "extracted_requirement": "^1.0.0", - "scope": "install", - "is_runtime": true, - "is_optional": true, + "scope": "dev-dependencies", + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -359,9 +359,9 @@ { "purl": "pkg:pypi/sphinxcontrib-apidoc", "extracted_requirement": "^0.3.0", - "scope": "install", - "is_runtime": true, - "is_optional": true, + "scope": "dev-dependencies", + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -370,9 +370,9 @@ { "purl": "pkg:pypi/sphinx-autobuild", "extracted_requirement": "^2021.3.14", - "scope": "install", - "is_runtime": true, - "is_optional": true, + "scope": "dev-dependencies", + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -381,9 +381,9 @@ { "purl": "pkg:pypi/sphinx-intl", "extracted_requirement": "^2.0.1", - "scope": "install", - "is_runtime": true, - "is_optional": true, + "scope": "dev-dependencies", + "is_runtime": false, + "is_optional": false, "is_resolved": false, "is_direct": true, "resolved_package": {}, diff --git a/tests/packagedcode/data/pypi/pyproject-toml/standard/attrs-pyproject.toml-expected.json b/tests/packagedcode/data/pypi/pyproject-toml/standard/attrs-pyproject.toml-expected.json index 5f48a55133d..88789cc3b79 100644 --- a/tests/packagedcode/data/pypi/pyproject-toml/standard/attrs-pyproject.toml-expected.json +++ b/tests/packagedcode/data/pypi/pyproject-toml/standard/attrs-pyproject.toml-expected.json @@ -128,7 +128,7 @@ "extracted_requirement": null, "scope": "tests-mypy", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -141,7 +141,7 @@ "extracted_requirement": "<1.10,>=1.6", "scope": "tests-mypy", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -154,7 +154,7 @@ "extracted_requirement": null, "scope": "tests", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -165,7 +165,7 @@ "extracted_requirement": null, "scope": "tests", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -176,7 +176,7 @@ "extracted_requirement": null, "scope": "tests", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -187,7 +187,7 @@ "extracted_requirement": ">=4.3.0", "scope": "tests", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -198,7 +198,7 @@ "extracted_requirement": null, "scope": "tests", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -209,7 +209,7 @@ "extracted_requirement": null, "scope": "tests", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -220,7 +220,7 @@ "extracted_requirement": null, "scope": "cov", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -231,7 +231,7 @@ "extracted_requirement": ">=5.3", "scope": "cov", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -242,7 +242,7 @@ "extracted_requirement": null, "scope": "docs", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -253,7 +253,7 @@ "extracted_requirement": null, "scope": "docs", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -264,7 +264,7 @@ "extracted_requirement": null, "scope": "docs", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -275,7 +275,7 @@ "extracted_requirement": null, "scope": "docs", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -286,7 +286,7 @@ "extracted_requirement": null, "scope": "docs", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -297,7 +297,7 @@ "extracted_requirement": null, "scope": "docs", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -308,7 +308,7 @@ "extracted_requirement": null, "scope": "dev", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -319,7 +319,7 @@ "extracted_requirement": null, "scope": "dev", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, diff --git a/tests/packagedcode/data/pypi/pyproject-toml/standard/flask-pyproject.toml-expected.json b/tests/packagedcode/data/pypi/pyproject-toml/standard/flask-pyproject.toml-expected.json index 07fe37e07d6..0926abc86b2 100644 --- a/tests/packagedcode/data/pypi/pyproject-toml/standard/flask-pyproject.toml-expected.json +++ b/tests/packagedcode/data/pypi/pyproject-toml/standard/flask-pyproject.toml-expected.json @@ -159,7 +159,7 @@ "extracted_requirement": ">=3.2", "scope": "async", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -170,7 +170,7 @@ "extracted_requirement": null, "scope": "dotenv", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, 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 9ecfc125423..6912a131756 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 @@ -159,7 +159,7 @@ "extracted_requirement": "<3.0.0,>=2.8.5", "scope": "install", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, @@ -404,7 +404,7 @@ "extracted_requirement": "<3.0.0,>=2.8.5", "scope": "install", "is_runtime": true, - "is_optional": false, + "is_optional": true, "is_resolved": false, "is_direct": true, "resolved_package": {}, From eae105e125411490f53cb3ed484b011899a2f089 Mon Sep 17 00:00:00 2001 From: Ayan Sinha Mahapatra Date: Mon, 1 Jul 2024 18:04:49 +0530 Subject: [PATCH 08/10] Replace deprecated macos-11 runner images Signed-off-by: Ayan Sinha Mahapatra --- .github/workflows/scancode-release.yml | 4 ++-- azure-pipelines.yml | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/scancode-release.yml b/.github/workflows/scancode-release.yml index b80549d8944..80506189fc6 100644 --- a/.github/workflows/scancode-release.yml +++ b/.github/workflows/scancode-release.yml @@ -235,7 +235,7 @@ jobs: strategy: fail-fast: true matrix: - os: [ubuntu-22.04, ubuntu-22.04, macos-11, macos-12] + os: [ubuntu-22.04, ubuntu-22.04, macos-12, macos-13] pyver: ["3.8", "3.9", "3.10", "3.11", "3.12"] steps: @@ -367,7 +367,7 @@ jobs: strategy: fail-fast: true matrix: - os: [macos-11, macos-12] + os: [macos-12, macos-13] pyver: ["3.8", "3.9", "3.10", "3.11", "3.12"] steps: diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 0771ddf8536..1bc57ce1825 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -211,19 +211,19 @@ jobs: python_versions: ['3.8', '3.9', '3.10', '3.11', '3.12'] test_suites: all: venv/bin/pip install --upgrade-strategy eager --force-reinstall --upgrade -e .[testing] && venv/bin/pytest -n 2 -vvs tests/scancode/test_cli.py - + - template: etc/ci/azure-posix.yml parameters: - job_name: macos11_cpython_latest_from_pip - image_name: macos-11 + job_name: macos12_cpython_latest_from_pip + image_name: macos-12 python_versions: ['3.8', '3.9', '3.10', '3.11', '3.12'] test_suites: all: venv/bin/pip install --upgrade-strategy eager --force-reinstall --upgrade -e .[testing] && venv/bin/pytest -n 2 -vvs tests/scancode/test_cli.py - template: etc/ci/azure-posix.yml parameters: - job_name: macos12_cpython_latest_from_pip - image_name: macos-12 + job_name: macos13_cpython_latest_from_pip + image_name: macos-13 python_versions: ['3.8', '3.9', '3.10', '3.11', '3.12'] test_suites: all: venv/bin/pip install --upgrade-strategy eager --force-reinstall --upgrade -e .[testing] && venv/bin/pytest -n 2 -vvs tests/scancode/test_cli.py From bc49ca0f63cdde8e80655064719013930e848560 Mon Sep 17 00:00:00 2001 From: Ayan Sinha Mahapatra Date: Mon, 1 Jul 2024 18:13:52 +0530 Subject: [PATCH 09/10] Add CHANGELOG entry and other minor updates Signed-off-by: Ayan Sinha Mahapatra --- CHANGELOG.rst | 14 ++++++++++ azure-pipelines.yml | 8 ------ .../reference/available_package_parsers.rst | 26 ++++++++++++++++++- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index fd3d8e9bd41..c13527cf07c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -46,6 +46,20 @@ v33.0.0 (next next, roadmap) from swift `swift-show-dependencies.deplock` generated by DepLock. See https://github.com/nexB/scancode-toolkit/pull/3829 +- Add support for `pip-inspect.deplock` files to parse and store + resolved packages and dependency relationships, to statically + resolve a python dependency graph. + See https://github.com/nexB/scancode.io/issues/1262 + +- Add support for poetry packages, with poetry specific pyproject.toml + support, poetry.lock and package assembly support. Also add support + for parsing and storing resolved packages and dependency relationships + required to statically resolve poetry dependecy graphs. + See https://github.com/nexB/scancode-toolkit/issues/2109 + +- Add support for pyproject.toml files in python projects. + See https://github.com/nexB/scancode-toolkit/issues/3753 + v32.2.0 - 2024-06-19 ---------------------- diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1bc57ce1825..35f1c35a080 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -126,14 +126,6 @@ jobs: test_suites: all: venv/bin/pytest -n 2 -vvs - - template: etc/ci/azure-posix.yml - parameters: - job_name: macos14_cpython - image_name: macOS-14-large - python_versions: ['3.8', '3.8', '3.9', '3.10', '3.12'] - test_suites: - all: venv/bin/pytest -n 2 -vvs - - template: etc/ci/azure-win.yml parameters: job_name: win2019_cpython_1 diff --git a/docs/source/reference/available_package_parsers.rst b/docs/source/reference/available_package_parsers.rst index d45630bee2f..eb593d62856 100644 --- a/docs/source/reference/available_package_parsers.rst +++ b/docs/source/reference/available_package_parsers.rst @@ -587,6 +587,12 @@ parsers in scancode-toolkit during documentation builds. - ``nuget_nupsec`` - None - https://docs.microsoft.com/en-us/nuget/reference/nuspec + * - NuGet packages.lock.json file + - ``*packages.lock.json`` + - ``nuget`` + - ``nuget_packages_lock`` + - None + - https://learn.microsoft.com/en-us/nuget/reference/cli-reference/cli-ref-restore * - Ocaml Opam file - ``*opam`` - ``opam`` @@ -661,12 +667,30 @@ parsers in scancode-toolkit during documentation builds. - ``pypi_egg_pkginfo`` - Python - https://peps.python.org/pep-0376/ + * - Python poetry pyproject.toml + - ``*pip-inspect.deplock`` + - ``pypi`` + - ``pypi_inspect_deplock`` + - Python + - https://pip.pypa.io/en/stable/cli/pip_inspect/ + * - Python poetry lockfile + - ``*poetry.lock`` + - ``pypi`` + - ``pypi_poetry_lock`` + - Python + - https://python-poetry.org/docs/basic-usage/#installing-with-poetrylock + * - Python poetry pyproject.toml + - ``*pyproject.toml`` + - ``pypi`` + - ``pypi_poetry_pyproject_toml`` + - Python + - https://packaging.python.org/en/latest/specifications/pyproject-toml/ * - Python pyproject.toml - ``*pyproject.toml`` - ``pypi`` - ``pypi_pyproject_toml`` - Python - - https://peps.python.org/pep-0621/ + - https://packaging.python.org/en/latest/specifications/pyproject-toml/ * - PyPI extracted sdist PKG-INFO - ``*/PKG-INFO`` - ``pypi`` From 56aa35d241ee84b2fdf521e5d2d35f5f4b5e322b Mon Sep 17 00:00:00 2001 From: Ayan Sinha Mahapatra Date: Mon, 1 Jul 2024 19:51:34 +0530 Subject: [PATCH 10/10] Remove usage of str.removesuffix() The removesuffix attribute is only available from Python 3.9+ Signed-off-by: Ayan Sinha Mahapatra --- src/packagedcode/swift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packagedcode/swift.py b/src/packagedcode/swift.py index 339b3e85516..1fd08a00cc1 100644 --- a/src/packagedcode/swift.py +++ b/src/packagedcode/swift.py @@ -418,7 +418,7 @@ def get_dependencies(dependencies): def get_namespace_and_name(url): parsed_url = parse.urlparse(url) hostname = parsed_url.hostname - path = parsed_url.path.removesuffix(".git") + path = parsed_url.path.replace(".git", "") canonical_name = hostname + path return canonical_name.rsplit("/", 1)