Commit a370e90b authored by Kevin Modzelewski's avatar Kevin Modzelewski

some basic -m support

parent 329f4095
...@@ -11,10 +11,10 @@ typedef PyObject *(*getter)(PyObject *, void *); ...@@ -11,10 +11,10 @@ typedef PyObject *(*getter)(PyObject *, void *);
typedef int (*setter)(PyObject *, PyObject *, void *); typedef int (*setter)(PyObject *, PyObject *, void *);
typedef struct PyGetSetDef { typedef struct PyGetSetDef {
char *name; const char *name;
getter get; getter get;
setter set; setter set;
char *doc; const char *doc;
void *closure; void *closure;
} PyGetSetDef; } PyGetSetDef;
......
...@@ -222,6 +222,41 @@ int handleArg(char code) { ...@@ -222,6 +222,41 @@ int handleArg(char code) {
return 0; return 0;
} }
static int RunModule(const char* module, int set_argv0) {
PyObject* runpy, *runmodule, *runargs, *result;
runpy = PyImport_ImportModule("runpy");
if (runpy == NULL) {
fprintf(stderr, "Could not import runpy module\n");
return -1;
}
runmodule = PyObject_GetAttrString(runpy, "_run_module_as_main");
if (runmodule == NULL) {
fprintf(stderr, "Could not access runpy._run_module_as_main\n");
Py_DECREF(runpy);
return -1;
}
runargs = Py_BuildValue("(si)", module, set_argv0);
if (runargs == NULL) {
fprintf(stderr, "Could not create arguments for runpy._run_module_as_main\n");
Py_DECREF(runpy);
Py_DECREF(runmodule);
return -1;
}
result = PyObject_Call(runmodule, runargs, NULL);
if (result == NULL) {
PyErr_Print();
}
Py_DECREF(runpy);
Py_DECREF(runmodule);
Py_DECREF(runargs);
if (result == NULL) {
return -1;
}
Py_DECREF(result);
return 0;
}
static int main(int argc, char** argv) { static int main(int argc, char** argv) {
argv0 = argv[0]; argv0 = argv[0];
...@@ -239,6 +274,7 @@ static int main(int argc, char** argv) { ...@@ -239,6 +274,7 @@ static int main(int argc, char** argv) {
int code; int code;
const char* command = NULL; const char* command = NULL;
const char* module = NULL;
char* env_args = getenv("PYSTON_RUN_ARGS"); char* env_args = getenv("PYSTON_RUN_ARGS");
...@@ -253,12 +289,17 @@ static int main(int argc, char** argv) { ...@@ -253,12 +289,17 @@ static int main(int argc, char** argv) {
// Suppress getopt errors so we can throw them ourselves // Suppress getopt errors so we can throw them ourselves
opterr = 0; opterr = 0;
while ((code = getopt(argc, argv, "+:OqdIibpjtrsSvnxEc:FuPTG")) != -1) { while ((code = getopt(argc, argv, "+:OqdIibpjtrsSvnxEc:FuPTGm:")) != -1) {
if (code == 'c') { if (code == 'c') {
assert(optarg); assert(optarg);
command = optarg; command = optarg;
// no more option parsing; the rest of our arguments go into sys.argv. // no more option parsing; the rest of our arguments go into sys.argv.
break; break;
} else if (code == 'm') {
assert(optarg);
module = optarg;
// no more option parsing; the rest of our arguments go into sys.argv.
break;
} else if (code == ':') { } else if (code == ':') {
fprintf(stderr, "Argument expected for the -%c option\n", optopt); fprintf(stderr, "Argument expected for the -%c option\n", optopt);
return 2; return 2;
...@@ -299,7 +340,10 @@ static int main(int argc, char** argv) { ...@@ -299,7 +340,10 @@ static int main(int argc, char** argv) {
// are parsed. // are parsed.
if (command) if (command)
addToSysArgv("-c"); addToSysArgv("-c");
else if (optind != argc) { else if (module) {
// CPython does this...
addToSysArgv("-c");
} else if (optind != argc) {
addToSysArgv(argv[optind]); addToSysArgv(argv[optind]);
if (strcmp("-", argv[optind]) != 0) if (strcmp("-", argv[optind]) != 0)
fn = argv[optind]; fn = argv[optind];
...@@ -352,10 +396,22 @@ static int main(int argc, char** argv) { ...@@ -352,10 +396,22 @@ static int main(int argc, char** argv) {
AST_Module* m = parse_string(command); AST_Module* m = parse_string(command);
compileAndRunModule(m, main_module); compileAndRunModule(m, main_module);
} catch (ExcInfo e) { } catch (ExcInfo e) {
int retcode = 1; if (!force_repl) {
(void)handle_toplevel_exn(e, &retcode); int retcode = 1;
Stats::dump(false); (void)handle_toplevel_exn(e, &retcode);
return retcode; Stats::dump(false);
return retcode;
}
}
} else if (module != NULL) {
// TODO: CPython uses the same main module for all code paths
main_module = createModule("__main__", "<string>");
bool sts = (RunModule(module, 1) != 0);
printf("TODO check this\n");
if (!force_repl) {
if (sts)
return 1;
return 0;
} }
} }
......
...@@ -1572,6 +1572,10 @@ static PyObject* file_isatty(BoxedFile* f) noexcept { ...@@ -1572,6 +1572,10 @@ static PyObject* file_isatty(BoxedFile* f) noexcept {
return PyBool_FromLong(res); return PyBool_FromLong(res);
} }
static PyObject* get_closed(BoxedFile* f, void* closure) noexcept {
return PyBool_FromLong((long)(f->f_fp == 0));
}
PyDoc_STRVAR(seek_doc, "seek(offset[, whence]) -> None. Move to new file position.\n" PyDoc_STRVAR(seek_doc, "seek(offset[, whence]) -> None. Move to new file position.\n"
"\n" "\n"
"Argument offset is a byte count. Optional argument whence defaults to\n" "Argument offset is a byte count. Optional argument whence defaults to\n"
...@@ -1592,13 +1596,17 @@ PyDoc_STRVAR(readlines_doc, "readlines([size]) -> list of strings, each a line f ...@@ -1592,13 +1596,17 @@ PyDoc_STRVAR(readlines_doc, "readlines([size]) -> list of strings, each a line f
PyDoc_STRVAR(isatty_doc, "isatty() -> true or false. True if the file is connected to a tty device."); PyDoc_STRVAR(isatty_doc, "isatty() -> true or false. True if the file is connected to a tty device.");
PyMethodDef file_methods[] = { static PyMethodDef file_methods[] = {
{ "seek", (PyCFunction)file_seek, METH_VARARGS, seek_doc }, { "seek", (PyCFunction)file_seek, METH_VARARGS, seek_doc },
{ "readlines", (PyCFunction)file_readlines, METH_VARARGS, readlines_doc }, { "readlines", (PyCFunction)file_readlines, METH_VARARGS, readlines_doc },
{ "writelines", (PyCFunction)file_writelines, METH_O, NULL }, { "writelines", (PyCFunction)file_writelines, METH_O, NULL },
{ "isatty", (PyCFunction)file_isatty, METH_NOARGS, isatty_doc }, { "isatty", (PyCFunction)file_isatty, METH_NOARGS, isatty_doc },
}; };
static PyGetSetDef file_getsetlist[] = {
{ "closed", (getter)get_closed, NULL, "True if the file is closed", NULL },
};
void fileDestructor(Box* b) { void fileDestructor(Box* b) {
assert(isSubclass(b->cls, file_cls)); assert(isSubclass(b->cls, file_cls));
BoxedFile* self = static_cast<BoxedFile*>(b); BoxedFile* self = static_cast<BoxedFile*>(b);
...@@ -1657,6 +1665,11 @@ void setupFile() { ...@@ -1657,6 +1665,11 @@ void setupFile() {
file_cls->giveAttr(md.ml_name, new BoxedMethodDescriptor(&md, file_cls)); file_cls->giveAttr(md.ml_name, new BoxedMethodDescriptor(&md, file_cls));
} }
for (auto& getset : file_getsetlist) {
file_cls->giveAttr(getset.name, new (capi_getset_cls) BoxedGetsetDescriptor(
getset.get, (void (*)(Box*, Box*, void*))getset.set, getset.closure));
}
file_cls->freeze(); file_cls->freeze();
} }
......
...@@ -1530,28 +1530,43 @@ public: ...@@ -1530,28 +1530,43 @@ public:
return boxInt(attrs->hcls->getStrAttrOffsets().size()); return boxInt(attrs->hcls->getStrAttrOffsets().size());
} }
static Box* update(Box* _self, Box* _container) { static Box* update(Box* _self, BoxedTuple* args, BoxedDict* kwargs) {
STAT_TIMER(t0, "us_timer_AttrWrapper_update"); STAT_TIMER(t0, "us_timer_AttrWrapper_update");
RELEASE_ASSERT(_self->cls == attrwrapper_cls, ""); RELEASE_ASSERT(_self->cls == attrwrapper_cls, "");
AttrWrapper* self = static_cast<AttrWrapper*>(_self); AttrWrapper* self = static_cast<AttrWrapper*>(_self);
if (_container->cls == attrwrapper_cls) { assert(args->cls == tuple_cls);
AttrWrapper* container = static_cast<AttrWrapper*>(_container); assert(kwargs);
HCAttrs* attrs = container->b->getHCAttrsPtr(); assert(kwargs->cls == dict_cls);
RELEASE_ASSERT(attrs->hcls->type == HiddenClass::NORMAL || attrs->hcls->type == HiddenClass::SINGLETON, ""); RELEASE_ASSERT(args->size() <= 1, ""); // should throw a TypeError
for (const auto& p : attrs->hcls->getStrAttrOffsets()) {
self->b->setattr(p.first(), attrs->attr_list->attrs[p.second], NULL); auto handle = [&](Box* _container) {
} if (_container->cls == attrwrapper_cls) {
} else if (_container->cls == dict_cls) { AttrWrapper* container = static_cast<AttrWrapper*>(_container);
BoxedDict* container = static_cast<BoxedDict*>(_container); HCAttrs* attrs = container->b->getHCAttrsPtr();
for (const auto& p : container->d) { RELEASE_ASSERT(attrs->hcls->type == HiddenClass::NORMAL || attrs->hcls->type == HiddenClass::SINGLETON,
AttrWrapper::setitem(self, p.first, p.second); "");
for (const auto& p : attrs->hcls->getStrAttrOffsets()) {
self->b->setattr(p.first(), attrs->attr_list->attrs[p.second], NULL);
}
} else if (_container->cls == dict_cls) {
BoxedDict* container = static_cast<BoxedDict*>(_container);
for (const auto& p : container->d) {
AttrWrapper::setitem(self, p.first, p.second);
}
} else {
RELEASE_ASSERT(0, "not implemented: %s", _container->cls->tp_name);
} }
} else { };
RELEASE_ASSERT(0, "not implemented: %s", _container->cls->tp_name);
for (auto e : *args) {
handle(e);
} }
handle(kwargs);
return None; return None;
} }
...@@ -2481,7 +2496,8 @@ void setupRuntime() { ...@@ -2481,7 +2496,8 @@ void setupRuntime() {
attrwrapper_cls->giveAttr("copy", new BoxedFunction(boxRTFunction((void*)AttrWrapper::copy, UNKNOWN, 1))); attrwrapper_cls->giveAttr("copy", new BoxedFunction(boxRTFunction((void*)AttrWrapper::copy, UNKNOWN, 1)));
attrwrapper_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)AttrWrapper::len, BOXED_INT, 1))); attrwrapper_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)AttrWrapper::len, BOXED_INT, 1)));
attrwrapper_cls->giveAttr("__iter__", new BoxedFunction(boxRTFunction((void*)AttrWrapper::iter, UNKNOWN, 1))); attrwrapper_cls->giveAttr("__iter__", new BoxedFunction(boxRTFunction((void*)AttrWrapper::iter, UNKNOWN, 1)));
attrwrapper_cls->giveAttr("update", new BoxedFunction(boxRTFunction((void*)AttrWrapper::update, NONE, 2))); attrwrapper_cls->giveAttr("update",
new BoxedFunction(boxRTFunction((void*)AttrWrapper::update, NONE, 1, 0, true, true)));
attrwrapper_cls->freeze(); attrwrapper_cls->freeze();
attrwrapperiter_cls->giveAttr("__hasnext__", attrwrapperiter_cls->giveAttr("__hasnext__",
......
import os
import sys
import subprocess
me = sys.executable
with open('/dev/null')as ignore:
def run(args):
print subprocess.call([me] + args, stderr=ignore)
# just prints out the usage
run(["-m", "pydoc"])
run(["-m", "doesnt_exist"])
os.environ["PYTHONPATH"] = os.path.dirname(__file__)
run(["-m", "import_target"])
...@@ -95,7 +95,7 @@ l.sort() ...@@ -95,7 +95,7 @@ l.sort()
print l print l
c = C1() c = C1()
c.__dict__.update(dict(a=1, b=5)) c.__dict__.update(dict(a=1, b=5), d=4)
print sorted(c.__dict__.items()) print sorted(c.__dict__.items())
class TestClass3: # old-style class TestClass3: # old-style
......
...@@ -91,3 +91,5 @@ try: ...@@ -91,3 +91,5 @@ try:
print "succeeded" print "succeeded"
except Exception as e: except Exception as e:
print e print e
print sys.stdout.closed
# expected: fail
import sys
print sys.stdout.closed
...@@ -20,3 +20,8 @@ __all__ = ['x', u'z'] ...@@ -20,3 +20,8 @@ __all__ = ['x', u'z']
def letMeCallThatForYou(f, *args): def letMeCallThatForYou(f, *args):
return f(*args) return f(*args)
if __name__ == "__main__":
import sys
print "running import_target as main"
print "argv:", sys.argv
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment