Skip to content

Commit 1cfa27c

Browse files
committed
do not backfill Project-URL: homepage into Home-page: field (causes duplicates on PyPI). prevent "UNKNOWN" vals from appearing in summary, license, platform. prevent an extra newline getting added in long description
1 parent ddb8844 commit 1cfa27c

3 files changed

Lines changed: 32 additions & 29 deletions

File tree

setuptools/config/_apply_pyprojecttoml.py

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -171,21 +171,7 @@ def _people(dist: "Distribution", val: List[dict], _root_dir: _Path, kind: str):
171171

172172

173173
def _project_urls(dist: "Distribution", val: dict, _root_dir):
174-
special = {"downloadurl": "download_url", "homepage": "url"}
175-
for key, url in val.items():
176-
norm_key = json_compatible_key(key).replace("_", "")
177-
_set_config(dist, special.get(norm_key, key), url)
178-
# If `homepage` is missing, distutils will warn the following message:
179-
# "warning: check: missing required meta-data: url"
180-
# In the context of PEP 621, users might ask themselves: "which url?".
181-
# Let's add a warning before distutils check to help users understand the problem:
182-
if not dist.metadata.url:
183-
msg = (
184-
"Missing `Homepage` url.\nIt is advisable to link some kind of reference "
185-
"for your project (e.g. source code or documentation).\n"
186-
)
187-
_logger.warning(msg)
188-
_set_config(dist, "project_urls", val.copy())
174+
_set_config(dist, "project_urls", val)
189175

190176

191177
def _python_requires(dist: "Distribution", val: dict, _root_dir):

setuptools/dist.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def _read_list_from_msg(msg: "Message", field: str) -> Optional[List[str]]:
102102

103103
def _read_payload_from_msg(msg: "Message") -> Optional[str]:
104104
value = msg.get_payload().strip()
105-
if value == 'UNKNOWN':
105+
if value == 'UNKNOWN' or not value:
106106
return None
107107
return value
108108

@@ -174,7 +174,10 @@ def write_field(key, value):
174174
write_field('Metadata-Version', str(version))
175175
write_field('Name', self.get_name())
176176
write_field('Version', self.get_version())
177-
write_field('Summary', single_line(self.get_description()))
177+
178+
summary = self.get_description()
179+
if summary:
180+
write_field('Summary', single_line(summary))
178181

179182
optional_fields = (
180183
('Home-page', 'url'),
@@ -190,16 +193,19 @@ def write_field(key, value):
190193
if attr_val is not None:
191194
write_field(field, attr_val)
192195

193-
license = rfc822_escape(self.get_license())
194-
write_field('License', license)
196+
license = self.get_license()
197+
if license:
198+
write_field('License', rfc822_escape(license))
199+
195200
for project_url in self.project_urls.items():
196201
write_field('Project-URL', '%s, %s' % project_url)
197202

198203
keywords = ','.join(self.get_keywords())
199204
if keywords:
200205
write_field('Keywords', keywords)
201206

202-
for platform in self.get_platforms():
207+
platforms = self.get_platforms() or []
208+
for platform in platforms:
203209
write_field('Platform', platform)
204210

205211
self._write_list(file, 'Classifier', self.get_classifiers())
@@ -222,7 +228,11 @@ def write_field(key, value):
222228

223229
self._write_list(file, 'License-File', self.license_files or [])
224230

225-
file.write("\n%s\n\n" % self.get_long_description())
231+
long_description = self.get_long_description()
232+
if long_description:
233+
file.write("\n%s" % long_description)
234+
if not long_description.endswith("\n"):
235+
file.write("\n")
226236

227237

228238
sequence = tuple, list

setuptools/tests/config/test_apply_pyprojecttoml.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -298,19 +298,26 @@ def test_example_file_not_in_wheel(self, setuptools_wheel):
298298
def core_metadata(dist) -> str:
299299
with io.StringIO() as buffer:
300300
dist.metadata.write_pkg_file(buffer)
301-
value = "\n".join(buffer.getvalue().strip().splitlines())
301+
pkg_file_txt = buffer.getvalue()
302302

303+
skip_prefixes = ()
304+
skip_lines = set()
303305
# ---- DIFF NORMALISATION ----
304306
# PEP 621 is very particular about author/maintainer metadata conversion, so skip
305-
value = re.sub(r"^(Author|Maintainer)(-email)?:.*$", "", value, flags=re.M)
307+
skip_prefixes += ("Author:", "Author-email:", "Maintainer:", "Maintainer-email:")
306308
# May be redundant with Home-page
307-
value = re.sub(r"^Project-URL: Homepage,.*$", "", value, flags=re.M)
309+
skip_prefixes += ("Project-URL: Homepage,", "Home-page:")
308310
# May be missing in original (relying on default) but backfilled in the TOML
309-
value = re.sub(r"^Description-Content-Type:.*$", "", value, flags=re.M)
311+
skip_prefixes += ("Description-Content-Type:",)
310312
# ini2toml can automatically convert `tests_require` to `testing` extra
311-
value = value.replace("Provides-Extra: testing\n", "")
313+
skip_lines.add("Provides-Extra: testing")
312314
# Remove empty lines
313-
value = re.sub(r"^\s*$", "", value, flags=re.M)
314-
value = re.sub(r"^\n", "", value, flags=re.M)
315+
skip_lines.add("")
315316

316-
return value
317+
result = []
318+
for line in pkg_file_txt.splitlines():
319+
if line.startswith(skip_prefixes) or line in skip_lines:
320+
continue
321+
result.append(line + "\n")
322+
323+
return "".join(result)

0 commit comments

Comments
 (0)