| Viewing file:  test_filelist.py (10.51 KB)      -rw-r--r-- Select action/file-type:
 
  (+) |  (+) |  (+) | Code (+) | Session (+) |  (+) | SDB (+) |  (+) |  (+) |  (+) |  (+) |  (+) | 
 
"""Tests for distutils.filelist."""
 import logging
 import os
 import re
 from distutils import debug, filelist
 from distutils.errors import DistutilsTemplateError
 from distutils.filelist import FileList, glob_to_re, translate_pattern
 
 import jaraco.path
 import pytest
 
 from .compat import py39 as os_helper
 
 MANIFEST_IN = """\
 include ok
 include xo
 exclude xo
 include foo.tmp
 include buildout.cfg
 global-include *.x
 global-include *.txt
 global-exclude *.tmp
 recursive-include f *.oo
 recursive-exclude global *.x
 graft dir
 prune dir3
 """
 
 
 def make_local_path(s):
 """Converts '/' in a string to os.sep"""
 return s.replace('/', os.sep)
 
 
 class TestFileList:
 def assertNoWarnings(self, caplog):
 warnings = [rec for rec in caplog.records if rec.levelno == logging.WARNING]
 assert not warnings
 caplog.clear()
 
 def assertWarnings(self, caplog):
 warnings = [rec for rec in caplog.records if rec.levelno == logging.WARNING]
 assert warnings
 caplog.clear()
 
 def test_glob_to_re(self):
 sep = os.sep
 if os.sep == '\\':
 sep = re.escape(os.sep)
 
 for glob, regex in (
 # simple cases
 ('foo*', r'(?s:foo[^%(sep)s]*)\Z'),
 ('foo?', r'(?s:foo[^%(sep)s])\Z'),
 ('foo??', r'(?s:foo[^%(sep)s][^%(sep)s])\Z'),
 # special cases
 (r'foo\\*', r'(?s:foo\\\\[^%(sep)s]*)\Z'),
 (r'foo\\\*', r'(?s:foo\\\\\\[^%(sep)s]*)\Z'),
 ('foo????', r'(?s:foo[^%(sep)s][^%(sep)s][^%(sep)s][^%(sep)s])\Z'),
 (r'foo\\??', r'(?s:foo\\\\[^%(sep)s][^%(sep)s])\Z'),
 ):
 regex = regex % {'sep': sep}
 assert glob_to_re(glob) == regex
 
 def test_process_template_line(self):
 # testing  all MANIFEST.in template patterns
 file_list = FileList()
 mlp = make_local_path
 
 # simulated file list
 file_list.allfiles = [
 'foo.tmp',
 'ok',
 'xo',
 'four.txt',
 'buildout.cfg',
 # filelist does not filter out VCS directories,
 # it's sdist that does
 mlp('.hg/last-message.txt'),
 mlp('global/one.txt'),
 mlp('global/two.txt'),
 mlp('global/files.x'),
 mlp('global/here.tmp'),
 mlp('f/o/f.oo'),
 mlp('dir/graft-one'),
 mlp('dir/dir2/graft2'),
 mlp('dir3/ok'),
 mlp('dir3/sub/ok.txt'),
 ]
 
 for line in MANIFEST_IN.split('\n'):
 if line.strip() == '':
 continue
 file_list.process_template_line(line)
 
 wanted = [
 'ok',
 'buildout.cfg',
 'four.txt',
 mlp('.hg/last-message.txt'),
 mlp('global/one.txt'),
 mlp('global/two.txt'),
 mlp('f/o/f.oo'),
 mlp('dir/graft-one'),
 mlp('dir/dir2/graft2'),
 ]
 
 assert file_list.files == wanted
 
 def test_debug_print(self, capsys, monkeypatch):
 file_list = FileList()
 file_list.debug_print('xxx')
 assert capsys.readouterr().out == ''
 
 monkeypatch.setattr(debug, 'DEBUG', True)
 file_list.debug_print('xxx')
 assert capsys.readouterr().out == 'xxx\n'
 
 def test_set_allfiles(self):
 file_list = FileList()
 files = ['a', 'b', 'c']
 file_list.set_allfiles(files)
 assert file_list.allfiles == files
 
 def test_remove_duplicates(self):
 file_list = FileList()
 file_list.files = ['a', 'b', 'a', 'g', 'c', 'g']
 # files must be sorted beforehand (sdist does it)
 file_list.sort()
 file_list.remove_duplicates()
 assert file_list.files == ['a', 'b', 'c', 'g']
 
 def test_translate_pattern(self):
 # not regex
 assert hasattr(translate_pattern('a', anchor=True, is_regex=False), 'search')
 
 # is a regex
 regex = re.compile('a')
 assert translate_pattern(regex, anchor=True, is_regex=True) == regex
 
 # plain string flagged as regex
 assert hasattr(translate_pattern('a', anchor=True, is_regex=True), 'search')
 
 # glob support
 assert translate_pattern('*.py', anchor=True, is_regex=False).search(
 'filelist.py'
 )
 
 def test_exclude_pattern(self):
 # return False if no match
 file_list = FileList()
 assert not file_list.exclude_pattern('*.py')
 
 # return True if files match
 file_list = FileList()
 file_list.files = ['a.py', 'b.py']
 assert file_list.exclude_pattern('*.py')
 
 # test excludes
 file_list = FileList()
 file_list.files = ['a.py', 'a.txt']
 file_list.exclude_pattern('*.py')
 assert file_list.files == ['a.txt']
 
 def test_include_pattern(self):
 # return False if no match
 file_list = FileList()
 file_list.set_allfiles([])
 assert not file_list.include_pattern('*.py')
 
 # return True if files match
 file_list = FileList()
 file_list.set_allfiles(['a.py', 'b.txt'])
 assert file_list.include_pattern('*.py')
 
 # test * matches all files
 file_list = FileList()
 assert file_list.allfiles is None
 file_list.set_allfiles(['a.py', 'b.txt'])
 file_list.include_pattern('*')
 assert file_list.allfiles == ['a.py', 'b.txt']
 
 def test_process_template(self, caplog):
 mlp = make_local_path
 # invalid lines
 file_list = FileList()
 for action in (
 'include',
 'exclude',
 'global-include',
 'global-exclude',
 'recursive-include',
 'recursive-exclude',
 'graft',
 'prune',
 'blarg',
 ):
 with pytest.raises(DistutilsTemplateError):
 file_list.process_template_line(action)
 
 # include
 file_list = FileList()
 file_list.set_allfiles(['a.py', 'b.txt', mlp('d/c.py')])
 
 file_list.process_template_line('include *.py')
 assert file_list.files == ['a.py']
 self.assertNoWarnings(caplog)
 
 file_list.process_template_line('include *.rb')
 assert file_list.files == ['a.py']
 self.assertWarnings(caplog)
 
 # exclude
 file_list = FileList()
 file_list.files = ['a.py', 'b.txt', mlp('d/c.py')]
 
 file_list.process_template_line('exclude *.py')
 assert file_list.files == ['b.txt', mlp('d/c.py')]
 self.assertNoWarnings(caplog)
 
 file_list.process_template_line('exclude *.rb')
 assert file_list.files == ['b.txt', mlp('d/c.py')]
 self.assertWarnings(caplog)
 
 # global-include
 file_list = FileList()
 file_list.set_allfiles(['a.py', 'b.txt', mlp('d/c.py')])
 
 file_list.process_template_line('global-include *.py')
 assert file_list.files == ['a.py', mlp('d/c.py')]
 self.assertNoWarnings(caplog)
 
 file_list.process_template_line('global-include *.rb')
 assert file_list.files == ['a.py', mlp('d/c.py')]
 self.assertWarnings(caplog)
 
 # global-exclude
 file_list = FileList()
 file_list.files = ['a.py', 'b.txt', mlp('d/c.py')]
 
 file_list.process_template_line('global-exclude *.py')
 assert file_list.files == ['b.txt']
 self.assertNoWarnings(caplog)
 
 file_list.process_template_line('global-exclude *.rb')
 assert file_list.files == ['b.txt']
 self.assertWarnings(caplog)
 
 # recursive-include
 file_list = FileList()
 file_list.set_allfiles(['a.py', mlp('d/b.py'), mlp('d/c.txt'), mlp('d/d/e.py')])
 
 file_list.process_template_line('recursive-include d *.py')
 assert file_list.files == [mlp('d/b.py'), mlp('d/d/e.py')]
 self.assertNoWarnings(caplog)
 
 file_list.process_template_line('recursive-include e *.py')
 assert file_list.files == [mlp('d/b.py'), mlp('d/d/e.py')]
 self.assertWarnings(caplog)
 
 # recursive-exclude
 file_list = FileList()
 file_list.files = ['a.py', mlp('d/b.py'), mlp('d/c.txt'), mlp('d/d/e.py')]
 
 file_list.process_template_line('recursive-exclude d *.py')
 assert file_list.files == ['a.py', mlp('d/c.txt')]
 self.assertNoWarnings(caplog)
 
 file_list.process_template_line('recursive-exclude e *.py')
 assert file_list.files == ['a.py', mlp('d/c.txt')]
 self.assertWarnings(caplog)
 
 # graft
 file_list = FileList()
 file_list.set_allfiles(['a.py', mlp('d/b.py'), mlp('d/d/e.py'), mlp('f/f.py')])
 
 file_list.process_template_line('graft d')
 assert file_list.files == [mlp('d/b.py'), mlp('d/d/e.py')]
 self.assertNoWarnings(caplog)
 
 file_list.process_template_line('graft e')
 assert file_list.files == [mlp('d/b.py'), mlp('d/d/e.py')]
 self.assertWarnings(caplog)
 
 # prune
 file_list = FileList()
 file_list.files = ['a.py', mlp('d/b.py'), mlp('d/d/e.py'), mlp('f/f.py')]
 
 file_list.process_template_line('prune d')
 assert file_list.files == ['a.py', mlp('f/f.py')]
 self.assertNoWarnings(caplog)
 
 file_list.process_template_line('prune e')
 assert file_list.files == ['a.py', mlp('f/f.py')]
 self.assertWarnings(caplog)
 
 
 class TestFindAll:
 @os_helper.skip_unless_symlink
 def test_missing_symlink(self, temp_cwd):
 os.symlink('foo', 'bar')
 assert filelist.findall() == []
 
 def test_basic_discovery(self, temp_cwd):
 """
 When findall is called with no parameters or with
 '.' as the parameter, the dot should be omitted from
 the results.
 """
 jaraco.path.build({'foo': {'file1.txt': ''}, 'bar': {'file2.txt': ''}})
 file1 = os.path.join('foo', 'file1.txt')
 file2 = os.path.join('bar', 'file2.txt')
 expected = [file2, file1]
 assert sorted(filelist.findall()) == expected
 
 def test_non_local_discovery(self, tmp_path):
 """
 When findall is called with another path, the full
 path name should be returned.
 """
 jaraco.path.build({'file1.txt': ''}, tmp_path)
 expected = [str(tmp_path / 'file1.txt')]
 assert filelist.findall(tmp_path) == expected
 
 @os_helper.skip_unless_symlink
 def test_symlink_loop(self, tmp_path):
 jaraco.path.build(
 {
 'link-to-parent': jaraco.path.Symlink('.'),
 'somefile': '',
 },
 tmp_path,
 )
 files = filelist.findall(tmp_path)
 assert len(files) == 1
 
 |