"""Tests for the packaging.uninstall module.""" import os import sys import logging import packaging.util from io import StringIO from packaging.run import main from packaging.errors import PackagingError from packaging.install import remove from packaging.database import disable_cache, enable_cache from packaging.command.install_dist import install_dist from packaging.tests import unittest, support SETUP_CFG = """ [metadata] name = %(name)s version = %(version)s [files] packages = %(pkg)s %(pkg)s.sub """ class UninstallTestCase(support.TempdirManager, support.LoggingCatcher, support.EnvironRestorer, unittest.TestCase): restore_environ = ['PLAT'] def setUp(self): super(UninstallTestCase, self).setUp() self.addCleanup(setattr, sys, 'stdout', sys.stdout) self.addCleanup(setattr, sys, 'stderr', sys.stderr) self.addCleanup(os.chdir, os.getcwd()) self.addCleanup(enable_cache) self.root_dir = self.mkdtemp() self.cwd = os.getcwd() disable_cache() def tearDown(self): os.chdir(self.cwd) packaging.util._path_created.clear() super(UninstallTestCase, self).tearDown() def run_setup(self, *args): # run setup with args args = ['run'] + list(args) dist = main(args) return dist def get_path(self, dist, name): cmd = install_dist(dist) cmd.prefix = self.root_dir cmd.finalize_options() return getattr(cmd, 'install_' + name) def make_dist(self, name='Foo', **kw): kw['name'] = name pkg = name.lower() if 'version' not in kw: kw['version'] = '0.1' project_dir, dist = self.create_dist(**kw) kw['pkg'] = pkg pkg_dir = os.path.join(project_dir, pkg) os.mkdir(pkg_dir) os.mkdir(os.path.join(pkg_dir, 'sub')) self.write_file((project_dir, 'setup.cfg'), SETUP_CFG % kw) self.write_file((pkg_dir, '__init__.py'), '#') self.write_file((pkg_dir, pkg + '_utils.py'), '#') self.write_file((pkg_dir, 'sub', '__init__.py'), '#') self.write_file((pkg_dir, 'sub', pkg + '_utils.py'), '#') return project_dir def install_dist(self, name='Foo', dirname=None, **kw): if not dirname: dirname = self.make_dist(name, **kw) os.chdir(dirname) sys.stderr = StringIO() dist = self.run_setup('install_dist', '--prefix=' + self.root_dir) site_packages = self.get_path(dist, 'purelib') return dist, site_packages def test_uninstall_unknown_distribution(self): dist, site_packages = self.install_dist('Foospam') self.assertRaises(PackagingError, remove, 'Foo', paths=[site_packages]) def test_uninstall(self): dist, site_packages = self.install_dist() self.assertIsFile(site_packages, 'foo', '__init__.py') self.assertIsFile(site_packages, 'foo', 'sub', '__init__.py') self.assertIsFile(site_packages, 'Foo-0.1.dist-info', 'RECORD') self.assertTrue(remove('Foo', paths=[site_packages])) self.assertIsNotFile(site_packages, 'foo', 'sub', '__init__.py') self.assertIsNotFile(site_packages, 'Foo-0.1.dist-info', 'RECORD') def test_uninstall_error_handling(self): # makes sure if there are OSErrors (like permission denied) # remove() stops and displays a clean error dist, site_packages = self.install_dist('Meh') # breaking os.rename old = os.rename def _rename(source, target): raise OSError(42, 'impossible operation') os.rename = _rename try: self.assertFalse(remove('Meh', paths=[site_packages])) finally: os.rename = old logs = [log for log in self.get_logs(logging.INFO) if log.startswith('Error:')] self.assertEqual(logs, ['Error: [Errno 42] impossible operation']) self.assertTrue(remove('Meh', paths=[site_packages])) def test_suite(): return unittest.makeSuite(UninstallTestCase) if __name__ == '__main__': unittest.main(defaultTest='test_suite')