diff options
author | John Wiegley <johnw@newartisans.com> | 2009-11-05 17:16:59 -0500 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2009-11-05 17:16:59 -0500 |
commit | 1bdb9330e56e49ecd660f3aafdc2d349a20e3044 (patch) | |
tree | f352e064a65bc7f3a87a634b1fcc689bb2441305 /src | |
parent | 312d4c5f5339c61253e86cd9ce825370eb4be053 (diff) | |
download | fork-ledger-1bdb9330e56e49ecd660f3aafdc2d349a20e3044.tar.gz fork-ledger-1bdb9330e56e49ecd660f3aafdc2d349a20e3044.tar.bz2 fork-ledger-1bdb9330e56e49ecd660f3aafdc2d349a20e3044.zip |
Simplified passing of scope objects in Python
Diffstat (limited to 'src')
-rw-r--r-- | src/py_account.cc | 10 | ||||
-rw-r--r-- | src/py_amount.cc | 16 | ||||
-rw-r--r-- | src/py_balance.cc | 12 | ||||
-rw-r--r-- | src/py_commodity.cc | 24 | ||||
-rw-r--r-- | src/py_flags.cc | 68 | ||||
-rw-r--r-- | src/py_post.cc | 4 | ||||
-rw-r--r-- | src/py_scope.cc | 55 | ||||
-rw-r--r-- | src/py_xact.cc | 2 | ||||
-rw-r--r-- | src/pyinterp.cc | 103 |
9 files changed, 97 insertions, 197 deletions
diff --git a/src/py_account.cc b/src/py_account.cc index 8310f5ec..d1d35cda 100644 --- a/src/py_account.cc +++ b/src/py_account.cc @@ -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) diff --git a/src/py_amount.cc b/src/py_amount.cc index c6b3284a..937ad484 100644 --- a/src/py_amount.cc +++ b/src/py_amount.cc @@ -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>()) diff --git a/src/py_balance.cc b/src/py_balance.cc index 6d0ad500..60df1317 100644 --- a/src/py_balance.cc +++ b/src/py_balance.cc @@ -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")) diff --git a/src/py_commodity.cc b/src/py_commodity.cc index c20053ad..08af8f62 100644 --- a/src/py_commodity.cc +++ b/src/py_commodity.cc @@ -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) ; } diff --git a/src/py_flags.cc b/src/py_flags.cc deleted file mode 100644 index 647be111..00000000 --- a/src/py_flags.cc +++ /dev/null @@ -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 diff --git a/src/py_post.cc b/src/py_post.cc index 64bdde83..80e7ee52 100644 --- a/src/py_post.cc +++ b/src/py_post.cc @@ -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<>()) ; } diff --git a/src/py_scope.cc b/src/py_scope.cc deleted file mode 100644 index c5c4fff6..00000000 --- a/src/py_scope.cc +++ /dev/null @@ -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 diff --git a/src/py_xact.cc b/src/py_xact.cc index f5453d15..d886bf90 100644 --- a/src/py_xact.cc +++ b/src/py_xact.cc @@ -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) diff --git a/src/pyinterp.cc b/src/pyinterp.cc index 8c79e9c7..3c86ed4b 100644 --- a/src/pyinterp.cc +++ b/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()); - - 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); + } + 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 { - 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&) { |