aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--changelog.d/1359.change.rst2
-rw-r--r--docs/setuptools.txt6
-rw-r--r--setuptools/config.py13
-rw-r--r--setuptools/tests/test_config.py17
4 files changed, 37 insertions, 1 deletions
diff --git a/changelog.d/1359.change.rst b/changelog.d/1359.change.rst
new file mode 100644
index 00000000..05746e73
--- /dev/null
+++ b/changelog.d/1359.change.rst
@@ -0,0 +1,2 @@
+Support using "file:" to load a PEP 440-compliant package version
+from a text file.
diff --git a/docs/setuptools.txt b/docs/setuptools.txt
index 76830e41..f7b9351b 100644
--- a/docs/setuptools.txt
+++ b/docs/setuptools.txt
@@ -2424,7 +2424,7 @@ Metadata
Key Aliases Type
============================== ================= =====
name str
-version attr:, str
+version attr:, file:, str
url home-page str
download_url download-url str
project_urls dict
@@ -2444,6 +2444,10 @@ requires list-comma
obsoletes list-comma
============================== ================= =====
+.. note::
+ A version loaded using the ``file:`` directive must comply with PEP 440.
+ It is easy to accidentally put something other than a valid version
+ string in such a file, so validation is stricter in this case.
Options
-------
diff --git a/setuptools/config.py b/setuptools/config.py
index 8eddcae8..6343840e 100644
--- a/setuptools/config.py
+++ b/setuptools/config.py
@@ -7,6 +7,7 @@ from functools import partial
from importlib import import_module
from distutils.errors import DistutilsOptionError, DistutilsFileError
+from setuptools.extern.packaging.version import LegacyVersion, parse
from setuptools.extern.six import string_types
@@ -427,6 +428,18 @@ class ConfigMetadataHandler(ConfigHandler):
:rtype: str
"""
+ version = self._parse_file(value)
+
+ if version != value:
+ version = version.strip()
+ # Be strict about versions loaded from file because it's easy to
+ # accidentally include newlines and other unintended content
+ if isinstance(parse(version), LegacyVersion):
+ raise DistutilsOptionError('Version loaded from %s does not comply with PEP 440: %s' % (
+ value, version
+ ))
+ return version
+
version = self._parse_attr(value)
if callable(version):
diff --git a/setuptools/tests/test_config.py b/setuptools/tests/test_config.py
index abb953a8..17ac09c8 100644
--- a/setuptools/tests/test_config.py
+++ b/setuptools/tests/test_config.py
@@ -268,6 +268,23 @@ class TestMetadata:
with get_dist(tmpdir) as dist:
assert dist.metadata.version == '2016.11.26'
+ def test_version_file(self, tmpdir):
+
+ _, config = fake_env(
+ tmpdir,
+ '[metadata]\n'
+ 'version = file: fake_package/version.txt\n'
+ )
+ tmpdir.join('fake_package', 'version.txt').write('1.2.3\n')
+
+ with get_dist(tmpdir) as dist:
+ assert dist.metadata.version == '1.2.3'
+
+ tmpdir.join('fake_package', 'version.txt').write('1.2.3\n4.5.6\n')
+ with pytest.raises(DistutilsOptionError):
+ with get_dist(tmpdir) as dist:
+ _ = dist.metadata.version
+
def test_unknown_meta_item(self, tmpdir):
fake_env(