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
28 changes: 19 additions & 9 deletions pyroma/projectdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import os
import pathlib
import re
from importlib.metadata import metadata
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be worth importing this under an alias, rather than having both metadata the import and metadata the variable in the same file?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure - or we can rename some of the variables to avoid the collision.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with calling the variable just "md", that's what we use for metadata at my work anyway. :-)


from setuptools.config.setupcfg import read_configuration
from distutils.errors import DistutilsFileError
Expand Down Expand Up @@ -39,20 +40,24 @@ def wheel_metadata(path, isolated=None):

def build_metadata(path, isolated=None):
try:
metadata = wheel_metadata(path, isolated)
data = wheel_metadata(path, isolated)
except build.BuildBackendException:
# The backend failed spectacularily. This happens with old packages,
# when we can't build a wheel. It's not always a fatal error. F ex, if
# you are getting info for a package from PyPI, we already have the
# metadata from PyPI, we just couldn't get the additional build data.
return {"_wheel_build_failed": True}

return normalize_metadata(data)


def normalize_metadata(data):
# As far as I can tell, we can't trust that the builders normalize the keys,
# so we do it here. Definitely most builders do not lower case them, which
# Core Metadata Specs recommend.
data = {}
for key in set(metadata.keys()):
value = metadata.get_all(key)
normalized = {}
for key in set(data.keys()):
value = data.get_all(key)
key = normalize(key)

if len(value) == 1:
Expand All @@ -61,15 +66,20 @@ def build_metadata(path, isolated=None):
# XXX This is also old behavior that may not hjappen any more.
continue

data[key] = value
normalized[key] = value

if "description" not in data.keys():
if "description" not in normalized.keys():
# XXX I *think* having the description as a payload doesn't happen anymore, but I haven't checked.
# Having the description as a payload tends to add two newlines, we clean that up here:
description = metadata.get_payload().strip()
description = data.get_payload().strip()
if description:
data["description"] = description + "\n"
return data
normalized["description"] = description + "\n"
return normalized


def installed_metadata(name):
"""Retrieve the metadata for an package that is installed in the environment."""
return normalize_metadata(metadata(name))


def get_build_data(path, isolated=None):
Expand Down
37 changes: 37 additions & 0 deletions pyroma/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,43 @@ def test_complete(self):
del data["_path"] # This changes, so I just ignore it
self.assertEqual(data, COMPLETE)

def test_installed(self):
# pyroma must be installed in the test environment.
data = projectdata.installed_metadata("pyroma")

# Verify some key metadata
self.assertEqual(data["name"], "pyroma")
self.assertEqual(data["summary"], "Test your project's packaging friendliness")
self.assertEqual(
data["classifier"],
[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
],
)
self.assertEqual(data["keywords"], "pypi,quality,testing")
self.assertEqual(data["author"], "Lennart Regebro")
self.assertEqual(data["author-email"], "[email protected]")
self.assertEqual(data["home-page"], "https://github.com/regebro/pyroma")
self.assertEqual(data["license"], "MIT")
self.assertEqual(data["license-file"], "LICENSE.txt")
self.assertEqual(data["project-url"], "Source Code, https://github.com/regebro/pyroma")
self.assertEqual(data["provides-extra"], "test")
self.assertEqual(data["requires-python"], ">=3.9")


class DistroDataTest(unittest.TestCase):
maxDiff = None
Expand Down
Loading