Commit 20516086 authored by Jeremy Hylton's avatar Jeremy Hylton

Update magic number.

Fix import support to work with import as variant of Python 2.0.  The
grammar for import changed, requiring changes in transformer and code
generator, even to handle compilation of imports with as.
parent 7527e000
import os import os
import marshal import marshal
import stat import stat
import string
import struct import struct
import types import types
from cStringIO import StringIO from cStringIO import StringIO
...@@ -44,7 +45,7 @@ class Module: ...@@ -44,7 +45,7 @@ class Module:
f.write(self.getPycHeader()) f.write(self.getPycHeader())
marshal.dump(self.code, f) marshal.dump(self.code, f)
MAGIC = (50811 | (ord('\r')<<16) | (ord('\n')<<24)) MAGIC = (50823 | (ord('\r')<<16) | (ord('\n')<<24))
def getPycHeader(self): def getPycHeader(self):
# compile.c uses marshal to write a long directly, with # compile.c uses marshal to write a long directly, with
...@@ -420,19 +421,32 @@ class CodeGenerator: ...@@ -420,19 +421,32 @@ class CodeGenerator:
def visitImport(self, node): def visitImport(self, node):
self.set_lineno(node) self.set_lineno(node)
for name in node.names: for name, alias in node.names:
self.emit('LOAD_CONST', None)
self.emit('IMPORT_NAME', name) self.emit('IMPORT_NAME', name)
self.storeName(name) self._resolveDots(name)
self.storeName(alias or name)
def visitFrom(self, node): def visitFrom(self, node):
self.set_lineno(node) self.set_lineno(node)
fromlist = map(lambda (name, alias): name, node.names)
self.emit('LOAD_CONST', tuple(fromlist))
self.emit('IMPORT_NAME', node.modname) self.emit('IMPORT_NAME', node.modname)
for name in node.names: for name, alias in node.names:
if name == '*': if name == '*':
self.namespace = 0 self.namespace = 0
self.emit('IMPORT_FROM', name) self.emit('IMPORT_FROM', name)
self._resolveDots(name)
self.storeName(alias or name)
self.emit('POP_TOP') self.emit('POP_TOP')
def _resolveDots(self, name):
elts = string.split(name, ".")
if len(elts) == 1:
return
for elt in elts[1:]:
self.emit('LOAD_ATTR', elt)
def visitGetattr(self, node): def visitGetattr(self, node):
self.visit(node.expr) self.visit(node.expr)
self.emit('LOAD_ATTR', node.attrname) self.emit('LOAD_ATTR', node.attrname)
...@@ -787,12 +801,12 @@ class LocalNameFinder: ...@@ -787,12 +801,12 @@ class LocalNameFinder:
pass pass
def visitImport(self, node): def visitImport(self, node):
for name in node.names: for name, alias in node.names:
self.names.add(name) self.names.add(alias or name)
def visitFrom(self, node): def visitFrom(self, node):
for name in node.names: for name, alias in node.names:
self.names.add(name) self.names.add(alias or name)
def visitClass(self, node): def visitClass(self, node):
self.names.add(node.name) self.names.add(node.name)
......
...@@ -402,19 +402,20 @@ class Transformer: ...@@ -402,19 +402,20 @@ class Transformer:
return n return n
def import_stmt(self, nodelist): def import_stmt(self, nodelist):
# import: dotted_name (',' dotted_name)* | # import_stmt: 'import' dotted_as_name (',' dotted_as_name)* |
# from: dotted_name 'import' ('*' | NAME (',' NAME)*) # from: 'from' dotted_name 'import'
names = [ ] # ('*' | import_as_name (',' import_as_name)*)
if nodelist[0][1][0] == 'f': names = []
is_as = 0
if nodelist[0][1] == 'from':
for i in range(3, len(nodelist), 2): for i in range(3, len(nodelist), 2):
# note: nodelist[i] could be (token.STAR, '*') or (token.NAME, name) names.append(self.com_import_as_name(nodelist[i][1]))
names.append(nodelist[i][1])
n = Node('from', self.com_dotted_name(nodelist[1]), names) n = Node('from', self.com_dotted_name(nodelist[1]), names)
n.lineno = nodelist[0][2] n.lineno = nodelist[0][2]
return n return n
for i in range(1, len(nodelist), 2): for i in range(1, len(nodelist), 2):
names.append(self.com_dotted_name(nodelist[i])) names.append(self.com_dotted_as_name(nodelist[i]))
n = Node('import', names) n = Node('import', names)
n.lineno = nodelist[0][2] n.lineno = nodelist[0][2]
return n return n
...@@ -738,6 +739,7 @@ class Transformer: ...@@ -738,6 +739,7 @@ class Transformer:
if node[0] not in _legal_node_types: if node[0] not in _legal_node_types:
raise error, 'illegal node passed to com_node: %s' % node[0] raise error, 'illegal node passed to com_node: %s' % node[0]
# print "dispatch", self._dispatch[node[0]].__name__, node
return self._dispatch[node[0]](node[1:]) return self._dispatch[node[0]](node[1:])
def com_arglist(self, nodelist): def com_arglist(self, nodelist):
...@@ -814,6 +816,22 @@ class Transformer: ...@@ -814,6 +816,22 @@ class Transformer:
name = name + n[1] + '.' name = name + n[1] + '.'
return name[:-1] return name[:-1]
def com_dotted_as_name(self, node):
dot = self.com_dotted_name(node[1])
if len(node) == 2:
return dot, None
assert node[2][1] == 'as'
assert node[3][0] == token.NAME
return dot, node[3][1]
def com_import_as_name(self, node):
if node[0] == token.NAME:
return node[1], None
assert len(node) == 4
assert node[2][1] == 'as'
assert node[3][0] == token.NAME
return node[1][1], node[3][1]
def com_bases(self, node): def com_bases(self, node):
bases = [ ] bases = [ ]
for i in range(1, len(node), 2): for i in range(1, len(node), 2):
......
import os import os
import marshal import marshal
import stat import stat
import string
import struct import struct
import types import types
from cStringIO import StringIO from cStringIO import StringIO
...@@ -44,7 +45,7 @@ class Module: ...@@ -44,7 +45,7 @@ class Module:
f.write(self.getPycHeader()) f.write(self.getPycHeader())
marshal.dump(self.code, f) marshal.dump(self.code, f)
MAGIC = (50811 | (ord('\r')<<16) | (ord('\n')<<24)) MAGIC = (50823 | (ord('\r')<<16) | (ord('\n')<<24))
def getPycHeader(self): def getPycHeader(self):
# compile.c uses marshal to write a long directly, with # compile.c uses marshal to write a long directly, with
...@@ -420,19 +421,32 @@ class CodeGenerator: ...@@ -420,19 +421,32 @@ class CodeGenerator:
def visitImport(self, node): def visitImport(self, node):
self.set_lineno(node) self.set_lineno(node)
for name in node.names: for name, alias in node.names:
self.emit('LOAD_CONST', None)
self.emit('IMPORT_NAME', name) self.emit('IMPORT_NAME', name)
self.storeName(name) self._resolveDots(name)
self.storeName(alias or name)
def visitFrom(self, node): def visitFrom(self, node):
self.set_lineno(node) self.set_lineno(node)
fromlist = map(lambda (name, alias): name, node.names)
self.emit('LOAD_CONST', tuple(fromlist))
self.emit('IMPORT_NAME', node.modname) self.emit('IMPORT_NAME', node.modname)
for name in node.names: for name, alias in node.names:
if name == '*': if name == '*':
self.namespace = 0 self.namespace = 0
self.emit('IMPORT_FROM', name) self.emit('IMPORT_FROM', name)
self._resolveDots(name)
self.storeName(alias or name)
self.emit('POP_TOP') self.emit('POP_TOP')
def _resolveDots(self, name):
elts = string.split(name, ".")
if len(elts) == 1:
return
for elt in elts[1:]:
self.emit('LOAD_ATTR', elt)
def visitGetattr(self, node): def visitGetattr(self, node):
self.visit(node.expr) self.visit(node.expr)
self.emit('LOAD_ATTR', node.attrname) self.emit('LOAD_ATTR', node.attrname)
...@@ -787,12 +801,12 @@ class LocalNameFinder: ...@@ -787,12 +801,12 @@ class LocalNameFinder:
pass pass
def visitImport(self, node): def visitImport(self, node):
for name in node.names: for name, alias in node.names:
self.names.add(name) self.names.add(alias or name)
def visitFrom(self, node): def visitFrom(self, node):
for name in node.names: for name, alias in node.names:
self.names.add(name) self.names.add(alias or name)
def visitClass(self, node): def visitClass(self, node):
self.names.add(node.name) self.names.add(node.name)
......
...@@ -402,19 +402,20 @@ class Transformer: ...@@ -402,19 +402,20 @@ class Transformer:
return n return n
def import_stmt(self, nodelist): def import_stmt(self, nodelist):
# import: dotted_name (',' dotted_name)* | # import_stmt: 'import' dotted_as_name (',' dotted_as_name)* |
# from: dotted_name 'import' ('*' | NAME (',' NAME)*) # from: 'from' dotted_name 'import'
names = [ ] # ('*' | import_as_name (',' import_as_name)*)
if nodelist[0][1][0] == 'f': names = []
is_as = 0
if nodelist[0][1] == 'from':
for i in range(3, len(nodelist), 2): for i in range(3, len(nodelist), 2):
# note: nodelist[i] could be (token.STAR, '*') or (token.NAME, name) names.append(self.com_import_as_name(nodelist[i][1]))
names.append(nodelist[i][1])
n = Node('from', self.com_dotted_name(nodelist[1]), names) n = Node('from', self.com_dotted_name(nodelist[1]), names)
n.lineno = nodelist[0][2] n.lineno = nodelist[0][2]
return n return n
for i in range(1, len(nodelist), 2): for i in range(1, len(nodelist), 2):
names.append(self.com_dotted_name(nodelist[i])) names.append(self.com_dotted_as_name(nodelist[i]))
n = Node('import', names) n = Node('import', names)
n.lineno = nodelist[0][2] n.lineno = nodelist[0][2]
return n return n
...@@ -738,6 +739,7 @@ class Transformer: ...@@ -738,6 +739,7 @@ class Transformer:
if node[0] not in _legal_node_types: if node[0] not in _legal_node_types:
raise error, 'illegal node passed to com_node: %s' % node[0] raise error, 'illegal node passed to com_node: %s' % node[0]
# print "dispatch", self._dispatch[node[0]].__name__, node
return self._dispatch[node[0]](node[1:]) return self._dispatch[node[0]](node[1:])
def com_arglist(self, nodelist): def com_arglist(self, nodelist):
...@@ -814,6 +816,22 @@ class Transformer: ...@@ -814,6 +816,22 @@ class Transformer:
name = name + n[1] + '.' name = name + n[1] + '.'
return name[:-1] return name[:-1]
def com_dotted_as_name(self, node):
dot = self.com_dotted_name(node[1])
if len(node) == 2:
return dot, None
assert node[2][1] == 'as'
assert node[3][0] == token.NAME
return dot, node[3][1]
def com_import_as_name(self, node):
if node[0] == token.NAME:
return node[1], None
assert len(node) == 4
assert node[2][1] == 'as'
assert node[3][0] == token.NAME
return node[1][1], node[3][1]
def com_bases(self, node): def com_bases(self, node):
bases = [ ] bases = [ ]
for i in range(1, len(node), 2): for i in range(1, len(node), 2):
......
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