Commit d17e481c authored by Robert Bradshaw's avatar Robert Bradshaw

Better error when using non-existant attributes from cimported modules.

When not imported, this caused was a runtime NameError.  Now an error
is given at compile time.
parent 71383c16
......@@ -1858,6 +1858,9 @@ class NameNode(AtomicExprNode):
self.entry = env.declare_var(self.name, type, self.pos)
if self.entry.is_declared_generic:
self.result_ctype = py_object_type
if self.entry.as_module:
# cimported modules namespace can shadow actual variables
self.entry.is_variable = 1
def analyse_types(self, env):
self.initialized_check = env.directives['initializedcheck']
......@@ -1963,10 +1966,16 @@ class NameNode(AtomicExprNode):
or entry.is_cpp_class):
if self.entry.as_variable:
self.entry = self.entry.as_variable
else:
elif not self.is_cython_module:
error(self.pos,
"'%s' is not a constant, variable or function identifier" % self.name)
def is_cimported_module_without_shadow(self, env):
if self.is_cython_module or self.cython_attribute:
return False
entry = self.entry or env.lookup(self.name)
return entry.as_module and not entry.is_variable
def is_simple(self):
# If it's not a C variable, it'll be in a temp.
return 1
......@@ -6374,6 +6383,9 @@ class AttributeNode(ExprNode):
entry.is_cglobal or entry.is_cfunction
or entry.is_type or entry.is_const):
return self.as_name_node(env, entry, target)
if self.is_cimported_module_without_shadow(env):
error(self.pos, "cimported module has no attribute '%s'" % self.attribute)
return self
return None
def analyse_as_type_attribute(self, env):
......@@ -6610,6 +6622,9 @@ class AttributeNode(ExprNode):
gil_message = "Accessing Python attribute"
def is_cimported_module_without_shadow(self, env):
return self.obj.is_cimported_module_without_shadow(env)
def is_simple(self):
if self.obj:
return self.result_in_temp() or self.obj.is_simple()
......
......@@ -1255,6 +1255,7 @@ class ModuleScope(Scope):
return entry
else:
entry = self.declare_var(name, py_object_type, pos)
entry.is_variable = 0
entry.as_module = scope
self.add_imported_module(scope)
return entry
......
# mode: compile
cimport libc
cimport libc.stdio
from libc cimport stdio
from libc.stdio cimport printf, puts, fputs, putchar, fputc, putc, stdout
libc.stdio.printf("hello %s\n", b"world")
stdio.printf("hello %s\n", b"world")
printf("hello %s\n", b"world")
printf("printf_output %d %d\n", 1, 2)
puts("puts_output")
fputs("fputs_output", stdout)
putchar(b'z')
fputc(b'x', stdout)
putc(b'c', stdout)
with nogil:
libc.stdio.printf("hello %s\n", b"world")
stdio.printf("hello %s\n", b"world")
printf("hello %s\n", b"world")
printf("printf_output %d %d\n", 1, 2)
puts("puts_output")
fputs("fputs_output", stdout)
putchar(b'z')
fputc(b'x', stdout)
putc(b'c', stdout)
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