<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>amounts.cc</filename>
    </added>
    <added>
      <filename>setup.py</filename>
    </added>
    <added>
      <filename>test.py</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,8 +1,14 @@
-lib_LTLIBRARIES = libledger.la
-libledger_la_CXXFLAGS =
-libledger_la_SOURCES = \
+lib_LTLIBRARIES = libamounts.la libledger.la
+libamounts_la_CXXFLAGS =
+libamounts_la_SOURCES = \
 	amount.cc      \
 	balance.cc     \
+	value.cc
+if HAVE_BOOST_PYTHON
+libamounts_la_CXXFLAGS += -DUSE_BOOST_PYTHON=1
+endif
+libledger_la_CXXFLAGS =
+libledger_la_SOURCES = \
 	binary.cc      \
 	config.cc      \
 	datetime.cc    \
@@ -19,7 +25,6 @@ libledger_la_SOURCES = \
 	startup.cc     \
 	textual.cc     \
 	valexpr.cc     \
-	value.cc       \
 	walk.cc
 if HAVE_EXPAT
 libledger_la_CXXFLAGS += -DHAVE_EXPAT=1
@@ -37,12 +42,16 @@ if DEBUG
 libledger_la_CXXFLAGS += -DDEBUG_LEVEL=4
 libledger_la_SOURCES  += debug.cc
 endif
-libledger_la_LDFLAGS = -version-info 3:0
+libledger_la_LDFLAGS = -version-info 2:6
 
 pkginclude_HEADERS = \
 	acconf.h     \
+		     \
 	amount.h     \
 	balance.h    \
+	value.h      \
+	util.h	     \
+		     \
 	binary.h     \
 	config.h     \
 	datetime.h   \
@@ -62,9 +71,7 @@ pkginclude_HEADERS = \
 	reconcile.h  \
 	textual.h    \
 	timing.h     \
-	util.h	     \
 	valexpr.h    \
-	value.h      \
 	walk.h       \
 	xml.h
 
@@ -73,18 +80,15 @@ pkginclude_HEADERS = \
 bin_PROGRAMS = ledger
 ledger_CXXFLAGS =
 ledger_SOURCES = main.cc
-ledger_LDADD = $(LIBOBJS) libledger.la
+ledger_LDADD = $(LIBOBJS) libamounts.la libledger.la
 if HAVE_EXPAT
 ledger_CXXFLAGS += -DHAVE_EXPAT=1
-ledger_LDADD += -lexpat
 endif
 if HAVE_XMLPARSE
 ledger_CXXFLAGS += -DHAVE_XMLPARSE=1
-ledger_LDADD += -lxmlparse -lxmltok
 endif
 if HAVE_LIBOFX
 ledger_CXXFLAGS += -DHAVE_LIBOFX=1
-ledger_LDADD += -lofx
 endif
 if DEBUG
 ledger_CXXFLAGS += -DDEBUG_LEVEL=4
@@ -100,6 +104,22 @@ dist_lisp_LISP = ledger.el timeclock.el
 
 ######################################################################
 
+if HAVE_BOOST_PYTHON
+
+noinst_PROGRAMS = amounts.so
+
+amounts.so: amounts.cc libamounts.la
+	CFLAGS=&quot;$(CPPFLAGS)&quot; LDFLAGS=&quot;$(LDFLAGS) -L. -L.libs&quot; \
+	    python setup.py build --build-lib=.
+
+install-exec-hook:
+	CFLAGS=&quot;$(CPPFLAGS)&quot; LDFLAGS=&quot;$(LDFLAGS) -L. -L.libs&quot; \
+	    python setup.py install --prefix=$(prefix)
+
+endif
+
+######################################################################
+
 all-clean: maintainer-clean
 	rm -fr	*~ .*~ .\#* *.html *.info *.pdf *.a *.so *.o *.lo *.la \
 		*.elc *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr \</diff>
      <filename>Makefile.am</filename>
    </modified>
    <modified>
      <diff>@@ -18,12 +18,13 @@ autoconf
 
 INCDIRS=&quot;-I/sw/include -I/usr/local/include/boost-1_33 -I/usr/include/httpd/xml&quot;
 #INCDIRS=&quot;$INCDIRS -I/sw/include/libofx&quot;
+INCDIRS=&quot;$INCDIRS -I/sw/include/python2.4&quot;
 INCDIRS=&quot;$INCDIRS -Wno-long-double&quot;
-LIBDIRS=&quot;-L/sw/lib -L/usr/local/lib&quot;
+LIBDIRS=&quot;-L/sw/lib -L/usr/local/lib -L/sw/lib/python2.4/config&quot;
 
 if [ &quot;$1&quot; = &quot;--debug&quot; ]; then
     ./configure CPPFLAGS=&quot;$INCDIRS&quot; LDFLAGS=&quot;$LIBDIRS&quot; CXXFLAGS=&quot;-g&quot; \
-	--enable-debug
+	--enable-debug --enable-python
 elif [ &quot;$1&quot; = &quot;--opt&quot; ]; then
     ./configure CPPFLAGS=&quot;$INCDIRS&quot; LDFLAGS=&quot;$LIBDIRS&quot; \
 	CXXFLAGS=&quot;-fomit-frame-pointer -O3 -mcpu=7450 -fPIC&quot;</diff>
      <filename>acprep</filename>
    </modified>
    <modified>
      <diff>@@ -1291,3 +1291,180 @@ amount_t commodity_t::value(const std::time_t moment)
 }
 
 } // namespace ledger
+
+#ifdef USE_BOOST_PYTHON
+
+#include &lt;boost/python.hpp&gt;
+#include &lt;Python.h&gt;
+
+using namespace boost::python;
+using namespace ledger;
+
+int py_amount_quantity(amount_t&amp; amount)
+{
+  std::string quant = amount.quantity_string();
+  return std::atol(quant.c_str());
+}
+
+void py_parse_1(amount_t&amp; amount, const std::string&amp; str,
+		unsigned short flags) {
+  amount.parse(str, flags);
+}
+void py_parse_2(amount_t&amp; amount, const std::string&amp; str) {
+  amount.parse(str);
+}
+
+struct commodity_updater_wrap : public commodity_t::updater_t
+{
+  PyObject * self;
+  commodity_updater_wrap(PyObject * self_) : self(self_) {}
+
+  virtual void operator()(commodity_t&amp;      commodity,
+			  const std::time_t moment,
+			  const std::time_t date,
+			  const std::time_t last,
+			  amount_t&amp;         price) {
+    call_method&lt;void&gt;(self, &quot;__call__&quot;, commodity, moment, date, last, price);
+  }
+};
+
+commodity_t * py_find_commodity_1(const std::string&amp; symbol)
+{
+  return commodity_t::find_commodity(symbol);
+}
+
+commodity_t * py_find_commodity_2(const std::string&amp; symbol, bool auto_create)
+{
+  return commodity_t::find_commodity(symbol, auto_create);
+}
+
+#define EXC_TRANSLATOR(type)				\
+  void exc_translate_ ## type(const type&amp; err) {	\
+    PyErr_SetString(PyExc_RuntimeError, err.what());	\
+  }
+
+EXC_TRANSLATOR(amount_error)
+
+void export_amount()
+{
+  scope().attr(&quot;AMOUNT_PARSE_NO_MIGRATE&quot;) = AMOUNT_PARSE_NO_MIGRATE;
+  scope().attr(&quot;AMOUNT_PARSE_NO_REDUCE&quot;)  = AMOUNT_PARSE_NO_REDUCE;
+
+  class_&lt; amount_t &gt; (&quot;Amount&quot;)
+    .def(init&lt;amount_t&gt;())
+    .def(init&lt;std::string&gt;())
+    .def(init&lt;char *&gt;())
+    .def(init&lt;bool&gt;())
+    .def(init&lt;long&gt;())
+    .def(init&lt;unsigned long&gt;())
+    .def(init&lt;double&gt;())
+
+    .def(self += self)
+    .def(self += long())
+    .def(self +  self)
+    .def(self +  long())
+    .def(self -= self)
+    .def(self -= long())
+    .def(self -  self)
+    .def(self -  long())
+    .def(self *= self)
+    .def(self *= long())
+    .def(self *  self)
+    .def(self *  long())
+    .def(self /= self)
+    .def(self /= long())
+    .def(self /  self)
+    .def(self /  long())
+    .def(- self)
+
+    .def(self &lt;  self)
+    .def(self &lt;  long())
+    .def(self &lt;= self)
+    .def(self &lt;= long())
+    .def(self &gt;  self)
+    .def(self &gt;  long())
+    .def(self &gt;= self)
+    .def(self &gt;= long())
+    .def(self == self)
+    .def(self == long())
+    .def(self != self)
+    .def(self != long())
+    .def(! self)
+
+    .def(self_ns::int_(self))
+    .def(self_ns::float_(self))
+    .def(self_ns::str(self))
+    .def(abs(self))
+
+    .add_property(&quot;commodity&quot;,
+		  make_function(&amp;amount_t::commodity,
+				return_value_policy&lt;reference_existing_object&gt;()),
+		  &amp;amount_t::set_commodity)
+    .add_property(&quot;quantity&quot;, py_amount_quantity)
+
+    .def(&quot;negate&quot;, &amp;amount_t::negate)
+    .def(&quot;parse&quot;, py_parse_1)
+    .def(&quot;parse&quot;, py_parse_2)
+    .def(&quot;reduce&quot;, &amp;amount_t::reduce)
+
+    .def(&quot;valid&quot;, &amp;amount_t::valid)
+    ;
+
+  class_&lt; commodity_t::updater_t, commodity_updater_wrap, boost::noncopyable &gt;
+    (&quot;Updater&quot;)
+    ;
+
+  scope().attr(&quot;COMMODITY_STYLE_DEFAULTS&quot;)  = COMMODITY_STYLE_DEFAULTS;
+  scope().attr(&quot;COMMODITY_STYLE_SUFFIXED&quot;)  = COMMODITY_STYLE_SUFFIXED;
+  scope().attr(&quot;COMMODITY_STYLE_SEPARATED&quot;) = COMMODITY_STYLE_SEPARATED;
+  scope().attr(&quot;COMMODITY_STYLE_EUROPEAN&quot;)  = COMMODITY_STYLE_EUROPEAN;
+  scope().attr(&quot;COMMODITY_STYLE_THOUSANDS&quot;) = COMMODITY_STYLE_THOUSANDS;
+  scope().attr(&quot;COMMODITY_STYLE_NOMARKET&quot;)  = COMMODITY_STYLE_NOMARKET;
+  scope().attr(&quot;COMMODITY_STYLE_VARIABLE&quot;)  = COMMODITY_STYLE_VARIABLE;
+
+  class_&lt; commodity_t &gt; (&quot;Commodity&quot;)
+    .def(init&lt;std::string, optional&lt;unsigned int, unsigned int&gt; &gt;())
+
+    .add_property(&quot;symbol&quot;, &amp;commodity_t::symbol,
+		  &amp;commodity_t::set_symbol)
+
+    // jww (2006-02-28): Use getters and setters!
+    .def_readwrite(&quot;name&quot;, &amp;commodity_t::name_)
+    .def_readwrite(&quot;note&quot;, &amp;commodity_t::note_)
+    .def_readwrite(&quot;precision&quot;, &amp;commodity_t::precision_)
+    .def_readwrite(&quot;flags&quot;, &amp;commodity_t::flags_)
+    .def_readwrite(&quot;ident&quot;, &amp;commodity_t::ident)
+    .def_readwrite(&quot;updater&quot;, &amp;commodity_t::updater)
+
+    .add_property(&quot;smaller&quot;,
+		  make_getter(&amp;commodity_t::smaller_,
+			      return_value_policy&lt;reference_existing_object&gt;()))
+    .add_property(&quot;larger&quot;,
+		  make_getter(&amp;commodity_t::larger_,
+			      return_value_policy&lt;reference_existing_object&gt;()))
+
+    .def(self_ns::str(self))
+
+    .def(&quot;add_price&quot;, &amp;commodity_t::add_price)
+    .def(&quot;remove_price&quot;, &amp;commodity_t::remove_price)
+    .def(&quot;value&quot;, &amp;commodity_t::value)
+
+    .def(&quot;valid&quot;, &amp;commodity_t::valid)
+    ;
+
+  scope().attr(&quot;NullCommodity&quot;) = commodity_t::null_commodity;
+
+  def(&quot;add_commodity&quot;, &amp;commodity_t::add_commodity);
+  def(&quot;remove_commodity&quot;, &amp;commodity_t::remove_commodity);
+  def(&quot;find_commodity&quot;, py_find_commodity_1,
+      return_value_policy&lt;reference_existing_object&gt;());
+  def(&quot;find_commodity&quot;, py_find_commodity_2,
+      return_value_policy&lt;reference_existing_object&gt;());
+
+#define EXC_TRANSLATE(type)					\
+  register_exception_translator&lt;type&gt;(&amp;exc_translate_ ## type);
+
+  EXC_TRANSLATE(amount_error);
+}
+
+#endif // USE_BOOST_PYTHON</diff>
      <filename>amount.cc</filename>
    </modified>
    <modified>
      <diff>@@ -190,3 +190,202 @@ balance_pair_t&amp; balance_pair_t::add(const amount_t&amp;  amount,
 }
 
 } // namespace ledger
+
+#ifdef USE_BOOST_PYTHON
+
+#include &lt;boost/python.hpp&gt;
+
+using namespace boost::python;
+using namespace ledger;
+
+unsigned int balance_len(balance_t&amp; bal)
+{
+  return bal.amounts.size();
+}
+
+amount_t balance_getitem(balance_t&amp; bal, int i)
+{
+  std::size_t len = bal.amounts.size();
+
+  if (abs(i) &gt;= len) {
+    PyErr_SetString(PyExc_IndexError, &quot;Index out of range&quot;);
+    throw_error_already_set();
+  }
+
+  int x = i &lt; 0 ? len + i : i;
+  amounts_map::iterator elem = bal.amounts.begin();
+  while (--x &gt;= 0)
+    elem++;
+
+  return (*elem).second;
+}
+
+unsigned int balance_pair_len(balance_pair_t&amp; bal_pair)
+{
+  return balance_len(bal_pair.quantity);
+}
+
+amount_t balance_pair_getitem(balance_pair_t&amp; bal_pair, int i)
+{
+  return balance_getitem(bal_pair.quantity, i);
+}
+
+void export_balance()
+{
+  class_&lt; balance_t &gt; (&quot;Balance&quot;)
+    .def(init&lt;balance_t&gt;())
+    .def(init&lt;amount_t&gt;())
+    .def(init&lt;long&gt;())
+    .def(init&lt;unsigned long&gt;())
+    .def(init&lt;double&gt;())
+
+    .def(self += self)
+    .def(self += other&lt;amount_t&gt;())
+    .def(self += long())
+    .def(self +  self)
+    .def(self +  other&lt;amount_t&gt;())
+    .def(self +  long())
+    .def(self -= self)
+    .def(self -= other&lt;amount_t&gt;())
+    .def(self -= long())
+    .def(self -  self)
+    .def(self -  other&lt;amount_t&gt;())
+    .def(self -  long())
+    .def(self *= self)
+    .def(self *= other&lt;amount_t&gt;())
+    .def(self *= long())
+    .def(self *  self)
+    .def(self *  other&lt;amount_t&gt;())
+    .def(self *  long())
+    .def(self /= self)
+    .def(self /= other&lt;amount_t&gt;())
+    .def(self /= long())
+    .def(self /  self)
+    .def(self /  other&lt;amount_t&gt;())
+    .def(self /  long())
+    .def(- self)
+
+    .def(self &lt;  self)
+    .def(self &lt;  other&lt;amount_t&gt;())
+    .def(self &lt;  long())
+    .def(self &lt;= self)
+    .def(self &lt;= other&lt;amount_t&gt;())
+    .def(self &lt;= long())
+    .def(self &gt;  self)
+    .def(self &gt;  other&lt;amount_t&gt;())
+    .def(self &gt;  long())
+    .def(self &gt;= self)
+    .def(self &gt;= other&lt;amount_t&gt;())
+    .def(self &gt;= long())
+    .def(self == self)
+    .def(self == other&lt;amount_t&gt;())
+    .def(self == long())
+    .def(self != self)
+    .def(self != other&lt;amount_t&gt;())
+    .def(self != long())
+    .def(! self)
+
+    .def(abs(self))
+    .def(self_ns::str(self))
+
+    .def(&quot;__len__&quot;, balance_len)
+    .def(&quot;__getitem__&quot;, balance_getitem)
+
+    .def(&quot;negate&quot;, &amp;balance_t::negate)
+    .def(&quot;amount&quot;, &amp;balance_t::amount)
+    .def(&quot;value&quot;,  &amp;balance_t::value)
+    .def(&quot;write&quot;,  &amp;balance_t::write)
+    .def(&quot;valid&quot;, &amp;balance_t::valid)
+    ;
+
+  class_&lt; balance_pair_t &gt; (&quot;BalancePair&quot;)
+    .def(init&lt;balance_pair_t&gt;())
+    .def(init&lt;balance_t&gt;())
+    .def(init&lt;amount_t&gt;())
+    .def(init&lt;long&gt;())
+    .def(init&lt;unsigned long&gt;())
+    .def(init&lt;double&gt;())
+
+    .def(self += self)
+    .def(self += other&lt;balance_t&gt;())
+    .def(self += other&lt;amount_t&gt;())
+    .def(self += long())
+    .def(self +  self)
+    .def(self +  other&lt;balance_t&gt;())
+    .def(self +  other&lt;amount_t&gt;())
+    .def(self +  long())
+    .def(self -= self)
+    .def(self -= other&lt;balance_t&gt;())
+    .def(self -= other&lt;amount_t&gt;())
+    .def(self -= long())
+    .def(self -  self)
+    .def(self -  other&lt;balance_t&gt;())
+    .def(self -  other&lt;amount_t&gt;())
+    .def(self -  long())
+    .def(self *= self)
+    .def(self *= other&lt;balance_t&gt;())
+    .def(self *= other&lt;amount_t&gt;())
+    .def(self *= long())
+    .def(self *  self)
+    .def(self *  other&lt;balance_t&gt;())
+    .def(self *  other&lt;amount_t&gt;())
+    .def(self *  long())
+    .def(self /= self)
+    .def(self /= other&lt;balance_t&gt;())
+    .def(self /= other&lt;amount_t&gt;())
+    .def(self /= long())
+    .def(self /  self)
+    .def(self /  other&lt;balance_t&gt;())
+    .def(self /  other&lt;amount_t&gt;())
+    .def(self /  long())
+    .def(- self)
+
+    .def(self &lt;  self)
+    .def(self &lt;  other&lt;balance_t&gt;())
+    .def(self &lt;  other&lt;amount_t&gt;())
+    .def(self &lt;  long())
+    .def(self &lt;= self)
+    .def(self &lt;= other&lt;balance_t&gt;())
+    .def(self &lt;= other&lt;amount_t&gt;())
+    .def(self &lt;= long())
+    .def(self &gt;  self)
+    .def(self &gt;  other&lt;balance_t&gt;())
+    .def(self &gt;  other&lt;amount_t&gt;())
+    .def(self &gt;  long())
+    .def(self &gt;= self)
+    .def(self &gt;= other&lt;balance_t&gt;())
+    .def(self &gt;= other&lt;amount_t&gt;())
+    .def(self &gt;= long())
+    .def(self == self)
+    .def(self == other&lt;balance_t&gt;())
+    .def(self == other&lt;amount_t&gt;())
+    .def(self == long())
+    .def(self != self)
+    .def(self != other&lt;balance_t&gt;())
+    .def(self != other&lt;amount_t&gt;())
+    .def(self != long())
+    .def(! self)
+
+    .def(abs(self))
+    .def(self_ns::str(self))
+
+    .def(&quot;__len__&quot;, balance_pair_len)
+    .def(&quot;__getitem__&quot;, balance_pair_getitem)
+
+    .add_property(&quot;price&quot;,
+		  make_getter(&amp;balance_pair_t::price,
+			      return_value_policy&lt;reference_existing_object&gt;()))
+    .add_property(&quot;cost&quot;,
+		  make_getter(&amp;balance_pair_t::cost,
+			      return_value_policy&lt;reference_existing_object&gt;()))
+
+    .def(&quot;negate&quot;, &amp;balance_pair_t::negate)
+    .def(&quot;amount&quot;, &amp;balance_pair_t::amount)
+    .def(&quot;value&quot;,  &amp;balance_pair_t::value)
+    .def(&quot;write&quot;,  &amp;balance_pair_t::write)
+
+    .def(&quot;valid&quot;, &amp;balance_pair_t::valid)
+    ;
+}
+
+#endif // USE_BOOST_PYTHON</diff>
      <filename>balance.cc</filename>
    </modified>
    <modified>
      <diff>@@ -12,9 +12,9 @@ namespace ledger {
 
 static unsigned long  binary_magic_number = 0xFFEED765;
 #ifdef DEBUG_ENABLED
-static unsigned long  format_version      = 0x0002050b;
+static unsigned long  format_version      = 0x00020601;
 #else
-static unsigned long  format_version      = 0x0002050a;
+static unsigned long  format_version      = 0x00020600;
 #endif
 
 static account_t **   accounts;</diff>
      <filename>binary.cc</filename>
    </modified>
    <modified>
      <diff>@@ -2,8 +2,8 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.59)
-AC_INIT(ledger, 2.5, johnw@newartisans.com)
-AM_INIT_AUTOMAKE(ledger, 2.5)
+AC_INIT(ledger, 2.6, johnw@newartisans.com)
+AM_INIT_AUTOMAKE(ledger, 2.6)
 AC_CONFIG_SRCDIR([main.cc])
 AC_CONFIG_HEADER([acconf.h])
 
@@ -129,7 +129,13 @@ if [test x$xml = xtrue ]; then
        [libexpat_avail=false])
      AC_LANG_POP
      LIBS=$libexpat_save_libs])
-  AM_CONDITIONAL(HAVE_EXPAT, test x$libexpat_avail = xtrue)
+
+  if [test x$libexpat_avail = xtrue ]; then
+    AM_CONDITIONAL(HAVE_EXPAT, true)
+    LIBS=&quot;-lexpat $LIBS&quot;
+  else
+    AM_CONDITIONAL(HAVE_EXPAT, false)
+  fi
 else
   AM_CONDITIONAL(HAVE_EXPAT, false)
 fi
@@ -153,7 +159,13 @@ if [test x$xml = xtrue ]; then
 	 [libxmlparse_avail=false])
        AC_LANG_POP
        LIBS=$libxmlparse_save_libs])
-    AM_CONDITIONAL(HAVE_XMLPARSE, test x$libxmlparse_avail = xtrue)
+
+    if [test x$libxmlparse_avail = xtrue ]; then
+      AM_CONDITIONAL(HAVE_XMLPARSE, true)
+      LIBS=&quot;-lxmlparse -lxmltok $LIBS&quot;
+    else
+      AM_CONDITIONAL(HAVE_XMLPARSE, false)
+    fi
   else
     AM_CONDITIONAL(HAVE_XMLPARSE, false)
   fi
@@ -185,11 +197,61 @@ if [test x$ofx = xtrue ]; then
        [libofx_avail=false])
      AC_LANG_POP
      LIBS=$libofx_save_libs])
-  AM_CONDITIONAL(HAVE_LIBOFX, test x$libofx_avail = xtrue)
+
+  if [test x$libofx_avail = xtrue ]; then
+    AM_CONDITIONAL(HAVE_LIBOFX, true)
+    LIBS=&quot;-lofx $LIBS&quot;
+  else
+    AM_CONDITIONAL(HAVE_LIBOFX, false)
+  fi
 else
   AM_CONDITIONAL(HAVE_LIBOFX, false)
 fi
 
+# check for Python
+AC_ARG_ENABLE(python,
+  [  --enable-python         Build the amounts library as a Python module],
+  [case &quot;${enableval}&quot; in
+    yes) python=true ;;
+    no)  python=false ;;
+    *) AC_MSG_ERROR(bad value ${enableval} for --enable-python) ;;
+  esac],[python=false])
+AM_CONDITIONAL(USE_PYTHON, test x$python = xtrue)
+
+if [test x$python = xtrue ]; then
+  AM_PATH_PYTHON(2.2,, :)
+  if [test &quot;$PYTHON&quot; != :]; then
+    AC_CACHE_CHECK(
+      [if boost_python is available],
+      [boost_python_cpplib_avail],
+      [boost_python_save_libs=$LIBS
+       LIBS=&quot;-lboost_python -lpython$PYTHON_VERSION $LIBS&quot;
+       AC_LANG_PUSH(C++)
+       AC_TRY_LINK(
+	 [#include &lt;boost/python.hpp&gt;
+	  using namespace boost::python;
+	  class foo {};
+	  BOOST_PYTHON_MODULE(samp) {
+	    class_&lt; foo &gt; (&quot;foo&quot;) ;
+	  }],
+	 [return 0],
+	 [boost_python_cpplib_avail=true],
+	 [boost_python_cpplib_avail=false])
+       AC_LANG_POP
+       LIBS=$boost_python_save_libs])
+    if [test x$boost_python_cpplib_avail = xtrue ]; then
+      AM_CONDITIONAL(HAVE_BOOST_PYTHON, true)
+      LIBS=&quot;-lboost_python -lpython$PYTHON_VERSION $LIBS&quot;
+    else
+      AM_CONDITIONAL(HAVE_BOOST_PYTHON, false)
+    fi
+  else
+    AM_CONDITIONAL(HAVE_BOOST_PYTHON, false)
+  fi
+else
+  AM_CONDITIONAL(HAVE_BOOST_PYTHON, false)
+fi
+
 # Check for options
 AC_ARG_ENABLE(debug,
   [  --enable-debug          Turn on debugging],</diff>
      <filename>configure.in</filename>
    </modified>
    <modified>
      <diff>@@ -814,3 +814,274 @@ value_t&amp; value_t::add(const amount_t&amp; amount,
 }
 
 } // namespace ledger
+
+#ifdef USE_BOOST_PYTHON
+
+#include &lt;boost/python.hpp&gt;
+
+using namespace boost::python;
+using namespace ledger;
+
+long	 balance_len(balance_t&amp; bal);
+amount_t balance_getitem(balance_t&amp; bal, int i);
+long	 balance_pair_len(balance_pair_t&amp; bal_pair);
+amount_t balance_pair_getitem(balance_pair_t&amp; bal_pair, int i);
+
+long value_len(value_t&amp; value)
+{
+  switch (value.type) {
+  case value_t::BOOLEAN:
+  case value_t::INTEGER:
+  case value_t::AMOUNT:
+    return 1;
+
+  case value_t::BALANCE:
+    return balance_len(*((balance_t *) value.data));
+
+  case value_t::BALANCE_PAIR:
+    return balance_pair_len(*((balance_pair_t *) value.data));
+
+  default:
+    assert(0);
+    break;
+  }
+  assert(0);
+  return 0;
+}
+
+amount_t value_getitem(value_t&amp; value, int i)
+{
+  std::size_t len = value_len(value);
+
+  if (abs(i) &gt;= len) {
+    PyErr_SetString(PyExc_IndexError, &quot;Index out of range&quot;);
+    throw_error_already_set();
+  }
+
+  switch (value.type) {
+  case value_t::BOOLEAN:
+  case value_t::INTEGER:
+    return long(value);
+
+  case value_t::AMOUNT:
+    return *((amount_t *) value.data);
+
+  case value_t::BALANCE:
+    return balance_getitem(*((balance_t *) value.data), i);
+
+  case value_t::BALANCE_PAIR:
+    return balance_pair_getitem(*((balance_pair_t *) value.data), i);
+
+  default:
+    assert(0);
+    break;
+  }
+  assert(0);
+  return 0L;
+}
+
+double py_to_float(value_t&amp; value)
+{
+  return double(value);
+}
+
+void export_value()
+{
+  scope in_value = class_&lt; value_t &gt; (&quot;Value&quot;)
+    .def(init&lt;value_t&gt;())
+    .def(init&lt;balance_pair_t&gt;())
+    .def(init&lt;balance_t&gt;())
+    .def(init&lt;amount_t&gt;())
+    .def(init&lt;std::string&gt;())
+    .def(init&lt;double&gt;())
+    .def(init&lt;long&gt;())
+
+    .def(self + self)
+    .def(self + other&lt;balance_pair_t&gt;())
+    .def(self + other&lt;balance_t&gt;())
+    .def(self + other&lt;amount_t&gt;())
+    .def(self + long())
+    .def(self + double())
+
+    .def(other&lt;balance_pair_t&gt;() + self)
+    .def(other&lt;balance_t&gt;() + self)
+    .def(other&lt;amount_t&gt;() + self)
+    .def(long() + self)
+    .def(double() + self)
+
+    .def(self - self)
+    .def(self - other&lt;balance_pair_t&gt;())
+    .def(self - other&lt;balance_t&gt;())
+    .def(self - other&lt;amount_t&gt;())
+    .def(self - long())
+    .def(self - double())
+
+    .def(other&lt;balance_pair_t&gt;() - self)
+    .def(other&lt;balance_t&gt;() - self)
+    .def(other&lt;amount_t&gt;() - self)
+    .def(long() - self)
+    .def(double() - self)
+
+    .def(self * self)
+    .def(self * other&lt;balance_pair_t&gt;())
+    .def(self * other&lt;balance_t&gt;())
+    .def(self * other&lt;amount_t&gt;())
+    .def(self * long())
+    .def(self * double())
+
+    .def(other&lt;balance_pair_t&gt;() * self)
+    .def(other&lt;balance_t&gt;() * self)
+    .def(other&lt;amount_t&gt;() * self)
+    .def(long() * self)
+    .def(double() * self)
+
+    .def(self / self)
+    .def(self / other&lt;balance_pair_t&gt;())
+    .def(self / other&lt;balance_t&gt;())
+    .def(self / other&lt;amount_t&gt;())
+    .def(self / long())
+    .def(self / double())
+
+    .def(other&lt;balance_pair_t&gt;() / self)
+    .def(other&lt;balance_t&gt;() / self)
+    .def(other&lt;amount_t&gt;() / self)
+    .def(long() / self)
+    .def(double() / self)
+
+    .def(- self)
+
+    .def(self += self)
+    .def(self += other&lt;balance_pair_t&gt;())
+    .def(self += other&lt;balance_t&gt;())
+    .def(self += other&lt;amount_t&gt;())
+    .def(self += long())
+    .def(self += double())
+
+    .def(self -= self)
+    .def(self -= other&lt;balance_pair_t&gt;())
+    .def(self -= other&lt;balance_t&gt;())
+    .def(self -= other&lt;amount_t&gt;())
+    .def(self -= long())
+    .def(self -= double())
+
+    .def(self *= self)
+    .def(self *= other&lt;balance_pair_t&gt;())
+    .def(self *= other&lt;balance_t&gt;())
+    .def(self *= other&lt;amount_t&gt;())
+    .def(self *= long())
+    .def(self *= double())
+
+    .def(self /= self)
+    .def(self /= other&lt;balance_pair_t&gt;())
+    .def(self /= other&lt;balance_t&gt;())
+    .def(self /= other&lt;amount_t&gt;())
+    .def(self /= long())
+    .def(self /= double())
+
+    .def(self &lt;  self)
+    .def(self &lt; other&lt;balance_pair_t&gt;())
+    .def(self &lt; other&lt;balance_t&gt;())
+    .def(self &lt; other&lt;amount_t&gt;())
+    .def(self &lt; long())
+    .def(self &lt; double())
+
+    .def(other&lt;balance_pair_t&gt;() &lt; self)
+    .def(other&lt;balance_t&gt;() &lt; self)
+    .def(other&lt;amount_t&gt;() &lt; self)
+    .def(long() &lt; self)
+    .def(double() &lt; self)
+
+    .def(self &lt;= self)
+    .def(self &lt;= other&lt;balance_pair_t&gt;())
+    .def(self &lt;= other&lt;balance_t&gt;())
+    .def(self &lt;= other&lt;amount_t&gt;())
+    .def(self &lt;= long())
+    .def(self &lt;= double())
+
+    .def(other&lt;balance_pair_t&gt;() &lt;= self)
+    .def(other&lt;balance_t&gt;() &lt;= self)
+    .def(other&lt;amount_t&gt;() &lt;= self)
+    .def(long() &lt;= self)
+    .def(double() &lt;= self)
+
+    .def(self &gt;  self)
+    .def(self &gt; other&lt;balance_pair_t&gt;())
+    .def(self &gt; other&lt;balance_t&gt;())
+    .def(self &gt; other&lt;amount_t&gt;())
+    .def(self &gt; long())
+    .def(self &gt; double())
+
+    .def(other&lt;balance_pair_t&gt;() &gt; self)
+    .def(other&lt;balance_t&gt;() &gt; self)
+    .def(other&lt;amount_t&gt;() &gt; self)
+    .def(long() &gt; self)
+    .def(double() &gt; self)
+
+    .def(self &gt;= self)
+    .def(self &gt;= other&lt;balance_pair_t&gt;())
+    .def(self &gt;= other&lt;balance_t&gt;())
+    .def(self &gt;= other&lt;amount_t&gt;())
+    .def(self &gt;= long())
+    .def(self &gt;= double())
+
+    .def(other&lt;balance_pair_t&gt;() &gt;= self)
+    .def(other&lt;balance_t&gt;() &gt;= self)
+    .def(other&lt;amount_t&gt;() &gt;= self)
+    .def(long() &gt;= self)
+    .def(double() &gt;= self)
+
+    .def(self == self)
+    .def(self == other&lt;balance_pair_t&gt;())
+    .def(self == other&lt;balance_t&gt;())
+    .def(self == other&lt;amount_t&gt;())
+    .def(self == long())
+    .def(self == double())
+
+    .def(other&lt;balance_pair_t&gt;() == self)
+    .def(other&lt;balance_t&gt;() == self)
+    .def(other&lt;amount_t&gt;() == self)
+    .def(long() == self)
+    .def(double() == self)
+
+    .def(self != self)
+    .def(self != other&lt;balance_pair_t&gt;())
+    .def(self != other&lt;balance_t&gt;())
+    .def(self != other&lt;amount_t&gt;())
+    .def(self != long())
+    .def(self != double())
+
+    .def(other&lt;balance_pair_t&gt;() != self)
+    .def(other&lt;balance_t&gt;() != self)
+    .def(other&lt;amount_t&gt;() != self)
+    .def(long() != self)
+    .def(double() != self)
+
+    .def(! self)
+
+    .def(self_ns::int_(self))
+    .def(self_ns::float_(self))
+    .def(self_ns::str(self))
+    .def(abs(self))
+
+    .def_readonly(&quot;type&quot;, &amp;value_t::type)
+
+    .def(&quot;__len__&quot;, value_len)
+    .def(&quot;__getitem__&quot;, value_getitem)
+
+    .def(&quot;cast&quot;, &amp;value_t::cast)
+    .def(&quot;negate&quot;, &amp;value_t::negate)
+    .def(&quot;price&quot;, &amp;value_t::price)
+    .def(&quot;cost&quot;, &amp;value_t::cost)
+    .def(&quot;add&quot;, &amp;value_t::add, return_internal_reference&lt;&gt;())
+    ;
+
+  enum_&lt; value_t::type_t &gt; (&quot;ValueType&quot;)
+    .value(&quot;BOOLEAN&quot;, value_t::BOOLEAN)
+    .value(&quot;INTEGER&quot;, value_t::INTEGER)
+    .value(&quot;AMOUNT&quot;, value_t::AMOUNT)
+    .value(&quot;BALANCE&quot;, value_t::BALANCE)
+    .value(&quot;BALANCE_PAIR&quot;, value_t::BALANCE_PAIR)
+    ;
+}
+
+#endif // USE_BOOST_PYTHON</diff>
      <filename>value.cc</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>9db08c4c7de7b2058363bec4a3000f48fc78d580</id>
    </parent>
  </parents>
  <author>
    <name>John Wiegley</name>
    <email>johnw@newartisans.com</email>
  </author>
  <url>http://github.com/jwiegley/ledger/commit/0c55a5ee1b5b35f399de7286cd8c6565a61e9634</url>
  <id>0c55a5ee1b5b35f399de7286cd8c6565a61e9634</id>
  <committed-date>2008-04-12T23:41:28-07:00</committed-date>
  <authored-date>2006-02-28T06:40:49-08:00</authored-date>
  <message>(read_binary_journal): Fixed a tiny memory leak when reading from a
binary cache.</message>
  <tree>47c247481db46d478133eddade540f90c34402b3</tree>
  <committer>
    <name>John Wiegley</name>
    <email>johnw@newartisans.com</email>
  </committer>
</commit>
