Fixes to Python importing; removed "hello" precommand
This commit is contained in:
parent
5ffa987daf
commit
91e8378f04
7 changed files with 144 additions and 117 deletions
|
|
@ -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
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
173
src/pyinterp.cc
173
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;
|
||||
|
||||
// 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);
|
||||
|
||||
if (exists(pathname / "ledger" / "__init__.py")) {
|
||||
if (python::object module_ledger = 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::logic_error,
|
||||
_("Python failed to initialize (couldn't find ledger)"));
|
||||
}
|
||||
path_initialized = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if defined(DEBUG_ON)
|
||||
if (! path_initialized)
|
||||
DEBUG("python.init",
|
||||
"Ledger failed to find 'ledger/__init__.py' on the PYTHONPATH");
|
||||
#endif
|
||||
}
|
||||
catch (const error_already_set&) {
|
||||
PyErr_Print();
|
||||
throw_(std::logic_error, _("Python failed to initialize"));
|
||||
throw_(std::runtime_error, _("Python failed to initialize"));
|
||||
}
|
||||
|
||||
TRACE_FINISH(python_init, 1);
|
||||
}
|
||||
|
||||
object python_interpreter_t::import(const string& str)
|
||||
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::list paths(sys_dict["path"]);
|
||||
|
||||
#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)
|
||||
path_initialized = true;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
#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_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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
interactive_t args(scope, "ss");
|
||||
parent->import_option(args.get<string>(1));
|
||||
});
|
||||
#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());
|
||||
});
|
||||
#endif // BOOST_VERSION >= 103700
|
||||
};
|
||||
|
||||
extern shared_ptr<python_interpreter_t> python_session;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue