Fix #441
authorDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Tue, 3 Nov 2009 15:35:19 +0000 (16:35 +0100)
committerDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Tue, 3 Nov 2009 15:35:19 +0000 (16:35 +0100)
Cython/Compiler/Code.py
Cython/Compiler/ModuleNode.py
Cython/Compiler/PyrexTypes.py
tests/run/complex_numbers_T305.pyx

index 45b880f90646378f4ac2b018f0c98c5485d80737..b514047e6ec2f6a29ec14ca013108a5212b493fb 100644 (file)
@@ -408,8 +408,10 @@ class GlobalState(object):
     code_layout = [
         'h_code',
         'utility_code_proto_before_types',
-        'type_declarations',
-        'utility_code_proto',
+        'numeric_typedefs',          # Let these detailed individual parts stay!,
+        'complex_type_declarations', # as the proper solution is to make a full DAG...
+        'type_declarations',         # More coarse-grained blocks would simply hide
+        'utility_code_proto',        # the ugliness, not fix it
         'module_declarations',
         'typeinfo',
         'before_global_var',
index 506010af71b3b5ea843a1aaf587594a3b033e46e..575414fc6dce51411215c8ac3efda326b0bc00e7 100644 (file)
@@ -654,8 +654,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
     
     def generate_typedef(self, entry, code):
         base_type = entry.type.typedef_base_type
-        code.putln("")
-        code.putln("typedef %s;" % base_type.declaration_code(entry.cname))
+        if base_type.is_numeric:
+            writer = code.globalstate['numeric_typedefs']
+        else:
+            writer = code
+        writer.putln("")
+        writer.putln("typedef %s;" % base_type.declaration_code(entry.cname))
 
     def sue_header_footer(self, type, kind, name):
         if type.typedef_flag:
index 282c51980d8d251cfdd98e52e4796309c72be350..9e73dc964a867187e966ce0adc678236aa4b378a 100644 (file)
@@ -871,12 +871,21 @@ class CComplexType(CNumericType):
     scope = None
     
     def __init__(self, real_type):
+        while real_type.is_typedef and not real_type.typedef_is_external:
+            real_type = real_type.typedef_base_type
+        if real_type.is_typedef and real_type.typedef_is_external:
+            # The below is not actually used: Coercions are currently disabled
+            # so that complex types of external types can not be created
+            self.funcsuffix = "_%s" % real_type.specalization_name()
+        else:
+            self.funcsuffix = real_type.math_h_modifier
+    
         self.real_type = real_type
         CNumericType.__init__(self, real_type.rank + 0.5, real_type.signed)
         self.binops = {}
         self.from_parts = "%s_from_parts" % self.specalization_name()
         self.default_value = "%s(0, 0)" % self.from_parts
-    
+
     def __eq__(self, other):
         if isinstance(self, CComplexType) and isinstance(other, CComplexType):
             return self.real_type == other.real_type
@@ -899,7 +908,7 @@ class CComplexType(CNumericType):
 
     def __hash__(self):
         return ~hash(self.real_type)
-    
+
     def declaration_code(self, entity_code, 
             for_display = 0, dll_linkage = None, pyrex = 0):
         if for_display:
@@ -915,8 +924,9 @@ class CComplexType(CNumericType):
     
     def assignable_from(self, src_type):
         # Temporary hack/feature disabling, see #441
-        if not src_type.is_complex and src_type.is_numeric and src_type.is_typedef:
-            return False
+        if (not src_type.is_complex and src_type.is_numeric and src_type.is_typedef
+            and src_type.typedef_is_external):
+             return False
         else:
             return super(CComplexType, self).assignable_from(src_type)
         
@@ -940,7 +950,7 @@ class CComplexType(CNumericType):
                     CFuncType(self, [CFuncTypeArg("self", self, None)]),
                     pos=None,
                     defining=1,
-                    cname="__Pyx_c_conj%s" % self.real_type.math_h_modifier)
+                    cname="__Pyx_c_conj%s" % self.funcsuffix)
 
         return True
 
@@ -956,7 +966,7 @@ class CComplexType(CNumericType):
                 utility_code.specialize(
                     self, 
                     real_type = self.real_type.declaration_code(''),
-                    m = self.real_type.math_h_modifier))
+                    m = self.funcsuffix))
         return True
 
     def create_to_py_utility_code(self, env):
@@ -973,7 +983,7 @@ class CComplexType(CNumericType):
                 utility_code.specialize(
                     self, 
                     real_type = self.real_type.declaration_code(''),
-                    m = self.real_type.math_h_modifier))
+                    m = self.funcsuffix))
         self.from_py_function = "__Pyx_PyComplex_As_" + self.specalization_name()
         return True
     
@@ -984,8 +994,7 @@ class CComplexType(CNumericType):
             pass
         try:
             op_name = complex_ops[nargs, op]
-            modifier = self.real_type.math_h_modifier
-            self.binops[nargs, op] = func_name = "__Pyx_c_%s%s" % (op_name, modifier)
+            self.binops[nargs, op] = func_name = "__Pyx_c_%s%s" % (op_name, self.funcsuffix)
             return func_name
         except KeyError:
             return None
@@ -1045,7 +1054,7 @@ proto="""
 """)
 
 complex_type_utility_code = UtilityCode(
-proto_block='utility_code_proto_before_types',
+proto_block='complex_type_declarations',
 proto="""
 #if CYTHON_CCOMPLEX
   #ifdef __cplusplus
@@ -1204,7 +1213,6 @@ impl="""
 #endif
 """)
 
-
 class CArrayType(CType):
     #  base_type     CType              Element type
     #  size          integer or None    Number of elements
index 6ae5aaad35f2fde1b2c43c33d661ae3a2c5b69ff..d3ce1024ae2deeccf51271b97fa2386a1e96c3f0 100644 (file)
@@ -123,15 +123,45 @@ def test_conjugate_double(double complex z):
 
 ctypedef double complex cdouble
 def test_conjugate_typedef(cdouble z):
+    """
+    >>> test_conjugate_typedef(2+3j)
+    (2-3j)
+    """
     return z.conjugate()
 
-#ctypedef double mydouble
-#def test_coerce_typedef_multiply(mydouble x, double complex z):
-#    """
-#    >>> test_coerce_typedef_multiply(3, 1j)
-#    (3j)
-#    """
-#    return x * z
+## cdef extern from "complex_numbers_T305.h":
+##     ctypedef double double_really_float "myfloat"
+##     ctypedef float float_really_double "mydouble"
+##     ctypedef float real_float "myfloat"
+##     ctypedef double real_double "mydouble"
+
+## def test_conjugate_nosizeassumptions(double_really_float x,
+##                                      float_really_double y,
+##                                      real_float z, real_double w):
+##     """
+##     >>> test_conjugate_nosizeassumptions(1, 1, 1, 1)
+##     (-1j, -1j, -1j, -1j)
+##     >>> ["%.2f" % x.imag for x in test_conjugate_nosizeassumptions(2e300, 2e300, 2e300, 2e300)]
+##     ['-inf', '-2e+300', '-inf', '-2e+300']
+##     """
+##     cdef double complex I = 1j
+##     return ((x*I).conjugate(), (y*I).conjugate(), (z*I).conjugate(), (w*I).conjugate())
+
+ctypedef double mydouble
+def test_coerce_typedef_multiply(mydouble x, double complex z):
+    """
+    >>> test_coerce_typedef_multiply(3, 1+1j)
+    (3+3j)
+    """
+    return x * z
+
+ctypedef int myint
+def test_coerce_typedef_multiply_int(myint x, double complex z):
+    """
+    >>> test_coerce_typedef_multiply_int(3, 1+1j)
+    (3+3j)
+    """
+    return x * z
 
 cpdef double complex complex_retval():
     """