Commit c67278b5 authored by Chris Toshok's avatar Chris Toshok

add support for relative imports, and bring our import api closer to cpython.

parent af25c3d3
...@@ -1279,7 +1279,13 @@ public: ...@@ -1279,7 +1279,13 @@ public:
import->args.push_back(new AST_Num()); import->args.push_back(new AST_Num());
static_cast<AST_Num*>(import->args[0])->num_type = AST_Num::INT; static_cast<AST_Num*>(import->args[0])->num_type = AST_Num::INT;
static_cast<AST_Num*>(import->args[0])->n_int = -1;
int level;
if (!(future_flags & FF_ABSOLUTE_IMPORT))
level = -1;
else
level = 0;
static_cast<AST_Num*>(import->args[0])->n_int = level;
import->args.push_back(new AST_LangPrimitive(AST_LangPrimitive::NONE)); import->args.push_back(new AST_LangPrimitive(AST_LangPrimitive::NONE));
import->args.push_back(new AST_Str(a->name.str())); import->args.push_back(new AST_Str(a->name.str()));
...@@ -1316,8 +1322,6 @@ public: ...@@ -1316,8 +1322,6 @@ public:
} }
bool visit_importfrom(AST_ImportFrom* node) override { bool visit_importfrom(AST_ImportFrom* node) override {
RELEASE_ASSERT(node->level == 0, "");
AST_LangPrimitive* import = new AST_LangPrimitive(AST_LangPrimitive::IMPORT_NAME); AST_LangPrimitive* import = new AST_LangPrimitive(AST_LangPrimitive::IMPORT_NAME);
import->lineno = node->lineno; import->lineno = node->lineno;
import->col_offset = node->col_offset; import->col_offset = node->col_offset;
......
...@@ -472,9 +472,6 @@ Box* bltinImport(Box* name, Box* globals, Box* locals, Box** args) { ...@@ -472,9 +472,6 @@ Box* bltinImport(Box* name, Box* globals, Box* locals, Box** args) {
Box* fromlist = args[0]; Box* fromlist = args[0];
Box* level = args[1]; Box* level = args[1];
RELEASE_ASSERT(globals == None, "not implemented");
RELEASE_ASSERT(locals == None, "not implemented");
if (name->cls != str_cls) { if (name->cls != str_cls) {
raiseExcHelper(TypeError, "__import__() argument 1 must be string, not %s", getTypeName(name)); raiseExcHelper(TypeError, "__import__() argument 1 must be string, not %s", getTypeName(name));
} }
...@@ -483,7 +480,7 @@ Box* bltinImport(Box* name, Box* globals, Box* locals, Box** args) { ...@@ -483,7 +480,7 @@ Box* bltinImport(Box* name, Box* globals, Box* locals, Box** args) {
raiseExcHelper(TypeError, "an integer is required"); raiseExcHelper(TypeError, "an integer is required");
} }
return import(((BoxedInt*)level)->n, fromlist, &static_cast<BoxedString*>(name)->s); return importModuleLevel(&static_cast<BoxedString*>(name)->s, globals, fromlist, ((BoxedInt*)level)->n);
} }
Box* delattrFunc(Box* obj, Box* _str) { Box* delattrFunc(Box* obj, Box* _str) {
......
...@@ -838,7 +838,7 @@ extern "C" PyObject* PyImport_Import(PyObject* module_name) noexcept { ...@@ -838,7 +838,7 @@ extern "C" PyObject* PyImport_Import(PyObject* module_name) noexcept {
RELEASE_ASSERT(module_name->cls == str_cls, ""); RELEASE_ASSERT(module_name->cls == str_cls, "");
try { try {
return import(-1, None, &static_cast<BoxedString*>(module_name)->s); return importModuleLevel(&static_cast<BoxedString*>(module_name)->s, None, None, -1);
} catch (ExcInfo e) { } catch (ExcInfo e) {
Py_FatalError("unimplemented"); Py_FatalError("unimplemented");
} }
......
This diff is collapsed.
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
namespace pyston { namespace pyston {
extern "C" Box* import(int level, Box* from_imports, const std::string* module_name); extern "C" Box* import(int level, Box* from_imports, const std::string* module_name);
extern Box* importModuleLevel(std::string* module_name, Box* globals, Box* from_imports, int level);
} }
#endif #endif
...@@ -82,9 +82,7 @@ class MyClass(object): ...@@ -82,9 +82,7 @@ class MyClass(object):
# Except if it's a dotted name: # Except if it's a dotted name:
import __foo.__bar import __foo.__bar
except ImportError, e: except ImportError, e:
# CPython says "no module named __foo.__bar__" but Pyston (and PyPy) say "no module named __foo". print e.message
# Canonicalize it slightly:
print e.message.split('.')[0]
# names inside classes with mangled names don't get the mangled class name: # names inside classes with mangled names don't get the mangled class name:
class MyClass(object): class MyClass(object):
......
# expected: fail
# - crashes rather than throws an error
try: try:
from . import doesnt_exist from . import doesnt_exist
except ImportError, e: except ValueError, e:
print e print e
# expected: fail import os
# - packages not supported
# - intra-package imports ("from . import foo") not supported
# - "from __future__ import absolute_import" not supported
import test_package import test_package
print test_package print 1, test_package.__name__, os.path.normpath(test_package.__file__)
import test_package.intrapackage_import import test_package.intrapackage_import
import test_package.absolute_import import test_package.absolute_import
......
import relative_import1_pkg
# Import names from pkg.string
from .string import name1, name2
# Import pkg.string
#from . import string
print "string.py"
def name1():
pass
def name2():
pass
from relative_import2_pkg import foo
import relative_import3_pkg
print "A.stuff"
all = [ 'func1' ]
def func1():
pass
print "C.py"
all = ['name1']
def name1():
pass
#from . import name3
#from ..B import name2
print "C.name1.py"
print "relative_import3_package.__init__"
from A.stuff import func1
from C import name1
import relative_import4_pkg
import re
print type(re.compile)
import os
import import_target import import_target
print import_target print 3, import_target.__name__, os.path.normpath(import_target.__file__)
from __future__ import absolute_import from __future__ import absolute_import
import os
import import_target import import_target
print import_target print 4, import_target.__name__, os.path.normpath(import_target.__file__)
import os
from . import import_target from . import import_target
print import_target print 2, import_target.__name__, os.path.normpath(import_target.__file__)
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