Skip to content

Commit

Permalink
Merge pull request #7 from python-packaging/homepage-project-urls
Browse files Browse the repository at this point in the history
Parse metadata fields from sdist artifacts
  • Loading branch information
amjith authored Nov 14, 2024
2 parents 5815c7a + e69ee20 commit 9bbb7cc
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 16 deletions.
49 changes: 37 additions & 12 deletions metadata_please/sdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,23 @@ def from_zip_sdist(zf: ZipFile) -> bytes:
def basic_metadata_from_zip_sdist(zf: ZipFile) -> BasicMetadata:
requires = [f for f in zf.namelist() if f.endswith("/requires.txt")]
requires.sort(key=len)
if not requires:
return BasicMetadata((), frozenset(), "-")
if requires:
requires_data = zf.read(requires[0])
assert requires_data is not None
else:
requires_data = b""

data = zf.read(requires[0])
assert data is not None
return BasicMetadata.from_sdist_pkg_info_and_requires(b"", data)
# Find the PKG-INFO file with the shortest path. This is to avoid picking up
# a PKG-INFO file from a nested test directory.
pkg_info = sorted(
(f for f in zf.namelist() if f == "PKG-INFO" or f.endswith("/PKG-INFO")),
key=len,
)[0]

pkg_info_data = zf.read(pkg_info)
assert pkg_info_data is not None

return BasicMetadata.from_sdist_pkg_info_and_requires(pkg_info_data, requires_data)


def from_tar_sdist(tf: TarFile) -> bytes:
Expand All @@ -58,17 +69,31 @@ def from_tar_sdist(tf: TarFile) -> bytes:
buf.append(f"Requires-Dist: {req}\n")
for extra in sorted(extras):
buf.append(f"Provides-Extra: {extra}\n")

return ("".join(buf)).encode("utf-8")


def basic_metadata_from_tar_sdist(tf: TarFile) -> BasicMetadata:
# XXX Why do ZipFile and TarFile not have a common interface ?!
requires = [f for f in tf.getnames() if f.endswith("/requires.txt")]
requires.sort(key=len)
if not requires:
return BasicMetadata((), frozenset())

fo = tf.extractfile(requires[0])
assert fo is not None

return BasicMetadata.from_sdist_pkg_info_and_requires(b"", fo.read())
if requires:
requires_fo = tf.extractfile(requires[0])
assert requires_fo is not None
requires_data = requires_fo.read()
else:
requires_data = b""

# Find the PKG-INFO file with the shortest path. This is to avoid picking up
# a PKG-INFO file from a nested test directory.
pkg_info = sorted(
(f for f in tf.getnames() if f == "PKG-INFO" or f.endswith("/PKG-INFO")),
key=len,
)[0]

pkg_info_fo = tf.extractfile(pkg_info)
assert pkg_info_fo is not None

return BasicMetadata.from_sdist_pkg_info_and_requires(
pkg_info_fo.read(), requires_data
)
15 changes: 15 additions & 0 deletions metadata_please/tests/metadata_contents.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
METADATA_CONTENTS = b"""\
Requires-Dist: foo
Version: 1.2.58
Summary: Some Summary
Home-page: http://example.com
Author: Chicken
Author-email: [email protected]
Keywords: farm,animals
Requires-Python: >=3.6
Description-Content-Type: text/markdown
# Foo
A very important package.
"""
44 changes: 42 additions & 2 deletions metadata_please/tests/sdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
)
from ._tar import MemoryTarFile
from ._zip import MemoryZipFile
from .metadata_contents import METADATA_CONTENTS


class ZipSdistTest(unittest.TestCase):
def test_requires_as_expected(self) -> None:
z = MemoryZipFile(
{
"foo/__init__.py": b"",
"foo.egg-info/PKG-INFO": b"\n",
"foo.egg-info/requires.txt": b"""\
a
[e]
Expand All @@ -36,6 +38,7 @@ def test_basic_metadata(self) -> None:
z = MemoryZipFile(
{
"foo/__init__.py": b"",
"foo.egg-info/PKG-INFO": b"\n",
"foo.egg-info/requires.txt": b"""\
a
[e]
Expand Down Expand Up @@ -68,6 +71,7 @@ def test_basic_metadata_absl_py_09(self) -> None:
z = MemoryZipFile(
{
"foo/__init__.py": b"",
"foo.egg-info/PKG-INFO": b"\n",
"foo.egg-info/requires.txt": b"""\
six
Expand All @@ -90,11 +94,32 @@ def test_basic_metadata_absl_py_09(self) -> None:
)
self.assertEqual({"test"}, bm.provides_extra)

def test_basic_metadata_fields(self) -> None:
"""
Modern setuptools will drop a PKG-INFO file in a sdist that is very similar to the METADATA file in a wheel.
"""
z = MemoryZipFile(
{
"foo/__init__.py": b"",
"PKG-INFO": METADATA_CONTENTS,
}
)
bm = basic_metadata_from_zip_sdist(z) # type: ignore
self.assertEqual(["foo"], bm.reqs)
self.assertEqual("1.2.58", bm.version)
self.assertEqual("Some Summary", bm.summary)
self.assertEqual("http://example.com", bm.url)
self.assertEqual("Chicken", bm.author)
self.assertEqual("[email protected]", bm.author_email)
self.assertEqual("farm,animals", bm.keywords)
self.assertEqual("text/markdown", bm.long_description_content_type)
self.assertEqual("# Foo\n\nA very important package.\n", bm.description)


class TarSdistTest(unittest.TestCase):
def test_requires_as_expected(self) -> None:
t = MemoryTarFile(
["foo.egg-info/requires.txt", "foo/__init__.py"],
["foo.egg-info/PKG-INFO", "foo.egg-info/requires.txt", "foo/__init__.py"],
read_value=b"""\
a
[e]
Expand All @@ -113,7 +138,7 @@ def test_requires_as_expected(self) -> None:

def test_basic_metadata(self) -> None:
t = MemoryTarFile(
["foo.egg-info/requires.txt", "foo/__init__.py"],
["foo.egg-info/PKG-INFO", "foo.egg-info/requires.txt", "foo/__init__.py"],
read_value=b"""\
a
[e]
Expand All @@ -126,3 +151,18 @@ def test_basic_metadata(self) -> None:
bm.reqs,
)
self.assertEqual({"e"}, bm.provides_extra)

def test_metadata_fields_from_tar_sdist(self) -> None:
t = MemoryTarFile(
["PKG-INFO", "foo/__init__.py"],
read_value=METADATA_CONTENTS,
)
bm = basic_metadata_from_tar_sdist(t) # type: ignore
self.assertEqual("1.2.58", bm.version)
self.assertEqual("Some Summary", bm.summary)
self.assertEqual("http://example.com", bm.url)
self.assertEqual("Chicken", bm.author)
self.assertEqual("[email protected]", bm.author_email)
self.assertEqual("farm,animals", bm.keywords)
self.assertEqual("text/markdown", bm.long_description_content_type)
self.assertEqual("# Foo\n\nA very important package.\n", bm.description)
5 changes: 3 additions & 2 deletions metadata_please/tests/wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from ..wheel import basic_metadata_from_wheel, from_wheel, InvalidWheel
from ._zip import MemoryZipFile
from .metadata_contents import METADATA_CONTENTS


class WheelTest(unittest.TestCase):
Expand Down Expand Up @@ -58,7 +59,7 @@ def test_basic_metadata(self) -> None:
def test_basic_metadata_more_fields(self) -> None:
z = MemoryZipFile(
{
"foo.dist-info/METADATA": b"Requires-Dist: foo\nVersion: 1.2.58\nSummary: Some Summary\nHome-page: http://example.com\nAuthor: Chicken\nAuthor-email: [email protected]\nKeywords: farm,animals\nRequires-Python: >=3.6\nDescription-Content-Type: text/markdown",
"foo.dist-info/METADATA": METADATA_CONTENTS,
"foo/__init__.py": b"",
}
)
Expand All @@ -71,4 +72,4 @@ def test_basic_metadata_more_fields(self) -> None:
self.assertEqual("[email protected]", bm.author_email)
self.assertEqual("farm,animals", bm.keywords)
self.assertEqual("text/markdown", bm.long_description_content_type)
self.assertEqual(None, bm.description)
self.assertEqual("# Foo\n\nA very important package.\n", bm.description)

0 comments on commit 9bbb7cc

Please sign in to comment.