diff options
author | Jason R. Coombs <jaraco@jaraco.com> | 2018-05-18 15:23:43 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-18 15:23:43 -0400 |
commit | 239ff9bd9fe9c38f811fab160491e34dbad5cbeb (patch) | |
tree | c2f1033b537db03a7372b47061f7b8bd7340b0f9 | |
parent | 811c4feac09125d6946c6a159557c4e610fa58de (diff) | |
parent | 07cd2e4e716264fd51aededcb77cefe37aafb25a (diff) | |
download | python-setuptools-git-239ff9bd9fe9c38f811fab160491e34dbad5cbeb.tar.gz |
Merge pull request #1343 from ianw/long-descr-type
Allow setting long_description_content_type externally
-rw-r--r-- | changelog.d/1343.misc.rst | 4 | ||||
-rw-r--r-- | setuptools/dist.py | 36 | ||||
-rw-r--r-- | setuptools/tests/test_config.py | 43 |
3 files changed, 69 insertions, 14 deletions
diff --git a/changelog.d/1343.misc.rst b/changelog.d/1343.misc.rst new file mode 100644 index 00000000..644320f4 --- /dev/null +++ b/changelog.d/1343.misc.rst @@ -0,0 +1,4 @@ +The ``setuptools`` specific ``long_description_content_type``, +``project_urls`` and ``provides_extras`` fields are now set +consistently after any ``distutils`` ``setup_keywords`` calls, +allowing them to override values. diff --git a/setuptools/dist.py b/setuptools/dist.py index 321ab6b7..6ee4a97f 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -328,6 +328,12 @@ class Distribution(Distribution_parse_config_files, _Distribution): distribution for the included and excluded features. """ + _DISTUTILS_UNSUPPORTED_METADATA = { + 'long_description_content_type': None, + 'project_urls': dict, + 'provides_extras': set, + } + _patched_dist = None def patch_missing_pkg_info(self, attrs): @@ -353,25 +359,29 @@ class Distribution(Distribution_parse_config_files, _Distribution): self.require_features = [] self.features = {} self.dist_files = [] + # Filter-out setuptools' specific options. self.src_root = attrs.pop("src_root", None) self.patch_missing_pkg_info(attrs) - self.project_urls = attrs.get('project_urls', {}) self.dependency_links = attrs.pop('dependency_links', []) self.setup_requires = attrs.pop('setup_requires', []) for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'): vars(self).setdefault(ep.name, None) - _Distribution.__init__(self, attrs) - - # The project_urls attribute may not be supported in distutils, so - # prime it here from our value if not automatically set - self.metadata.project_urls = getattr( - self.metadata, 'project_urls', self.project_urls) - self.metadata.long_description_content_type = attrs.get( - 'long_description_content_type' - ) - self.metadata.provides_extras = getattr( - self.metadata, 'provides_extras', set() - ) + _Distribution.__init__(self, { + k: v for k, v in attrs.items() + if k not in self._DISTUTILS_UNSUPPORTED_METADATA + }) + + # Fill-in missing metadata fields not supported by distutils. + # Note some fields may have been set by other tools (e.g. pbr) + # above; they are taken preferrentially to setup() arguments + for option, default in self._DISTUTILS_UNSUPPORTED_METADATA.items(): + for source in self.metadata.__dict__, attrs: + if option in source: + value = source[option] + break + else: + value = default() if default else None + setattr(self.metadata, option, value) if isinstance(self.metadata.version, numbers.Number): # Some people apparently take "version number" too literally :) diff --git a/setuptools/tests/test_config.py b/setuptools/tests/test_config.py index de7c8b4d..19b37633 100644 --- a/setuptools/tests/test_config.py +++ b/setuptools/tests/test_config.py @@ -1,7 +1,8 @@ import contextlib import pytest from distutils.errors import DistutilsOptionError, DistutilsFileError -from setuptools.dist import Distribution +from mock import patch +from setuptools.dist import Distribution, _Distribution from setuptools.config import ConfigHandler, read_configuration @@ -645,3 +646,43 @@ class TestOptions: with get_dist(tmpdir) as dist: assert dist.entry_points == expected + +saved_dist_init = _Distribution.__init__ +class TestExternalSetters: + # During creation of the setuptools Distribution() object, we call + # the init of the parent distutils Distribution object via + # _Distribution.__init__ (). + # + # It's possible distutils calls out to various keyword + # implementations (i.e. distutils.setup_keywords entry points) + # that may set a range of variables. + # + # This wraps distutil's Distribution.__init__ and simulates + # pbr or something else setting these values. + def _fake_distribution_init(self, dist, attrs): + saved_dist_init(dist, attrs) + # see self._DISTUTUILS_UNSUPPORTED_METADATA + setattr(dist.metadata, 'long_description_content_type', + 'text/something') + # Test overwrite setup() args + setattr(dist.metadata, 'project_urls', { + 'Link One': 'https://example.com/one/', + 'Link Two': 'https://example.com/two/', + }) + return None + + @patch.object(_Distribution, '__init__', autospec=True) + def test_external_setters(self, mock_parent_init, tmpdir): + mock_parent_init.side_effect = self._fake_distribution_init + + dist = Distribution(attrs={ + 'project_urls': { + 'will_be': 'ignored' + } + }) + + assert dist.metadata.long_description_content_type == 'text/something' + assert dist.metadata.project_urls == { + 'Link One': 'https://example.com/one/', + 'Link Two': 'https://example.com/two/', + } |