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
                     # Otherwise, we'll check the particular type of
                     # the object.
                     # the object.
                     condition = '(isinstance(_args[' + `level` + '], ' + typeName + '))'
                     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')
                 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
         It is valid to pass in None for methodClass if you are not in any methodClass
         """
         """
         if FFIConstants.wantTypeChecking:
         if FFIConstants.wantTypeChecking:
-            for methodArgSpec in args:
+            for i in range(len(args)):
+                methodArgSpec = args[i]
                 typeDesc = methodArgSpec.typeDescriptor.recursiveTypeDescriptor()
                 typeDesc = methodArgSpec.typeDescriptor.recursiveTypeDescriptor()
                 typeName = FFIOverload.getTypeName(methodClass, typeDesc)
                 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)
                     # Get the real return type (not derived)
                     if ((not typeDesc.isNested) and
                     if ((not typeDesc.isNested) and
                         # Do not put our own module in the import list
                         # 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, '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):
     def outputCFunctionComment(self, file, nesting):
         """
         """