Skip to content

Commit

Permalink
ENH: respect exclude_dirs and exclude_files in editable installs
Browse files Browse the repository at this point in the history
Add support for the exclude_dirs and exclude_files arguments of
install_subdir() Meson function. Extend editable install tests to
cover this functionality and a more complex package layout.
  • Loading branch information
dnicolodi committed Feb 4, 2024
1 parent 18b75fc commit 3092827
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 21 deletions.
28 changes: 19 additions & 9 deletions mesonpy/_editable.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,13 +222,21 @@ def get(self, key: Union[str, Tuple[str, ...]]) -> Optional[Union[Node, str]]:
return dict.get(node, key)


def walk(root: str, path: str = '') -> Iterator[pathlib.Path]:
with os.scandir(os.path.join(root, path)) as entries:
for entry in entries:
if entry.is_dir():
yield from walk(root, os.path.join(path, entry.name))
else:
yield pathlib.Path(path, entry.name)
def walk(src: str, exclude_files: Set[str], exclude_dirs: Set[str]) -> Iterator[str]:
for root, dirnames, filenames in os.walk(src):
for name in dirnames.copy():
dirsrc = os.path.join(root, name)
relpath = os.path.relpath(dirsrc, src)
if relpath in exclude_dirs:
dirnames.remove(name)
# sort to process directories determninistically
dirnames.sort()
for name in sorted(filenames):
filesrc = os.path.join(root, name)
relpath = os.path.relpath(filesrc, src)
if relpath in exclude_files:
continue
yield relpath


def collect(install_plan: Dict[str, Dict[str, Any]]) -> Node:
Expand All @@ -238,8 +246,10 @@ def collect(install_plan: Dict[str, Dict[str, Any]]) -> Node:
path = pathlib.Path(target['destination'])
if path.parts[0] in {'{py_platlib}', '{py_purelib}'}:
if key == 'install_subdirs' and os.path.isdir(src):
for entry in walk(src):
tree[(*path.parts[1:], *entry.parts)] = os.path.join(src, *entry.parts)
exclude_files = {os.path.normpath(x) for x in target.get('exclude_files', [])}
exclude_dirs = {os.path.normpath(x) for x in target.get('exclude_dirs', [])}
for entry in walk(src, exclude_files, exclude_dirs):
tree[(*path.parts[1:], *entry.split(os.sep))] = os.path.join(src, entry)
else:
tree[path.parts[1:]] = src
return tree
Expand Down
39 changes: 31 additions & 8 deletions tests/packages/complex/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,36 @@ endif

py = import('python').find_installation()

py.install_sources('move.py', subdir: 'complex/more', pure: false)

install_data('foo.py', rename: 'bar.py', install_dir: py.get_install_dir(pure: false) / 'complex')

install_subdir('complex', install_dir: py.get_install_dir(pure: false))

py.extension_module('test', 'test.pyx', install: true, subdir: 'complex')
py.extension_module('baz', 'complex/more/baz.pyx', install: true, subdir: 'complex/more')
py.install_sources(
'move.py',
subdir: 'complex/more',
pure: false,
)

install_data(
'foo.py',
rename: 'bar.py',
install_dir: py.get_install_dir(pure: false) / 'complex',
)

install_subdir(
'complex',
install_dir: py.get_install_dir(pure: false),
exclude_files: ['more/meson.build', 'more/baz.pyx'],
)

py.extension_module(
'test',
'test.pyx',
install: true,
subdir: 'complex',
)

py.extension_module(
'baz',
'complex/more/baz.pyx',
install: true,
subdir: 'complex/more',
)

subdir('complex/more')
10 changes: 6 additions & 4 deletions tests/test_editable.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@


def test_walk(package_complex):
entries = set(_editable.walk(os.fspath(package_complex / 'complex')))
assert entries == {
entries = _editable.walk(
os.fspath(package_complex / 'complex'),
[os.path.normpath('more/meson.build'), os.path.normpath('more/baz.pyx')],
['namespace'],
)
assert {pathlib.Path(x) for x in entries} == {
pathlib.Path('__init__.py'),
pathlib.Path('more/__init__.py'),
pathlib.Path('namespace/bar.py'),
pathlib.Path('namespace/foo.py')
}


Expand Down

0 comments on commit 3092827

Please sign in to comment.