[PATCH 4 of 4] hook: don't crash on syntax errors in python hooks

Siddharth Agarwal sid0 at fb.com
Fri Feb 12 17:53:51 EST 2016


# HG changeset patch
# User Siddharth Agarwal <sid0 at fb.com>
# Date 1455317410 28800
#      Fri Feb 12 14:50:10 2016 -0800
# Node ID d046c71f86718d41b9c5e9f601ca0f0d87606239
# Parent  c9fcff42975be8331c4e10add62d3bca983d155e
# Available At http://42.netv6.net/sid0-wip/hg/
#              hg pull http://42.netv6.net/sid0-wip/hg/ -r d046c71f8671
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.

diff --git a/mercurial/hook.py b/mercurial/hook.py
--- a/mercurial/hook.py
+++ b/mercurial/hook.py
@@ -49,12 +49,12 @@ def _pythonhook(ui, repo, name, hname, f
         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 '
diff --git a/tests/test-hook.t b/tests/test-hook.t
--- a/tests/test-hook.t
+++ b/tests/test-hook.t
@@ -436,6 +436,10 @@ preoutgoing hook can prevent outgoing ch
   >     unreachable = 1
   > EOF
 
+  $ cat > syntaxerror.py << EOF
+  > (foo
+  > EOF
+
 test python hooks
 
 #if windows
@@ -518,6 +522,30 @@ test python hooks
   [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


More information about the Mercurial-devel mailing list