Skip to content

Commit e0fd60c

Browse files
authored
Merge pull request #1359 from jmbowman/jmbowman/version_from_file
Support loading version from a file
2 parents 5668d15 + a960ee1 commit e0fd60c

File tree

4 files changed

+37
-1
lines changed

4 files changed

+37
-1
lines changed

changelog.d/1359.change.rst

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Support using "file:" to load a PEP 440-compliant package version
2+
from a text file.

docs/setuptools.txt

+5-1
Original file line numberDiff line numberDiff line change
@@ -2424,7 +2424,7 @@ Metadata
24242424
Key Aliases Type
24252425
============================== ================= =====
24262426
name str
2427-
version attr:, str
2427+
version attr:, file:, str
24282428
url home-page str
24292429
download_url download-url str
24302430
project_urls dict
@@ -2444,6 +2444,10 @@ requires list-comma
24442444
obsoletes list-comma
24452445
============================== ================= =====
24462446

2447+
.. note::
2448+
A version loaded using the ``file:`` directive must comply with PEP 440.
2449+
It is easy to accidentally put something other than a valid version
2450+
string in such a file, so validation is stricter in this case.
24472451

24482452
Options
24492453
-------

setuptools/config.py

+13
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from importlib import import_module
88

99
from distutils.errors import DistutilsOptionError, DistutilsFileError
10+
from setuptools.extern.packaging.version import LegacyVersion, parse
1011
from setuptools.extern.six import string_types
1112

1213

@@ -427,6 +428,18 @@ def _parse_version(self, value):
427428
:rtype: str
428429
429430
"""
431+
version = self._parse_file(value)
432+
433+
if version != value:
434+
version = version.strip()
435+
# Be strict about versions loaded from file because it's easy to
436+
# accidentally include newlines and other unintended content
437+
if isinstance(parse(version), LegacyVersion):
438+
raise DistutilsOptionError('Version loaded from %s does not comply with PEP 440: %s' % (
439+
value, version
440+
))
441+
return version
442+
430443
version = self._parse_attr(value)
431444

432445
if callable(version):

setuptools/tests/test_config.py

+17
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,23 @@ def test_version(self, tmpdir):
268268
with get_dist(tmpdir) as dist:
269269
assert dist.metadata.version == '2016.11.26'
270270

271+
def test_version_file(self, tmpdir):
272+
273+
_, config = fake_env(
274+
tmpdir,
275+
'[metadata]\n'
276+
'version = file: fake_package/version.txt\n'
277+
)
278+
tmpdir.join('fake_package', 'version.txt').write('1.2.3\n')
279+
280+
with get_dist(tmpdir) as dist:
281+
assert dist.metadata.version == '1.2.3'
282+
283+
tmpdir.join('fake_package', 'version.txt').write('1.2.3\n4.5.6\n')
284+
with pytest.raises(DistutilsOptionError):
285+
with get_dist(tmpdir) as dist:
286+
_ = dist.metadata.version
287+
271288
def test_unknown_meta_item(self, tmpdir):
272289

273290
fake_env(

0 commit comments

Comments
 (0)