Commit 226ad9cf authored by Stefan Behnel's avatar Stefan Behnel

more explicit method to check if a type can coerce to a Python object

parent d5419f9e
...@@ -3013,7 +3013,7 @@ class AttributeNode(ExprNode): ...@@ -3013,7 +3013,7 @@ class AttributeNode(ExprNode):
self.type = py_object_type self.type = py_object_type
self.is_py_attr = 1 self.is_py_attr = 1
if not obj_type.is_pyobject and not obj_type.is_error: if not obj_type.is_pyobject and not obj_type.is_error:
if obj_type.create_to_py_utility_code(env): if obj_type.can_coerce_to_pyobject(env):
self.obj = self.obj.coerce_to_pyobject(env) self.obj = self.obj.coerce_to_pyobject(env)
else: else:
error(self.pos, error(self.pos,
...@@ -4242,7 +4242,7 @@ class TypecastNode(ExprNode): ...@@ -4242,7 +4242,7 @@ class TypecastNode(ExprNode):
if from_py and not to_py and self.operand.is_ephemeral() and not self.type.is_numeric: if from_py and not to_py and self.operand.is_ephemeral() and not self.type.is_numeric:
error(self.pos, "Casting temporary Python object to non-numeric non-Python type") error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
if to_py and not from_py: if to_py and not from_py:
if self.operand.type.create_to_py_utility_code(env): if self.operand.type.can_coerce_to_pyobject(env):
self.result_ctype = py_object_type self.result_ctype = py_object_type
self.operand = self.operand.coerce_to_pyobject(env) self.operand = self.operand.coerce_to_pyobject(env)
else: else:
......
...@@ -11,6 +11,9 @@ class BaseType(object): ...@@ -11,6 +11,9 @@ class BaseType(object):
# #
# Base class for all Pyrex types including pseudo-types. # Base class for all Pyrex types including pseudo-types.
def can_coerce_to_pyobject(self, env):
return False
def cast_code(self, expr_code): def cast_code(self, expr_code):
return "((%s)%s)" % (self.declaration_code(""), expr_code) return "((%s)%s)" % (self.declaration_code(""), expr_code)
...@@ -349,6 +352,9 @@ class PyObjectType(PyrexType): ...@@ -349,6 +352,9 @@ class PyObjectType(PyrexType):
def __repr__(self): def __repr__(self):
return "<PyObjectType>" return "<PyObjectType>"
def can_coerce_to_pyobject(self, env):
return True
def assignable_from(self, src_type): def assignable_from(self, src_type):
# except for pointers, conversion will be attempted # except for pointers, conversion will be attempted
return not src_type.is_ptr or src_type.is_string return not src_type.is_ptr or src_type.is_string
...@@ -556,6 +562,9 @@ class CType(PyrexType): ...@@ -556,6 +562,9 @@ class CType(PyrexType):
def create_from_py_utility_code(self, env): def create_from_py_utility_code(self, env):
return self.from_py_function is not None return self.from_py_function is not None
def can_coerce_to_pyobject(self, env):
return self.create_to_py_utility_code(env)
def error_condition(self, result_code): def error_condition(self, result_code):
conds = [] conds = []
if self.is_string: if self.is_string:
......
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