applied fix by haoyu for bug #543
[cython.git] / Cython / Compiler / ModuleNode.py
index dd3161b7a6c3d9f868ebf2f1f1e4fec440e93bec..143ccbfbbc02c6e913fbf5ad5187881a84893e17 100644 (file)
@@ -227,7 +227,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         h_code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
             Naming.extern_c_macro,
             type.typeobj_cname))
-        #self.generate_obj_struct_definition(type, h_code)
     
     def generate_cclass_include_code(self, type, i_code):
         i_code.putln("cdef extern class %s.%s:" % (
@@ -260,22 +259,25 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         globalstate.module_pos = self.pos
         globalstate.directives = self.directives
 
-        globalstate.use_utility_code(refcount_utility_code)
+        globalstate.use_utility_code(refnanny_utility_code)
 
         code = globalstate['before_global_var']
         code.putln('#define __Pyx_MODULE_NAME "%s"' % self.full_module_name)
-        code.putln("int %s%s = %s;" % (Naming.module_is_main, self.full_module_name.replace('.', '__'), int(Options.embed)))
+        code.putln("int %s%s = 0;" % (Naming.module_is_main, self.full_module_name.replace('.', '__')))
         code.putln("")
         code.putln("/* Implementation of %s */" % env.qualified_name)
 
         code = globalstate['all_the_rest']
 
         self.generate_cached_builtins_decls(env, code)
+        # generate lambda function definitions
+        for node in env.lambda_defs:
+            node.generate_function_definitions(env, code)
+        # generate normal function definitions
         self.body.generate_function_definitions(env, code)
         code.mark_pos(None)
         self.generate_typeobj_definitions(env, code)
         self.generate_method_table(env, code)
-        self.generate_filename_init_prototype(code)
         if env.has_import_star:
             self.generate_import_star(env, code)
         self.generate_pymoduledef_struct(env, code)
@@ -390,9 +392,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
                     elif type.is_enum:
                         self.generate_enum_definition(entry, code)
                     elif type.is_extension_type and entry not in vtabslot_entries:
-                        self.generate_obj_struct_definition(type, code)
+                        self.generate_objstruct_definition(type, code)
         for entry in vtabslot_list:
-            self.generate_obj_struct_definition(entry.type, code)
+            self.generate_objstruct_definition(entry.type, code)
         for entry in vtab_list:
             self.generate_typeobject_predeclaration(entry, code)
             self.generate_exttype_vtable_struct(entry, code)
@@ -409,160 +411,215 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         for module in modules:
             defined_here = module is env
             modulecode.putln("/* Module declarations from %s */" %
-                       module.qualified_name.encode("ASCII", "ignore"))
+                             module.qualified_name)
             self.generate_global_declarations(module, modulecode, defined_here)
             self.generate_cfunction_predeclarations(module, modulecode, defined_here)
 
     def generate_module_preamble(self, env, cimported_modules, code):
-        code.putln('/* Generated by Cython %s on %s */' % (
+        code.putln("/* Generated by Cython %s on %s */" % (
             Version.version, time.asctime()))
-        code.putln('')
-        code.putln('#define PY_SSIZE_T_CLEAN')
+        code.putln("")
+        code.putln("#define PY_SSIZE_T_CLEAN")
         for filename in env.python_include_files:
             code.putln('#include "%s"' % filename)
         code.putln("#ifndef Py_PYTHON_H")
         code.putln("    #error Python headers needed to compile C extensions, please install development version of Python.")
         code.putln("#else")
         code.globalstate["end"].putln("#endif /* Py_PYTHON_H */")
-        code.putln("#ifndef PY_LONG_LONG")
-        code.putln("  #define PY_LONG_LONG LONG_LONG")
-        code.putln("#endif")
-        code.putln("#ifndef DL_EXPORT")
-        code.putln("  #define DL_EXPORT(t) t")
-        code.putln("#endif")
-        code.putln("#if PY_VERSION_HEX < 0x02040000")
-        code.putln("  #define METH_COEXIST 0")
-        code.putln("  #define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type)")
-        code.putln("#endif")
+        
+        code.put("""
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
 
-        code.putln("#if PY_VERSION_HEX < 0x02050000")
-        code.putln("  typedef int Py_ssize_t;")
-        code.putln("  #define PY_SSIZE_T_MAX INT_MAX")
-        code.putln("  #define PY_SSIZE_T_MIN INT_MIN")
-        code.putln("  #define PY_FORMAT_SIZE_T \"\"")
-        code.putln("  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)")
-        code.putln("  #define PyInt_AsSsize_t(o)   PyInt_AsLong(o)")
-        code.putln("  #define PyNumber_Index(o)    PyNumber_Int(o)")
-        code.putln("  #define PyIndex_Check(o)     PyNumber_Check(o)")
-        code.putln("#endif")
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+  #ifndef __stdcall
+    #define __stdcall
+  #endif
+  #ifndef __cdecl
+    #define __cdecl
+  #endif
+  #ifndef __fastcall
+    #define __fastcall
+  #endif
+#endif
 
-        code.putln("#if PY_VERSION_HEX < 0x02060000")
-        code.putln("  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)")
-        code.putln("  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)")
-        code.putln("  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)")
-        code.putln("  #define PyVarObject_HEAD_INIT(type, size) \\")
-        code.putln("          PyObject_HEAD_INIT(type) size,")
-        code.putln("  #define PyType_Modified(t)")
-        code.putln("")
-        code.putln("  typedef struct {")
-        code.putln("     void *buf;")
-        code.putln("     PyObject *obj;")
-        code.putln("     Py_ssize_t len;")
-        code.putln("     Py_ssize_t itemsize;")
-        code.putln("     int readonly;")
-        code.putln("     int ndim;")
-        code.putln("     char *format;")
-        code.putln("     Py_ssize_t *shape;")
-        code.putln("     Py_ssize_t *strides;")
-        code.putln("     Py_ssize_t *suboffsets;")
-        code.putln("     void *internal;")
-        code.putln("  } Py_buffer;")
-        code.putln("")
-        code.putln("  #define PyBUF_SIMPLE 0")
-        code.putln("  #define PyBUF_WRITABLE 0x0001")
-        code.putln("  #define PyBUF_FORMAT 0x0004")
-        code.putln("  #define PyBUF_ND 0x0008")
-        code.putln("  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)")
-        code.putln("  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)")
-        code.putln("  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)")
-        code.putln("  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)")
-        code.putln("  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)")
-        code.putln("")
-        code.putln("#endif")
+#ifndef DL_IMPORT
+  #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+  #define DL_EXPORT(t) t
+#endif
 
-        code.put(builtin_module_name_utility_code.proto)
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
 
-        code.putln("#if PY_MAJOR_VERSION >= 3")
-        code.putln("  #define Py_TPFLAGS_CHECKTYPES 0")
-        code.putln("  #define Py_TPFLAGS_HAVE_INDEX 0")
-        code.putln("#endif")
+#if PY_VERSION_HEX < 0x02040000
+  #define METH_COEXIST 0
+  #define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type)
+  #define PyDict_Contains(d,o)   PySequence_Contains(d,o)
+#endif
 
-        code.putln("#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)")
-        code.putln("  #define Py_TPFLAGS_HAVE_NEWBUFFER 0")
-        code.putln("#endif")
+#if PY_VERSION_HEX < 0x02050000
+  typedef int Py_ssize_t;
+  #define PY_SSIZE_T_MAX INT_MAX
+  #define PY_SSIZE_T_MIN INT_MIN
+  #define PY_FORMAT_SIZE_T \"\"
+  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
+  #define PyInt_AsSsize_t(o)   PyInt_AsLong(o)
+  #define PyNumber_Index(o)    PyNumber_Int(o)
+  #define PyIndex_Check(o)     PyNumber_Check(o)
+  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
+#endif
 
-        code.putln("#if PY_MAJOR_VERSION >= 3")
-        code.putln("  #define PyBaseString_Type            PyUnicode_Type")
-        code.putln("  #define PyString_Type                PyBytes_Type")
-        code.putln("  #define PyString_CheckExact          PyBytes_CheckExact")
-        code.putln("  #define PyInt_Type                   PyLong_Type")
-        code.putln("  #define PyInt_Check(op)              PyLong_Check(op)")
-        code.putln("  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)")
-        code.putln("  #define PyInt_FromString             PyLong_FromString")
-        code.putln("  #define PyInt_FromUnicode            PyLong_FromUnicode")
-        code.putln("  #define PyInt_FromLong               PyLong_FromLong")
-        code.putln("  #define PyInt_FromSize_t             PyLong_FromSize_t")
-        code.putln("  #define PyInt_FromSsize_t            PyLong_FromSsize_t")
-        code.putln("  #define PyInt_AsLong                 PyLong_AsLong")
-        code.putln("  #define PyInt_AS_LONG                PyLong_AS_LONG")
-        code.putln("  #define PyInt_AsSsize_t              PyLong_AsSsize_t")
-        code.putln("  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask")
-        code.putln("  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask")
-        code.putln("  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)")
-        code.putln("#else")
+#if PY_VERSION_HEX < 0x02060000
+  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
+  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
+  #define PyVarObject_HEAD_INIT(type, size) \\
+          PyObject_HEAD_INIT(type) size,
+  #define PyType_Modified(t)
+
+  typedef struct {
+     void *buf;
+     PyObject *obj;
+     Py_ssize_t len;
+     Py_ssize_t itemsize;
+     int readonly;
+     int ndim;
+     char *format;
+     Py_ssize_t *shape;
+     Py_ssize_t *strides;
+     Py_ssize_t *suboffsets;
+     void *internal;
+  } Py_buffer;
+
+  #define PyBUF_SIMPLE 0
+  #define PyBUF_WRITABLE 0x0001
+  #define PyBUF_FORMAT 0x0004
+  #define PyBUF_ND 0x0008
+  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
+  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
+  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
+  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
+  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
+
+#endif
+
+#if PY_MAJOR_VERSION < 3
+  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+#else
+  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+#endif
+
+#if PY_MAJOR_VERSION >= 3
+  #define Py_TPFLAGS_CHECKTYPES 0
+  #define Py_TPFLAGS_HAVE_INDEX 0
+#endif
+
+#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+
+#if PY_MAJOR_VERSION >= 3
+  #define PyBaseString_Type            PyUnicode_Type
+  #define PyStringObject               PyUnicodeObject
+  #define PyString_Type                PyUnicode_Type
+  #define PyString_Check               PyUnicode_Check
+  #define PyString_CheckExact          PyUnicode_CheckExact
+#endif
+
+#if PY_VERSION_HEX < 0x02060000
+  #define PyBytesObject                PyStringObject
+  #define PyBytes_Type                 PyString_Type
+  #define PyBytes_Check                PyString_Check
+  #define PyBytes_CheckExact           PyString_CheckExact
+  #define PyBytes_FromString           PyString_FromString
+  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
+  #define PyBytes_FromFormat           PyString_FromFormat
+  #define PyBytes_DecodeEscape         PyString_DecodeEscape
+  #define PyBytes_AsString             PyString_AsString
+  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
+  #define PyBytes_Size                 PyString_Size
+  #define PyBytes_AS_STRING            PyString_AS_STRING
+  #define PyBytes_GET_SIZE             PyString_GET_SIZE
+  #define PyBytes_Repr                 PyString_Repr
+  #define PyBytes_Concat               PyString_Concat
+  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
+#endif
+
+#if PY_MAJOR_VERSION >= 3
+  #define PyInt_Type                   PyLong_Type
+  #define PyInt_Check(op)              PyLong_Check(op)
+  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
+  #define PyInt_FromString             PyLong_FromString
+  #define PyInt_FromUnicode            PyLong_FromUnicode
+  #define PyInt_FromLong               PyLong_FromLong
+  #define PyInt_FromSize_t             PyLong_FromSize_t
+  #define PyInt_FromSsize_t            PyLong_FromSsize_t
+  #define PyInt_AsLong                 PyLong_AsLong
+  #define PyInt_AS_LONG                PyLong_AS_LONG
+  #define PyInt_AsSsize_t              PyLong_AsSsize_t
+  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
+  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+#endif
+""")
+
+        code.put("""
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
+  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
+#else
+""")
         if Future.division in env.context.future_directives:
             code.putln("  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)")
+            code.putln("  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)")
         else:
             code.putln("  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)")
-        code.putln("  #define PyBytes_Type                 PyString_Type")
+            code.putln("  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)")
         code.putln("#endif")
 
-        code.putln("#if PY_MAJOR_VERSION >= 3")
-        code.putln("  #define PyMethod_New(func, self, klass) PyInstanceMethod_New(func)")
-        code.putln("#endif")
-
-        code.putln("#if !defined(WIN32) && !defined(MS_WINDOWS)")
-        code.putln("  #ifndef __stdcall")
-        code.putln("    #define __stdcall")
-        code.putln("  #endif")
-        code.putln("  #ifndef __cdecl")
-        code.putln("    #define __cdecl")
-        code.putln("  #endif")
-        code.putln("  #ifndef __fastcall")
-        code.putln("    #define __fastcall")
-        code.putln("  #endif")
-        code.putln("#else")
-        code.putln("  #define _USE_MATH_DEFINES")
-        code.putln("#endif")
+        code.put("""
+#if PY_MAJOR_VERSION >= 3
+  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#endif
 
-        code.putln("#if PY_VERSION_HEX < 0x02050000")
-        code.putln("  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))")
-        code.putln("  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))")
-        code.putln("  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))")
-        code.putln("#else")
-        code.putln("  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))")
-        code.putln("  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))")
-        code.putln("  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))")
-        code.putln("#endif")
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#else
+  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
+  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
+  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#endif
 
-        code.putln("#if PY_VERSION_HEX < 0x02050000")
-        code.putln("  #define __Pyx_NAMESTR(n) ((char *)(n))")
-        code.putln("  #define __Pyx_DOCSTR(n)  ((char *)(n))")
-        code.putln("#else")
-        code.putln("  #define __Pyx_NAMESTR(n) (n)")
-        code.putln("  #define __Pyx_DOCSTR(n)  (n)")
-        code.putln("#endif")
+#if PY_VERSION_HEX < 0x02050000
+  #define __Pyx_NAMESTR(n) ((char *)(n))
+  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#else
+  #define __Pyx_NAMESTR(n) (n)
+  #define __Pyx_DOCSTR(n)  (n)
+#endif
+""")
 
+        code.putln("")
         self.generate_extern_c_macro_definition(code)
+        code.putln("")
+        code.putln("#if defined(WIN32) || defined(MS_WINDOWS)")
+        code.putln("#define _USE_MATH_DEFINES")
+        code.putln("#endif")
         code.putln("#include <math.h>")
         code.putln("#define %s" % Naming.api_guard_prefix + self.api_name(env))
         self.generate_includes(env, cimported_modules, code)
-        if env.directives['c99_complex']:
-            code.putln("#ifndef _Complex_I")
-            code.putln("#include <complex.h>")
+        if env.directives['ccomplex']:
+            code.putln("")
+            code.putln("#if !defined(CYTHON_CCOMPLEX)")
+            code.putln("#define CYTHON_CCOMPLEX 1")
             code.putln("#endif")
-        code.putln("#define __PYX_USE_C99_COMPLEX defined(_Complex_I)")
-        code.putln('')
+            code.putln("")
         code.put(Nodes.utility_function_predeclarations)
         code.put(PyrexTypes.type_conversion_predeclarations)
         code.put(Nodes.branch_prediction_macros)
@@ -577,7 +634,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.putln('static int %s = 0;' % Naming.clineno_cname)
         code.putln('static const char * %s= %s;' % (Naming.cfilenm_cname, Naming.file_c_macro))
         code.putln('static const char *%s;' % Naming.filename_cname)
-        code.putln('static const char **%s;' % Naming.filetable_cname)
 
         # XXX this is a mess
         for utility_code in PyrexTypes.c_int_from_py_function.specialize_list:
@@ -596,18 +652,20 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
     def generate_includes(self, env, cimported_modules, code):
         includes = []
         for filename in env.include_files:
-            # fake decoding of filenames to their original byte sequence
-            code.putln('#include "%s"' % filename)
+            byte_decoded_filenname = str(filename)
+            if byte_decoded_filenname[0] == '<' and byte_decoded_filenname[-1] == '>':
+                code.putln('#include %s' % byte_decoded_filenname)
+            else:
+                code.putln('#include "%s"' % byte_decoded_filenname)
     
     def generate_filename_table(self, code):
         code.putln("")
-        code.putln("static const char *%s[] = {" % Naming.filenames_cname)
+        code.putln("static const char *%s[] = {" % Naming.filetable_cname)
         if code.globalstate.filename_list:
             for source_desc in code.globalstate.filename_list:
                 filename = os.path.basename(source_desc.get_filenametable_entry())
                 escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"')
-                code.putln('"%s",' % 
-                    escaped_filename)
+                code.putln('"%s",' % escaped_filename)
         else:
             # Some C compilers don't like an empty array
             code.putln("0")
@@ -631,7 +689,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
                 elif type.is_enum:
                     self.generate_enum_definition(entry, code)
                 elif type.is_extension_type:
-                    self.generate_obj_struct_definition(type, code)
+                    self.generate_objstruct_definition(type, code)
         
     def generate_gcc33_hack(self, env, code):
         # Workaround for spurious warning generation in gcc 3.3
@@ -649,8 +707,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:
@@ -773,7 +835,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
                 type.vtabstruct_cname,
                 type.vtabptr_cname))
     
-    def generate_obj_struct_definition(self, type, code):
+    def generate_objstruct_definition(self, type, code):
         code.mark_pos(type.pos)
         # Generate object struct definition for an
         # extension type.
@@ -865,7 +927,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
                     if scope.defines_any(["__setitem__", "__delitem__"]):
                         self.generate_ass_subscript_function(scope, code)
                     if scope.defines_any(["__setslice__", "__delslice__"]):
-                        warning(self.pos, "__setslice__ and __delslice__ are not supported by Python 3", 1)
+                        warning(self.pos, "__setslice__ and __delslice__ are not supported by Python 3, use __setitem__ and __getitem__ instead", 1)
                         self.generate_ass_slice_function(scope, code)
                     if scope.defines_any(["__getattr__","__getattribute__"]):
                         self.generate_getattro_function(scope, code)
@@ -877,7 +939,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
                         self.generate_descr_set_function(scope, code)
                     self.generate_property_accessors(scope, code)
                     self.generate_method_table(scope, code)
-                    self.generate_member_table(scope, code)
                     self.generate_getset_table(scope, code)
                     self.generate_typeobj_definition(full_module_name, entry, code)
     
@@ -943,7 +1004,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
                 type.vtabslot_cname,
                 struct_type_cast, type.vtabptr_cname))
         for entry in py_attrs:
-            if entry.name == "__weakref__":
+            if scope.is_internal or entry.name == "__weakref__":
+                # internal classes do not need None inits
                 code.putln("p->%s = 0;" % entry.cname)
             else:
                 code.put_init_var_to_py_none(entry, "p->%s", nanny=False)
@@ -1192,6 +1254,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         # Setting and deleting a slice are both done through
         # the ass_slice method, so we dispatch to user's __setslice__
         # or __delslice__, or raise an exception.
+        code.putln("#if PY_MAJOR_VERSION >= 3")
+        code.putln("#error __setslice__ and __delslice__ not supported in Python 3.")
+        code.putln("#endif")
         base_type = scope.parent_type.base_type
         set_entry = scope.lookup_here("__setslice__")
         del_entry = scope.lookup_here("__delslice__")
@@ -1476,7 +1541,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         if type.typedef_flag:
             objstruct = type.objstruct_cname
         else:
-            #objstruct = "struct %s" % scope.parent_type.objstruct_cname
             objstruct = "struct %s" % type.objstruct_cname
         code.putln(
             "sizeof(%s), /*tp_basicsize*/" %
@@ -1491,7 +1555,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
     def generate_method_table(self, env, code):
         code.putln("")
         code.putln(
-            "static struct PyMethodDef %s[] = {" % 
+            "static PyMethodDef %s[] = {" % 
                 env.method_table_cname)
         for entry in env.pyfunc_entries:
             code.put_pymethoddef(entry, ",")
@@ -1500,34 +1564,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.putln(
             "};")
     
-    def generate_member_table(self, env, code):
-        #print "ModuleNode.generate_member_table: scope =", env ###
-        if env.public_attr_entries:
-            code.putln("")
-            code.putln(
-                "static struct PyMemberDef %s[] = {" %
-                    env.member_table_cname)
-            type = env.parent_type
-            if type.typedef_flag:
-                objstruct = type.objstruct_cname
-            else:
-                objstruct = "struct %s" % type.objstruct_cname
-            for entry in env.public_attr_entries:
-                type_code = entry.type.pymemberdef_typecode
-                if entry.visibility == 'readonly':
-                    flags = "READONLY"
-                else:
-                    flags = "0"
-                code.putln('{(char *)"%s", %s, %s, %s, 0},' % (
-                    entry.name,
-                    type_code,
-                    "offsetof(%s, %s)" % (objstruct, entry.cname),
-                    flags))
-            code.putln(
-                    "{0, 0, 0, 0, 0}")
-            code.putln(
-                "};")
-    
     def generate_getset_table(self, env, code):
         if env.property_entries:
             code.putln("")
@@ -1550,10 +1586,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
             code.putln(
                 "};")
 
-    def generate_filename_init_prototype(self, code):
-        code.putln("");
-        code.putln("static void %s(void); /*proto*/" % Naming.fileinit_cname)
-        
     def generate_import_star(self, env, code):
         env.use_utility_code(streq_utility_code)
         code.putln()
@@ -1632,25 +1664,24 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.putln("{")
         tempdecl_code = code.insertion_point()
 
-        self.generate_filename_init_call(code)
-        code.putln("#ifdef CYTHON_REFNANNY")
-        code.putln("void* __pyx_refchk = NULL;")
-        code.putln("__Pyx_Refnanny = __Pyx_ImportRefcountAPI(\"refnanny\");")
-        code.putln("if (!__Pyx_Refnanny) {")
+        code.putln("#if CYTHON_REFNANNY")
+        code.putln("void* __pyx_refnanny = NULL;")
+        code.putln("__Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"refnanny\");")
+        code.putln("if (!__Pyx_RefNanny) {")
         code.putln("  PyErr_Clear();")
-        code.putln("  __Pyx_Refnanny = __Pyx_ImportRefcountAPI(\"Cython.Runtime.refnanny\");")
-        code.putln("  if (!__Pyx_Refnanny)")
-        code.putln("      Py_FatalError(\"failed to import refnanny module\");")
+        code.putln("  __Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"Cython.Runtime.refnanny\");")
+        code.putln("  if (!__Pyx_RefNanny)")
+        code.putln("      Py_FatalError(\"failed to import 'refnanny' module\");")
         code.putln("}")
-        code.putln("__pyx_refchk = __Pyx_Refnanny->NewContext(\"%s\", __LINE__, __FILE__);"% header3)
+        code.putln("__pyx_refnanny = __Pyx_RefNanny->SetupContext(\"%s\", __LINE__, __FILE__);"% header3)
         code.putln("#endif")
 
         code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)));
-        code.putln("#if PY_MAJOR_VERSION < 3");
-        code.putln("%s = PyString_FromStringAndSize(\"\", 0); %s" % (Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos)));
-        code.putln("#else");
         code.putln("%s = PyBytes_FromStringAndSize(\"\", 0); %s" % (Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos)));
-        code.putln("#endif");
+
+        code.putln("#ifdef %s_USED" % Naming.binding_cfunc)
+        code.putln("if (%s_init() < 0) %s" % (Naming.binding_cfunc, code.error_goto(self.pos)))
+        code.putln("#endif")
 
         code.putln("/*--- Library function declarations ---*/")
         env.generate_library_function_declarations(code)
@@ -1740,7 +1771,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         if not Options.generate_cleanup_code:
             return
         code.globalstate.use_utility_code(register_cleanup_utility_code)
-        code.putln('static PyObject* %s(PyObject *self, PyObject *unused) {' % Naming.cleanup_cname)
+        code.putln('static PyObject *%s(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED PyObject *unused) {' % 
+                   Naming.cleanup_cname)
         if Options.generate_cleanup_code >= 2:
             code.putln("/*--- Global cleanup code ---*/")
             rev_entries = list(env.var_entries)
@@ -1779,13 +1811,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
 #                code.putln("Py_DECREF(%s); %s = 0;" % (
 #                    code.entry_as_pyobject(entry), entry.cname))
         code.putln("Py_INCREF(Py_None); return Py_None;")
-        code.putln('}')
 
     def generate_main_method(self, env, code):
-        code.globalstate.use_utility_code(main_method.specialize(module_name=env.module_name))
-
-    def generate_filename_init_call(self, code):
-        code.putln("%s();" % Naming.fileinit_cname)
+        module_is_main = "%s%s" % (Naming.module_is_main, self.full_module_name.replace('.', '__'))
+        code.globalstate.use_utility_code(main_method.specialize(module_name=env.module_name, module_is_main=module_is_main))
 
     def generate_pymoduledef_struct(self, env, code):
         if env.doc:
@@ -1969,18 +1998,19 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
             module_name = '__Pyx_BUILTIN_MODULE_NAME'
         if type.name in self.py3_type_name_map:
             code.putln("#if PY_MAJOR_VERSION >= 3")
-            code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s)); %s' % (
+            code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s), 1); %s' % (
                     type.typeptr_cname,
                     module_name,
                     self.py3_type_name_map[type.name],
                     objstruct,
                     error_code))
             code.putln("#else")
-        code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s)); %s' % (
+        code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s), %i); %s' % (
                 type.typeptr_cname,
                 module_name,
                 type.name,
                 objstruct,
+                not type.is_external or type.is_subclassed,
                 error_code))
         if type.name in self.py3_type_name_map:
             code.putln("#endif")
@@ -2081,23 +2111,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
 #
 #------------------------------------------------------------------------------------
 
-builtin_module_name_utility_code = UtilityCode(
-proto = """\
-#if PY_MAJOR_VERSION < 3
-  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
-#else
-  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
-#endif
-""")
-
-#------------------------------------------------------------------------------------
-
 streq_utility_code = UtilityCode(
 proto = """
-static INLINE int __Pyx_StrEq(const char *, const char *); /*proto*/
+static CYTHON_INLINE int __Pyx_StrEq(const char *, const char *); /*proto*/
 """,
 impl = """
-static INLINE int __Pyx_StrEq(const char *s1, const char *s2) {
+static CYTHON_INLINE int __Pyx_StrEq(const char *s1, const char *s2) {
      while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; }
      return *s1 == *s2;
 }
@@ -2137,17 +2156,18 @@ bad:
 
 type_import_utility_code = UtilityCode(
 proto = """
-static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, long size);  /*proto*/
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, long size, int strict);  /*proto*/
 """,
 impl = """
 #ifndef __PYX_HAVE_RT_ImportType
 #define __PYX_HAVE_RT_ImportType
 static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
-    long size)
+    long size, int strict)
 {
     PyObject *py_module = 0;
     PyObject *result = 0;
     PyObject *py_name = 0;
+    char warning[200];
 
     py_module = __Pyx_ImportModule(module_name);
     if (!py_module)
@@ -2172,9 +2192,19 @@ static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class
             module_name, class_name);
         goto bad;
     }
-    if (((PyTypeObject *)result)->tp_basicsize != size) {
+    if (!strict && ((PyTypeObject *)result)->tp_basicsize > size) {
+        PyOS_snprintf(warning, sizeof(warning), 
+            "%s.%s size changed, may indicate binary incompatibility",
+            module_name, class_name);
+        #if PY_VERSION_HEX < 0x02050000
+        PyErr_Warn(NULL, warning);
+        #else
+        PyErr_WarnEx(NULL, warning, 0);
+        #endif
+    }
+    else if (((PyTypeObject *)result)->tp_basicsize != size) {
         PyErr_Format(PyExc_ValueError, 
-            "%s.%s does not appear to be the correct type object",
+            "%s.%s has the wrong size, try recompiling",
             module_name, class_name);
         goto bad;
     }
@@ -2195,11 +2225,6 @@ static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *s
 """,
 impl = r"""
 static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *sig) {
-#if PY_VERSION_HEX < 0x02050000
-    char *api = (char *)"%(API)s";
-#else
-    const char *api = "%(API)s";
-#endif
     PyObject *d = 0;
     PyObject *cobj = 0;
     union {
@@ -2207,19 +2232,22 @@ static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *s
         void *p;
     } tmp;
 
-
-    d = PyObject_GetAttrString(%(MODULE)s, api);
+    d = PyObject_GetAttrString(%(MODULE)s, (char *)"%(API)s");
     if (!d) {
         PyErr_Clear();
         d = PyDict_New();
         if (!d)
             goto bad;
         Py_INCREF(d);
-        if (PyModule_AddObject(%(MODULE)s, api, d) < 0)
+        if (PyModule_AddObject(%(MODULE)s, (char *)"%(API)s", d) < 0)
             goto bad;
     }
     tmp.fp = f;
+#if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
+    cobj = PyCapsule_New(tmp.p, sig, 0);
+#else
     cobj = PyCObject_FromVoidPtrAndDesc(tmp.p, (void *)sig, 0);
+#endif
     if (!cobj)
         goto bad;
     if (PyDict_SetItemString(d, name, cobj) < 0)
@@ -2235,8 +2263,6 @@ bad:
 """ % {'MODULE': Naming.module_cname, 'API': Naming.api_name}
 )
 
-#------------------------------------------------------------------------------------
-
 function_import_utility_code = UtilityCode(
 proto = """
 static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig); /*proto*/
@@ -2245,21 +2271,14 @@ impl = """
 #ifndef __PYX_HAVE_RT_ImportFunction
 #define __PYX_HAVE_RT_ImportFunction
 static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig) {
-#if PY_VERSION_HEX < 0x02050000
-    char *api = (char *)"%(API)s";
-#else
-    const char *api = "%(API)s";
-#endif
     PyObject *d = 0;
     PyObject *cobj = 0;
-    const char *desc;
-    const char *s1, *s2;
     union {
         void (*fp)(void);
         void *p;
     } tmp;
 
-    d = PyObject_GetAttrString(module, api);
+    d = PyObject_GetAttrString(module, (char *)"%(API)s");
     if (!d)
         goto bad;
     cobj = PyDict_GetItemString(d, funcname);
@@ -2269,6 +2288,16 @@ static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**
                 PyModule_GetName(module), funcname);
         goto bad;
     }
+#if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
+    if (!PyCapsule_IsValid(cobj, sig)) {
+        PyErr_Format(PyExc_TypeError,
+            "C function %%s.%%s has wrong signature (expected %%s, got %%s)",
+             PyModule_GetName(module), funcname, sig, PyCapsule_GetName(cobj));
+        goto bad;
+    }
+    tmp.p = PyCapsule_GetPointer(cobj, sig);
+#else
+    {const char *desc, *s1, *s2;
     desc = (const char *)PyCObject_GetDesc(cobj);
     if (!desc)
         goto bad;
@@ -2280,8 +2309,11 @@ static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**
              PyModule_GetName(module), funcname, sig, desc);
         goto bad;
     }
-    tmp.p = PyCObject_AsVoidPtr(cobj);
+    tmp.p = PyCObject_AsVoidPtr(cobj);}
+#endif
     *f = tmp.fp;
+    if (!(*f))
+        goto bad;
     Py_DECREF(d);
     return 0;
 bad:
@@ -2292,12 +2324,14 @@ bad:
 """ % dict(API = Naming.api_name)
 )
 
+#------------------------------------------------------------------------------------
+
 register_cleanup_utility_code = UtilityCode(
 proto = """
 static int __Pyx_RegisterCleanup(void); /*proto*/
-static PyObject* __pyx_module_cleanup(PyObject *self, PyObject *unused); /*proto*/
-static PyMethodDef cleanup_def = {__Pyx_NAMESTR("__cleanup"), (PyCFunction)&__pyx_module_cleanup, METH_NOARGS, 0};
-""",
+static PyObject* %(module_cleanup)s(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyMethodDef cleanup_def = {__Pyx_NAMESTR("__cleanup"), (PyCFunction)&%(module_cleanup)s, METH_NOARGS, 0};
+""" % {'module_cleanup': Naming.cleanup_cname},
 impl = """
 static int __Pyx_RegisterCleanup(void) {
     /* Don't use Py_AtExit because that has a 32-call limit 
@@ -2414,6 +2448,9 @@ static int %(IMPORT_STAR)s(PyObject* m) {
     char* s;
     PyObject *locals = 0;
     PyObject *list = 0;
+#if PY_MAJOR_VERSION >= 3
+    PyObject *utf8_name = 0;
+#endif
     PyObject *name;
     PyObject *item;
     
@@ -2424,86 +2461,266 @@ static int %(IMPORT_STAR)s(PyObject* m) {
     for(i=0; i<PyList_GET_SIZE(list); i++) {
         name = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 0);
         item = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 1);
-#if PY_MAJOR_VERSION < 3
-        s = PyString_AsString(name);
+#if PY_MAJOR_VERSION >= 3
+        utf8_name = PyUnicode_AsUTF8String(name);
+        if (!utf8_name) goto bad;
+        s = PyBytes_AS_STRING(utf8_name);
+        if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad;
+        Py_DECREF(utf8_name); utf8_name = 0;
 #else
-        s = PyUnicode_AsString(name);
-#endif
+        s = PyString_AsString(name);
         if (!s) goto bad;
         if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad;
+#endif
     }
     ret = 0;
     
 bad:
     Py_XDECREF(locals);
     Py_XDECREF(list);
+#if PY_MAJOR_VERSION >= 3
+    Py_XDECREF(utf8_name);
+#endif
     return ret;
 }
 """ % {'IMPORT_STAR'     : Naming.import_star,
        'IMPORT_STAR_SET' : Naming.import_star_set }
         
-refcount_utility_code = UtilityCode(proto="""
-#ifdef CYTHON_REFNANNY
-typedef struct {
-  void (*INCREF)(void*, PyObject*, int);
-  void (*DECREF)(void*, PyObject*, int);
-  void (*GOTREF)(void*, PyObject*, int);
-  void (*GIVEREF)(void*, PyObject*, int);
-  void* (*NewContext)(const char*, int, const char*);
-  void (*FinishContext)(void**);
-} __Pyx_RefnannyAPIStruct;
-static __Pyx_RefnannyAPIStruct *__Pyx_Refnanny = NULL;
-#define __Pyx_ImportRefcountAPI(name) \
-  (__Pyx_RefnannyAPIStruct *) PyCObject_Import((char *)name, (char *)\"RefnannyAPI\")
-#define __Pyx_INCREF(r) __Pyx_Refnanny->INCREF(__pyx_refchk, (PyObject *)(r), __LINE__)
-#define __Pyx_DECREF(r) __Pyx_Refnanny->DECREF(__pyx_refchk, (PyObject *)(r), __LINE__)
-#define __Pyx_GOTREF(r) __Pyx_Refnanny->GOTREF(__pyx_refchk, (PyObject *)(r), __LINE__)
-#define __Pyx_GIVEREF(r) __Pyx_Refnanny->GIVEREF(__pyx_refchk, (PyObject *)(r), __LINE__)
-#define __Pyx_XDECREF(r) if((r) == NULL) ; else __Pyx_DECREF(r)
-#define __Pyx_SetupRefcountContext(name) \
-  void* __pyx_refchk = __Pyx_Refnanny->NewContext((name), __LINE__, __FILE__)
-#define __Pyx_FinishRefcountContext() \
-  __Pyx_Refnanny->FinishContext(&__pyx_refchk)
+refnanny_utility_code = UtilityCode(proto="""
+#ifndef CYTHON_REFNANNY
+  #define CYTHON_REFNANNY 0
+#endif
+
+#if CYTHON_REFNANNY
+  typedef struct {
+    void (*INCREF)(void*, PyObject*, int);
+    void (*DECREF)(void*, PyObject*, int);
+    void (*GOTREF)(void*, PyObject*, int);
+    void (*GIVEREF)(void*, PyObject*, int);
+    void* (*SetupContext)(const char*, int, const char*);
+    void (*FinishContext)(void**);
+  } __Pyx_RefNannyAPIStruct;
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+  static __Pyx_RefNannyAPIStruct * __Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)\"RefNannyAPI\");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+  end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+  }
+  #define __Pyx_RefNannySetupContext(name) \
+          void *__pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+  #define __Pyx_RefNannyFinishContext() \
+          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+  #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+  #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r);} } while(0)
 #else
-#define __Pyx_INCREF(r) Py_INCREF(r)
-#define __Pyx_DECREF(r) Py_DECREF(r)
-#define __Pyx_GOTREF(r)
-#define __Pyx_GIVEREF(r)
-#define __Pyx_XDECREF(r) Py_XDECREF(r)
-#define __Pyx_SetupRefcountContext(name)
-#define __Pyx_FinishRefcountContext()
+  #define __Pyx_RefNannySetupContext(name)
+  #define __Pyx_RefNannyFinishContext()
+  #define __Pyx_INCREF(r) Py_INCREF(r)
+  #define __Pyx_DECREF(r) Py_DECREF(r)
+  #define __Pyx_GOTREF(r)
+  #define __Pyx_GIVEREF(r)
+  #define __Pyx_XDECREF(r) Py_XDECREF(r)
 #endif /* CYTHON_REFNANNY */
-#define __Pyx_XGIVEREF(r) if((r) == NULL) ; else __Pyx_GIVEREF(r)
-#define __Pyx_XGOTREF(r) if((r) == NULL) ; else __Pyx_GOTREF(r)
+#define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);} } while(0)
+#define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r);} } while(0)
 """)
 
 
 main_method = UtilityCode(
 impl = """
-#if PY_MAJOR_VERSION < 3 || (!defined(WIN32) && !defined(MS_WINDOWS))
+#ifdef __FreeBSD__
+#include <floatingpoint.h>
+#endif
+
+#if PY_MAJOR_VERSION < 3
 int main(int argc, char** argv) {
-#else
+#elif defined(WIN32) || defined(MS_WINDOWS)
 int wmain(int argc, wchar_t **argv) {
+#else
+static int __Pyx_main(int argc, wchar_t **argv) {
 #endif
     int r = 0;
     PyObject* m = NULL;
+    /* 754 requires that FP exceptions run in "no stop" mode by default,
+     * and until C vendors implement C99's ways to control FP exceptions,
+     * Python requires non-stop mode.  Alas, some platforms enable FP
+     * exceptions by default.  Here we disable them.
+     */
+#ifdef __FreeBSD__
+    fp_except_t m;
+
+    m = fpgetmask();
+    fpsetmask(m & ~FP_X_OFL);
+#endif
     Py_SetProgramName(argv[0]);
     Py_Initialize();
     PySys_SetArgv(argc, argv);
+    %(module_is_main)s = 1;
 #if PY_MAJOR_VERSION < 3
         init%(module_name)s();
 #else
-        m = PyInit_%(module_name)s(name);
+        m = PyInit_%(module_name)s();
 #endif
     if (PyErr_Occurred() != NULL) {
         r = 1;
         PyErr_Print(); /* This exits with the right code if SystemExit. */
+#if PY_MAJOR_VERSION < 3
         if (Py_FlushLine()) PyErr_Clear();
+#endif
     }
     Py_XDECREF(m);
     Py_Finalize();
     return r;
 }
+
+
+#if PY_MAJOR_VERSION >= 3 && !defined(WIN32) && !defined(MS_WINDOWS)
+#include <locale.h>
+
+static wchar_t*
+__Pyx_char2wchar(char* arg)
+{
+       wchar_t *res;
+#ifdef HAVE_BROKEN_MBSTOWCS
+       /* Some platforms have a broken implementation of
+        * mbstowcs which does not count the characters that
+        * would result from conversion.  Use an upper bound.
+        */
+       size_t argsize = strlen(arg);
+#else
+       size_t argsize = mbstowcs(NULL, arg, 0);
+#endif
+       size_t count;
+       unsigned char *in;
+       wchar_t *out;
+#ifdef HAVE_MBRTOWC
+       mbstate_t mbs;
+#endif
+       if (argsize != (size_t)-1) {
+               res = (wchar_t *)malloc((argsize+1)*sizeof(wchar_t));
+               if (!res)
+                       goto oom;
+               count = mbstowcs(res, arg, argsize+1);
+               if (count != (size_t)-1) {
+                       wchar_t *tmp;
+                       /* Only use the result if it contains no
+                          surrogate characters. */
+                       for (tmp = res; *tmp != 0 &&
+                                    (*tmp < 0xd800 || *tmp > 0xdfff); tmp++)
+                               ;
+                       if (*tmp == 0)
+                               return res;
+               }
+               free(res);
+       }
+       /* Conversion failed. Fall back to escaping with surrogateescape. */
+#ifdef HAVE_MBRTOWC
+       /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */
+
+       /* Overallocate; as multi-byte characters are in the argument, the
+          actual output could use less memory. */
+       argsize = strlen(arg) + 1;
+       res = malloc(argsize*sizeof(wchar_t));
+       if (!res) goto oom;
+       in = (unsigned char*)arg;
+       out = res;
+       memset(&mbs, 0, sizeof mbs);
+       while (argsize) {
+               size_t converted = mbrtowc(out, (char*)in, argsize, &mbs);
+               if (converted == 0)
+                       /* Reached end of string; null char stored. */
+                       break;
+               if (converted == (size_t)-2) {
+                       /* Incomplete character. This should never happen,
+                          since we provide everything that we have -
+                          unless there is a bug in the C library, or I
+                          misunderstood how mbrtowc works. */
+                       fprintf(stderr, "unexpected mbrtowc result -2\\n");
+                       return NULL;
+               }
+               if (converted == (size_t)-1) {
+                       /* Conversion error. Escape as UTF-8b, and start over
+                          in the initial shift state. */
+                       *out++ = 0xdc00 + *in++;
+                       argsize--;
+                       memset(&mbs, 0, sizeof mbs);
+                       continue;
+               }
+               if (*out >= 0xd800 && *out <= 0xdfff) {
+                       /* Surrogate character.  Escape the original
+                          byte sequence with surrogateescape. */
+                       argsize -= converted;
+                       while (converted--)
+                               *out++ = 0xdc00 + *in++;
+                       continue;
+               }
+               /* successfully converted some bytes */
+               in += converted;
+               argsize -= converted;
+               out++;
+       }
+#else
+       /* Cannot use C locale for escaping; manually escape as if charset
+          is ASCII (i.e. escape all bytes > 128. This will still roundtrip
+          correctly in the locale's charset, which must be an ASCII superset. */
+       res = malloc((strlen(arg)+1)*sizeof(wchar_t));
+       if (!res) goto oom;
+       in = (unsigned char*)arg;
+       out = res;
+       while(*in)
+               if(*in < 128)
+                       *out++ = *in++;
+               else
+                       *out++ = 0xdc00 + *in++;
+       *out = 0;
+#endif
+       return res;
+oom:
+       fprintf(stderr, "out of memory\\n");
+       return NULL;
+}
+
+int
+main(int argc, char **argv)
+{
+       wchar_t **argv_copy = (wchar_t **)malloc(sizeof(wchar_t*)*argc);
+       /* We need a second copies, as Python might modify the first one. */
+       wchar_t **argv_copy2 = (wchar_t **)malloc(sizeof(wchar_t*)*argc);
+       int i, res;
+       char *oldloc;
+       if (!argv_copy || !argv_copy2) {
+               fprintf(stderr, "out of memory\\n");
+               return 1;
+       }
+       oldloc = strdup(setlocale(LC_ALL, NULL));
+       setlocale(LC_ALL, "");
+       for (i = 0; i < argc; i++) {
+               argv_copy2[i] = argv_copy[i] = __Pyx_char2wchar(argv[i]);
+               if (!argv_copy[i])
+                       return 1;
+       }
+       setlocale(LC_ALL, oldloc);
+       free(oldloc);
+       res = __Pyx_main(argc, argv_copy);
+       for (i = 0; i < argc; i++) {
+               free(argv_copy2[i]);
+       }
+       free(argv_copy);
+       free(argv_copy2);
+       return res;
+}
+#endif
 """)
 
 packed_struct_utility_code = UtilityCode(proto="""