diff --git a/src/bindings/python/hammer_tests.py b/src/bindings/python/hammer_tests.py
index 7a7d5f1af8b4b7b2e88319f34712341aa4abec30..587fbd5dbe052dcc279fb6f713e3208eeef33138 100644
--- a/src/bindings/python/hammer_tests.py
+++ b/src/bindings/python/hammer_tests.py
@@ -402,15 +402,15 @@ class TestEpsilonP3(unittest.TestCase):
     def test_failure(self):
         pass
 
-# class TestAttrBool(unittest.TestCase):
-#     @classmethod
-#     def setUpClass(cls):
-#         cls.parser = h.h_attr_bool(h.h_many1(h.h_choice__a([h.h_ch("a"), h.h_ch("b")])), lambda x: x[0] == x[1])
-#     def test_success(self):
-#         self.assertEqual(h.h_parse(self.parser, "aa"), ["a", "a"])
-#         self.assertEqual(h.h_parse(self.parser, "bb"), ["b", "b"])
-#     def test_failure(self):
-#         self.assertEqual(h.h_parse(self.parser, "ab"), None)
+class TestAttrBool(unittest.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        cls.parser = h.h_attr_bool(h.h_many1(h.h_choice__a([h.h_ch("a"), h.h_ch("b")])), lambda x: x[0] == x[1])
+    def test_success(self):
+        self.assertEqual(h.h_parse(self.parser, "aa"), ("a", "a"))
+        self.assertEqual(h.h_parse(self.parser, "bb"), ("b", "b"))
+    def test_failure(self):
+        self.assertEqual(h.h_parse(self.parser, "ab"), None)
 
 class TestAnd1(unittest.TestCase):
     @classmethod
diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i
index a2a8940ca114760616c6c56e022dddf06864290f..20661c85df05a13fb4d87d2c3565ea337b9e96b5 100644
--- a/src/bindings/swig/hammer.i
+++ b/src/bindings/swig/hammer.i
@@ -135,26 +135,28 @@
 
 
 
-/*
-%typemap(in) (HPredicate* pred, void* user_data) {
+
+%typemap(in) (HPredicate pred, void* user_data) {
   Py_INCREF($input);
   $2 = $input;
   $1 = call_predicate;
  }
-*/
+
 %typemap(in) (const HAction a, void* user_data) {
   Py_INCREF($input);
   $2 = $input;
   $1 = call_action;
  }
 
-%inline {
+%inline %{
+
   struct HParsedToken_;
   struct HParseResult_;
   static PyObject* hpt_to_python(const struct HParsedToken_ *token);
   
   static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data);
- }
+  static int call_predicate(const struct HParseResult_ *p, void* user_data);
+ %}
 #else
   #warning no uint8_t* typemaps defined
 #endif
@@ -164,6 +166,7 @@
 #include "allocator.h"
 #include "hammer.h"
 #include "internal.h"
+#include "glue.h"
 %}
 %include "allocator.h"
 %include "hammer.h"
@@ -233,11 +236,30 @@
       assert(ret != NULL);
     }	
     // TODO: add reference to ret to parse-local data
+    // For now, just hold onto reference
     HParsedToken *tok = h_make(p->arena, h_tt_python, ret);
     return tok;
    }
   
+  static int call_predicate(const struct HParseResult_ *p, void* user_data) {
+    PyObject *callable = user_data;
+    PyObject *ret = PyObject_CallFunctionObjArgs(callable,
+						 hpt_to_python(p->ast),
+						 NULL);
+    int rret = 0;
+    if (ret == NULL) {
+      // TODO: throw exception
+      PyErr_Print();
+      assert(ret != NULL);
+    }	
+    // TODO: add reference to ret to parse-local data
+    rret = PyObject_IsTrue(ret);
+    Py_DECREF(ret);
+    return rret;
+  }
+  
  }
 
 
+
 #endif