diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 0d745db06a..a02b023245 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -10,6 +10,8 @@ Next release https://github.com/aboutcode-org/scancode-toolkit/pull/4474 https://github.com/aboutcode-org/scancode-toolkit/issues/4101 +- Replace unmaintained ``toml`` library with ``tomllib`` / ``tomli``. + https://github.com/aboutcode-org/scancode-toolkit/issues/4532 v32.4.1 - 2025-07-23 -------------------- diff --git a/requirements-dev.txt b/requirements-dev.txt index b995b2305b..2699cb82ec 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -25,7 +25,7 @@ requests-toolbelt==0.9.1 rfc3986==2.0.0 rich==12.5.1 secretstorage==3.3.2 -tomli==2.0.1 +tomli==2.3.0 tqdm==4.64.0 twine==6.1.0 typing_extensions==4.14.0 diff --git a/requirements.txt b/requirements.txt index 8d7b458c84..4cdb3fdebc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -69,7 +69,7 @@ six==1.17.0 soupsieve==2.7 spdx-tools==0.8.2 text-unidecode==1.3 -toml==0.10.2 +tomli==2.3.0 typecode==30.0.2 typecode-libmagic==5.39.210531 typing-extensions==4.14.0 diff --git a/setup-mini.cfg b/setup-mini.cfg index 8f3a043d8a..2b7196b4a9 100644 --- a/setup-mini.cfg +++ b/setup-mini.cfg @@ -109,7 +109,7 @@ install_requires = saneyaml >= 0.6.0 spdx_tools == 0.8.2 text_unidecode >= 1.0 - toml >= 0.10.0 + tomli >= 2; python_version < "3.11" urlpy xmltodict >= 0.11.0 typecode >= 30.0.1 diff --git a/setup.cfg b/setup.cfg index 770b70542b..c2fa168ed1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -110,7 +110,7 @@ install_requires = saneyaml >= 0.6.0 spdx_tools == 0.8.2 text_unidecode >= 1.0 - toml >= 0.10.0 + tomli >= 2; python_version < "3.11" urlpy xmltodict >= 0.11.0 typecode >= 30.0.1 diff --git a/src/packagedcode/cargo.py b/src/packagedcode/cargo.py index 3a0533d8f9..8cd087c2cc 100644 --- a/src/packagedcode/cargo.py +++ b/src/packagedcode/cargo.py @@ -12,11 +12,19 @@ import re import sys -import toml from packageurl import PackageURL from packagedcode import models +# 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 + """ Handle Rust cargo crates """ @@ -170,7 +178,8 @@ class CargoTomlHandler(CargoBaseHandler): @classmethod def parse(cls, location, package_only=False): - package_data_toml = toml.load(location, _dict=dict) + with open(location, "rb") as fp: + package_data_toml = tomllib.load(fp) workspace = package_data_toml.get('workspace', {}) core_package_data = package_data_toml.get('package', {}) extra_data = {} @@ -283,7 +292,8 @@ class CargoLockHandler(CargoBaseHandler): @classmethod def parse(cls, location, package_only=False): - cargo_lock = toml.load(location, _dict=dict) + with open(location, "rb") as fp: + cargo_lock = tomllib.load(fp) dependencies = [] package = cargo_lock.get('package', []) for dep in package: diff --git a/src/packagedcode/pypi.py b/src/packagedcode/pypi.py index 2610f43a01..cff5a8335a 100644 --- a/src/packagedcode/pypi.py +++ b/src/packagedcode/pypi.py @@ -29,7 +29,6 @@ import packvers as packaging import pip_requirements_parser import pkginfo2 -import toml from commoncode import fileutils from commoncode.fileutils import as_posixpath from commoncode.resource import Resource @@ -46,6 +45,15 @@ from packagedcode.utils import yield_dependencies_from_package_resource from packagedcode.utils import get_base_purl +# 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 + try: from zipfile import Path as ZipPath except ImportError: @@ -463,7 +471,8 @@ def is_datafile(cls, location, filetypes=tuple()): @classmethod def parse(cls, location, package_only=False): - package_data = toml.load(location, _dict=dict) + with open(location, "rb") as fp: + package_data = tomllib.load(fp) project_data = package_data.get("project") if not project_data: return @@ -647,7 +656,8 @@ def parse_non_group_dependencies( @classmethod def parse(cls, location, package_only=False): - toml_data = toml.load(location, _dict=dict) + with open(location, "rb") as fp: + toml_data = tomllib.load(fp) tool_data = toml_data.get('tool') if not tool_data: @@ -725,7 +735,8 @@ class PoetryLockHandler(BasePoetryPythonLayout): @classmethod def parse(cls, location, package_only=False): - toml_data = toml.load(location, _dict=dict) + with open(location, "rb") as fp: + toml_data = tomllib.load(fp) packages = toml_data.get('package') if not packages: