Skip to content

Commit a7cfb56

Browse files
authored
Merge pull request #138 from wimglenn/optional-metadata
Optional fields are really optional
2 parents 13bb77f + 5bac124 commit a7cfb56

File tree

11 files changed

+51
-92
lines changed

11 files changed

+51
-92
lines changed

distutils/ccompiler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ def _fix_compile_args(self, output_dir, macros, include_dirs):
392392
return output_dir, macros, include_dirs
393393

394394
def _prep_compile(self, sources, output_dir, depends=None):
395-
"""Decide which souce files must be recompiled.
395+
"""Decide which source files must be recompiled.
396396
397397
Determine the list of object files corresponding to 'sources',
398398
and figure out which ones really need to be recompiled.

distutils/command/bdist_msi.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -231,11 +231,7 @@ def run(self):
231231
if os.path.exists(installer_name): os.unlink(installer_name)
232232

233233
metadata = self.distribution.metadata
234-
author = metadata.author
235-
if not author:
236-
author = metadata.maintainer
237-
if not author:
238-
author = "UNKNOWN"
234+
author = metadata.author or metadata.maintainer
239235
version = metadata.get_version()
240236
# ProductVersion must be strictly numeric
241237
# XXX need to deal with prerelease versions

distutils/command/bdist_rpm.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ def _make_spec_file(self):
399399
'%define unmangled_version ' + self.distribution.get_version(),
400400
'%define release ' + self.release.replace('-','_'),
401401
'',
402-
'Summary: ' + self.distribution.get_description(),
402+
'Summary: ' + (self.distribution.get_description() or "UNKNOWN"),
403403
]
404404

405405
# Workaround for #14443 which affects some RPM based systems such as
@@ -438,7 +438,7 @@ def _make_spec_file(self):
438438
spec_file.append('Source0: %{name}-%{unmangled_version}.tar.gz')
439439

440440
spec_file.extend([
441-
'License: ' + self.distribution.get_license(),
441+
'License: ' + (self.distribution.get_license() or "UNKNOWN"),
442442
'Group: ' + self.group,
443443
'BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot',
444444
'Prefix: %{_prefix}', ])
@@ -464,7 +464,7 @@ def _make_spec_file(self):
464464
spec_file.append('%s: %s' % (field, val))
465465

466466

467-
if self.distribution.get_url() != 'UNKNOWN':
467+
if self.distribution.get_url():
468468
spec_file.append('Url: ' + self.distribution.get_url())
469469

470470
if self.distribution_name:
@@ -483,7 +483,7 @@ def _make_spec_file(self):
483483
spec_file.extend([
484484
'',
485485
'%description',
486-
self.distribution.get_long_description()
486+
self.distribution.get_long_description() or "",
487487
])
488488

489489
# put locale descriptions into spec file

distutils/command/check.py

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -82,54 +82,19 @@ def check_metadata(self):
8282
"""Ensures that all required elements of meta-data are supplied.
8383
8484
Required fields:
85-
name, version, URL
86-
87-
Recommended fields:
88-
(author and author_email) or (maintainer and maintainer_email))
85+
name, version
8986
9087
Warns if any are missing.
9188
"""
9289
metadata = self.distribution.metadata
9390

9491
missing = []
95-
for attr in ('name', 'version', 'url'):
96-
if not (hasattr(metadata, attr) and getattr(metadata, attr)):
92+
for attr in 'name', 'version':
93+
if not getattr(metadata, attr, None):
9794
missing.append(attr)
9895

9996
if missing:
100-
self.warn("missing required meta-data: %s" % ', '.join(missing))
101-
if not (
102-
self._check_contact("author", metadata) or
103-
self._check_contact("maintainer", metadata)
104-
):
105-
self.warn("missing meta-data: either (author and author_email) " +
106-
"or (maintainer and maintainer_email) " +
107-
"should be supplied")
108-
109-
def _check_contact(self, kind, metadata):
110-
"""
111-
Returns True if the contact's name is specified and False otherwise.
112-
This function will warn if the contact's email is not specified.
113-
"""
114-
name = getattr(metadata, kind) or ''
115-
email = getattr(metadata, kind + '_email') or ''
116-
117-
msg = ("missing meta-data: if '{}' supplied, " +
118-
"'{}' should be supplied too")
119-
120-
if name and email:
121-
return True
122-
123-
if name:
124-
self.warn(msg.format(kind, kind + '_email'))
125-
return True
126-
127-
addresses = [(alias, addr) for alias, addr in getaddresses([email])]
128-
if any(alias and addr for alias, addr in addresses):
129-
# The contact's name can be encoded in the email: `Name <email>`
130-
return True
131-
132-
return False
97+
self.warn("missing required meta-data: %s" % ', '.join(missing))
13398

13499
def check_restructuredtext(self):
135100
"""Checks if the long string fields are reST-compliant."""

distutils/dist.py

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,9 +1064,8 @@ def read_pkg_file(self, file):
10641064

10651065
def _read_field(name):
10661066
value = msg[name]
1067-
if value == 'UNKNOWN':
1068-
return None
1069-
return value
1067+
if value and value != "UNKNOWN":
1068+
return value
10701069

10711070
def _read_list(name):
10721071
values = msg.get_all(name, None)
@@ -1125,23 +1124,24 @@ def write_pkg_file(self, file):
11251124
self.classifiers or self.download_url):
11261125
version = '1.1'
11271126

1127+
# required fields
11281128
file.write('Metadata-Version: %s\n' % version)
11291129
file.write('Name: %s\n' % self.get_name())
11301130
file.write('Version: %s\n' % self.get_version())
1131-
file.write('Summary: %s\n' % self.get_description())
1132-
file.write('Home-page: %s\n' % self.get_url())
1133-
file.write('Author: %s\n' % self.get_contact())
1134-
file.write('Author-email: %s\n' % self.get_contact_email())
1135-
file.write('License: %s\n' % self.get_license())
1136-
if self.download_url:
1137-
file.write('Download-URL: %s\n' % self.download_url)
11381131

1139-
long_desc = rfc822_escape(self.get_long_description())
1140-
file.write('Description: %s\n' % long_desc)
1132+
def maybe_write(header, val):
1133+
if val:
1134+
file.write("{}: {}\n".format(header, val))
11411135

1142-
keywords = ','.join(self.get_keywords())
1143-
if keywords:
1144-
file.write('Keywords: %s\n' % keywords)
1136+
# optional fields
1137+
maybe_write("Summary", self.get_description())
1138+
maybe_write("Home-page", self.get_url())
1139+
maybe_write("Author", self.get_contact())
1140+
maybe_write("Author-email", self.get_contact_email())
1141+
maybe_write("License", self.get_license())
1142+
maybe_write("Download-URL", self.download_url)
1143+
maybe_write("Description", rfc822_escape(self.get_long_description() or ""))
1144+
maybe_write("Keywords", ",".join(self.get_keywords()))
11451145

11461146
self._write_list(file, 'Platform', self.get_platforms())
11471147
self._write_list(file, 'Classifier', self.get_classifiers())
@@ -1152,6 +1152,7 @@ def write_pkg_file(self, file):
11521152
self._write_list(file, 'Obsoletes', self.get_obsoletes())
11531153

11541154
def _write_list(self, file, name, values):
1155+
values = values or []
11551156
for value in values:
11561157
file.write('%s: %s\n' % (name, value))
11571158

@@ -1167,35 +1168,35 @@ def get_fullname(self):
11671168
return "%s-%s" % (self.get_name(), self.get_version())
11681169

11691170
def get_author(self):
1170-
return self.author or "UNKNOWN"
1171+
return self.author
11711172

11721173
def get_author_email(self):
1173-
return self.author_email or "UNKNOWN"
1174+
return self.author_email
11741175

11751176
def get_maintainer(self):
1176-
return self.maintainer or "UNKNOWN"
1177+
return self.maintainer
11771178

11781179
def get_maintainer_email(self):
1179-
return self.maintainer_email or "UNKNOWN"
1180+
return self.maintainer_email
11801181

11811182
def get_contact(self):
1182-
return self.maintainer or self.author or "UNKNOWN"
1183+
return self.maintainer or self.author
11831184

11841185
def get_contact_email(self):
1185-
return self.maintainer_email or self.author_email or "UNKNOWN"
1186+
return self.maintainer_email or self.author_email
11861187

11871188
def get_url(self):
1188-
return self.url or "UNKNOWN"
1189+
return self.url
11891190

11901191
def get_license(self):
1191-
return self.license or "UNKNOWN"
1192+
return self.license
11921193
get_licence = get_license
11931194

11941195
def get_description(self):
1195-
return self.description or "UNKNOWN"
1196+
return self.description
11961197

11971198
def get_long_description(self):
1198-
return self.long_description or "UNKNOWN"
1199+
return self.long_description
11991200

12001201
def get_keywords(self):
12011202
return self.keywords or []
@@ -1204,7 +1205,7 @@ def set_keywords(self, value):
12041205
self.keywords = _ensure_list(value, 'keywords')
12051206

12061207
def get_platforms(self):
1207-
return self.platforms or ["UNKNOWN"]
1208+
return self.platforms
12081209

12091210
def set_platforms(self, value):
12101211
self.platforms = _ensure_list(value, 'platforms')
@@ -1216,7 +1217,7 @@ def set_classifiers(self, value):
12161217
self.classifiers = _ensure_list(value, 'classifiers')
12171218

12181219
def get_download_url(self):
1219-
return self.download_url or "UNKNOWN"
1220+
return self.download_url
12201221

12211222
# PEP 314
12221223
def get_requires(self):

distutils/tests/test_check.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def test_check_metadata(self):
4343
# by default, check is checking the metadata
4444
# should have some warnings
4545
cmd = self._run()
46-
self.assertEqual(cmd._warnings, 2)
46+
self.assertEqual(cmd._warnings, 1)
4747

4848
# now let's add the required fields
4949
# and run it again, to make sure we don't get
@@ -81,17 +81,16 @@ def test_check_author_maintainer(self):
8181
cmd = self._run(metadata)
8282
self.assertEqual(cmd._warnings, 0)
8383

84-
# the check should warn if only email is given and it does not
85-
# contain the name
84+
# the check should not warn if only email is given
8685
metadata[kind + '_email'] = '[email protected]'
8786
cmd = self._run(metadata)
88-
self.assertEqual(cmd._warnings, 1)
87+
self.assertEqual(cmd._warnings, 0)
8988

90-
# the check should warn if only the name is given
89+
# the check should not warn if only the name is given
9190
metadata[kind] = "Name"
9291
del metadata[kind + '_email']
9392
cmd = self._run(metadata)
94-
self.assertEqual(cmd._warnings, 1)
93+
self.assertEqual(cmd._warnings, 0)
9594

9695
@unittest.skipUnless(HAS_DOCUTILS, "won't test without docutils")
9796
def test_check_document(self):

distutils/tests/test_dist.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ def test_read_metadata(self):
519519
self.assertEqual(metadata.description, "xxx")
520520
self.assertEqual(metadata.download_url, 'http://example.com')
521521
self.assertEqual(metadata.keywords, ['one', 'two'])
522-
self.assertEqual(metadata.platforms, ['UNKNOWN'])
522+
self.assertEqual(metadata.platforms, None)
523523
self.assertEqual(metadata.obsoletes, None)
524524
self.assertEqual(metadata.requires, ['foo'])
525525

distutils/tests/test_register.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ def _no_way(prompt=''):
154154
req1 = dict(self.conn.reqs[0].headers)
155155
req2 = dict(self.conn.reqs[1].headers)
156156

157-
self.assertEqual(req1['Content-length'], '1374')
158-
self.assertEqual(req2['Content-length'], '1374')
157+
self.assertEqual(req1['Content-length'], '1359')
158+
self.assertEqual(req2['Content-length'], '1359')
159159
self.assertIn(b'xxx', self.conn.reqs[1].data)
160160

161161
def test_password_not_in_file(self):

distutils/tests/test_sdist.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ def test_metadata_check_option(self):
251251
cmd.run()
252252
warnings = [msg for msg in self.get_logs(WARN) if
253253
msg.startswith('warning: check:')]
254-
self.assertEqual(len(warnings), 2)
254+
self.assertEqual(len(warnings), 1)
255255

256256
# trying with a complete set of metadata
257257
self.clear_logs()

docs/distutils/examples.rst

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,9 +253,7 @@ Running the ``check`` command will display some warnings:
253253
254254
$ python setup.py check
255255
running check
256-
warning: check: missing required meta-data: version, url
257-
warning: check: missing meta-data: either (author and author_email) or
258-
(maintainer and maintainer_email) should be supplied
256+
warning: check: missing required meta-data: version
259257
260258
261259
If you use the reStructuredText syntax in the ``long_description`` field and

0 commit comments

Comments
 (0)