"""Tests for packaging.util.""" import os import sys import time import logging import tempfile import subprocess from io import StringIO from packaging.tests import support, unittest from packaging.tests.test_config import SETUP_CFG from packaging.errors import ( PackagingPlatformError, PackagingByteCompileError, PackagingFileError, PackagingExecError, InstallationException) from packaging import util from packaging.dist import Distribution from packaging.util import ( convert_path, change_root, split_quoted, strtobool, get_compiler_versions, _MAC_OS_X_LD_VERSION, byte_compile, find_packages, spawn, get_pypirc_path, generate_pypirc, read_pypirc, resolve_name, iglob, RICH_GLOB, egginfo_to_distinfo, is_setuptools, is_distutils, is_packaging, get_install_method, cfg_to_args, encode_multipart) PYPIRC = """\ [distutils] index-servers = pypi server1 [pypi] username:me password:xxxx [server1] repository:http://example.com username:tarek password:secret """ PYPIRC_OLD = """\ [server-login] username:tarek password:secret """ WANTED = """\ [distutils] index-servers = pypi [pypi] username:tarek password:xxx """ EXPECTED_MULTIPART_OUTPUT = [ b'---x', b'Content-Disposition: form-data; name="username"', b'', b'wok', b'---x', b'Content-Disposition: form-data; name="password"', b'', b'secret', b'---x', b'Content-Disposition: form-data; name="picture"; filename="wok.png"', b'', b'PNG89', b'---x--', b'', ] class FakePopen: test_class = None def __init__(self, args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=()): if isinstance(args, str): args = args.split() self.cmd = args[0] exes = self.test_class._exes if self.cmd not in exes: # we don't want to call the system, returning an empty # output so it doesn't match self.stdout = StringIO() self.stderr = StringIO() else: self.stdout = StringIO(exes[self.cmd]) self.stderr = StringIO() def communicate(self, input=None, timeout=None): return self.stdout.read(), self.stderr.read() def wait(self, timeout=None): return 0 class UtilTestCase(support.EnvironRestorer, support.TempdirManager, support.LoggingCatcher, unittest.TestCase): restore_environ = ['HOME', 'PLAT'] def setUp(self): super(UtilTestCase, self).setUp() self.addCleanup(os.chdir, os.getcwd()) tempdir = self.mkdtemp() self.rc = os.path.join(tempdir, '.pypirc') os.environ['HOME'] = tempdir os.chdir(tempdir) # saving the environment self.name = os.name self.platform = sys.platform self.version = sys.version self.sep = os.sep self.join = os.path.join self.isabs = os.path.isabs self.splitdrive = os.path.splitdrive # patching os.uname if hasattr(os, 'uname'): self.uname = os.uname self._uname = os.uname() else: self.uname = None self._uname = None os.uname = self._get_uname # patching POpen self.old_find_executable = util.find_executable util.find_executable = self._find_executable self._exes = {} self.old_popen = subprocess.Popen self.old_stdout = sys.stdout self.old_stderr = sys.stderr FakePopen.test_class = self subprocess.Popen = FakePopen def tearDown(self): # getting back the environment os.name = self.name sys.platform = self.platform sys.version = self.version os.sep = self.sep os.path.join = self.join os.path.isabs = self.isabs os.path.splitdrive = self.splitdrive if self.uname is not None: os.uname = self.uname else: del os.uname util.find_executable = self.old_find_executable subprocess.Popen = self.old_popen sys.old_stdout = self.old_stdout sys.old_stderr = self.old_stderr super(UtilTestCase, self).tearDown() def _set_uname(self, uname): self._uname = uname def _get_uname(self): return self._uname def test_convert_path(self): # linux/mac os.sep = '/' def _join(path): return '/'.join(path) os.path.join = _join self.assertEqual(convert_path('/home/to/my/stuff'), '/home/to/my/stuff') # win os.sep = '\\' def _join(*path): return '\\'.join(path) os.path.join = _join self.assertRaises(ValueError, convert_path, '/home/to/my/stuff') self.assertRaises(ValueError, convert_path, 'home/to/my/stuff/') self.assertEqual(convert_path('home/to/my/stuff'), 'home\\to\\my\\stuff') self.assertEqual(convert_path('.'), os.curdir) def test_change_root(self): # linux/mac os.name = 'posix' def _isabs(path): return path[0] == '/' os.path.isabs = _isabs def _join(*path): return '/'.join(path) os.path.join = _join self.assertEqual(change_root('/root', '/old/its/here'), '/root/old/its/here') self.assertEqual(change_root('/root', 'its/here'), '/root/its/here') # windows os.name = 'nt' def _isabs(path): return path.startswith('c:\\') os.path.isabs = _isabs def _splitdrive(path): if path.startswith('c:'): return '', path.replace('c:', '') return '', path os.path.splitdrive = _splitdrive def _join(*path): return '\\'.join(path) os.path.join = _join self.assertEqual(change_root('c:\\root', 'c:\\old\\its\\here'), 'c:\\root\\old\\its\\here') self.assertEqual(change_root('c:\\root', 'its\\here'), 'c:\\root\\its\\here') # BugsBunny os (it's a great os) os.name = 'BugsBunny' self.assertRaises(PackagingPlatformError, change_root, 'c:\\root', 'its\\here') # XXX platforms to be covered: os2, mac def test_split_quoted(self): self.assertEqual(split_quoted('""one"" "two" \'three\' \\four'), ['one', 'two', 'three', 'four']) def test_strtobool(self): yes = ('y', 'Y', 'yes', 'True', 't', 'true', 'True', 'On', 'on', '1') no = ('n', 'no', 'f', 'false', 'off', '0', 'Off', 'No', 'N') for y in yes: self.assertTrue(strtobool(y)) for n in no: self.assertFalse(strtobool(n)) def test_find_exe_version(self): # the ld version scheme under MAC OS is: # ^@(#)PROGRAM:ld PROJECT:ld64-VERSION # # where VERSION is a 2-digit number for major # revisions. For instance under Leopard, it's # currently 77 # # Dots are used when branching is done. # # The SnowLeopard ld64 is currently 95.2.12 for output, version in (('@(#)PROGRAM:ld PROJECT:ld64-77', '77'), ('@(#)PROGRAM:ld PROJECT:ld64-95.2.12', '95.2.12')): result = _MAC_OS_X_LD_VERSION.search(output) self.assertEqual(result.group(1), version) def _find_executable(self, name): if name in self._exes: return name return None def test_get_compiler_versions(self): # get_versions calls distutils.spawn.find_executable on # 'gcc', 'ld' and 'dllwrap' self.assertEqual(get_compiler_versions(), (None, None, None)) # Let's fake we have 'gcc' and it returns '3.4.5' self._exes['gcc'] = 'gcc (GCC) 3.4.5 (mingw special)\nFSF' res = get_compiler_versions() self.assertEqual(str(res[0]), '3.4.5') # and let's see what happens when the version # doesn't match the regular expression # (\d+\.\d+(\.\d+)*) self._exes['gcc'] = 'very strange output' res = get_compiler_versions() self.assertEqual(res[0], None) # same thing for ld if sys.platform != 'darwin': self._exes['ld'] = 'GNU ld version 2.17.50 20060824' res = get_compiler_versions() self.assertEqual(str(res[1]), '2.17.50') self._exes['ld'] = '@(#)PROGRAM:ld PROJECT:ld64-77' res = get_compiler_versions() self.assertEqual(res[1], None) else: self._exes['ld'] = 'GNU ld version 2.17.50 20060824' res = get_compiler_versions() self.assertEqual(res[1], None) self._exes['ld'] = '@(#)PROGRAM:ld PROJECT:ld64-77' res = get_compiler_versions() self.assertEqual(str(res[1]), '77') # and dllwrap self._exes['dllwrap'] = 'GNU dllwrap 2.17.50 20060824\nFSF' res = get_compiler_versions() self.assertEqual(str(res[2]), '2.17.50') self._exes['dllwrap'] = 'Cheese Wrap' res = get_compiler_versions() self.assertEqual(res[2], None) @unittest.skipUnless(hasattr(sys, 'dont_write_bytecode'), 'sys.dont_write_bytecode not supported') def test_dont_write_bytecode(self): # makes sure byte_compile raise a PackagingError # if sys.dont_write_bytecode is True old_dont_write_bytecode = sys.dont_write_bytecode sys.dont_write_bytecode = True try: self.assertRaises(PackagingByteCompileError, byte_compile, []) finally: sys.dont_write_bytecode = old_dont_write_bytecode def test_newer(self): self.assertRaises(PackagingFileError, util.newer, 'xxx', 'xxx') self.newer_f1 = self.mktempfile() time.sleep(1) self.newer_f2 = self.mktempfile() self.assertTrue(util.newer(self.newer_f2.name, self.newer_f1.name)) def test_find_packages(self): # let's create a structure we want to scan: # # pkg1 # __init__ # pkg2 # __init__ # pkg3 # __init__ # pkg6 # __init__ # pkg4 <--- not a pkg # pkg8 # __init__ # pkg5 # __init__ # root = self.mkdtemp() pkg1 = os.path.join(root, 'pkg1') os.mkdir(pkg1) self.write_file(os.path.join(pkg1, '__init__.py')) os.mkdir(os.path.join(pkg1, 'pkg2')) self.write_file(os.path.join(pkg1, 'pkg2', '__init__.py')) os.mkdir(os.path.join(pkg1, 'pkg3')) self.write_file(os.path.join(pkg1, 'pkg3', '__init__.py')) os.mkdir(os.path.join(pkg1, 'pkg3', 'pkg6')) self.write_file(os.path.join(pkg1, 'pkg3', 'pkg6', '__init__.py')) os.mkdir(os.path.join(pkg1, 'pkg4')) os.mkdir(os.path.join(pkg1, 'pkg4', 'pkg8')) self.write_file(os.path.join(pkg1, 'pkg4', 'pkg8', '__init__.py')) pkg5 = os.path.join(root, 'pkg5') os.mkdir(pkg5) self.write_file(os.path.join(pkg5, '__init__.py')) res = find_packages([root], ['pkg1.pkg2']) self.assertEqual(set(res), set(['pkg1', 'pkg5', 'pkg1.pkg3', 'pkg1.pkg3.pkg6'])) def test_resolve_name(self): self.assertIs(str, resolve_name('builtins.str')) self.assertEqual( UtilTestCase.__name__, resolve_name("packaging.tests.test_util.UtilTestCase").__name__) self.assertEqual( UtilTestCase.test_resolve_name.__name__, resolve_name("packaging.tests.test_util.UtilTestCase." "test_resolve_name").__name__) self.assertRaises(ImportError, resolve_name, "packaging.tests.test_util.UtilTestCaseNot") self.assertRaises(ImportError, resolve_name, "packaging.tests.test_util.UtilTestCase." "nonexistent_attribute") def test_import_nested_first_time(self): tmp_dir = self.mkdtemp() os.makedirs(os.path.join(tmp_dir, 'a', 'b')) self.write_file(os.path.join(tmp_dir, 'a', '__init__.py'), '') self.write_file(os.path.join(tmp_dir, 'a', 'b', '__init__.py'), '') self.write_file(os.path.join(tmp_dir, 'a', 'b', 'c.py'), 'class Foo: pass') try: sys.path.append(tmp_dir) resolve_name("a.b.c.Foo") # assert nothing raised finally: sys.path.remove(tmp_dir) @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher') def test_run_2to3_on_code(self): content = "print 'test'" converted_content = "print('test')" file_handle = self.mktempfile() file_name = file_handle.name file_handle.write(content) file_handle.flush() file_handle.seek(0) from packaging.util import run_2to3 run_2to3([file_name]) new_content = "".join(file_handle.read()) file_handle.close() self.assertEqual(new_content, converted_content) @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher') def test_run_2to3_on_doctests(self): # to check if text files containing doctests only get converted. content = ">>> print 'test'\ntest\n" converted_content = ">>> print('test')\ntest\n\n" file_handle = self.mktempfile() file_name = file_handle.name file_handle.write(content) file_handle.flush() file_handle.seek(0) from packaging.util import run_2to3 run_2to3([file_name], doctests_only=True) new_content = "".join(file_handle.readlines()) file_handle.close() self.assertEqual(new_content, converted_content) @unittest.skipUnless(os.name in ('nt', 'posix'), 'runs only under posix or nt') def test_spawn(self): # no patching of Popen here subprocess.Popen = self.old_popen tmpdir = self.mkdtemp() # creating something executable # through the shell that returns 1 if os.name == 'posix': exe = os.path.join(tmpdir, 'foo.sh') self.write_file(exe, '#!/bin/sh\nexit 1') os.chmod(exe, 0o777) else: exe = os.path.join(tmpdir, 'foo.bat') self.write_file(exe, 'exit 1') os.chmod(exe, 0o777) self.assertRaises(PackagingExecError, spawn, [exe]) # now something that works if os.name == 'posix': exe = os.path.join(tmpdir, 'foo.sh') self.write_file(exe, '#!/bin/sh\nexit 0') os.chmod(exe, 0o777) else: exe = os.path.join(tmpdir, 'foo.bat') self.write_file(exe, 'exit 0') os.chmod(exe, 0o777) spawn([exe]) # should work without any error def test_server_registration(self): # This test makes sure we know how to: # 1. handle several sections in .pypirc # 2. handle the old format # new format self.write_file(self.rc, PYPIRC) config = read_pypirc() config = sorted(config.items()) expected = [('password', 'xxxx'), ('realm', 'pypi'), ('repository', 'http://pypi.python.org/pypi'), ('server', 'pypi'), ('username', 'me')] self.assertEqual(config, expected) # old format self.write_file(self.rc, PYPIRC_OLD) config = read_pypirc() config = sorted(config.items()) expected = [('password', 'secret'), ('realm', 'pypi'), ('repository', 'http://pypi.python.org/pypi'), ('server', 'server-login'), ('username', 'tarek')] self.assertEqual(config, expected) def test_server_empty_registration(self): rc = get_pypirc_path() self.assertFalse(os.path.exists(rc)) generate_pypirc('tarek', 'xxx') self.assertTrue(os.path.exists(rc)) with open(rc) as f: content = f.read() self.assertEqual(content, WANTED) def test_cfg_to_args(self): opts = {'description-file': 'README', 'extra-files': '', 'setup-hooks': 'packaging.tests.test_config.version_hook'} self.write_file('setup.cfg', SETUP_CFG % opts, encoding='utf-8') self.write_file('README', 'loooong description') args = cfg_to_args() # use Distribution to get the contents of the setup.cfg file dist = Distribution() dist.parse_config_files() metadata = dist.metadata self.assertEqual(args['name'], metadata['Name']) # + .dev1 because the test SETUP_CFG also tests a hook function in # test_config.py for appending to the version string self.assertEqual(args['version'] + '.dev1', metadata['Version']) self.assertEqual(args['author'], metadata['Author']) self.assertEqual(args['author_email'], metadata['Author-Email']) self.assertEqual(args['maintainer'], metadata['Maintainer']) self.assertEqual(args['maintainer_email'], metadata['Maintainer-Email']) self.assertEqual(args['description'], metadata['Summary']) self.assertEqual(args['long_description'], metadata['Description']) self.assertEqual(args['classifiers'], metadata['Classifier']) self.assertEqual(args['requires'], metadata['Requires-Dist']) self.assertEqual(args['provides'], metadata['Provides-Dist']) self.assertEqual(args['package_dir'].get(''), dist.package_dir) self.assertEqual(args['packages'], dist.packages) self.assertEqual(args['scripts'], dist.scripts) self.assertEqual(args['py_modules'], dist.py_modules) def test_encode_multipart(self): fields = [('username', 'wok'), ('password', 'secret')] files = [('picture', 'wok.png', b'PNG89')] content_type, body = encode_multipart(fields, files, b'-x') self.assertEqual(b'multipart/form-data; boundary=-x', content_type) self.assertEqual(EXPECTED_MULTIPART_OUTPUT, body.split(b'\r\n')) class GlobTestCaseBase(support.TempdirManager, support.LoggingCatcher, unittest.TestCase): def build_files_tree(self, files): tempdir = self.mkdtemp() for filepath in files: is_dir = filepath.endswith('/') filepath = os.path.join(tempdir, *filepath.split('/')) if is_dir: dirname = filepath else: dirname = os.path.dirname(filepath) if dirname and not os.path.exists(dirname): os.makedirs(dirname) if not is_dir: self.write_file(filepath, 'babar') return tempdir @staticmethod def os_dependent_path(path): path = path.rstrip('/').split('/') return os.path.join(*path) def clean_tree(self, spec): files = [] for path, includes in spec.items(): if includes: files.append(self.os_dependent_path(path)) return files class GlobTestCase(GlobTestCaseBase): def setUp(self): super(GlobTestCase, self).setUp() self.cwd = os.getcwd() def tearDown(self): os.chdir(self.cwd) super(GlobTestCase, self).tearDown() def assertGlobMatch(self, glob, spec): """""" tempdir = self.build_files_tree(spec) expected = self.clean_tree(spec) os.chdir(tempdir) result = list(iglob(glob)) self.assertCountEqual(expected, result) def test_regex_rich_glob(self): matches = RICH_GLOB.findall( r"babar aime les {fraises} est les {huitres}") self.assertEqual(["fraises", "huitres"], matches) def test_simple_glob(self): glob = '*.tp?' spec = {'coucou.tpl': True, 'coucou.tpj': True, 'Donotwant': False} self.assertGlobMatch(glob, spec) def test_simple_glob_in_dir(self): glob = os.path.join('babar', '*.tp?') spec = {'babar/coucou.tpl': True, 'babar/coucou.tpj': True, 'babar/toto.bin': False, 'Donotwant': False} self.assertGlobMatch(glob, spec) def test_recursive_glob_head(self): glob = os.path.join('**', 'tip', '*.t?l') spec = {'babar/zaza/zuzu/tip/coucou.tpl': True, 'babar/z/tip/coucou.tpl': True, 'babar/tip/coucou.tpl': True, 'babar/zeop/tip/babar/babar.tpl': False, 'babar/z/tip/coucou.bin': False, 'babar/toto.bin': False, 'zozo/zuzu/tip/babar.tpl': True, 'zozo/tip/babar.tpl': True, 'Donotwant': False} self.assertGlobMatch(glob, spec) def test_recursive_glob_tail(self): glob = os.path.join('babar', '**') spec = {'babar/zaza/': True, 'babar/zaza/zuzu/': True, 'babar/zaza/zuzu/babar.xml': True, 'babar/zaza/zuzu/toto.xml': True, 'babar/zaza/zuzu/toto.csv': True, 'babar/zaza/coucou.tpl': True, 'babar/bubu.tpl': True, 'zozo/zuzu/tip/babar.tpl': False, 'zozo/tip/babar.tpl': False, 'Donotwant': False} self.assertGlobMatch(glob, spec) def test_recursive_glob_middle(self): glob = os.path.join('babar', '**', 'tip', '*.t?l') spec = {'babar/zaza/zuzu/tip/coucou.tpl': True, 'babar/z/tip/coucou.tpl': True, 'babar/tip/coucou.tpl': True, 'babar/zeop/tip/babar/babar.tpl': False, 'babar/z/tip/coucou.bin': False, 'babar/toto.bin': False, 'zozo/zuzu/tip/babar.tpl': False, 'zozo/tip/babar.tpl': False, 'Donotwant': False} self.assertGlobMatch(glob, spec) def test_glob_set_tail(self): glob = os.path.join('bin', '*.{bin,sh,exe}') spec = {'bin/babar.bin': True, 'bin/zephir.sh': True, 'bin/celestine.exe': True, 'bin/cornelius.bat': False, 'bin/cornelius.xml': False, 'toto/yurg': False, 'Donotwant': False} self.assertGlobMatch(glob, spec) def test_glob_set_middle(self): glob = os.path.join('xml', '{babar,toto}.xml') spec = {'xml/babar.xml': True, 'xml/toto.xml': True, 'xml/babar.xslt': False, 'xml/cornelius.sgml': False, 'xml/zephir.xml': False, 'toto/yurg.xml': False, 'Donotwant': False} self.assertGlobMatch(glob, spec) def test_glob_set_head(self): glob = os.path.join('{xml,xslt}', 'babar.*') spec = {'xml/babar.xml': True, 'xml/toto.xml': False, 'xslt/babar.xslt': True, 'xslt/toto.xslt': False, 'toto/yurg.xml': False, 'Donotwant': False} self.assertGlobMatch(glob, spec) def test_glob_all(self): dirs = '{%s,%s}' % (os.path.join('xml', '*'), os.path.join('xslt', '**')) glob = os.path.join(dirs, 'babar.xml') spec = {'xml/a/babar.xml': True, 'xml/b/babar.xml': True, 'xml/a/c/babar.xml': False, 'xslt/a/babar.xml': True, 'xslt/b/babar.xml': True, 'xslt/a/c/babar.xml': True, 'toto/yurg.xml': False, 'Donotwant': False} self.assertGlobMatch(glob, spec) def test_invalid_glob_pattern(self): invalids = [ 'ppooa**', 'azzaeaz4**/', '/**ddsfs', '**##1e"&e', 'DSFb**c009', '{', '{aaQSDFa', '}', 'aQSDFSaa}', '{**a,', ',**a}', '{a**,', ',b**}', '{a**a,babar}', '{bob,b**z}', ] for pattern in invalids: self.assertRaises(ValueError, iglob, pattern) class EggInfoToDistInfoTestCase(support.TempdirManager, support.LoggingCatcher, unittest.TestCase): def get_metadata_file_paths(self, distinfo_path): req_metadata_files = ['METADATA', 'RECORD', 'INSTALLER'] metadata_file_paths = [] for metadata_file in req_metadata_files: path = os.path.join(distinfo_path, metadata_file) metadata_file_paths.append(path) return metadata_file_paths def test_egginfo_to_distinfo_setuptools(self): distinfo = 'hello-0.1.1-py3.3.dist-info' egginfo = 'hello-0.1.1-py3.3.egg-info' dirs = [egginfo] files = ['hello.py', 'hello.pyc'] extra_metadata = ['dependency_links.txt', 'entry_points.txt', 'not-zip-safe', 'PKG-INFO', 'top_level.txt', 'SOURCES.txt'] for f in extra_metadata: files.append(os.path.join(egginfo, f)) tempdir, record_file = self.build_dist_tree(files, dirs) distinfo_path = os.path.join(tempdir, distinfo) egginfo_path = os.path.join(tempdir, egginfo) metadata_file_paths = self.get_metadata_file_paths(distinfo_path) egginfo_to_distinfo(record_file) # test that directories and files get created self.assertTrue(os.path.isdir(distinfo_path)) self.assertTrue(os.path.isdir(egginfo_path)) for mfile in metadata_file_paths: self.assertTrue(os.path.isfile(mfile)) def test_egginfo_to_distinfo_distutils(self): distinfo = 'hello-0.1.1-py3.3.dist-info' egginfo = 'hello-0.1.1-py3.3.egg-info' # egginfo is a file in distutils which contains the metadata files = ['hello.py', 'hello.pyc', egginfo] tempdir, record_file = self.build_dist_tree(files, dirs=[]) distinfo_path = os.path.join(tempdir, distinfo) egginfo_path = os.path.join(tempdir, egginfo) metadata_file_paths = self.get_metadata_file_paths(distinfo_path) egginfo_to_distinfo(record_file) # test that directories and files get created self.assertTrue(os.path.isdir(distinfo_path)) self.assertTrue(os.path.isfile(egginfo_path)) for mfile in metadata_file_paths: self.assertTrue(os.path.isfile(mfile)) def build_dist_tree(self, files, dirs): tempdir = self.mkdtemp() record_file_path = os.path.join(tempdir, 'RECORD') file_paths, dir_paths = ([], []) for d in dirs: path = os.path.join(tempdir, d) os.makedirs(path) dir_paths.append(path) for f in files: path = os.path.join(tempdir, f) with open(path, 'w') as _f: _f.write(f) file_paths.append(path) with open(record_file_path, 'w') as record_file: for fpath in file_paths: record_file.write(fpath + '\n') for dpath in dir_paths: record_file.write(dpath + '\n') return (tempdir, record_file_path) class PackagingLibChecks(support.TempdirManager, support.LoggingCatcher, unittest.TestCase): def setUp(self): super(PackagingLibChecks, self).setUp() self._empty_dir = self.mkdtemp() def test_empty_package_is_not_based_on_anything(self): self.assertFalse(is_setuptools(self._empty_dir)) self.assertFalse(is_distutils(self._empty_dir)) self.assertFalse(is_packaging(self._empty_dir)) def test_setup_py_importing_setuptools_is_setuptools_based(self): self.assertTrue(is_setuptools(self._setuptools_setup_py_pkg())) def test_egg_info_dir_and_setup_py_is_setuptools_based(self): self.assertTrue(is_setuptools(self._setuptools_egg_info_pkg())) def test_egg_info_and_non_setuptools_setup_py_is_setuptools_based(self): self.assertTrue(is_setuptools(self._egg_info_with_no_setuptools())) def test_setup_py_not_importing_setuptools_is_not_setuptools_based(self): self.assertFalse(is_setuptools(self._random_setup_py_pkg())) def test_setup_py_importing_distutils_is_distutils_based(self): self.assertTrue(is_distutils(self._distutils_setup_py_pkg())) def test_pkg_info_file_and_setup_py_is_distutils_based(self): self.assertTrue(is_distutils(self._distutils_pkg_info())) def test_pkg_info_and_non_distutils_setup_py_is_distutils_based(self): self.assertTrue(is_distutils(self._pkg_info_with_no_distutils())) def test_setup_py_not_importing_distutils_is_not_distutils_based(self): self.assertFalse(is_distutils(self._random_setup_py_pkg())) def test_setup_cfg_with_no_metadata_section_is_not_packaging_based(self): self.assertFalse(is_packaging(self._setup_cfg_with_no_metadata_pkg())) def test_setup_cfg_with_valid_metadata_section_is_packaging_based(self): self.assertTrue(is_packaging(self._valid_setup_cfg_pkg())) def test_setup_cfg_and_invalid_setup_cfg_is_not_packaging_based(self): self.assertFalse(is_packaging(self._invalid_setup_cfg_pkg())) def test_get_install_method_with_setuptools_pkg(self): path = self._setuptools_setup_py_pkg() self.assertEqual("setuptools", get_install_method(path)) def test_get_install_method_with_distutils_pkg(self): path = self._distutils_pkg_info() self.assertEqual("distutils", get_install_method(path)) def test_get_install_method_with_packaging_pkg(self): path = self._valid_setup_cfg_pkg() self.assertEqual("packaging", get_install_method(path)) def test_get_install_method_with_unknown_pkg(self): path = self._invalid_setup_cfg_pkg() self.assertRaises(InstallationException, get_install_method, path) def test_is_setuptools_logs_setup_py_text_found(self): is_setuptools(self._setuptools_setup_py_pkg()) expected = ['setup.py file found.', 'No egg-info directory found.', 'Found setuptools text in setup.py.'] self.assertEqual(expected, self.get_logs(logging.DEBUG)) def test_is_setuptools_logs_setup_py_text_not_found(self): directory = self._random_setup_py_pkg() is_setuptools(directory) expected = ['setup.py file found.', 'No egg-info directory found.', 'No setuptools text found in setup.py.'] self.assertEqual(expected, self.get_logs(logging.DEBUG)) def test_is_setuptools_logs_egg_info_dir_found(self): is_setuptools(self._setuptools_egg_info_pkg()) expected = ['setup.py file found.', 'Found egg-info directory.'] self.assertEqual(expected, self.get_logs(logging.DEBUG)) def test_is_distutils_logs_setup_py_text_found(self): is_distutils(self._distutils_setup_py_pkg()) expected = ['setup.py file found.', 'No PKG-INFO file found.', 'Found distutils text in setup.py.'] self.assertEqual(expected, self.get_logs(logging.DEBUG)) def test_is_distutils_logs_setup_py_text_not_found(self): directory = self._random_setup_py_pkg() is_distutils(directory) expected = ['setup.py file found.', 'No PKG-INFO file found.', 'No distutils text found in setup.py.'] self.assertEqual(expected, self.get_logs(logging.DEBUG)) def test_is_distutils_logs_pkg_info_file_found(self): is_distutils(self._distutils_pkg_info()) expected = ['setup.py file found.', 'PKG-INFO file found.'] self.assertEqual(expected, self.get_logs(logging.DEBUG)) def test_is_packaging_logs_setup_cfg_found(self): is_packaging(self._valid_setup_cfg_pkg()) expected = ['setup.cfg file found.'] self.assertEqual(expected, self.get_logs(logging.DEBUG)) def test_is_packaging_logs_setup_cfg_not_found(self): is_packaging(self._empty_dir) expected = ['No setup.cfg file found.'] self.assertEqual(expected, self.get_logs(logging.DEBUG)) def _write_setuptools_setup_py(self, directory): self.write_file((directory, 'setup.py'), "from setuptools import setup") def _write_distutils_setup_py(self, directory): self.write_file([directory, 'setup.py'], "from distutils.core import setup") def _write_packaging_setup_cfg(self, directory): self.write_file([directory, 'setup.cfg'], ("[metadata]\n" "name = mypackage\n" "version = 0.1.0\n")) def _setuptools_setup_py_pkg(self): tmp = self.mkdtemp() self._write_setuptools_setup_py(tmp) return tmp def _distutils_setup_py_pkg(self): tmp = self.mkdtemp() self._write_distutils_setup_py(tmp) return tmp def _valid_setup_cfg_pkg(self): tmp = self.mkdtemp() self._write_packaging_setup_cfg(tmp) return tmp def _setuptools_egg_info_pkg(self): tmp = self.mkdtemp() self._write_setuptools_setup_py(tmp) tempfile.mkdtemp(suffix='.egg-info', dir=tmp) return tmp def _distutils_pkg_info(self): tmp = self._distutils_setup_py_pkg() self.write_file([tmp, 'PKG-INFO'], '', encoding='UTF-8') return tmp def _setup_cfg_with_no_metadata_pkg(self): tmp = self.mkdtemp() self.write_file([tmp, 'setup.cfg'], ("[othersection]\n" "foo = bar\n")) return tmp def _invalid_setup_cfg_pkg(self): tmp = self.mkdtemp() self.write_file([tmp, 'setup.cfg'], ("[metadata]\n" "name = john\n" "last_name = doe\n")) return tmp def _egg_info_with_no_setuptools(self): tmp = self._random_setup_py_pkg() tempfile.mkdtemp(suffix='.egg-info', dir=tmp) return tmp def _pkg_info_with_no_distutils(self): tmp = self._random_setup_py_pkg() self.write_file([tmp, 'PKG-INFO'], '', encoding='UTF-8') return tmp def _random_setup_py_pkg(self): tmp = self.mkdtemp() self.write_file((tmp, 'setup.py'), "from mypackage import setup") return tmp def test_suite(): suite = unittest.makeSuite(UtilTestCase) suite.addTest(unittest.makeSuite(GlobTestCase)) suite.addTest(unittest.makeSuite(EggInfoToDistInfoTestCase)) suite.addTest(unittest.makeSuite(PackagingLibChecks)) return suite if __name__ == "__main__": unittest.main(defaultTest="test_suite")