diff --git a/importlib_metadata/_adapters.py b/importlib_metadata/_adapters.py index 3c5a7db9..e67941ee 100644 --- a/importlib_metadata/_adapters.py +++ b/importlib_metadata/_adapters.py @@ -132,7 +132,13 @@ def json(self): def transform(key): value = self.get_all(key) if key in self.multiple_use_keys else self[key] if key == 'Keywords': - value = re.split(r'\s+', value) + # Core Metadata separates keywords with commas; older + # metadata (and PEP 566) used whitespace. + value = ( + [keyword.strip() for keyword in value.split(',')] + if ',' in value + else re.split(r'\s+', value) + ) tk = key.lower().replace('-', '_') return tk, value diff --git a/newsfragments/+json-keywords.bugfix.rst b/newsfragments/+json-keywords.bugfix.rst new file mode 100644 index 00000000..c37d0f2a --- /dev/null +++ b/newsfragments/+json-keywords.bugfix.rst @@ -0,0 +1 @@ +Split comma-separated ``Keywords`` into separate items in JSON-compatible metadata, since Core Metadata separates keywords with commas. diff --git a/tests/test_api.py b/tests/test_api.py index 2d660b3d..76b06e15 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -311,6 +311,24 @@ def test_as_json_odd_case(self): assert len(md['requires_dist']) == 2 assert md['keywords'] == ['SAMPLE', 'PACKAGE'] + @fixtures.parameterize( + dict(value='sample,package', expected=['sample', 'package']), + dict(value='sample, package', expected=['sample', 'package']), + dict(value='sample package,tool', expected=['sample package', 'tool']), + ) + def test_as_json_comma_separated_keywords(self, value, expected): + """ + Core Metadata and the tools that write it separate keywords with + commas. + """ + content = ( + 'Metadata-Version: 2.4\nName: distinfo-pkg\nVersion: 1.0.0\n' + f'Keywords: {value}\n' + ) + path = self.site_dir / 'distinfo_pkg-1.0.0.dist-info' / 'METADATA' + path.write_text(content, encoding='utf-8') + assert metadata('distinfo-pkg').json['keywords'] == expected + class LegacyDots(fixtures.DistInfoPkgWithDotLegacy, unittest.TestCase): def test_name_normalization(self):