Browse Source

more robust handling of numeric parameters

David Rose 21 years ago
parent
commit
a4bad0eb36
2 changed files with 21 additions and 26 deletions
  1. 10 6
      direct/src/ffi/FFIOverload.py
  2. 11 20
      direct/src/ffi/FFISpecs.py

+ 10 - 6
direct/src/ffi/FFIOverload.py

@@ -420,12 +420,16 @@ class FFIMethodArgumentTree:
                     # Otherwise, we'll check the particular type of
                     # the object.
                     condition = '(isinstance(_args[' + `level` + '], ' + typeName + '))'
-                    # If it is looking for a float or a long, make it
-                    # accept an integer too
-                    if (typeName == 'types.FloatType' or typeName == 'types.LongType'):
-                        condition += (' or (isinstance(_args[' + `level` + '], '
-                                      + 'types.IntType'
-                                      + '))')
+                    # Legal types for a float parameter include int and long.
+                    if (typeName == 'types.FloatType'):
+                        condition += (' or (isinstance(_args[' + `level` + '], types.IntType))')
+                        condition += (' or (isinstance(_args[' + `level` + '], types.LongType))')
+                    # Legal types for a long parameter include int.
+                    elif (typeName == 'types.LongType'):
+                        condition += (' or (isinstance(_args[' + `level` + '], types.IntType))')
+                    # Legal types for an int parameter include long.
+                    elif (typeName == 'types.IntType'):
+                        condition += (' or (isinstance(_args[' + `level` + '], types.LongType))')
                     
                 indent(file, nesting+2, 'if ' + condition + ':\n')
                     

+ 11 - 20
direct/src/ffi/FFISpecs.py

@@ -36,33 +36,24 @@ class FunctionSpecification:
         It is valid to pass in None for methodClass if you are not in any methodClass
         """
         if FFIConstants.wantTypeChecking:
-            for methodArgSpec in args:
+            for i in range(len(args)):
+                methodArgSpec = args[i]
                 typeDesc = methodArgSpec.typeDescriptor.recursiveTypeDescriptor()
                 typeName = FFIOverload.getTypeName(methodClass, typeDesc)
 
-                # Special case:
-                # If it is looking for a float or a long, accept an int as well
-                # C++ will cast it properly, and it is much more convenient
-                if (typeName == 'types.FloatType'):
-                    indent(file, nesting, 'assert((isinstance(' +
-                           methodArgSpec.name + ', types.FloatType) or isinstance(' +
-                           methodArgSpec.name + ', types.IntType)))\n')
-
-                elif (typeName == 'types.LongType'):
-                    indent(file, nesting, 'assert((isinstance(' +
-                           methodArgSpec.name + ', types.LongType) or isinstance(' +
-                           methodArgSpec.name + ', types.IntType)))\n')
-
-                elif typeDesc.__class__ != FFITypes.PyObjectTypeDescriptor:
+                # We only do type checking on class types.  C++ can do
+                # type checking on the primitive types, and will do a
+                # better job anyway.
+                if typeDesc.__class__ == FFITypes.ClassTypeDescriptor:
                     # Get the real return type (not derived)
                     if ((not typeDesc.isNested) and
                         # Do not put our own module in the import list
-                        (methodClass != typeDesc) and
-                        # If this is a class (not a primitive), put it on the list
-                        (typeDesc.__class__ == FFITypes.ClassTypeDescriptor)):
+                        (methodClass != typeDesc)):
                         indent(file, nesting, 'import ' + typeDesc.foreignTypeName + '\n')
-                    indent(file, nesting, 'assert(isinstance(' +
-                           methodArgSpec.name + ', ' + typeName + '))\n')
+                    indent(file, nesting, 'if not isinstance(' +
+                           methodArgSpec.name + ', ' + typeName + '):\n')
+                    indent(file, nesting + 1,
+                           'raise TypeError, "Invalid argument %s, expected <%s>"\n' % (i, typeDesc.foreignTypeName))
 
     def outputCFunctionComment(self, file, nesting):
         """