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 *);
typedef int (*setter)(PyObject *, PyObject *, void *);
typedef struct PyGetSetDef {
char *name;
const char *name;
getter get;
setter set;
char *doc;
const char *doc;
void *closure;
} PyGetSetDef;
......
......@@ -222,6 +222,41 @@ int handleArg(char code) {
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) {
argv0 = argv[0];
......@@ -239,6 +274,7 @@ static int main(int argc, char** argv) {
int code;
const char* command = NULL;
const char* module = NULL;
char* env_args = getenv("PYSTON_RUN_ARGS");
......@@ -253,12 +289,17 @@ static int main(int argc, char** argv) {
// Suppress getopt errors so we can throw them ourselves
opterr = 0;
while ((code = getopt(argc, argv, "+:OqdIibpjtrsSvnxEc:FuPTG")) != -1) {
while ((code = getopt(argc, argv, "+:OqdIibpjtrsSvnxEc:FuPTGm:")) != -1) {
if (code == 'c') {
assert(optarg);
command = optarg;
// no more option parsing; the rest of our arguments go into sys.argv.
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 == ':') {
fprintf(stderr, "Argument expected for the -%c option\n", optopt);
return 2;
......@@ -299,7 +340,10 @@ static int main(int argc, char** argv) {
// are parsed.
if (command)
addToSysArgv("-c");
else if (optind != argc) {
else if (module) {
// CPython does this...
addToSysArgv("-c");
} else if (optind != argc) {
addToSysArgv(argv[optind]);
if (strcmp("-", argv[optind]) != 0)
fn = argv[optind];
......@@ -352,10 +396,22 @@ static int main(int argc, char** argv) {
AST_Module* m = parse_string(command);
compileAndRunModule(m, main_module);
} catch (ExcInfo e) {
int retcode = 1;
(void)handle_toplevel_exn(e, &retcode);
Stats::dump(false);
return retcode;
if (!force_repl) {
int retcode = 1;
(void)handle_toplevel_exn(e, &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 {
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"
"\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
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 },
{ "readlines", (PyCFunction)file_readlines, METH_VARARGS, readlines_doc },
{ "writelines", (PyCFunction)file_writelines, METH_O, NULL },
{ "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) {
assert(isSubclass(b->cls, file_cls));
BoxedFile* self = static_cast<BoxedFile*>(b);
......@@ -1657,6 +1665,11 @@ void setupFile() {
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();
}
......
......@@ -1530,28 +1530,43 @@ public:
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");
RELEASE_ASSERT(_self->cls == attrwrapper_cls, "");
AttrWrapper* self = static_cast<AttrWrapper*>(_self);
if (_container->cls == attrwrapper_cls) {
AttrWrapper* container = static_cast<AttrWrapper*>(_container);
HCAttrs* attrs = container->b->getHCAttrsPtr();
assert(args->cls == tuple_cls);
assert(kwargs);
assert(kwargs->cls == dict_cls);
RELEASE_ASSERT(attrs->hcls->type == HiddenClass::NORMAL || attrs->hcls->type == HiddenClass::SINGLETON, "");
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);
RELEASE_ASSERT(args->size() <= 1, ""); // should throw a TypeError
auto handle = [&](Box* _container) {
if (_container->cls == attrwrapper_cls) {
AttrWrapper* container = static_cast<AttrWrapper*>(_container);
HCAttrs* attrs = container->b->getHCAttrsPtr();
for (const auto& p : container->d) {
AttrWrapper::setitem(self, p.first, p.second);
RELEASE_ASSERT(attrs->hcls->type == HiddenClass::NORMAL || attrs->hcls->type == HiddenClass::SINGLETON,
"");
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;
}
......@@ -2481,7 +2496,8 @@ void setupRuntime() {
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("__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();
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()
print l
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())
class TestClass3: # old-style
......
......@@ -91,3 +91,5 @@ try:
print "succeeded"
except Exception as e:
print e
print sys.stdout.closed
# expected: fail
import sys
print sys.stdout.closed
......@@ -20,3 +20,8 @@ __all__ = ['x', u'z']
def letMeCallThatForYou(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