Commit d53646f1 authored by da-woods's avatar da-woods Committed by GitHub

Fix type inference on builtin max (GH-4156)

Also remove ErrorType type defaults for nodes in ExprNodes

Closes https://github.com/cython/cython/issues/4155
parent 30f72282
......@@ -6874,7 +6874,6 @@ class AttributeNode(ExprNode):
is_attribute = 1
subexprs = ['obj']
type = PyrexTypes.error_type
entry = None
is_called = 0
needs_none_check = True
......@@ -6964,6 +6963,8 @@ class AttributeNode(ExprNode):
return node
def analyse_types(self, env, target = 0):
if not self.type:
self.type = PyrexTypes.error_type # default value if it isn't analysed successfully
self.initialized_check = env.directives['initializedcheck']
node = self.analyse_as_cimported_attribute_node(env, target)
if node is None and not target:
......@@ -10998,8 +10999,6 @@ class TypeidNode(ExprNode):
# arg_type ExprNode
# is_variable boolean
type = PyrexTypes.error_type
subexprs = ['operand']
arg_type = None
......@@ -11017,19 +11016,25 @@ class TypeidNode(ExprNode):
cpp_message = 'typeid operator'
def analyse_types(self, env):
if not self.type:
self.type = PyrexTypes.error_type # default value if it isn't analysed successfully
self.cpp_check(env)
type_info = self.get_type_info_type(env)
if not type_info:
self.error("The 'libcpp.typeinfo' module must be cimported to use the typeid() operator")
return self
if self.operand is None:
return self # already analysed, no need to repeat
self.type = type_info
as_type = self.operand.analyse_as_specialized_type(env)
if as_type:
self.arg_type = as_type
self.is_type = True
self.operand = None # nothing further uses self.operand - will only cause problems if its used in code generation
else:
self.arg_type = self.operand.analyse_types(env)
self.is_type = False
self.operand = None # nothing further uses self.operand - will only cause problems if its used in code generation
if self.arg_type.type.is_pyobject:
self.error("Cannot use typeid on a Python object")
return self
......
......@@ -789,3 +789,16 @@ def test_bound_methods():
default_arg = o.default_arg
assert default_arg(2) == 12, default_arg(2)
assert default_arg(2, 3) == 15, default_arg(2, 2)
def test_builtin_max():
"""
# builtin max is slightly complicated because it gets transformed to EvalWithTempExprNode
# See https://github.com/cython/cython/issues/4155
>>> test_builtin_max()
"""
class C:
a = 2
def get_max(self):
a = max(self.a, self.a)
assert typeof(a) == "Python object", typeof(a)
C().get_max()
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