diff --git a/changelog.d/1806.change.rst b/changelog.d/1806.change.rst new file mode 100644 index 0000000000..100b689967 --- /dev/null +++ b/changelog.d/1806.change.rst @@ -0,0 +1 @@ +Allowed recursive globs (`**`) in `package_data`. -- by :user:`nullableVoidPtr` diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index c3fdc0927c..ac7cff95da 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -1,3 +1,4 @@ +from functools import partial from glob import glob from distutils.util import convert_path import distutils.command.build_py as orig @@ -98,7 +99,7 @@ def find_data_files(self, package, src_dir): package, src_dir, ) - globs_expanded = map(glob, patterns) + globs_expanded = map(partial(glob, recursive=True), patterns) # flatten the expanded globs into an iterable of matches globs_matches = itertools.chain.from_iterable(globs_expanded) glob_files = filter(os.path.isfile, globs_matches) diff --git a/setuptools/tests/test_build_py.py b/setuptools/tests/test_build_py.py index 19c8b780b8..f6f0d944e6 100644 --- a/setuptools/tests/test_build_py.py +++ b/setuptools/tests/test_build_py.py @@ -25,6 +25,29 @@ def test_directories_in_package_data_glob(tmpdir_cwd): dist.run_commands() +def test_recursive_in_package_data_glob(tmpdir_cwd): + """ + Files matching recursive globs (**) in package_data should + be included in the package data. + + #1806 + """ + dist = Distribution(dict( + script_name='setup.py', + script_args=['build_py'], + packages=[''], + package_data={'': ['path/**/data']}, + )) + os.makedirs('path/subpath/subsubpath') + open('path/subpath/subsubpath/data', 'w').close() + + dist.parse_command_line() + dist.run_commands() + + assert stat.S_ISREG(os.stat('build/lib/path/subpath/subsubpath/data').st_mode), \ + "File is not included" + + def test_read_only(tmpdir_cwd): """ Ensure read-only flag is not preserved in copy