Skip to content

Commit

Permalink
Fix #52 by handlingKeyboardInterrupt during inifile collection.
Browse files Browse the repository at this point in the history
  • Loading branch information
joeyespo committed Apr 8, 2016
1 parent 8945212 commit 00a29bc
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 13 deletions.
3 changes: 2 additions & 1 deletion pytest_watch/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ def main(argv=None):
pytest_args.extend(['-c', args['--config']])

# Merge config file options
merge_config(args, pytest_args)
if not merge_config(args, pytest_args):
return 0

# Adjust pytest args
if args['--pdb']:
Expand Down
42 changes: 30 additions & 12 deletions pytest_watch/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,16 @@
except ImportError:
from ConfigParser import ConfigParser

from .constants import EXIT_INTERRUPTED, EXIT_NOTESTSCOLLECTED, EXIT_OK


CLI_OPTION_PREFIX = '--'


class CollectError(Exception):
pass


class CollectConfig(object):
"""
A pytest plugin to gets the configuration file.
Expand All @@ -33,39 +39,49 @@ def pytest_cmdline_main(self, config):
self.path = str(inifile)


def collect(pytest_args, silent=True):
collect_config = CollectConfig()
def _run_pytest_collect(pytest_args):
collect_config_plugin = CollectConfig()
argv = pytest_args + ['--collect-only']

exit_code = pytest.main(argv, plugins=[collect_config_plugin])
if exit_code == EXIT_INTERRUPTED:
raise KeyboardInterrupt()
if exit_code not in [EXIT_OK, EXIT_NOTESTSCOLLECTED]:
raise CollectError()

return collect_config_plugin.path


def _collect_config(pytest_args, silent=True):
if silent:
try:
with silence():
exit_code = pytest.main(argv, plugins=[collect_config])
if exit_code == 0:
return collect_config.path
return _run_pytest_collect(pytest_args)
except KeyboardInterrupt:
raise
except Exception:
pass
# Print message and run again without silencing
print('Error: Could not run --collect-only to find the pytest config '
'file. Trying again without silencing stdout...',
file=sys.stderr)

status_code = pytest.main(argv, plugins=[collect_config])
if not collect_config.path and status_code != 0:
print('Could not determine the pytest config file.', file=sys.stderr)
return collect_config.path
return _run_pytest_collect(pytest_args)


def merge_config(args, pytest_args, silent=True):
config_path = collect(pytest_args, silent)
try:
config_path = _collect_config(pytest_args, silent)
except (KeyboardInterrupt, CollectError):
return False

if not config_path:
return
return True

config = ConfigParser()
config.read(config_path)
if not config.has_section('pytest-watch'):
return
return True

for cli_name in args:
if not cli_name.startswith(CLI_OPTION_PREFIX):
Expand All @@ -87,3 +103,5 @@ def merge_config(args, pytest_args, silent=True):
args[cli_name] = config.getboolean('pytest-watch', config_name)
else:
args[cli_name] = config.get('pytest-watch', config_name)

return True

0 comments on commit 00a29bc

Please sign in to comment.