Simplified passing of scope objects in Python
This commit is contained in:
parent
312d4c5f53
commit
1bdb9330e5
10 changed files with 96 additions and 198 deletions
|
|
@ -189,9 +189,9 @@ void export_account()
|
|||
.def("remove_account", &account_t::remove_account)
|
||||
|
||||
.def("find_account", &account_t::find_account,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
.def("find_account_re", &account_t::find_account,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
|
||||
.def("add_post", &account_t::add_post)
|
||||
.def("remove_post", &account_t::remove_post)
|
||||
|
|
@ -211,15 +211,15 @@ void export_account()
|
|||
.def("has_xdata", &account_t::has_xdata)
|
||||
.def("clear_xdata", &account_t::clear_xdata)
|
||||
.def("xdata", py_xdata,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
|
||||
.def("amount", &account_t::amount)
|
||||
.def("total", &account_t::total)
|
||||
|
||||
.def("self_details", &account_t::self_details,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
.def("family_details", &account_t::family_details,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
|
||||
.def("has_xflags", &account_t::has_xflags)
|
||||
.def("children_with_flags", &account_t::children_with_flags)
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ void export_amount()
|
|||
class_< amount_t > ("Amount")
|
||||
.add_static_property("current_pool",
|
||||
make_getter(&amount_t::current_pool,
|
||||
return_value_policy<reference_existing_object>()))
|
||||
return_internal_reference<>()))
|
||||
|
||||
.def("initialize", py_amount_initialize) // only for the PyUnitTests
|
||||
.staticmethod("initialize")
|
||||
|
|
@ -204,7 +204,7 @@ internal precision."))
|
|||
|
||||
.def("negated", &amount_t::negated)
|
||||
.def("in_place_negate", &amount_t::in_place_negate,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
.def(- self)
|
||||
|
||||
.def("abs", &amount_t::abs)
|
||||
|
|
@ -214,23 +214,23 @@ internal precision."))
|
|||
|
||||
.def("rounded", &amount_t::rounded)
|
||||
.def("in_place_round", &amount_t::in_place_round,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
|
||||
.def("truncated", &amount_t::truncated)
|
||||
.def("in_place_truncate", &amount_t::in_place_truncate,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
|
||||
.def("unrounded", &amount_t::unrounded)
|
||||
.def("in_place_unround", &amount_t::in_place_unround,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
|
||||
.def("reduced", &amount_t::reduced)
|
||||
.def("in_place_reduce", &amount_t::in_place_reduce,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
|
||||
.def("unreduced", &amount_t::unreduced)
|
||||
.def("in_place_unreduce", &amount_t::in_place_unreduce,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
|
||||
.def("value", py_value_0)
|
||||
.def("value", py_value_1, args("primary_only"))
|
||||
|
|
@ -259,7 +259,7 @@ internal precision."))
|
|||
.def("quantity_string", &amount_t::quantity_string)
|
||||
|
||||
.def("commodity", &amount_t::commodity,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
.def("has_commodity", &amount_t::has_commodity)
|
||||
.def("set_commodity", &amount_t::set_commodity,
|
||||
with_custodian_and_ward<1, 2>())
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ void export_balance()
|
|||
|
||||
.def("negated", &balance_t::negated)
|
||||
.def("in_place_negate", &balance_t::in_place_negate,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
.def(- self)
|
||||
|
||||
.def("abs", &balance_t::abs)
|
||||
|
|
@ -170,23 +170,23 @@ void export_balance()
|
|||
|
||||
.def("rounded", &balance_t::rounded)
|
||||
.def("in_place_round", &balance_t::in_place_round,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
|
||||
.def("truncated", &balance_t::truncated)
|
||||
.def("in_place_truncate", &balance_t::in_place_truncate,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
|
||||
.def("unrounded", &balance_t::unrounded)
|
||||
.def("in_place_unround", &balance_t::in_place_unround,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
|
||||
.def("reduced", &balance_t::reduced)
|
||||
.def("in_place_reduce", &balance_t::in_place_reduce,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
|
||||
.def("unreduced", &balance_t::unreduced)
|
||||
.def("in_place_unreduce", &balance_t::in_place_unreduce,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
|
||||
.def("value", py_value_0)
|
||||
.def("value", py_value_1, args("primary_only"))
|
||||
|
|
|
|||
|
|
@ -157,23 +157,23 @@ void export_commodity()
|
|||
|
||||
.def("make_qualified_name", &commodity_pool_t::make_qualified_name)
|
||||
|
||||
.def("create", py_create_1, return_value_policy<reference_existing_object>())
|
||||
.def("create", py_create_2, return_value_policy<reference_existing_object>())
|
||||
.def("create", py_create_1, return_internal_reference<>())
|
||||
.def("create", py_create_2, return_internal_reference<>())
|
||||
|
||||
.def("find_or_create", py_find_or_create_1,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
.def("find_or_create", py_find_or_create_2,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
|
||||
.def("find", py_find_1, return_value_policy<reference_existing_object>())
|
||||
.def("find", py_find_2, return_value_policy<reference_existing_object>())
|
||||
.def("find", py_find_1, return_internal_reference<>())
|
||||
.def("find", py_find_2, return_internal_reference<>())
|
||||
|
||||
.def("exchange", py_exchange_3, with_custodian_and_ward<1, 2>())
|
||||
.def("exchange", py_exchange_5)
|
||||
|
||||
.def("parse_price_directive", &commodity_pool_t::parse_price_directive)
|
||||
.def("parse_price_expression", &commodity_pool_t::parse_price_expression,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
;
|
||||
|
||||
scope().attr("COMMODITY_STYLE_DEFAULTS") = COMMODITY_STYLE_DEFAULTS;
|
||||
|
|
@ -211,16 +211,16 @@ void export_commodity()
|
|||
|
||||
#if 0
|
||||
.def("referent", &commodity_t::referent,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
#endif
|
||||
|
||||
.def("is_annotated", &commodity_t::is_annotated)
|
||||
.def("strip_annotations", &commodity_t::strip_annotations,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
.def("write_annotations", &commodity_t::write_annotations)
|
||||
|
||||
.def("pool", &commodity_t::pool,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
|
||||
.def("base_symbol", &commodity_t::base_symbol)
|
||||
.def("symbol", &commodity_t::symbol)
|
||||
|
|
@ -308,11 +308,11 @@ void export_commodity()
|
|||
|
||||
#if 0
|
||||
.def("referent", &annotated_commodity_t::referent,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
#endif
|
||||
|
||||
.def("strip_annotations", &annotated_commodity_t::strip_annotations,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
.def("write_annotations", &annotated_commodity_t::write_annotations)
|
||||
;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of New Artisans LLC nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <system.hh>
|
||||
|
||||
#include "pyinterp.h"
|
||||
|
||||
namespace ledger {
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
#define EXC_TRANSLATOR(type) \
|
||||
void exc_translate_ ## type(const type& err) { \
|
||||
PyErr_SetString(PyExc_ArithmeticError, err.what()); \
|
||||
}
|
||||
|
||||
//EXC_TRANSLATOR(flags_error)
|
||||
|
||||
void export_flags()
|
||||
{
|
||||
#if 0
|
||||
class_< supports_flags > ("SupportsFlags")
|
||||
;
|
||||
class_< basic_flags_t > ("BasicFlags")
|
||||
;
|
||||
class_< delegates_flags > ("DelegatesFlags")
|
||||
;
|
||||
#endif
|
||||
|
||||
//register_optional_to_python<amount_t>();
|
||||
|
||||
//implicitly_convertible<string, amount_t>();
|
||||
|
||||
#define EXC_TRANSLATE(type) \
|
||||
register_exception_translator<type>(&exc_translate_ ## type);
|
||||
|
||||
//EXC_TRANSLATE(flags_error);
|
||||
}
|
||||
|
||||
} // namespace ledger
|
||||
|
|
@ -169,13 +169,13 @@ void export_post()
|
|||
.def("has_xdata", &post_t::has_xdata)
|
||||
.def("clear_xdata", &post_t::clear_xdata)
|
||||
.def("xdata", py_xdata,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
|
||||
.def("add_to_value", &post_t::add_to_value)
|
||||
.def("set_reported_account", &post_t::set_reported_account)
|
||||
|
||||
.def("reported_account", py_reported_account,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of New Artisans LLC nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <system.hh>
|
||||
|
||||
#include "pyinterp.h"
|
||||
|
||||
namespace ledger {
|
||||
|
||||
using namespace boost::python;
|
||||
|
||||
namespace {
|
||||
}
|
||||
|
||||
void export_scope()
|
||||
{
|
||||
class_< scope_t, boost::noncopyable > ("Scope", no_init)
|
||||
#if 0
|
||||
.def("is_posting", )
|
||||
.def("is_transaction", )
|
||||
.def("is_account", )
|
||||
.def("is_journal", )
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
} // namespace ledger
|
||||
|
|
@ -91,7 +91,7 @@ void export_xact()
|
|||
|
||||
.def("__len__", posts_len)
|
||||
.def("__getitem__", posts_getitem,
|
||||
return_value_policy<reference_existing_object>())
|
||||
return_internal_reference<>())
|
||||
|
||||
.def("add_post", &xact_base_t::add_post, with_custodian_and_ward<1, 2>())
|
||||
.def("remove_post", &xact_base_t::add_post)
|
||||
|
|
|
|||
101
src/pyinterp.cc
101
src/pyinterp.cc
|
|
@ -32,6 +32,9 @@
|
|||
#include <system.hh>
|
||||
|
||||
#include "pyinterp.h"
|
||||
#include "account.h"
|
||||
#include "xact.h"
|
||||
#include "post.h"
|
||||
|
||||
namespace ledger {
|
||||
|
||||
|
|
@ -46,12 +49,10 @@ void export_amount();
|
|||
void export_balance();
|
||||
void export_commodity();
|
||||
void export_expr();
|
||||
void export_flags();
|
||||
void export_format();
|
||||
void export_item();
|
||||
void export_journal();
|
||||
void export_post();
|
||||
void export_scope();
|
||||
void export_times();
|
||||
void export_utils();
|
||||
void export_value();
|
||||
|
|
@ -64,22 +65,14 @@ void initialize_for_python()
|
|||
export_balance();
|
||||
export_commodity();
|
||||
export_expr();
|
||||
export_flags();
|
||||
export_format();
|
||||
export_item();
|
||||
export_journal();
|
||||
export_post();
|
||||
export_scope();
|
||||
export_times();
|
||||
export_utils();
|
||||
export_value();
|
||||
export_xact();
|
||||
|
||||
#if 0
|
||||
// jww (2009-11-04): This is not valid unless I export the session object.
|
||||
// But I think Python scripters will interace with a journal instead.
|
||||
scope().attr("current_session") = python_session;
|
||||
#endif
|
||||
}
|
||||
|
||||
struct python_run
|
||||
|
|
@ -323,11 +316,39 @@ expr_t::ptr_op_t python_interpreter_t::lookup(const symbol_t::kind_t kind,
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
namespace {
|
||||
void append_value(list& lst, const value_t& value)
|
||||
{
|
||||
if (value.is_scope()) {
|
||||
const scope_t * scope = value.as_scope();
|
||||
if (const post_t * post = dynamic_cast<const post_t *>(scope))
|
||||
lst.append(ptr(post));
|
||||
else if (const xact_t * xact = dynamic_cast<const xact_t *>(scope))
|
||||
lst.append(ptr(xact));
|
||||
else if (const account_t * account =
|
||||
dynamic_cast<const account_t *>(scope))
|
||||
lst.append(ptr(account));
|
||||
else if (const period_xact_t * period_xact =
|
||||
dynamic_cast<const period_xact_t *>(scope))
|
||||
lst.append(ptr(period_xact));
|
||||
else if (const auto_xact_t * auto_xact =
|
||||
dynamic_cast<const auto_xact_t *>(scope))
|
||||
lst.append(ptr(auto_xact));
|
||||
else
|
||||
throw_(std::runtime_error,
|
||||
_("Cannot downcast scoped object to specific type"));
|
||||
} else {
|
||||
lst.append(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
value_t python_interpreter_t::functor_t::operator()(call_scope_t& args)
|
||||
{
|
||||
try {
|
||||
std::signal(SIGINT, SIG_DFL);
|
||||
|
||||
if (! PyCallable_Check(func.ptr())) {
|
||||
extract<value_t> val(func);
|
||||
std::signal(SIGINT, sigint_handler);
|
||||
|
|
@ -341,40 +362,42 @@ value_t python_interpreter_t::functor_t::operator()(call_scope_t& args)
|
|||
throw_(calc_error,
|
||||
_("Could not evaluate Python variable '%1'") << name);
|
||||
#endif
|
||||
} else {
|
||||
if (args.size() > 0) {
|
||||
list arglist;
|
||||
if (args.value().is_sequence())
|
||||
foreach (const value_t& value, args.value().as_sequence())
|
||||
arglist.append(value);
|
||||
else
|
||||
arglist.append(args.value());
|
||||
}
|
||||
else if (args.size() > 0) {
|
||||
list arglist;
|
||||
// jww (2009-11-05): What about a single argument which is a sequence,
|
||||
// rather than a sequence of arguments?
|
||||
if (args.value().is_sequence())
|
||||
foreach (const value_t& value, args.value().as_sequence())
|
||||
append_value(arglist, value);
|
||||
else
|
||||
append_value(arglist, args.value());
|
||||
|
||||
if (PyObject * val =
|
||||
PyObject_CallObject(func.ptr(), python::tuple(arglist).ptr())) {
|
||||
extract<value_t> xval(val);
|
||||
value_t result;
|
||||
if (xval.check()) {
|
||||
result = xval();
|
||||
Py_DECREF(val);
|
||||
} else {
|
||||
Py_DECREF(val);
|
||||
throw_(calc_error,
|
||||
_("Could not evaluate Python variable '%1'") << name);
|
||||
}
|
||||
std::signal(SIGINT, sigint_handler);
|
||||
return result;
|
||||
}
|
||||
else if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
throw_(calc_error, _("Failed call to Python function '%1'") << name);
|
||||
if (PyObject * val =
|
||||
PyObject_CallObject(func.ptr(), python::tuple(arglist).ptr())) {
|
||||
extract<value_t> xval(val);
|
||||
value_t result;
|
||||
if (xval.check()) {
|
||||
result = xval();
|
||||
Py_DECREF(val);
|
||||
} else {
|
||||
assert(false);
|
||||
Py_DECREF(val);
|
||||
throw_(calc_error,
|
||||
_("Could not evaluate Python variable '%1'") << name);
|
||||
}
|
||||
} else {
|
||||
std::signal(SIGINT, sigint_handler);
|
||||
return call<value_t>(func.ptr());
|
||||
return result;
|
||||
}
|
||||
else if (PyErr_Occurred()) {
|
||||
PyErr_Print();
|
||||
throw_(calc_error, _("Failed call to Python function '%1'") << name);
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::signal(SIGINT, sigint_handler);
|
||||
return call<value_t>(func.ptr());
|
||||
}
|
||||
}
|
||||
catch (const error_already_set&) {
|
||||
|
|
|
|||
|
|
@ -210,12 +210,10 @@ libledger_python_la_SOURCES = \
|
|||
src/py_balance.cc \
|
||||
src/py_commodity.cc \
|
||||
src/py_expr.cc \
|
||||
src/py_flags.cc \
|
||||
src/py_format.cc \
|
||||
src/py_item.cc \
|
||||
src/py_journal.cc \
|
||||
src/py_post.cc \
|
||||
src/py_scope.cc \
|
||||
src/py_times.cc \
|
||||
src/py_utils.cc \
|
||||
src/py_value.cc \
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue