cpython/Lib/packaging/tests/test_dist.py

267 lines
9.1 KiB
Python
Raw Normal View History

"""Tests for packaging.dist."""
import os
import sys
import textwrap
import packaging.dist
from packaging.dist import Distribution
from packaging.command import set_command, _COMMANDS
from packaging.command.cmd import Command
from packaging.errors import PackagingModuleError, PackagingOptionError
from packaging.tests import captured_stdout
from packaging.tests import support, unittest
from packaging.tests.support import create_distribution
from test.support import unload
class test_dist(Command):
"""Sample packaging extension command."""
user_options = [
("sample-option=", "S", "help text"),
]
def initialize_options(self):
self.sample_option = None
def finalize_options(self):
pass
def run(self):
pass
class DistributionTestCase(support.TempdirManager,
support.LoggingCatcher,
support.EnvironRestorer,
unittest.TestCase):
restore_environ = ['HOME', 'PLAT']
def setUp(self):
super(DistributionTestCase, self).setUp()
# XXX this is ugly, we should fix the functions to accept args
# (defaulting to sys.argv)
self.argv = sys.argv, sys.argv[:]
del sys.argv[1:]
self._commands = _COMMANDS.copy()
def tearDown(self):
sys.argv = self.argv[0]
sys.argv[:] = self.argv[1]
# XXX maybe we need a public API to remove commands
_COMMANDS.clear()
_COMMANDS.update(self._commands)
super(DistributionTestCase, self).tearDown()
@unittest.skip('needs to be updated')
def test_debug_mode(self):
tmpdir = self.mkdtemp()
setupcfg = os.path.join(tmpdir, 'setup.cfg')
with open(setupcfg, "w") as f:
f.write("[global]\n")
f.write("command_packages = foo.bar, splat")
files = [setupcfg]
sys.argv.append("build")
__, stdout = captured_stdout(create_distribution, files)
self.assertEqual(stdout, '')
# XXX debug mode does not exist anymore, test logging levels in this
# test instead
packaging.dist.DEBUG = True
try:
__, stdout = captured_stdout(create_distribution, files)
self.assertEqual(stdout, '')
finally:
packaging.dist.DEBUG = False
def test_bad_attr(self):
Distribution(attrs={'author': 'xxx',
'name': 'xxx',
'version': '1.2',
'home_page': 'xxxx',
'badoptname': 'xxx'})
logs = self.get_logs()
self.assertEqual(len(logs), 1)
self.assertIn('unknown argument', logs[0])
def test_empty_options(self):
# an empty options dictionary should not stay in the
# list of attributes
dist = Distribution(attrs={'author': 'xxx', 'name': 'xxx',
'version': '1.2', 'home_page': 'xxxx',
'options': {}})
self.assertEqual(self.get_logs(), [])
self.assertNotIn('options', dir(dist))
def test_non_empty_options(self):
# TODO: how to actually use options is not documented except
# for a few cryptic comments in dist.py. If this is to stay
# in the public API, it deserves some better documentation.
# Here is an example of how it's used out there:
# http://svn.pythonmac.org/py2app/py2app/trunk/doc/
# index.html#specifying-customizations
dist = Distribution(attrs={'author': 'xxx',
'name': 'xxx',
'version': 'xxx',
'home_page': 'xxxx',
'options': {'sdist': {'owner': 'root'}}})
self.assertIn('owner', dist.get_option_dict('sdist'))
def test_finalize_options(self):
attrs = {'keywords': 'one,two',
'platform': 'one,two'}
dist = Distribution(attrs=attrs)
dist.finalize_options()
# finalize_option splits platforms and keywords
self.assertEqual(dist.metadata['platform'], ['one', 'two'])
self.assertEqual(dist.metadata['keywords'], ['one', 'two'])
def test_custom_pydistutils(self):
# Bug #2166: make sure pydistutils.cfg is found
if os.name == 'posix':
user_filename = ".pydistutils.cfg"
else:
user_filename = "pydistutils.cfg"
temp_dir = self.mkdtemp()
user_filename = os.path.join(temp_dir, user_filename)
with open(user_filename, 'w') as f:
f.write('.')
dist = Distribution()
os.environ['HOME'] = temp_dir
files = dist.find_config_files()
self.assertIn(user_filename, files)
def test_find_config_files_disable(self):
# Bug #1180: Allow users to disable their own config file.
temp_home = self.mkdtemp()
if os.name == 'posix':
user_filename = os.path.join(temp_home, ".pydistutils.cfg")
else:
user_filename = os.path.join(temp_home, "pydistutils.cfg")
with open(user_filename, 'w') as f:
f.write('[distutils2]\n')
def _expander(path):
return temp_home
old_expander = os.path.expanduser
os.path.expanduser = _expander
try:
d = packaging.dist.Distribution()
all_files = d.find_config_files()
d = packaging.dist.Distribution(attrs={'script_args':
['--no-user-cfg']})
files = d.find_config_files()
finally:
os.path.expanduser = old_expander
# make sure --no-user-cfg disables the user cfg file
self.assertEqual((len(all_files) - 1), len(files))
def test_special_hooks_parsing(self):
temp_home = self.mkdtemp()
config_files = [os.path.join(temp_home, "config1.cfg"),
os.path.join(temp_home, "config2.cfg")]
# Store two aliased hooks in config files
self.write_file((temp_home, "config1.cfg"),
'[test_dist]\npre-hook.a = type')
self.write_file((temp_home, "config2.cfg"),
'[test_dist]\npre-hook.b = type')
set_command('packaging.tests.test_dist.test_dist')
dist = create_distribution(config_files)
cmd = dist.get_command_obj("test_dist")
self.assertEqual(cmd.pre_hook, {"a": 'type', "b": 'type'})
def test_hooks_get_run(self):
temp_home = self.mkdtemp()
module_name = os.path.split(temp_home)[-1]
pyname = '%s.py' % module_name
config_file = os.path.join(temp_home, "config1.cfg")
hooks_module = os.path.join(temp_home, pyname)
self.write_file(config_file, textwrap.dedent('''\
[test_dist]
pre-hook.test = %(modname)s.log_pre_call
post-hook.test = %(modname)s.log_post_call'''
% {'modname': module_name}))
self.write_file(hooks_module, textwrap.dedent('''\
record = []
def log_pre_call(cmd):
record.append('pre-%s' % cmd.get_command_name())
def log_post_call(cmd):
record.append('post-%s' % cmd.get_command_name())
'''))
set_command('packaging.tests.test_dist.test_dist')
d = create_distribution([config_file])
cmd = d.get_command_obj("test_dist")
# prepare the call recorders
sys.path.append(temp_home)
self.addCleanup(sys.path.remove, temp_home)
self.addCleanup(unload, module_name)
record = __import__(module_name).record
cmd.run = lambda: record.append('run')
cmd.finalize_options = lambda: record.append('finalize')
d.run_command('test_dist')
self.assertEqual(record, ['finalize',
'pre-test_dist',
'run',
'post-test_dist'])
def test_hooks_importable(self):
temp_home = self.mkdtemp()
config_file = os.path.join(temp_home, "config1.cfg")
self.write_file(config_file, textwrap.dedent('''\
[test_dist]
pre-hook.test = nonexistent.dotted.name'''))
set_command('packaging.tests.test_dist.test_dist')
d = create_distribution([config_file])
cmd = d.get_command_obj("test_dist")
cmd.ensure_finalized()
self.assertRaises(PackagingModuleError, d.run_command, 'test_dist')
def test_hooks_callable(self):
temp_home = self.mkdtemp()
config_file = os.path.join(temp_home, "config1.cfg")
self.write_file(config_file, textwrap.dedent('''\
[test_dist]
pre-hook.test = packaging.tests.test_dist.__doc__'''))
set_command('packaging.tests.test_dist.test_dist')
d = create_distribution([config_file])
cmd = d.get_command_obj("test_dist")
cmd.ensure_finalized()
self.assertRaises(PackagingOptionError, d.run_command, 'test_dist')
def test_suite():
return unittest.makeSuite(DistributionTestCase)
if __name__ == "__main__":
unittest.main(defaultTest="test_suite")