hook: don't crash on syntax errors in python hooks
We had some real-world cases where syntax errors in Python hooks would crash
the whole process and leave it in an indeterminate state. Handle those better.
--- a/mercurial/hook.py Fri Feb 12 11:44:35 2016 -0800
+++ b/mercurial/hook.py Fri Feb 12 14:50:10 2016 -0800
@@ -49,12 +49,12 @@
with demandimport.deactivated():
try:
obj = __import__(modname)
- except ImportError:
+ except (ImportError, SyntaxError):
e1 = sys.exc_info()
try:
# extensions are loaded with hgext_ prefix
obj = __import__("hgext_%s" % modname)
- except ImportError:
+ except (ImportError, SyntaxError):
e2 = sys.exc_info()
if ui.tracebackflag:
ui.warn(_('exception from first failed import '
--- a/tests/test-hook.t Fri Feb 12 11:44:35 2016 -0800
+++ b/tests/test-hook.t Fri Feb 12 14:50:10 2016 -0800
@@ -436,6 +436,10 @@
> unreachable = 1
> EOF
+ $ cat > syntaxerror.py << EOF
+ > (foo
+ > EOF
+
test python hooks
#if windows
@@ -518,6 +522,30 @@
[255]
$ echo '[hooks]' > ../a/.hg/hgrc
+ $ echo 'preoutgoing.syntaxerror = python:syntaxerror.syntaxerror' >> ../a/.hg/hgrc
+ $ hg pull ../a
+ pulling from ../a
+ searching for changes
+ abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
+ (run with --traceback for stack trace)
+ [255]
+
+ $ hg pull ../a --traceback 2>&1 | egrep -v '^( +File| [_a-zA-Z*(])'
+ pulling from ../a
+ searching for changes
+ exception from first failed import attempt:
+ Traceback (most recent call last):
+
+ ^
+ SyntaxError: invalid syntax
+ exception from second failed import attempt:
+ Traceback (most recent call last):
+ ImportError: No module named hgext_syntaxerror
+ Traceback (most recent call last):
+ HookLoadError: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
+ abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
+
+ $ echo '[hooks]' > ../a/.hg/hgrc
$ echo 'preoutgoing.pass = python:hooktests.passhook' >> ../a/.hg/hgrc
$ hg pull ../a
pulling from ../a