Commit f7b2cfd1 authored by Xavier Thompson's avatar Xavier Thompson

Fix type inference of qualified cypclass looping forever

parent 2b51fc1f
...@@ -11379,6 +11379,8 @@ class ConsumeNode(ExprNode): ...@@ -11379,6 +11379,8 @@ class ConsumeNode(ExprNode):
def infer_type(self, env): def infer_type(self, env):
operand_type = self.operand.infer_type(env) operand_type = self.operand.infer_type(env)
if operand_type.is_cyp_class: if operand_type.is_cyp_class:
if operand_type.is_qualified_cyp_class:
operand_type = operand_type.qual_base_type
return PyrexTypes.cyp_class_qualified_type(operand_type, 'iso~') return PyrexTypes.cyp_class_qualified_type(operand_type, 'iso~')
else: else:
return operand_type return operand_type
......
...@@ -4538,9 +4538,10 @@ def compute_mro_generic(cls): ...@@ -4538,9 +4538,10 @@ def compute_mro_generic(cls):
return mro_C3_merge(inputs) return mro_C3_merge(inputs)
class CypClassType(CppClassType): class CypClassType(CppClassType):
# _mro [CppClassType] or None the Method Resolution Order of this cypclass according to Python # _mro [CppClassType] or None the Method Resolution Order of this cypclass
# support_wrapper boolean whether this cypclass will be wrapped # support_wrapper boolean whether this cypclass will be wrapped
# wrapper_type PyExtensionType or None the type of the cclass wrapper # wrapper_type PyExtensionType or None the type of the cclass wrapper
# _qualified_types {string: QualifiedCypclassType} a cache of qualified versions of this type
is_cyp_class = 1 is_cyp_class = 1
to_py_function = None to_py_function = None
...@@ -4553,6 +4554,7 @@ class CypClassType(CppClassType): ...@@ -4553,6 +4554,7 @@ class CypClassType(CppClassType):
self.support_wrapper = False self.support_wrapper = False
self.wrapper_type = None self.wrapper_type = None
self._wrapped_base_type = None self._wrapped_base_type = None
self._qualified_types = {}
# iterate over the direct bases that support wrapping # iterate over the direct bases that support wrapping
def iter_wrapped_base_types(self): def iter_wrapped_base_types(self):
...@@ -4827,6 +4829,18 @@ class QualifiedCypclassType(BaseType): ...@@ -4827,6 +4829,18 @@ class QualifiedCypclassType(BaseType):
'locked': ('locked', 'iso~'), 'locked': ('locked', 'iso~'),
} }
def __new__(cls, base_type, qualifier):
# The qualified type is cached in the unqualified type to avoid duplicates.
try:
return base_type._qualified_types[qualifier]
except KeyError:
if base_type.is_qualified_cyp_class:
base_type = base_type.qual_base_type
qualified_type = BaseType.__new__(cls)
qualified_type.__init__(base_type, qualifier)
base_type._qualified_types[qualifier] = qualified_type
return qualified_type
def __init__(self, base_type, qualifier): def __init__(self, base_type, qualifier):
assert base_type.is_cyp_class assert base_type.is_cyp_class
self.qual_base_type = base_type self.qual_base_type = base_type
......
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