Skip to content

Fixes from time import *; print sleep #80

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Oct 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions grumpy-runtime-src/runtime/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,58 @@ func importOne(f *Frame, name string) (*Object, *BaseException) {
return o, nil
}

// LoadMembers scans over all the members in module
// and populates globals with them, taking __all__ into
// account.
func LoadMembers(f *Frame, module *Object) *BaseException {
allAttr, raised := GetAttr(f, module, NewStr("__all__"), nil)
if raised != nil && !raised.isInstance(AttributeErrorType) {
return raised
}
f.RestoreExc(nil, nil)

if raised == nil {
raised = loadMembersFromIterable(f, module, allAttr, nil)
if raised != nil {
return raised
}
return nil
}

// Fall back on __dict__
dictAttr := module.dict.ToObject()
raised = loadMembersFromIterable(f, module, dictAttr, func(key *Object) bool {
return strings.HasPrefix(toStrUnsafe(key).value, "_")
})
if raised != nil {
return raised
}
return nil
}

func loadMembersFromIterable(f *Frame, module, iterable *Object, filterF func(*Object) bool) *BaseException {
globals := f.Globals()
raised := seqForEach(f, iterable, func(memberName *Object) *BaseException {
if !memberName.isInstance(StrType) {
errorMessage := fmt.Sprintf("attribute name must be string, not '%v'", memberName.typ.Name())
return f.RaiseType(AttributeErrorType, errorMessage)
}
member, raised := GetAttr(f, module, toStrUnsafe(memberName), nil)
if raised != nil {
return raised
}
if filterF != nil && filterF(memberName) {
return nil
}
raised = globals.SetItem(f, memberName, member)
if raised != nil {
return raised
}
return nil
})
return raised
}

// newModule creates a new Module object with the given fully qualified name
// (e.g a.b.c) and its corresponding Python filename and package.
func newModule(name, filename string) *Module {
Expand Down
1 change: 0 additions & 1 deletion grumpy-runtime-src/runtime/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ func TestImportModule(t *testing.T) {
}
}
}

func TestModuleGetNameAndFilename(t *testing.T) {
fun := wrapFuncForTest(func(f *Frame, m *Module) (*Tuple, *BaseException) {
name, raised := m.GetName(f)
Expand Down
10 changes: 9 additions & 1 deletion grumpy-tools-src/grumpy_tools/compiler/imputil.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class Import(object):

MODULE = "<BindType 'module'>"
MEMBER = "<BindType 'member'>"
STAR = "<BindType 'star'>"

def __init__(self, name, script=None, is_native=False):
self.name = name
Expand Down Expand Up @@ -104,7 +105,14 @@ def visit_Import(self, node):

def visit_ImportFrom(self, node):
if any(a.name == '*' for a in node.names):
raise util.ImportError(node, 'wildcard member import is not implemented')
if len(node.names) != 1:
# TODO: Change to SyntaxError, as CPython does on "from foo import *, bar"
raise util.ImportError(node, 'invalid syntax on wildcard import')

# Imported name is * (star). Will bind __all__ the module contents.
imp = self._resolve_import(node, node.module)
imp.add_binding(Import.STAR, '*', imp.name.count('.'))
return [imp]

if not node.level and node.module == '__future__':
return []
Expand Down
5 changes: 2 additions & 3 deletions grumpy-tools-src/grumpy_tools/compiler/imputil_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,8 @@ def testImportFromAsMembers(self):
imp.add_binding(imputil.Import.MEMBER, 'baz', 'bar')
self._check_imports('from foo import bar as baz', [imp])

def testImportFromWildcardRaises(self):
self.assertRaises(util.ImportError, self.importer.visit,
pythonparser.parse('from foo import *').body[0])
# def testImportFromWildcardRaises(self):
# self._check_imports('from foo import *', [])

def testImportFromFuture(self):
self._check_imports('from __future__ import print_function', [])
Expand Down
2 changes: 2 additions & 0 deletions grumpy-tools-src/grumpy_tools/compiler/stmt.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,8 @@ def _import_and_bind(self, imp):
self.writer.write('{} = {}[{}]'.format(
mod.name, mod_slice.expr, binding.value))
self.block.bind_var(self.writer, binding.alias, mod.expr)
elif binding.bind_type == imputil.Import.STAR:
self.writer.write_checked_call1('πg.LoadMembers(πF, {}[0])', mod_slice.name)
else:
self.writer.write('{} = {}[{}]'.format(
mod.name, mod_slice.expr, imp.name.count('.')))
Expand Down
14 changes: 7 additions & 7 deletions grumpy-tools-src/grumpy_tools/compiler/stmt_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,19 +333,19 @@ def testImportNativeType(self):
from "__go__/time" import Duration
print Duration""")))

def testImportWildcardMemberRaises(self):
regexp = 'wildcard member import is not implemented'
self.assertRaisesRegexp(util.ImportError, regexp, _ParseAndVisit,
'from foo import *')
self.assertRaisesRegexp(util.ImportError, regexp, _ParseAndVisit,
'from "__go__/foo" import *')

def testPrintStatement(self):
self.assertEqual((0, 'abc 123\nfoo bar\n'), _GrumpRun(textwrap.dedent("""\
print 'abc',
print '123'
print 'foo', 'bar'""")))

def testImportWildcard(self):
result = _GrumpRun(textwrap.dedent("""\
from time import *
print sleep"""))
self.assertEqual(0, result[0])
self.assertIn('<function sleep at', result[1])

def testPrintFunction(self):
want = "abc\n123\nabc 123\nabcx123\nabc 123 "
self.assertEqual((0, want), _GrumpRun(textwrap.dedent("""\
Expand Down