diff options
-rw-r--r-- | changelog.d/1359.change.rst | 2 | ||||
-rw-r--r-- | docs/setuptools.txt | 6 | ||||
-rw-r--r-- | setuptools/config.py | 13 | ||||
-rw-r--r-- | setuptools/tests/test_config.py | 17 |
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( |