From 346370c349faab23e464455e0b9c890cee6b2e85 Mon Sep 17 00:00:00 2001 From: Aishwary Dongre <87765118+aishwary-dongre@users.noreply.github.com> Date: Fri, 18 Sep 2026 15:08:36 +0530 Subject: [PATCH] Remove unreachable duplicate LGPL key in rubygems licenses mapping LICENSES_MAPPING in src/packagedcode/rubygems.py declared 'LGPL' twice on consecutive lines. A dict literal keeps only the last value for a repeated key, so 'LGPL': 'lgpl' was dead at import time and every gem declaring a bare LGPL already resolved to lgpl-2.0-plus. Remove the unreachable line rather than the effective one. 'lgpl' is not a ScanCode license key: there is no lgpl.LICENSE in the license data, active or inactive, and it is the only target in this mapping that does not resolve to a real key. Keeping lgpl-2.0-plus also matches how the mapping handles other bare family names, for example 'GPL': 'gpl-2.0'. Detection behaviour is therefore unchanged. Whether a bare LGPL declaration should imply lgpl-2.0-plus at all is a separate question about license semantics and is left out of scope here. Add a test that parses the module source with ast, since a duplicated key cannot be observed on the loaded dict. Reference: https://github.com/aboutcode-org/scancode-toolkit/issues/5314 Signed-off-by: Aishwary Dongre <87765118+aishwary-dongre@users.noreply.github.com> --- src/packagedcode/rubygems.py | 1 - tests/packagedcode/test_rubygems.py | 32 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/packagedcode/rubygems.py b/src/packagedcode/rubygems.py index e38c798646..e98d1ffb23 100644 --- a/src/packagedcode/rubygems.py +++ b/src/packagedcode/rubygems.py @@ -676,7 +676,6 @@ def get_dependencies(dependencies): 'ISC': 'isc', 'LGPL-2.1+': 'lgpl-2.1-plus', 'LGPL-3': 'lgpl-3.0', - 'LGPL': 'lgpl', 'LGPL': 'lgpl-2.0-plus', 'LGPLv2.1+': 'lgpl-2.1-plus', 'MIT': 'mit', diff --git a/tests/packagedcode/test_rubygems.py b/tests/packagedcode/test_rubygems.py index fffee60c3e..37ece9e876 100644 --- a/tests/packagedcode/test_rubygems.py +++ b/tests/packagedcode/test_rubygems.py @@ -7,9 +7,11 @@ # See https://aboutcode.org for more information about nexB OSS projects. # +import ast import io import json import os +from pathlib import Path from commoncode import text from commoncode.testcase import FileBasedTesting @@ -113,6 +115,36 @@ def test_build_rubygem_package_does_not_crash(self): rubygems.GemMetadataArchiveExtractedHandler.parse(test_file) +class TestRubygemsLicensesMapping(object): + + def test_licenses_mapping_has_no_duplicated_declared_license(self): + # A duplicated key in a dict literal is silently dropped by Python, so + # this has to be checked on the source rather than on the loaded dict. + source = Path(rubygems.__file__).read_text(encoding='utf-8') + + mapping = None + for node in ast.walk(ast.parse(source)): + if isinstance(node, ast.Assign) and any( + isinstance(target, ast.Name) and target.id == 'LICENSES_MAPPING' + for target in node.targets + ): + mapping = node.value + + assert mapping is not None, 'LICENSES_MAPPING not found in rubygems.py' + + declared = [ + key.value for key in mapping.keys + if isinstance(key, ast.Constant) + ] + duplicated = sorted( + {key for key in declared if declared.count(key) > 1} + ) + assert duplicated == [] + + def test_licenses_mapping_maps_bare_lgpl_to_lgpl_2_0_plus(self): + assert rubygems.LICENSES_MAPPING['LGPL'] == 'lgpl-2.0-plus' + + def relative_walk(dir_path, extension='.gem'): """ Walk `dir_path` and yield paths that end with `extension` relative to