PyObject -> Py_ssize_t now uses __index__ rather than __int__ (even in function signa...
authorRobert Bradshaw <robertwb@math.washington.edu>
Sun, 19 Aug 2007 00:40:39 +0000 (17:40 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Sun, 19 Aug 2007 00:40:39 +0000 (17:40 -0700)
Cython/Compiler/ModuleNode.py
Cython/Compiler/Nodes.py
Cython/Compiler/PyrexTypes.py

index 4fd310fcc112ea13ae5fae01db6e88876a1c1089..390860cf896ef3c9b33c9421c8f290cb1af73be2 100644 (file)
@@ -173,6 +173,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.putln("  #define PY_SSIZE_T_MIN INT_MIN")
         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")
         self.generate_extern_c_macro_definition(code)
         code.putln("%s double pow(double, double);" % Naming.extern_c_macro)
index 9273012063b022805f81deeab6a679d26bb17aa3..c7329d5781e5160ce224bcd37a3f0ef23f967e67 100644 (file)
@@ -851,6 +851,12 @@ class DefNode(FuncDefNode):
                 if arg.is_generic and arg.type.is_extension_type:
                     arg.needs_type_test = 1
                     any_type_tests_needed = 1
+                elif arg.type is PyrexTypes.c_py_ssize_t_type:
+                    # Want to use __index__ rather than __int__ method
+                    # that PyArg_ParseTupleAndKeywords calls
+                    arg.needs_conversion = 1
+                    arg.hdr_type = PyrexTypes.py_object_type
+                    arg.hdr_cname = Naming.arg_prefix + arg.name
         if any_type_tests_needed:
             env.use_utility_code(arg_type_test_utility_code)
     
@@ -980,7 +986,11 @@ class DefNode(FuncDefNode):
     def generate_argument_declarations(self, env, code):
         for arg in self.args:
             if arg.is_generic: # or arg.needs_conversion:
-                code.put_var_declaration(arg.entry)
+                if arg.needs_conversion:
+                    code.putln("PyObject *%s = 0;" % arg.hdr_cname)
+                else:
+                    code.put_var_declaration(arg.entry)
+                    
     
     def generate_keyword_list(self, code):
         if self.entry.signature.has_generic_args:
@@ -994,7 +1004,7 @@ class DefNode(FuncDefNode):
                             arg.name)
             code.putln(
                 "0};")
-    
+                        
     def generate_argument_parsing_code(self, code):
         # Generate PyArg_ParseTuple call for generic
         # arguments, if any.
@@ -1015,8 +1025,12 @@ class DefNode(FuncDefNode):
                         default_seen = 1
                     elif default_seen:
                         error(arg.pos, "Non-default argument following default argument")
-                    arg_addrs.append("&" + arg_entry.cname)
-                    format = arg_entry.type.parsetuple_format
+                    if arg.needs_conversion:
+                        arg_addrs.append("&" + arg.hdr_cname)
+                        format = arg.hdr_type.parsetuple_format
+                    else:
+                        arg_addrs.append("&" + arg_entry.cname)
+                        format = arg_entry.type.parsetuple_format
                     if format:
                         arg_formats.append(format)
                     else:
@@ -1088,7 +1102,9 @@ class DefNode(FuncDefNode):
         old_type = arg.hdr_type
         new_type = arg.type
         if old_type.is_pyobject:
+            code.putln("if (%s) {" % arg.hdr_cname)
             self.generate_arg_conversion_from_pyobject(arg, code)
+            code.putln("}")
         elif new_type.is_pyobject:
             self.generate_arg_conversion_to_pyobject(arg, code)
         else:
@@ -2602,6 +2618,8 @@ typedef struct {const char *s; const void **p;} __Pyx_CApiTabEntry; /*proto*/
 typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/
 typedef struct {PyObject **p; char *s; long n;} __Pyx_StringTabEntry; /*proto*/
 
+#define __pyx_PyIndex_AsSsize_t(b) PyInt_AsSsize_t(PyNumber_Index(b))
+
 #define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
 static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
    if (x == Py_True) return 1;
index b25fbc30fb884c3ec0930e60f7cbd9e8c5fc2f65..594f8836dd0fa83dac773e435c183228596c0a7e 100644 (file)
@@ -352,7 +352,7 @@ class CBIntType(CIntType):
 class CPySSizeTType(CIntType):
 
     to_py_function = "PyInt_FromSsize_t"
-    from_py_function = "PyInt_AsSsize_t"
+    from_py_function = "__pyx_PyIndex_AsSsize_t"
 
 
 class CUIntType(CIntType):