summaryrefslogtreecommitdiff
path: root/setuptools
diff options
context:
space:
mode:
Diffstat (limited to 'setuptools')
-rw-r--r--setuptools/config.py31
-rw-r--r--setuptools/tests/test_config.py35
2 files changed, 65 insertions, 1 deletions
diff --git a/setuptools/config.py b/setuptools/config.py
index 44de7cf5..7ab6bfd7 100644
--- a/setuptools/config.py
+++ b/setuptools/config.py
@@ -9,6 +9,7 @@ import importlib
from collections import defaultdict
from functools import partial
from functools import wraps
+from glob import iglob
import contextlib
from distutils.errors import DistutilsOptionError, DistutilsFileError
@@ -256,6 +257,34 @@ class ConfigHandler:
return [chunk.strip() for chunk in value if chunk.strip()]
@classmethod
+ def _parse_list_glob(cls, value, separator=','):
+ """Equivalent to _parse_list() but expands any glob patterns using glob().
+
+ However, unlike with glob() calls, the results remain relative paths.
+
+ :param value:
+ :param separator: List items separator character.
+ :rtype: list
+ """
+ glob_characters = ('*', '?', '[', ']', '{', '}')
+ values = cls._parse_list(value, separator=separator)
+ expanded_values = []
+ for value in values:
+
+ # Has globby characters?
+ if any(char in value for char in glob_characters):
+ # then expand the glob pattern while keeping paths *relative*:
+ expanded_values.extend(sorted(
+ os.path.relpath(path, os.getcwd())
+ for path in iglob(os.path.abspath(value))))
+
+ else:
+ # take the value as-is:
+ expanded_values.append(value)
+
+ return expanded_values
+
+ @classmethod
def _parse_dict(cls, value):
"""Represents value as a dict.
@@ -711,5 +740,5 @@ class ConfigOptionsHandler(ConfigHandler):
:param dict section_options:
"""
- parsed = self._parse_section_to_dict(section_options, self._parse_list)
+ parsed = self._parse_section_to_dict(section_options, self._parse_list_glob)
self['data_files'] = [(k, v) for k, v in parsed.items()]
diff --git a/setuptools/tests/test_config.py b/setuptools/tests/test_config.py
index 21f1becd..ec65250e 100644
--- a/setuptools/tests/test_config.py
+++ b/setuptools/tests/test_config.py
@@ -893,6 +893,41 @@ class TestOptions:
]
assert sorted(dist.data_files) == sorted(expected)
+ def test_data_files_globby(self, tmpdir):
+ fake_env(
+ tmpdir,
+ '[options.data_files]\n'
+ 'cfg =\n'
+ ' a/b.conf\n'
+ ' c/d.conf\n'
+ 'data = *.dat\n'
+ 'icons = \n'
+ ' *.ico\n'
+ 'audio = \n'
+ ' *.wav\n'
+ ' sounds.db\n'
+ )
+
+ # Create dummy files for glob()'s sake:
+ tmpdir.join('a.dat').write('')
+ tmpdir.join('b.dat').write('')
+ tmpdir.join('c.dat').write('')
+ tmpdir.join('a.ico').write('')
+ tmpdir.join('b.ico').write('')
+ tmpdir.join('c.ico').write('')
+ tmpdir.join('beep.wav').write('')
+ tmpdir.join('boop.wav').write('')
+ tmpdir.join('sounds.db').write('')
+
+ with get_dist(tmpdir) as dist:
+ expected = [
+ ('cfg', ['a/b.conf', 'c/d.conf']),
+ ('data', ['a.dat', 'b.dat', 'c.dat']),
+ ('icons', ['a.ico', 'b.ico', 'c.ico']),
+ ('audio', ['beep.wav', 'boop.wav', 'sounds.db']),
+ ]
+ assert sorted(dist.data_files) == sorted(expected)
+
def test_python_requires_simple(self, tmpdir):
fake_env(
tmpdir,