From f4d8469085cf5d97fb9e1b1fefa19fb229a23ed6 Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Mon, 1 Dec 2014 22:35:25 -0800 Subject: [PATCH] Preventing ConfigParser from swallowing file read IOErrors, so that the user gets a more useful message. --- atticmatic/command.py | 13 ++++++++++--- atticmatic/config.py | 6 ++++-- atticmatic/tests/unit/test_config.py | 3 ++- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/atticmatic/command.py b/atticmatic/command.py index 1466c30..7ea236b 100644 --- a/atticmatic/command.py +++ b/atticmatic/command.py @@ -7,7 +7,10 @@ from atticmatic.attic import create_archive, prune_archives from atticmatic.config import parse_configuration -def main(): +def parse_arguments(): + ''' + Parse the command-line arguments from sys.argv and return them as an ArgumentParser instance. + ''' parser = ArgumentParser() parser.add_argument( '--config', @@ -26,13 +29,17 @@ def main(): action='store_true', help='Display verbose progress information', ) - args = parser.parse_args() + return parser.parse_args() + + +def main(): try: + args = parse_arguments() location_config, retention_config = parse_configuration(args.config_filename) create_archive(args.excludes_filename, args.verbose, *location_config) prune_archives(location_config.repository, args.verbose, *retention_config) - except (ValueError, CalledProcessError) as error: + except (ValueError, IOError, CalledProcessError) as error: print(error, file=sys.stderr) sys.exit(1) diff --git a/atticmatic/config.py b/atticmatic/config.py index 20caa34..ac8cad1 100644 --- a/atticmatic/config.py +++ b/atticmatic/config.py @@ -23,10 +23,12 @@ RetentionConfig = namedtuple('RetentionConfig', CONFIG_FORMAT[CONFIG_SECTION_RET def parse_configuration(config_filename): ''' Given a config filename of the expected format, return the parse configuration as a tuple of - (LocationConfig, RetentionConfig). Raise if the format is not as expected. + (LocationConfig, RetentionConfig). + + Raise IOError if the file cannot be read, or ValueError if the format is not as expected. ''' parser = ConfigParser() - parser.read((config_filename,)) + parser.readfp(open(config_filename)) section_names = parser.sections() expected_section_names = CONFIG_FORMAT.keys() diff --git a/atticmatic/tests/unit/test_config.py b/atticmatic/tests/unit/test_config.py index 818d3db..f393533 100644 --- a/atticmatic/tests/unit/test_config.py +++ b/atticmatic/tests/unit/test_config.py @@ -6,8 +6,9 @@ from atticmatic import config as module def insert_mock_parser(section_names): parser = flexmock() - parser.should_receive('read') + parser.should_receive('readfp') parser.should_receive('sections').and_return(section_names) + flexmock(module).open = lambda filename: None flexmock(module).ConfigParser = parser return parser