Commit e884efb9 authored by Stefan Behnel's avatar Stefan Behnel

prevent absolute cimports from trying relative imports

parent 6528682e
......@@ -7087,6 +7087,7 @@ class EnsureGILNode(GILExitNode):
def generate_execution_code(self, code):
code.put_ensure_gil(declare_gilstate=False)
utility_code_for_cimports = {
# utility code (or inlining c) in a pxd (or pyx) file.
# TODO: Consider a generic user-level mechanism for importing
......@@ -7094,19 +7095,23 @@ utility_code_for_cimports = {
'cpython.array.array' : ("ArrayAPI", "arrayarray.h"),
}
class CImportStatNode(StatNode):
# cimport statement
#
# module_name string Qualified name of module being imported
# as_name string or None Name specified in "as" clause, if any
# is_absolute bool True for absolute imports, False otherwise
child_attrs = []
is_absolute = False
def analyse_declarations(self, env):
if not env.is_module_scope:
error(self.pos, "cimport only allowed at module level")
return
module_scope = env.find_module(self.module_name, self.pos)
module_scope = env.find_module(
self.module_name, self.pos, relative_level=0 if self.is_absolute else -1)
if "." in self.module_name:
names = [EncodedString(name) for name in self.module_name.split(".")]
top_name = names[0]
......
......@@ -1279,38 +1279,43 @@ def p_raise_statement(s):
else:
return Nodes.ReraiseStatNode(pos)
def p_import_statement(s):
# s.sy in ('import', 'cimport')
pos = s.position()
kind = s.sy
s.next()
items = [p_dotted_name(s, as_allowed = 1)]
items = [p_dotted_name(s, as_allowed=1)]
while s.sy == ',':
s.next()
items.append(p_dotted_name(s, as_allowed = 1))
items.append(p_dotted_name(s, as_allowed=1))
stats = []
is_absolute = Future.absolute_import in s.context.future_directives
for pos, target_name, dotted_name, as_name in items:
dotted_name = EncodedString(dotted_name)
if kind == 'cimport':
stat = Nodes.CImportStatNode(pos,
module_name = dotted_name,
as_name = as_name)
stat = Nodes.CImportStatNode(
pos,
module_name=dotted_name,
as_name=as_name,
is_absolute=is_absolute)
else:
if as_name and "." in dotted_name:
name_list = ExprNodes.ListNode(pos, args = [
ExprNodes.IdentifierStringNode(pos, value = EncodedString("*"))])
name_list = ExprNodes.ListNode(pos, args=[
ExprNodes.IdentifierStringNode(pos, value=EncodedString("*"))])
else:
name_list = None
stat = Nodes.SingleAssignmentNode(pos,
lhs = ExprNodes.NameNode(pos,
name = as_name or target_name),
rhs = ExprNodes.ImportNode(pos,
module_name = ExprNodes.IdentifierStringNode(
pos, value = dotted_name),
level = None,
name_list = name_list))
stat = Nodes.SingleAssignmentNode(
pos,
lhs=ExprNodes.NameNode(pos, name=as_name or target_name),
rhs=ExprNodes.ImportNode(
pos,
module_name=ExprNodes.IdentifierStringNode(pos, value=dotted_name),
level=0 if is_absolute else None,
name_list=name_list))
stats.append(stat)
return Nodes.StatListNode(pos, stats = stats)
return Nodes.StatListNode(pos, stats=stats)
def p_from_import_statement(s, first_statement = 0):
# s.sy == 'from'
......
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