diff options
author | John Wiegley <johnw@newartisans.com> | 2009-11-10 14:16:40 -0500 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2009-11-10 14:16:40 -0500 |
commit | 91e8378f04d33137f8e6281928ae70af12be3b2b (patch) | |
tree | 1fe03ea8d7eeb21aa4f923373fbbd8c06f536d75 | |
parent | 5ffa987daf4d97c52066e4c28733d826d3726297 (diff) | |
download | fork-ledger-91e8378f04d33137f8e6281928ae70af12be3b2b.tar.gz fork-ledger-91e8378f04d33137f8e6281928ae70af12be3b2b.tar.bz2 fork-ledger-91e8378f04d33137f8e6281928ae70af12be3b2b.zip |
Fixes to Python importing; removed "hello" precommand
-rw-r--r-- | python/hello.py | 7 | ||||
-rw-r--r-- | python/server.py | 5 | ||||
-rw-r--r-- | src/pyinterp.cc | 169 | ||||
-rw-r--r-- | src/pyinterp.h | 50 | ||||
-rw-r--r-- | src/report.cc | 20 | ||||
-rw-r--r-- | src/report.h | 2 | ||||
-rw-r--r-- | tools/Makefile.am | 4 |
7 files changed, 142 insertions, 115 deletions
diff --git a/python/hello.py b/python/hello.py deleted file mode 100644 index b5b072bb..00000000 --- a/python/hello.py +++ /dev/null @@ -1,7 +0,0 @@ -import ledger - -def precmd_hello(): - hello = ledger.Value() - hello.set_string("Well, hello yourself! This is Ledger, coming to you from Python Land.") - print hello - return hello diff --git a/python/server.py b/python/server.py index 64a91ca3..3c6ddb91 100644 --- a/python/server.py +++ b/python/server.py @@ -20,7 +20,7 @@ class LedgerHandler(BaseHTTPRequestHandler): except Exception: print "Saw exception in POST handler" -def cmd_server(): +def main(*args): try: port = 9000 server = HTTPServer(('', port), LedgerHandler) @@ -31,3 +31,6 @@ def cmd_server(): print "Shutting down server" server.socket.close() +print __name__ +if __name__ == '__main__': + main() diff --git a/src/pyinterp.cc b/src/pyinterp.cc index 6a2dea03..394739c4 100644 --- a/src/pyinterp.cc +++ b/src/pyinterp.cc @@ -99,66 +99,75 @@ void python_interpreter_t::initialize() Py_Initialize(); assert(Py_IsInitialized()); + hack_system_paths(); + object main_module = python::import("__main__"); if (! main_module) - throw_(std::logic_error, + throw_(std::runtime_error, _("Python failed to initialize (couldn't find __main__)")); main_nspace = extract<dict>(main_module.attr("__dict__")); if (! main_nspace) - throw_(std::logic_error, + throw_(std::runtime_error, _("Python failed to initialize (couldn't find __dict__)")); python::detail::init_module("ledger", &initialize_for_python); is_initialized = true; + } + catch (const error_already_set&) { + PyErr_Print(); + throw_(std::runtime_error, _("Python failed to initialize")); + } - // Hack ledger.__path__ so it points to a real location - python::object module_sys = import("sys"); - python::object sys_dict = module_sys.attr("__dict__"); - - python::list paths(sys_dict["path"]); - - bool path_initialized = false; - int n = python::extract<int>(paths.attr("__len__")()); - for (int i = 0; i < n; i++) { - python::extract<std::string> str(paths[i]); - path pathname(str); - DEBUG("python.interp", "sys.path = " << pathname); + TRACE_FINISH(python_init, 1); +} - if (exists(pathname / "ledger" / "__init__.py")) { - if (python::object module_ledger = import("ledger")) { - DEBUG("python.interp", - "Setting ledger.__path__ = " << (pathname / "ledger")); +void python_interpreter_t::hack_system_paths() +{ + // Hack ledger.__path__ so it points to a real location + python::object sys_module = python::import("sys"); + python::object sys_dict = sys_module.attr("__dict__"); - python::object ledger_dict = module_ledger.attr("__dict__"); - python::list temp_list; - temp_list.append((pathname / "ledger").string()); + python::list paths(sys_dict["path"]); - ledger_dict["__path__"] = temp_list; - } else { - throw_(std::logic_error, - _("Python failed to initialize (couldn't find ledger)")); - } - path_initialized = true; - break; +#if defined(DEBUG_ON) + bool path_initialized = false; +#endif + int n = python::extract<int>(paths.attr("__len__")()); + for (int i = 0; i < n; i++) { + python::extract<std::string> str(paths[i]); + path pathname(str); + DEBUG("python.interp", "sys.path = " << pathname); + + if (exists(pathname / "ledger" / "__init__.py")) { + if (python::object module_ledger = python::import("ledger")) { + DEBUG("python.interp", + "Setting ledger.__path__ = " << (pathname / "ledger")); + + python::object ledger_dict = module_ledger.attr("__dict__"); + python::list temp_list; + temp_list.append((pathname / "ledger").string()); + + ledger_dict["__path__"] = temp_list; + } else { + throw_(std::runtime_error, + _("Python failed to initialize (couldn't find ledger)")); } - } #if defined(DEBUG_ON) - if (! path_initialized) - DEBUG("python.init", - "Ledger failed to find 'ledger/__init__.py' on the PYTHONPATH"); + path_initialized = true; #endif + break; + } } - catch (const error_already_set&) { - PyErr_Print(); - throw_(std::logic_error, _("Python failed to initialize")); - } - - TRACE_FINISH(python_init, 1); +#if defined(DEBUG_ON) + if (! path_initialized) + DEBUG("python.init", + "Ledger failed to find 'ledger/__init__.py' on the PYTHONPATH"); +#endif } -object python_interpreter_t::import(const string& str) +object python_interpreter_t::import_into_main(const string& str) { if (! is_initialized) initialize(); @@ -166,7 +175,8 @@ object python_interpreter_t::import(const string& str) try { object mod = python::import(str.c_str()); if (! mod) - throw_(std::logic_error, _("Failed to import Python module %1") << str); + throw_(std::runtime_error, + _("Failed to import Python module %1") << str); // Import all top-level entries directly into the main namespace main_nspace.update(mod.attr("__dict__")); @@ -179,6 +189,32 @@ object python_interpreter_t::import(const string& str) return object(); } +object python_interpreter_t::import_option(const string& str) +{ + path file(str); + + python::object sys_module = python::import("sys"); + python::object sys_dict = sys_module.attr("__dict__"); + + python::list paths(sys_dict["path"]); + +#if BOOST_VERSION >= 103700 + paths.insert(0, file.parent_path().string()); + sys_dict["path"] = paths; + + string name = file.filename(); + if (contains(name, ".py")) + name = file.stem(); +#else // BOOST_VERSION >= 103700 + paths.insert(0, file.branch_path().string()); + sys_dict["path"] = paths; + + string name = file.leaf(); +#endif // BOOST_VERSION >= 103700 + + return python::import(python::str(name.c_str())); +} + object python_interpreter_t::eval(std::istream& in, py_eval_mode_t mode) { bool first = true; @@ -212,7 +248,7 @@ object python_interpreter_t::eval(std::istream& in, py_eval_mode_t mode) } catch (const error_already_set&) { PyErr_Print(); - throw_(std::logic_error, _("Failed to evaluate Python code")); + throw_(std::runtime_error, _("Failed to evaluate Python code")); } return object(); } @@ -234,7 +270,7 @@ object python_interpreter_t::eval(const string& str, py_eval_mode_t mode) } catch (const error_already_set&) { PyErr_Print(); - throw_(std::logic_error, _("Failed to evaluate Python code")); + throw_(std::runtime_error, _("Failed to evaluate Python code")); } return object(); } @@ -255,7 +291,7 @@ value_t python_interpreter_t::python_command(call_scope_t& args) std::strcpy(argv[i + 1], arg.c_str()); } - int status; + int status = 1; try { status = Py_Main(static_cast<int>(args.size()) + 1, argv); @@ -277,6 +313,44 @@ value_t python_interpreter_t::python_command(call_scope_t& args) return NULL_VALUE; } +value_t python_interpreter_t::server_command(call_scope_t& args) +{ + if (! is_initialized) + initialize(); + + python::object server_module; + + try { + server_module = python::import("ledger.server"); + if (! server_module) + throw_(std::runtime_error, + _("Could not import ledger.server; please check your PYTHONPATH")); + } + catch (const error_already_set&) { + PyErr_Print(); + throw_(std::runtime_error, + _("Could not import ledger.server; please check your PYTHONPATH")); + } + + if (python::object main_function = server_module.attr("main")) { + functor_t func(main_function, "main"); + try { + func(args); + } + catch (const error_already_set&) { + PyErr_Print(); + throw_(std::runtime_error, + _("Error while invoking ledger.server's main() function")); + } + return true; + } else { + throw_(std::runtime_error, + _("The ledger.server module is missing its main() function!")); + } + + return false; +} + option_t<python_interpreter_t> * python_interpreter_t::lookup_option(const char * p) { @@ -304,7 +378,7 @@ expr_t::ptr_op_t python_interpreter_t::lookup(const symbol_t::kind_t kind, DEBUG("python.interp", "Python lookup: " << name); if (python::object obj = main_nspace.get(name.c_str())) - return WRAP_FUNCTOR(functor_t(name, obj)); + return WRAP_FUNCTOR(functor_t(obj, name)); } break; @@ -320,6 +394,11 @@ expr_t::ptr_op_t python_interpreter_t::lookup(const symbol_t::kind_t kind, if (is_eq(p, "python")) return MAKE_FUNCTOR(python_interpreter_t::python_command); break; + + case 's': + if (is_eq(p, "server")) + return MAKE_FUNCTOR(python_interpreter_t::server_command); + break; } } @@ -349,7 +428,7 @@ namespace { dynamic_cast<const auto_xact_t *>(scope)) lst.append(ptr(auto_xact)); else - throw_(std::runtime_error, + throw_(std::logic_error, _("Cannot downcast scoped object to specific type")); } else { lst.append(value); diff --git a/src/pyinterp.h b/src/pyinterp.h index 002e8af1..f2d7b760 100644 --- a/src/pyinterp.h +++ b/src/pyinterp.h @@ -57,8 +57,10 @@ public: } void initialize(); + void hack_system_paths(); - python::object import(const string& name); + python::object import_into_main(const string& name); + python::object import_option(const string& name); enum py_eval_mode_t { PY_EVAL_EXPR, @@ -67,16 +69,17 @@ public: }; python::object eval(std::istream& in, - py_eval_mode_t mode = PY_EVAL_EXPR); + py_eval_mode_t mode = PY_EVAL_EXPR); python::object eval(const string& str, - py_eval_mode_t mode = PY_EVAL_EXPR); + py_eval_mode_t mode = PY_EVAL_EXPR); python::object eval(const char * c_str, - py_eval_mode_t mode = PY_EVAL_EXPR) { + py_eval_mode_t mode = PY_EVAL_EXPR) { string str(c_str); return eval(str, mode); } value_t python_command(call_scope_t& scope); + value_t server_command(call_scope_t& args); class functor_t { functor_t(); @@ -87,9 +90,9 @@ public: public: string name; - functor_t(const string& _name, python::object _func) + functor_t(python::object _func, const string& _name) : func(_func), name(_name) { - TRACE_CTOR(functor_t, "const string&, python::object"); + TRACE_CTOR(functor_t, "python::object, const string&"); } functor_t(const functor_t& other) : func(other.func), name(other.name) { @@ -106,41 +109,10 @@ public: virtual expr_t::ptr_op_t lookup(const symbol_t::kind_t kind, const string& name); -#if BOOST_VERSION >= 103700 OPTION_(python_interpreter_t, import_, DO_(scope) { - interactive_t args(scope, "s"); - - path file(args.get<string>(0)); - - python::object module_sys = parent->import("sys"); - python::object sys_dict = module_sys.attr("__dict__"); - - python::list paths(sys_dict["path"]); - paths.insert(0, file.parent_path().string()); - sys_dict["path"] = paths; - - string name = file.filename(); - if (contains(name, ".py")) - parent->import(file.stem()); - else - parent->import(name); - }); -#else // BOOST_VERSION >= 103700 - OPTION_(python_interpreter_t, import_, DO_(scope) { - interactive_t args(scope, "s"); - - path file(args.get<string>(0)); - - python::object module_sys = parent->import("sys"); - python::object sys_dict = module_sys.attr("__dict__"); - - python::list paths(sys_dict["path"]); - paths.insert(0, file.branch_path().string()); - sys_dict["path"] = paths; - - parent->import(file.leaf()); + interactive_t args(scope, "ss"); + parent->import_option(args.get<string>(1)); }); -#endif // BOOST_VERSION >= 103700 }; extern shared_ptr<python_interpreter_t> python_session; diff --git a/src/report.cc b/src/report.cc index e05b4bc1..0f04a212 100644 --- a/src/report.cc +++ b/src/report.cc @@ -453,15 +453,6 @@ value_t report_t::echo_command(call_scope_t& scope) return true; } -bool report_t::maybe_import(const string& module) -{ - if (lookup(symbol_t::OPTION, "import_")) { - expr_t(string("import_(\"") + module + "\")").calc(*this); - return true; - } - return false; -} - option_t<report_t> * report_t::lookup_option(const char * p) { switch (*p) { @@ -930,8 +921,6 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind, (reporter<post_t, post_handler_ptr, &report_t::commodities_report> (new format_posts(*this, report_format(HANDLER(pricesdb_format_))), *this, "#pricesdb")); - else if (is_eq(p, "python") && maybe_import("ledger.interp")) - return session.lookup(symbol_t::COMMAND, "python"); break; case 'r': @@ -947,9 +936,8 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind, case 's': if (is_eq(p, "stats") || is_eq(p, "stat")) return WRAP_FUNCTOR(report_statistics); - else - if (is_eq(p, "server") && maybe_import("ledger.server")) - return session.lookup(symbol_t::COMMAND, "server"); + else if (is_eq(p, "server")) + return session.lookup(symbol_t::COMMAND, "server"); break; case 'x': @@ -981,10 +969,6 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind, (reporter<post_t, post_handler_ptr, &report_t::generate_report> (new format_posts(*this, report_format(HANDLER(print_format_)), false), *this, "#generate")); - case 'h': - if (is_eq(p, "hello") && maybe_import("ledger.hello")) - return session.lookup(symbol_t::PRECOMMAND, "hello"); - break; case 'p': if (is_eq(p, "parse")) return WRAP_FUNCTOR(parse_command); diff --git a/src/report.h b/src/report.h index 38b2b07e..02fd2c8d 100644 --- a/src/report.h +++ b/src/report.h @@ -183,8 +183,6 @@ public: HANDLED(lots_actual)); } - bool maybe_import(const string& module); - void report_options(std::ostream& out) { HANDLER(abbrev_len_).report(out); diff --git a/tools/Makefile.am b/tools/Makefile.am index 8c042a94..8c28277b 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -235,9 +235,7 @@ ledger_la_DEPENDENCIES = $(lib_LTLIBRARIES) ledger_la_LDFLAGS = -avoid-version -module ledger_la_LIBADD = $(LIBOBJS) $(lib_LTLIBRARIES) $(INTLLIBS) -pkgpython_PYTHON = python/__init__.py \ - python/hello.py \ - python/server.py +pkgpython_PYTHON = python/__init__.py python/server.py endif |