--- a/tests/test-hook
+++ b/tests/test-hook
@@ -87,4 +87,93 @@ hg undo
echo 'preoutgoing.forbid = echo preoutgoing.forbid hook; exit 1' >> ../a/.hg/hgrc
hg pull ../a
+cat > hooktests.py <<EOF
+from mercurial import util
+
+uncallable = 0
+
+def printargs(args):
+ args.pop('ui', None)
+ args.pop('repo', None)
+ a = list(args.items())
+ a.sort()
+ print 'hook args:'
+ for k, v in a:
+ print ' ', k, v
+ return True
+
+def passhook(**args):
+ printargs(args)
+ return True
+
+def failhook(**args):
+ printargs(args)
+
+class LocalException(Exception):
+ pass
+
+def raisehook(**args):
+ raise LocalException('exception from hook')
+
+def aborthook(**args):
+ raise util.Abort('raise abort from hook')
+
+def brokenhook(**args):
+ return 1 + {}
+
+class container:
+ unreachable = 1
+EOF
+
+echo '# test python hooks'
+PYTHONPATH="$PWD:$PYTHONPATH"
+export PYTHONPATH
+
+echo '[hooks]' > ../a/.hg/hgrc
+echo 'preoutgoing.broken = python:hooktests.brokenhook' >> ../a/.hg/hgrc
+hg pull ../a 2>&1 | grep 'raised an exception'
+
+echo '[hooks]' > ../a/.hg/hgrc
+echo 'preoutgoing.raise = python:hooktests.raisehook' >> ../a/.hg/hgrc
+hg pull ../a 2>&1 | grep 'raised an exception'
+
+echo '[hooks]' > ../a/.hg/hgrc
+echo 'preoutgoing.abort = python:hooktests.aborthook' >> ../a/.hg/hgrc
+hg pull ../a
+
+echo '[hooks]' > ../a/.hg/hgrc
+echo 'preoutgoing.fail = python:hooktests.failhook' >> ../a/.hg/hgrc
+hg pull ../a
+
+echo '[hooks]' > ../a/.hg/hgrc
+echo 'preoutgoing.uncallable = python:hooktests.uncallable' >> ../a/.hg/hgrc
+hg pull ../a
+
+echo '[hooks]' > ../a/.hg/hgrc
+echo 'preoutgoing.nohook = python:hooktests.nohook' >> ../a/.hg/hgrc
+hg pull ../a
+
+echo '[hooks]' > ../a/.hg/hgrc
+echo 'preoutgoing.nomodule = python:nomodule' >> ../a/.hg/hgrc
+hg pull ../a
+
+echo '[hooks]' > ../a/.hg/hgrc
+echo 'preoutgoing.badmodule = python:nomodule.nowhere' >> ../a/.hg/hgrc
+hg pull ../a
+
+echo '[hooks]' > ../a/.hg/hgrc
+echo 'preoutgoing.unreachable = python:hooktests.container.unreachable' >> ../a/.hg/hgrc
+hg pull ../a
+
+echo '[hooks]' > ../a/.hg/hgrc
+echo 'preoutgoing.pass = python:hooktests.passhook' >> ../a/.hg/hgrc
+hg pull ../a
+
+echo '# make sure --traceback works'
+echo '[hooks]' > .hg/hgrc
+echo 'commit.abort = python:hooktests.aborthook' >> .hg/hgrc
+
+echo a >> a
+hg --traceback commit -A -m a 2>&1 | grep '^Traceback'
+
exit 0