Branch merge

This commit is contained in:
Éric Araujo 2011-10-14 16:56:02 +02:00
commit 77466be08a
6 changed files with 438 additions and 20 deletions

View File

@ -1,11 +1,25 @@
"""Tests for distutils.filelist.""" """Tests for distutils.filelist."""
import re
import unittest import unittest
from distutils.filelist import glob_to_re, FileList
from test.support import captured_stdout, run_unittest
from distutils import debug from distutils import debug
from distutils.log import WARN
from distutils.errors import DistutilsTemplateError
from distutils.filelist import glob_to_re, translate_pattern, FileList
class FileListTestCase(unittest.TestCase): from test.support import captured_stdout, run_unittest
from distutils.tests import support
class FileListTestCase(support.LoggingSilencer,
unittest.TestCase):
def assertNoWarnings(self):
self.assertEqual(self.get_logs(WARN), [])
self.clear_logs()
def assertWarnings(self):
self.assertGreater(len(self.get_logs(WARN)), 0)
self.clear_logs()
def test_glob_to_re(self): def test_glob_to_re(self):
# simple cases # simple cases
@ -23,18 +37,191 @@ class FileListTestCase(unittest.TestCase):
file_list = FileList() file_list = FileList()
with captured_stdout() as stdout: with captured_stdout() as stdout:
file_list.debug_print('xxx') file_list.debug_print('xxx')
stdout.seek(0) self.assertEqual(stdout.getvalue(), '')
self.assertEqual(stdout.read(), '')
debug.DEBUG = True debug.DEBUG = True
try: try:
with captured_stdout() as stdout: with captured_stdout() as stdout:
file_list.debug_print('xxx') file_list.debug_print('xxx')
stdout.seek(0) self.assertEqual(stdout.getvalue(), 'xxx\n')
self.assertEqual(stdout.read(), 'xxx\n')
finally: finally:
debug.DEBUG = False debug.DEBUG = False
def test_set_allfiles(self):
file_list = FileList()
files = ['a', 'b', 'c']
file_list.set_allfiles(files)
self.assertEqual(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()
self.assertEqual(file_list.files, ['a', 'b', 'c', 'g'])
def test_translate_pattern(self):
# not regex
self.assertTrue(hasattr(
translate_pattern('a', anchor=True, is_regex=False),
'search'))
# is a regex
regex = re.compile('a')
self.assertEqual(
translate_pattern(regex, anchor=True, is_regex=True),
regex)
# plain string flagged as regex
self.assertTrue(hasattr(
translate_pattern('a', anchor=True, is_regex=True),
'search'))
# glob support
self.assertTrue(translate_pattern(
'*.py', anchor=True, is_regex=False).search('filelist.py'))
def test_exclude_pattern(self):
# return False if no match
file_list = FileList()
self.assertFalse(file_list.exclude_pattern('*.py'))
# return True if files match
file_list = FileList()
file_list.files = ['a.py', 'b.py']
self.assertTrue(file_list.exclude_pattern('*.py'))
# test excludes
file_list = FileList()
file_list.files = ['a.py', 'a.txt']
file_list.exclude_pattern('*.py')
self.assertEqual(file_list.files, ['a.txt'])
def test_include_pattern(self):
# return False if no match
file_list = FileList()
file_list.set_allfiles([])
self.assertFalse(file_list.include_pattern('*.py'))
# return True if files match
file_list = FileList()
file_list.set_allfiles(['a.py', 'b.txt'])
self.assertTrue(file_list.include_pattern('*.py'))
# test * matches all files
file_list = FileList()
self.assertIsNone(file_list.allfiles)
file_list.set_allfiles(['a.py', 'b.txt'])
file_list.include_pattern('*')
self.assertEqual(file_list.allfiles, ['a.py', 'b.txt'])
def test_process_template(self):
# invalid lines
file_list = FileList()
for action in ('include', 'exclude', 'global-include',
'global-exclude', 'recursive-include',
'recursive-exclude', 'graft', 'prune', 'blarg'):
self.assertRaises(DistutilsTemplateError,
file_list.process_template_line, action)
# include
file_list = FileList()
file_list.set_allfiles(['a.py', 'b.txt', 'd/c.py'])
file_list.process_template_line('include *.py')
self.assertEqual(file_list.files, ['a.py'])
self.assertNoWarnings()
file_list.process_template_line('include *.rb')
self.assertEqual(file_list.files, ['a.py'])
self.assertWarnings()
# exclude
file_list = FileList()
file_list.files = ['a.py', 'b.txt', 'd/c.py']
file_list.process_template_line('exclude *.py')
self.assertEqual(file_list.files, ['b.txt', 'd/c.py'])
self.assertNoWarnings()
file_list.process_template_line('exclude *.rb')
self.assertEqual(file_list.files, ['b.txt', 'd/c.py'])
self.assertWarnings()
# global-include
file_list = FileList()
file_list.set_allfiles(['a.py', 'b.txt', 'd/c.py'])
file_list.process_template_line('global-include *.py')
self.assertEqual(file_list.files, ['a.py', 'd/c.py'])
self.assertNoWarnings()
file_list.process_template_line('global-include *.rb')
self.assertEqual(file_list.files, ['a.py', 'd/c.py'])
self.assertWarnings()
# global-exclude
file_list = FileList()
file_list.files = ['a.py', 'b.txt', 'd/c.py']
file_list.process_template_line('global-exclude *.py')
self.assertEqual(file_list.files, ['b.txt'])
self.assertNoWarnings()
file_list.process_template_line('global-exclude *.rb')
self.assertEqual(file_list.files, ['b.txt'])
self.assertWarnings()
# recursive-include
file_list = FileList()
file_list.set_allfiles(['a.py', 'd/b.py', 'd/c.txt', 'd/d/e.py'])
file_list.process_template_line('recursive-include d *.py')
self.assertEqual(file_list.files, ['d/b.py', 'd/d/e.py'])
self.assertNoWarnings()
file_list.process_template_line('recursive-include e *.py')
self.assertEqual(file_list.files, ['d/b.py', 'd/d/e.py'])
self.assertWarnings()
# recursive-exclude
file_list = FileList()
file_list.files = ['a.py', 'd/b.py', 'd/c.txt', 'd/d/e.py']
file_list.process_template_line('recursive-exclude d *.py')
self.assertEqual(file_list.files, ['a.py', 'd/c.txt'])
self.assertNoWarnings()
file_list.process_template_line('recursive-exclude e *.py')
self.assertEqual(file_list.files, ['a.py', 'd/c.txt'])
self.assertWarnings()
# graft
file_list = FileList()
file_list.set_allfiles(['a.py', 'd/b.py', 'd/d/e.py', 'f/f.py'])
file_list.process_template_line('graft d')
self.assertEqual(file_list.files, ['d/b.py', 'd/d/e.py'])
self.assertNoWarnings()
file_list.process_template_line('graft e')
self.assertEqual(file_list.files, ['d/b.py', 'd/d/e.py'])
self.assertWarnings()
# prune
file_list = FileList()
file_list.files = ['a.py', 'd/b.py', 'd/d/e.py', 'f/f.py']
file_list.process_template_line('prune d')
self.assertEqual(file_list.files, ['a.py', 'f/f.py'])
self.assertNoWarnings()
file_list.process_template_line('prune e')
self.assertEqual(file_list.files, ['a.py', 'f/f.py'])
self.assertWarnings()
def test_suite(): def test_suite():
return unittest.makeSuite(FileListTestCase) return unittest.makeSuite(FileListTestCase)

View File

@ -147,7 +147,9 @@ class Manifest(object):
def _parse_template_line(self, line): def _parse_template_line(self, line):
words = line.split() words = line.split()
if len(words) == 1: if len(words) == 1 and words[0] not in (
'include', 'exclude', 'global-include', 'global-exclude',
'recursive-include', 'recursive-exclude', 'graft', 'prune'):
# no action given, let's use the default 'include' # no action given, let's use the default 'include'
words.insert(0, 'include') words.insert(0, 'include')

View File

@ -56,6 +56,15 @@ class CheckTestCase(support.LoggingCatcher,
cmd = self._run(metadata, strict=True) cmd = self._run(metadata, strict=True)
self.assertEqual([], self.get_logs(logging.WARNING)) self.assertEqual([], self.get_logs(logging.WARNING))
# now a test with non-ASCII characters
metadata = {'home_page': 'xxx', 'author': '\u00c9ric',
'author_email': 'xxx', 'name': 'xxx',
'version': '1.2',
'summary': 'Something about esszet \u00df',
'description': 'More things about esszet \u00df'}
cmd = self._run(metadata)
self.assertEqual([], self.get_logs(logging.WARNING))
def test_check_metadata_1_2(self): def test_check_metadata_1_2(self):
# let's run the command with no metadata at all # let's run the command with no metadata at all
# by default, check is checking the metadata # by default, check is checking the metadata
@ -95,14 +104,26 @@ class CheckTestCase(support.LoggingCatcher,
@unittest.skipUnless(_HAS_DOCUTILS, "requires docutils") @unittest.skipUnless(_HAS_DOCUTILS, "requires docutils")
def test_check_restructuredtext(self): def test_check_restructuredtext(self):
# let's see if it detects broken rest in long_description # let's see if it detects broken rest in description
broken_rest = 'title\n===\n\ntest' broken_rest = 'title\n===\n\ntest'
pkg_info, dist = self.create_dist(description=broken_rest) pkg_info, dist = self.create_dist(description=broken_rest)
cmd = check(dist) cmd = check(dist)
cmd.check_restructuredtext() cmd.check_restructuredtext()
self.assertEqual(len(self.get_logs(logging.WARNING)), 1) self.assertEqual(len(self.get_logs(logging.WARNING)), 1)
# clear warnings from the previous call
self.loghandler.flush()
pkg_info, dist = self.create_dist(description='title\n=====\n\ntest') # let's see if we have an error with strict=1
metadata = {'home_page': 'xxx', 'author': 'xxx',
'author_email': 'xxx',
'name': 'xxx', 'version': '1.2',
'description': broken_rest}
self.assertRaises(PackagingSetupError, self._run, metadata,
strict=True, all=True)
self.loghandler.flush()
# and non-broken rest, including a non-ASCII character to test #12114
dist = self.create_dist(description='title\n=====\n\ntest \u00df')[1]
cmd = check(dist) cmd = check(dist)
cmd.check_restructuredtext() cmd.check_restructuredtext()
self.assertEqual([], self.get_logs(logging.WARNING)) self.assertEqual([], self.get_logs(logging.WARNING))

View File

@ -200,12 +200,10 @@ class RegisterTestCase(support.TempdirManager,
@unittest.skipUnless(DOCUTILS_SUPPORT, 'needs docutils') @unittest.skipUnless(DOCUTILS_SUPPORT, 'needs docutils')
def test_strict(self): def test_strict(self):
# testing the script option # testing the strict option: when on, the register command stops if the
# when on, the register command stops if # metadata is incomplete or if description contains bad reST
# the metadata is incomplete or if
# long_description is not reSt compliant
# empty metadata # empty metadata # XXX this is not really empty..
cmd = self._get_cmd({'name': 'xxx', 'version': 'xxx'}) cmd = self._get_cmd({'name': 'xxx', 'version': 'xxx'})
cmd.ensure_finalized() cmd.ensure_finalized()
cmd.strict = True cmd.strict = True
@ -213,16 +211,15 @@ class RegisterTestCase(support.TempdirManager,
register_module.input = inputs register_module.input = inputs
self.assertRaises(PackagingSetupError, cmd.run) self.assertRaises(PackagingSetupError, cmd.run)
# metadata is OK but long_description is broken # metadata is OK but description is broken
metadata = {'home_page': 'xxx', 'author': 'xxx', metadata = {'home_page': 'xxx', 'author': 'xxx',
'author_email': 'éxéxé', 'author_email': 'éxéxé',
'name': 'xxx', 'version': 'xxx', 'name': 'xxx', 'version': '4.2',
'description': 'title\n==\n\ntext'} 'description': 'title\n==\n\ntext'}
cmd = self._get_cmd(metadata) cmd = self._get_cmd(metadata)
cmd.ensure_finalized() cmd.ensure_finalized()
cmd.strict = True cmd.strict = True
self.assertRaises(PackagingSetupError, cmd.run) self.assertRaises(PackagingSetupError, cmd.run)
# now something that works # now something that works
@ -243,6 +240,21 @@ class RegisterTestCase(support.TempdirManager,
cmd.ensure_finalized() cmd.ensure_finalized()
cmd.run() cmd.run()
# and finally a Unicode test (bug #12114)
metadata = {'home_page': 'xxx', 'author': '\u00c9ric',
'author_email': 'xxx', 'name': 'xxx',
'version': 'xxx',
'summary': 'Something about esszet \u00df',
'description': 'More things about esszet \u00df'}
cmd = self._get_cmd(metadata)
cmd.ensure_finalized()
cmd.strict = True
inputs = Inputs('1', 'tarek', 'y')
register_module.input = inputs
cmd.ensure_finalized()
cmd.run()
def test_register_pep345(self): def test_register_pep345(self):
cmd = self._get_cmd({}) cmd = self._get_cmd({})
cmd.ensure_finalized() cmd.ensure_finalized()

View File

@ -1,8 +1,10 @@
"""Tests for packaging.manifest.""" """Tests for packaging.manifest."""
import os import os
import re
import logging import logging
from io import StringIO from io import StringIO
from packaging.manifest import Manifest from packaging.errors import PackagingTemplateError
from packaging.manifest import Manifest, _translate_pattern, _glob_to_re
from packaging.tests import unittest, support from packaging.tests import unittest, support
@ -34,6 +36,12 @@ class ManifestTestCase(support.TempdirManager,
os.chdir(self.cwd) os.chdir(self.cwd)
super(ManifestTestCase, self).tearDown() super(ManifestTestCase, self).tearDown()
def assertNoWarnings(self):
self.assertEqual(self.get_logs(logging.WARNING), [])
def assertWarnings(self):
self.assertGreater(len(self.get_logs(logging.WARNING)), 0)
def test_manifest_reader(self): def test_manifest_reader(self):
tmpdir = self.mkdtemp() tmpdir = self.mkdtemp()
MANIFEST = os.path.join(tmpdir, 'MANIFEST.in') MANIFEST = os.path.join(tmpdir, 'MANIFEST.in')
@ -69,6 +77,193 @@ class ManifestTestCase(support.TempdirManager,
manifest.read_template(content) manifest.read_template(content)
self.assertEqual(['README', 'file1'], manifest.files) self.assertEqual(['README', 'file1'], manifest.files)
def test_glob_to_re(self):
# simple cases
self.assertEqual(_glob_to_re('foo*'), 'foo[^/]*\\Z(?ms)')
self.assertEqual(_glob_to_re('foo?'), 'foo[^/]\\Z(?ms)')
self.assertEqual(_glob_to_re('foo??'), 'foo[^/][^/]\\Z(?ms)')
# special cases
self.assertEqual(_glob_to_re(r'foo\\*'), r'foo\\\\[^/]*\Z(?ms)')
self.assertEqual(_glob_to_re(r'foo\\\*'), r'foo\\\\\\[^/]*\Z(?ms)')
self.assertEqual(_glob_to_re('foo????'), r'foo[^/][^/][^/][^/]\Z(?ms)')
self.assertEqual(_glob_to_re(r'foo\\??'), r'foo\\\\[^/][^/]\Z(?ms)')
def test_remove_duplicates(self):
manifest = Manifest()
manifest.files = ['a', 'b', 'a', 'g', 'c', 'g']
# files must be sorted beforehand
manifest.sort()
manifest.remove_duplicates()
self.assertEqual(manifest.files, ['a', 'b', 'c', 'g'])
def test_translate_pattern(self):
# blackbox test of a private function
# not regex
pattern = _translate_pattern('a', anchor=True, is_regex=False)
self.assertTrue(hasattr(pattern, 'search'))
# is a regex
regex = re.compile('a')
pattern = _translate_pattern(regex, anchor=True, is_regex=True)
self.assertEqual(pattern, regex)
# plain string flagged as regex
pattern = _translate_pattern('a', anchor=True, is_regex=True)
self.assertTrue(hasattr(pattern, 'search'))
# glob support
pattern = _translate_pattern('*.py', anchor=True, is_regex=False)
self.assertTrue(pattern.search('filelist.py'))
def test_exclude_pattern(self):
# return False if no match
manifest = Manifest()
self.assertFalse(manifest.exclude_pattern('*.py'))
# return True if files match
manifest = Manifest()
manifest.files = ['a.py', 'b.py']
self.assertTrue(manifest.exclude_pattern('*.py'))
# test excludes
manifest = Manifest()
manifest.files = ['a.py', 'a.txt']
manifest.exclude_pattern('*.py')
self.assertEqual(manifest.files, ['a.txt'])
def test_include_pattern(self):
# return False if no match
manifest = Manifest()
manifest.allfiles = []
self.assertFalse(manifest._include_pattern('*.py'))
# return True if files match
manifest = Manifest()
manifest.allfiles = ['a.py', 'b.txt']
self.assertTrue(manifest._include_pattern('*.py'))
# test * matches all files
manifest = Manifest()
self.assertIsNone(manifest.allfiles)
manifest.allfiles = ['a.py', 'b.txt']
manifest._include_pattern('*')
self.assertEqual(manifest.allfiles, ['a.py', 'b.txt'])
def test_process_template(self):
# invalid lines
manifest = Manifest()
for action in ('include', 'exclude', 'global-include',
'global-exclude', 'recursive-include',
'recursive-exclude', 'graft', 'prune'):
self.assertRaises(PackagingTemplateError,
manifest._process_template_line, action)
# implicit include
manifest = Manifest()
manifest.allfiles = ['a.py', 'b.txt', 'd/c.py']
manifest._process_template_line('*.py')
self.assertEqual(manifest.files, ['a.py'])
self.assertNoWarnings()
# include
manifest = Manifest()
manifest.allfiles = ['a.py', 'b.txt', 'd/c.py']
manifest._process_template_line('include *.py')
self.assertEqual(manifest.files, ['a.py'])
self.assertNoWarnings()
manifest._process_template_line('include *.rb')
self.assertEqual(manifest.files, ['a.py'])
self.assertWarnings()
# exclude
manifest = Manifest()
manifest.files = ['a.py', 'b.txt', 'd/c.py']
manifest._process_template_line('exclude *.py')
self.assertEqual(manifest.files, ['b.txt', 'd/c.py'])
self.assertNoWarnings()
manifest._process_template_line('exclude *.rb')
self.assertEqual(manifest.files, ['b.txt', 'd/c.py'])
self.assertWarnings()
# global-include
manifest = Manifest()
manifest.allfiles = ['a.py', 'b.txt', 'd/c.py']
manifest._process_template_line('global-include *.py')
self.assertEqual(manifest.files, ['a.py', 'd/c.py'])
self.assertNoWarnings()
manifest._process_template_line('global-include *.rb')
self.assertEqual(manifest.files, ['a.py', 'd/c.py'])
self.assertWarnings()
# global-exclude
manifest = Manifest()
manifest.files = ['a.py', 'b.txt', 'd/c.py']
manifest._process_template_line('global-exclude *.py')
self.assertEqual(manifest.files, ['b.txt'])
self.assertNoWarnings()
manifest._process_template_line('global-exclude *.rb')
self.assertEqual(manifest.files, ['b.txt'])
self.assertWarnings()
# recursive-include
manifest = Manifest()
manifest.allfiles = ['a.py', 'd/b.py', 'd/c.txt', 'd/d/e.py']
manifest._process_template_line('recursive-include d *.py')
self.assertEqual(manifest.files, ['d/b.py', 'd/d/e.py'])
self.assertNoWarnings()
manifest._process_template_line('recursive-include e *.py')
self.assertEqual(manifest.files, ['d/b.py', 'd/d/e.py'])
self.assertWarnings()
# recursive-exclude
manifest = Manifest()
manifest.files = ['a.py', 'd/b.py', 'd/c.txt', 'd/d/e.py']
manifest._process_template_line('recursive-exclude d *.py')
self.assertEqual(manifest.files, ['a.py', 'd/c.txt'])
self.assertNoWarnings()
manifest._process_template_line('recursive-exclude e *.py')
self.assertEqual(manifest.files, ['a.py', 'd/c.txt'])
self.assertWarnings()
# graft
manifest = Manifest()
manifest.allfiles = ['a.py', 'd/b.py', 'd/d/e.py', 'f/f.py']
manifest._process_template_line('graft d')
self.assertEqual(manifest.files, ['d/b.py', 'd/d/e.py'])
self.assertNoWarnings()
manifest._process_template_line('graft e')
self.assertEqual(manifest.files, ['d/b.py', 'd/d/e.py'])
self.assertWarnings()
# prune
manifest = Manifest()
manifest.files = ['a.py', 'd/b.py', 'd/d/e.py', 'f/f.py']
manifest._process_template_line('prune d')
self.assertEqual(manifest.files, ['a.py', 'f/f.py'])
self.assertNoWarnings()
manifest._process_template_line('prune e')
self.assertEqual(manifest.files, ['a.py', 'f/f.py'])
self.assertWarnings()
def test_suite(): def test_suite():
return unittest.makeSuite(ManifestTestCase) return unittest.makeSuite(ManifestTestCase)

View File

@ -590,6 +590,7 @@ Nick Lockwood
Stephanie Lockwood Stephanie Lockwood
Anne Lord Anne Lord
Tom Loredo Tom Loredo
Justin Love
Jason Lowe Jason Lowe
Tony Lownds Tony Lownds
Ray Loyzaga Ray Loyzaga