Skip to content

Commit a228795

Browse files
committed
Merge branch 'main' into 856-verbose-response
2 parents c800a21 + a60c565 commit a228795

File tree

6 files changed

+56
-34
lines changed

6 files changed

+56
-34
lines changed

changelog/861.feature.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Show more helpful error message for invalid metadata.

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ install_requires=
4040
readme_renderer >= 21.0
4141
requests >= 2.20
4242
requests-toolbelt >= 0.8.0, != 0.9.0
43+
urllib3 >= 1.26.0
4344
tqdm >= 4.14
4445
importlib_metadata >= 3.6
4546
keyring >= 15.1

tests/test_package.py

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -337,23 +337,46 @@ def test_fips_metadata_excludes_md5_and_blake2(monkeypatch):
337337
assert "blake2_256_digest" not in mddict
338338

339339

340-
def test_pkginfo_returns_no_metadata(monkeypatch):
340+
@pytest.mark.parametrize(
341+
"read_data, missing_fields",
342+
[
343+
pytest.param(
344+
b"Metadata-Version: 2.3\nName: test-package\nVersion: 1.0.0\n",
345+
"Name, Version",
346+
id="unsupported Metadata-Version",
347+
),
348+
pytest.param(
349+
b"Metadata-Version: 2.2\nName: UNKNOWN\nVersion: UNKNOWN\n",
350+
"Name, Version",
351+
id="missing Name and Version",
352+
),
353+
pytest.param(
354+
b"Metadata-Version: 2.2\nName: UNKNOWN\nVersion: 1.0.0\n",
355+
"Name",
356+
id="missing Name",
357+
),
358+
pytest.param(
359+
b"Metadata-Version: 2.2\nName: test-package\nVersion: UNKNOWN\n",
360+
"Version",
361+
id="missing Version",
362+
),
363+
],
364+
)
365+
def test_pkginfo_returns_no_metadata(read_data, missing_fields, monkeypatch):
341366
"""Raise an exception when pkginfo can't interpret the metadata.
342367
343368
This could be caused by a version number or format it doesn't support yet.
344369
"""
345-
346-
def EmptyDist(filename):
347-
return pretend.stub(name=None, version=None)
348-
349-
monkeypatch.setattr(package_file, "DIST_TYPES", {"bdist_wheel": EmptyDist})
370+
monkeypatch.setattr(package_file.wheel.Wheel, "read", lambda _: read_data)
350371
filename = "tests/fixtures/twine-1.5.0-py2.py3-none-any.whl"
351372

352373
with pytest.raises(exceptions.InvalidDistribution) as err:
353374
package_file.PackageFile.from_filename(filename, comment=None)
354375

355-
assert "Invalid distribution metadata" in err.value.args[0]
356-
assert "1.0, 1.1, 1.2, 2.0, 2.1, and 2.2" in err.value.args[0]
376+
assert (
377+
f"Metadata is missing required fields: {missing_fields}." in err.value.args[0]
378+
)
379+
assert "1.0, 1.1, 1.2, 2.0, 2.1, 2.2" in err.value.args[0]
357380

358381

359382
def test_malformed_from_file(monkeypatch):

twine/cli.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,18 @@
1414
import argparse
1515
from typing import Any, List, Tuple
1616

17-
from importlib_metadata import entry_points
18-
from importlib_metadata import version
17+
import importlib_metadata
18+
from packaging import requirements
1919

2020
import twine
2121

2222
args = argparse.Namespace()
2323

2424

2525
def list_dependencies_and_versions() -> List[Tuple[str, str]]:
26-
deps = (
27-
"importlib_metadata",
28-
"pkginfo",
29-
"requests",
30-
"requests-toolbelt",
31-
"tqdm",
32-
)
33-
return [(dep, version(dep)) for dep in deps] # type: ignore[no-untyped-call] # python/importlib_metadata#288 # noqa: E501
26+
requires = importlib_metadata.requires("twine") # type: ignore[no-untyped-call] # python/importlib_metadata#288 # noqa: E501
27+
deps = [requirements.Requirement(r).name for r in requires]
28+
return [(dep, importlib_metadata.version(dep)) for dep in deps] # type: ignore[no-untyped-call] # python/importlib_metadata#288 # noqa: E501
3429

3530

3631
def dep_versions() -> str:
@@ -40,7 +35,9 @@ def dep_versions() -> str:
4035

4136

4237
def dispatch(argv: List[str]) -> Any:
43-
registered_commands = entry_points(group="twine.registered_commands")
38+
registered_commands = importlib_metadata.entry_points(
39+
group="twine.registered_commands"
40+
)
4441
parser = argparse.ArgumentParser(prog="twine")
4542
parser.add_argument(
4643
"--version",

twine/package.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,21 @@ def from_filename(cls, filename: str, comment: Optional[str]) -> "PackageFile":
101101
"Unknown distribution format: '%s'" % os.path.basename(filename)
102102
)
103103

104-
# If pkginfo encounters a metadata version it doesn't support, it may
105-
# give us back empty metadata. At the very least, we should have a name
106-
# and version
107-
if not (meta.name and meta.version):
104+
# If pkginfo encounters a metadata version it doesn't support, it may give us
105+
# back empty metadata. At the very least, we should have a name and version,
106+
# which could also be empty if, for example, a MANIFEST.in doesn't include
107+
# setup.cfg.
108+
missing_fields = [
109+
f.capitalize() for f in ["name", "version"] if not getattr(meta, f)
110+
]
111+
if missing_fields:
108112
supported_metadata = list(pkginfo.distribution.HEADER_ATTRS)
109113
raise exceptions.InvalidDistribution(
110-
"Invalid distribution metadata. "
111-
"This version of twine supports Metadata-Version "
112-
f"{', '.join(supported_metadata[:-1])}, and {supported_metadata[-1]}"
114+
"Metadata is missing required fields: "
115+
f"{', '.join(missing_fields)}.\n"
116+
"Make sure the distribution includes the files where those fields "
117+
"are specified, and is using a supported Metadata-Version: "
118+
f"{', '.join(supported_metadata)}."
113119
)
114120

115121
py_version: Optional[str]

twine/repository.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,19 +77,13 @@ def __init__(
7777

7878
@staticmethod
7979
def _make_adapter_with_retries() -> adapters.HTTPAdapter:
80-
retry_kwargs = dict(
80+
retry = urllib3.Retry(
81+
allowed_methods=["GET"],
8182
connect=5,
8283
total=10,
8384
status_forcelist=[500, 501, 502, 503],
8485
)
8586

86-
try:
87-
retry = urllib3.Retry(allowed_methods=["GET"], **retry_kwargs)
88-
except TypeError: # pragma: no cover
89-
# Avoiding DeprecationWarning starting in urllib3 1.26
90-
# Remove when that's the mininum version
91-
retry = urllib3.Retry(method_whitelist=["GET"], **retry_kwargs)
92-
9387
return adapters.HTTPAdapter(max_retries=retry)
9488

9589
@staticmethod

0 commit comments

Comments
 (0)