Commit 4cfcb3cb authored by Vitja Makarov's avatar Vitja Makarov

Lookup variable in globals if not found in pyclass scope, see ticket #671

parent ffea991b
......@@ -1529,12 +1529,24 @@ class NameNode(AtomicExprNode):
namespace = Naming.builtins_cname
else: # entry.is_pyglobal
namespace = entry.scope.namespace_cname
code.putln(
'%s = PyObject_GetItem(%s, %s); %s' % (
self.result(),
namespace,
interned_cname,
code.error_goto_if_null(self.result(), self.pos)))
if not self.cf_is_null:
code.putln(
'%s = PyObject_GetItem(%s, %s);' % (
self.result(),
namespace,
interned_cname))
if self.cf_maybe_null:
if not self.cf_is_null:
code.putln('if (unlikely(!%s)) {' % self.result())
code.putln('PyErr_Clear();')
code.putln(
'%s = __Pyx_GetName(%s, %s);' % (
self.result(),
Naming.module_cname,
interned_cname))
if not self.cf_is_null:
code.putln("}");
code.putln(code.error_goto_if_null(self.result(), self.pos))
code.put_gotref(self.py_result())
elif entry.is_pyglobal or entry.is_builtin:
......
......@@ -474,7 +474,7 @@ def check_definitions(flow, compiler_directives):
node.cf_maybe_null = True
if not entry.from_closure and len(node.cf_state) == 1:
node.cf_is_null = True
if node.allow_null or entry.from_closure:
if node.allow_null or entry.from_closure or entry.is_pyclass_attr:
pass # Can be uninitialized here
elif node.cf_is_null:
if (entry.type.is_pyobject or entry.type.is_unspecified or
......
# cython: warn.maybe_uninitialized=True
# mode: error
# tag: werror
# class scope
def foo(c):
class Foo(object):
if c > 0:
b = 1
print a, b
a = 1
return Foo
_ERRORS = """
10:15: local variable 'a' referenced before assignment
10:18: local variable 'b' might be referenced before assignment
"""
# mode: run
# ticket: 671
A = 1234
class SimpleAssignment(object):
"""
>>> SimpleAssignment.A
1234
"""
A = A
class SimpleRewrite(object):
"""
>>> SimpleRewrite.A
4321
"""
A = 4321
A = A
def simple_inner(a):
"""
>>> simple_inner(4321).A
1234
"""
A = a
class X(object):
A = A
return X
def conditional(a, cond):
"""
>>> conditional(4321, False).A
1234
>>> conditional(4321, True).A
4321
"""
class X(object):
if cond:
A = a
A = A
return X
def name_error():
"""
>>> name_error() #doctest: +ELLIPSIS
Traceback (most recent call last):
...
NameError: ...B...
"""
class X(object):
B = B
def conditional_name_error(cond):
"""
>>> conditional_name_error(True).B
4321
>>> conditional_name_error(False).B #doctest: +ELLIPSIS
Traceback (most recent call last):
...
NameError: ...B...
"""
class X(object):
if cond:
B = 4321
B = B
return X
C = 1111
del C
def name_error_deleted():
"""
>>> name_error_deleted() #doctest: +ELLIPSIS
Traceback (most recent call last):
...
NameError: ...C...
"""
class X(object):
C = C
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