From ac530bb531a4873f37d32fd16b17502fe5d7b2f8 Mon Sep 17 00:00:00 2001 From: Ayan Sinha Mahapatra Date: Mon, 1 Jul 2024 13:18:06 +0530 Subject: [PATCH] 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 ++- .../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 +- 15 files changed, 4748 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/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')