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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 63 additions & 5 deletions src/packagedcode/pypi.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
import sys
import tempfile
import zipfile

# NOTE: adjust the location to the actual code in packagedcode/python.py
def is_pylock_toml(location):
return location.endswith("pylock.toml")
from configparser import ConfigParser
from fnmatch import fnmatchcase
from pathlib import Path
Expand Down Expand Up @@ -45,14 +49,66 @@
from packagedcode.utils import yield_dependencies_from_package_resource
from packagedcode.utils import get_base_purl


class PyLockPackage(models.PackageData):
datasource_id = 'pylock_toml'
type = 'python'
primary_language = 'Python'


# tomli was added to the stdlib as tomllib in Python 3.11.
# It's the same code.
# Still, prefer tomli if it's installed, as on newer Python versions, it is
# compiled with mypyc and is more performant.
try:
import tomli as tomllib
except ImportError:
import tomllib
# compiled with mypyc and is more performant.
try:
import tomli as tomllib # Python 3.11+
except ImportError:
import tomllib

# NOTE: adjust the location to the actual code in packagedcode/python.py
def parse_pylock(location):
with open(location, "rb") as f:
data = tomllib.load(f)
return data

def extract_pylock_packages(pylock_data):
packages = []

for pkg in pylock_data.get("package", []):
packages.append({
"name": pkg.get("name"),
"version": pkg.get("version"),
"dependencies": [
dep.get("name") for dep in pkg.get("dependencies", [])
],
"hashes": pkg.get("hashes", []),
"source": pkg.get("source", {}),
})

return packages


from packagedcode.models import PyLockPackage

def parse_pylock_toml(location, package_only=False):
data = parse_pylock(location)
packages = extract_pylock_packages(data)

results = []
for pkg in packages:
results.append(
PyLockPackage(
name=pkg["name"],
version=pkg["version"],
dependencies=pkg["dependencies"],
extra_data={
"hashes": pkg["hashes"],
"source": pkg["source"],
}
)
)
return results


try:
from zipfile import Path as ZipPath
Expand Down Expand Up @@ -1214,6 +1270,8 @@ class BaseDependencyFileHandler(models.DatafileHandler):

@classmethod
def parse(cls, location, package_only=False):
if is_pylock_toml(location):
return parse_pylock_toml(location)
file_name = fileutils.file_name(location)

dependency_type = get_dparse2_supported_file_name(file_name)
Expand Down
34 changes: 34 additions & 0 deletions tests/data/pylock.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package = [
{
name = "click",
version = "8.0.4",
dependencies = [
"setuptools",
],
hashes = [
"sha256:d826a4f4d2f8087796d859424c585c5c99141d6b052140a3f707011d17960d75",
],
source = {
type = "url",
url = "https://files.pythonhosted.org/packages/source/c/click/click-8.0.4.tar.gz",
hashes = {
sha256 = "d826a4f4d2f8087796d859424c585c5c99141d6b052140a3f707011d17960d75",
},
},
},
{
name = "setuptools",
version = "60.5.0",
dependencies = [],
hashes = [
"sha256:8b030b7e28b8b42c4b8e7e1b5b8c9d0d3a5a7f9a1f3a9e3a3c2a8f8a1a1a1a1a",
],
source = {
type = "url",
url = "https://files.pythonhosted.org/packages/source/s/setuptools/setuptools-60.5.0.tar.gz",
hashes = {
sha256 = "8b030b7e28b8b42c4b8e7e1b5b8c9d0d3a5a7f9a1f3a9e3a3c2a8f8a1a1a1a1a",
},
},
},
]
17 changes: 17 additions & 0 deletions tests/packagedcode/test_pylock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from os.path import join, dirname, abspath

from packagedcode.pypi import is_pylock_toml
from packagedcode.pypi import parse_pylock

TEST_DATA_DIR = join(abspath(dirname(__file__)), 'data')

def test_is_pylock_toml():
assert is_pylock_toml("pylock.toml")

def test_parse_pylock():
location = join(TEST_DATA_DIR, "pylock.toml")
data = parse_pylock(location)
assert "package" in data
assert len(data["package"]) == 2
assert data["package"][0]["name"] == "click"
assert data["package"][1]["name"] == "setuptools"
Loading