Skip to content

Commit 6e992d6

Browse files
Migrate candidate.py to use packaging.metadata.Metadata
- Replace email.parser.BytesParser with packaging.metadata.Metadata - Remove complex TYPE_CHECKING type alias workaround - Update metadata access patterns to use typed attributes - Improve type safety and API consistency Signed-off-by: Lalatendu Mohanty <lmohanty@redhat.com>
1 parent bdada13 commit 6e992d6

File tree

1 file changed

+12
-18
lines changed

1 file changed

+12
-18
lines changed

src/fromager/candidate.py

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,14 @@
11
import typing
2-
from email.message import EmailMessage, Message
3-
from email.parser import BytesParser
42
from io import BytesIO
5-
from typing import TYPE_CHECKING
63
from zipfile import ZipFile
74

5+
from packaging.metadata import Metadata, parse_email
86
from packaging.requirements import Requirement
97
from packaging.utils import BuildTag, canonicalize_name
108
from packaging.version import Version
119

1210
from .request_session import session
1311

14-
# fix for runtime errors caused by inheriting classes that are generic in stubs but not runtime
15-
# https://mypy.readthedocs.io/en/latest/runtime_troubles.html#using-classes-that-are-generic-in-stubs-but-not-at-runtime
16-
if TYPE_CHECKING:
17-
Metadata = Message[str, str]
18-
else:
19-
Metadata = Message
20-
2112

2213
class Candidate:
2314
def __init__(
@@ -51,11 +42,10 @@ def metadata(self) -> Metadata:
5142
return self._metadata
5243

5344
def _get_dependencies(self) -> typing.Iterable[Requirement]:
54-
deps = self.metadata.get_all("Requires-Dist", [])
45+
deps = self.metadata.requires_dist or []
5546
extras = self.extras if self.extras else [""]
5647

57-
for d in deps:
58-
r = Requirement(d)
48+
for r in deps:
5949
if r.marker is None:
6050
yield r
6151
else:
@@ -71,16 +61,20 @@ def dependencies(self) -> list[Requirement]:
7161

7262
@property
7363
def requires_python(self) -> str | None:
74-
return self.metadata.get("Requires-Python")
64+
spec = self.metadata.requires_python
65+
return str(spec) if spec is not None else None
7566

7667

7768
def get_metadata_for_wheel(url: str) -> Metadata:
7869
data = session.get(url).content
7970
with ZipFile(BytesIO(data)) as z:
8071
for n in z.namelist():
8172
if n.endswith(".dist-info/METADATA"):
82-
p = BytesParser()
83-
return p.parse(z.open(n), headersonly=True)
73+
metadata_content = z.read(n)
74+
raw_metadata, unparsed_fields = parse_email(metadata_content)
75+
metadata = Metadata.from_raw(raw_metadata)
76+
return metadata
8477

85-
# If we didn't find the metadata, return an empty dict
86-
return EmailMessage()
78+
# If we didn't find the metadata, return an empty metadata object
79+
raw_metadata, _ = parse_email(b"")
80+
return Metadata.from_raw(raw_metadata)

0 commit comments

Comments
 (0)