| | """The wrapping code for providing natural ctypes-based OpenGL interface""" |
| | import ctypes, logging |
| | from OpenGL import platform, error |
| | from OpenGL._configflags import STORE_POINTERS, ERROR_ON_COPY, SIZE_1_ARRAY_UNPACK |
| | from OpenGL import converters |
| | from OpenGL.converters import DefaultCConverter |
| | from OpenGL.converters import returnCArgument,returnPyArgument |
| | from OpenGL.latebind import LateBind |
| | from OpenGL.arrays import arrayhelpers, arraydatatype |
| | from OpenGL._null import NULL |
| | _log = logging.getLogger( 'OpenGL.wrapper' ) |
| |
|
| | from OpenGL import acceleratesupport |
| | cWrapper = None |
| | if acceleratesupport.ACCELERATE_AVAILABLE: |
| | try: |
| | from OpenGL_accelerate.latebind import LateBind |
| | from OpenGL_accelerate.wrapper import ( |
| | Wrapper as cWrapper, |
| | CArgCalculator, |
| | PyArgCalculator, |
| | CArgumentCalculator, |
| | ) |
| | except ImportError as err: |
| | _log.warn( """OpenGL_accelerate seems to be installed, but unable to import expected wrapper entry points!""" ) |
| |
|
| | if not STORE_POINTERS: |
| | if not ERROR_ON_COPY: |
| | _log.error( """You've specified (not STORE_POINTERS) yet ERROR_ON_COPY is False, this would cause segfaults, so (not STORE_POINTERS) is being ignored""" ) |
| | STORE_POINTERS = True |
| |
|
| |
|
| | def asList( o ): |
| | """Convert to a list if not already one""" |
| | if not isinstance( o, list ): |
| | return list(o) |
| | return o |
| |
|
| | def none_or_pass( incoming, function, arguments ): |
| | return incoming |
| | none_or_pass.optional=True |
| |
|
| | class Wrapper( LateBind ): |
| | """Wrapper around a ctypes cFunction object providing SWIG-like hooks |
| | |
| | Attributes: |
| | |
| | wrappedOperation -- base operation, normally a ctypes function |
| | with data-types and error-checking specified |
| | pyConverters -- converters for incoming Python arguments, |
| | provide 1:1 mapping to incoming Python arguments, can |
| | suppress an argument from the argument-set as well |
| | see setPyConverter |
| | pyConverterNames -- caching/storage of the argument names |
| | for the Python converters |
| | cConverters -- converters for incoming C-level arguments |
| | produce Python-level objects in 1:1 mapping to ctypes |
| | arguments from pyConverters results |
| | see setCConverter |
| | cResolvers -- converters turning Python-level objects into |
| | ctypes-compatible data-types |
| | see setCResolver |
| | |
| | Generic Attributes: |
| | |
| | {ARG1}_LOOKUP_{ARG2} -- lookup dictionaries to provide sizes for |
| | ARG1 output value from the value of ARG2, provided for |
| | documentation/reference |
| | {ARG1}_FROM_{ARG2} -- lookup functions to provide sizes for ARG1 |
| | output value from the value of ARG2, provided for |
| | documentation/reference |
| | """ |
| | localProperties = ( |
| | 'wrappedOperation', |
| | '__file__', |
| | 'pyConverters', |
| | 'pyConverterNames', |
| | 'cConverters', |
| | 'cResolvers', |
| | 'storeValues', |
| | 'returnValues', |
| | '_finalCall', |
| | ) |
| | def __init__( self, wrappedOperation ): |
| | """Initialise the wrapper, storing wrappedOperation""" |
| | if isinstance( wrappedOperation, Wrapper ): |
| | wrappedOperation = wrappedOperation.wrappedOperation |
| | self.wrappedOperation = wrappedOperation |
| | def __getattr__( self, key ): |
| | """Delegate attribute lookup to our wrappedOperation""" |
| | if key != 'wrappedOperation': |
| | return getattr( self.wrappedOperation, key ) |
| | raise AttributeError( key ) |
| | def __nonzero__( self ): |
| | """Is this function/wrapper available?""" |
| | return bool( self.wrappedOperation ) |
| | __bool__ = __nonzero__ |
| | def __setattr__( self, key, value ): |
| | """Forward attribute setting to our wrappedOperation""" |
| | if key in self.localProperties: |
| | super( Wrapper, self ).__setattr__( key, value ) |
| | else: |
| | return setattr( self.wrappedOperation, key, value ) |
| | def pyArgIndex( self, argName ): |
| | """Return the Python-argument index for the given argument name""" |
| | argNames = getattr( self, 'pyConverterNames', None ) |
| | if argNames is None: |
| | argNames = self.wrappedOperation.argNames |
| | try: |
| | return asList( argNames ).index( argName ) |
| | except (ValueError,IndexError) as err: |
| | raise KeyError( """No argument %r in argument list %r"""%( |
| | argName, argNames |
| | )) |
| | def cArgIndex( self, argName ): |
| | """Return the C-argument index for the given argument name""" |
| | argNames = self.wrappedOperation.argNames |
| | try: |
| | return asList( argNames ).index( argName ) |
| | except (ValueError,IndexError) as err: |
| | raise KeyError( """No argument %r in argument list %r"""%( |
| | argName, argNames |
| | )) |
| | def setOutput( |
| | self, outArg, size=(1,), pnameArg=None, |
| | arrayType=None, oldStyleReturn=SIZE_1_ARRAY_UNPACK, |
| | orPassIn = False, |
| | ): |
| | """Set the given argName to be an output array |
| | |
| | size -- either a tuple compatible with arrayType.zeros or |
| | a function taking pname to produce such a value. |
| | arrayType -- array data-type used to generate the output |
| | array using the zeros class method... |
| | pnameArg -- optional argument passed into size function, that |
| | is, the name of the argument whose *value* will be passed |
| | to the size function, often the name of an input argument |
| | to be "sized" to match the output argument. |
| | """ |
| | if arrayType is None: |
| | |
| | index = self.cArgIndex( outArg ) |
| | arrayType = self.wrappedOperation.argtypes[ index ] |
| | if not hasattr( arrayType, 'asArray' ): |
| | if arrayType == ctypes.c_void_p: |
| | from OpenGL.arrays import GLubyteArray |
| | arrayType = GLubyteArray |
| | else: |
| | raise TypeError( "Should only have array types for output parameters" ) |
| | if pnameArg is None: |
| | assert not hasattr(size,'__call__' ) |
| | if orPassIn: |
| | cls = converters.OutputOrInput |
| | else: |
| | cls = converters.Output |
| | conv = cls( |
| | name=outArg, |
| | size=size, |
| | arrayType=arrayType, |
| | ) |
| | else: |
| | if isinstance( size, dict ): |
| | setattr( self, '%s_LOOKUP_%s'%(outArg,pnameArg), size ) |
| | size = size.__getitem__ |
| | else: |
| | setattr( self, '%s_FROM_%s'%(outArg,pnameArg), size ) |
| | assert hasattr( size, '__call__' ) |
| | if orPassIn: |
| | cls = converters.SizedOutputOrInput |
| | else: |
| | cls = converters.SizedOutput |
| | conv = cls( |
| | name=outArg, |
| | specifier=pnameArg, |
| | lookup=size, |
| | arrayType=arrayType, |
| | ) |
| | if oldStyleReturn: |
| | returnObject = conv.oldStyleReturn |
| | else: |
| | returnObject = converters.returnCArgument( outArg ) |
| | if orPassIn: |
| | self.setPyConverter( |
| | outArg, none_or_pass |
| | ) |
| | else: |
| | self.setPyConverter( outArg ) |
| | return self.setCConverter( |
| | outArg, conv, |
| | ).setReturnValues( |
| | returnObject |
| | ) |
| | def typeOfArg( self, outArg ): |
| | """Retrieve the defined data-type for the given outArg (name)""" |
| | index = self.cArgIndex( outArg ) |
| | return self.wrappedOperation.argtypes[ index ] |
| | |
| | if not ERROR_ON_COPY: |
| | def setInputArraySize( self, argName, size=None ): |
| | """Decorate function with vector-handling code for a single argument |
| | |
| | if OpenGL.ERROR_ON_COPY is False, then we return the |
| | named argument, converting to the passed array type, |
| | optionally checking that the array matches size. |
| | |
| | if OpenGL.ERROR_ON_COPY is True, then we will dramatically |
| | simplify this function, only wrapping if size is True, i.e. |
| | only wrapping if we intend to do a size check on the array. |
| | """ |
| | arrayType = self.typeOfArg( argName ) |
| | if not hasattr( arrayType, 'asArray' ): |
| | if arrayType == ctypes.c_void_p: |
| | |
| | self.setPyConverter( |
| | argName, |
| | converters.CallFuncPyConverter( arraydatatype.ArrayDatatype.asArray ) |
| | ) |
| | self.setCConverter( argName, converters.getPyArgsName( argName ) ) |
| | return self |
| | elif hasattr( arrayType, '_type_' ) and hasattr(arrayType._type_, '_type_' ): |
| | |
| | |
| | return self |
| | else: |
| | raise TypeError( "Should only have array types for output parameters: got %s"%(arrayType,) ) |
| | if size is not None: |
| | self.setPyConverter( argName, arrayhelpers.asArrayTypeSize(arrayType, size) ) |
| | else: |
| | self.setPyConverter( argName, arrayhelpers.asArrayType(arrayType) ) |
| | self.setCConverter( argName, converters.getPyArgsName( argName ) ) |
| | return self |
| | else: |
| | def setInputArraySize( self, argName, size=None ): |
| | """Decorate function with vector-handling code for a single argument |
| | |
| | if OpenGL.ERROR_ON_COPY is False, then we return the |
| | named argument, converting to the passed array type, |
| | optionally checking that the array matches size. |
| | |
| | if OpenGL.ERROR_ON_COPY is True, then we will dramatically |
| | simplify this function, only wrapping if size is True, i.e. |
| | only wrapping if we intend to do a size check on the array. |
| | """ |
| | if size is not None: |
| | arrayType = self.typeOfArg( argName ) |
| | |
| | if hasattr( arrayType, 'asArray' ): |
| | self.setPyConverter( argName, arrayhelpers.asArrayTypeSize(arrayType, size) ) |
| | self.setCConverter( argName, |
| | converters.getPyArgsName( argName ) |
| | ) |
| | return self |
| | |
| | def setPyConverter( self, argName, function = NULL ): |
| | """Set Python-argument converter for given argument |
| | |
| | argName -- the argument name which will be coerced to a usable internal |
| | format using the function provided. |
| | function -- None (indicating a simple copy), NULL (default) to eliminate |
| | the argument from the Python argument-list, or a callable object with |
| | the signature: |
| | |
| | converter(arg, wrappedOperation, args) |
| | |
| | where arg is the particular argument on which the convert is working, |
| | wrappedOperation is the underlying wrapper, and args is the set of |
| | original Python arguments to the function. |
| | |
| | Note that you need exactly the same number of pyConverters as Python |
| | arguments. |
| | """ |
| | if not hasattr( self, 'pyConverters' ): |
| | self.pyConverters = [None]*len( self.wrappedOperation.argNames ) |
| | self.pyConverterNames = list(self.wrappedOperation.argNames) |
| | try: |
| | i = asList( self.pyConverterNames ).index( argName ) |
| | except ValueError: |
| | raise AttributeError( """No argument named %r left in pyConverters for %r: %s"""%( |
| | argName, self.wrappedOperation.__name__, self.pyConverterNames, |
| | )) |
| | if function is NULL: |
| | del self.pyConverters[i] |
| | del self.pyConverterNames[i] |
| | else: |
| | self.pyConverters[i] = function |
| | return self |
| | def setCConverter( self, argName, function ): |
| | """Set C-argument converter for a given argument |
| | |
| | argName -- the argument name whose C-compatible representation will |
| | be calculated with the passed function. |
| | function -- None (indicating a simple copy), a non-callable object to |
| | be copied into the result-list itself, or a callable object with |
| | the signature: |
| | |
| | converter( pyArgs, index, wrappedOperation ) |
| | |
| | where pyArgs is the set of passed Python arguments, with the |
| | pyConverters already applied, index is the index of the C argument |
| | and wrappedOperation is the underlying function. |
| | |
| | C-argument converters are your chance to expand/contract a Python |
| | argument list (pyArgs) to match the number of arguments expected by |
| | the ctypes baseOperation. You can't have a "null" C-argument converter, |
| | as *something* has to be passed to the C-level function in the |
| | parameter. |
| | """ |
| | if not hasattr( self, 'cConverters' ): |
| | self.cConverters = [None]*len( self.wrappedOperation.argNames ) |
| | try: |
| | if not isinstance(self.wrappedOperation.argNames, list): |
| | self.wrappedOperation.argNames = list( self.wrappedOperation.argNames ) |
| | i = asList( self.wrappedOperation.argNames ).index( argName ) |
| | except ValueError: |
| | raise AttributeError( """No argument named %r left in cConverters: %s"""%( |
| | argName, self.wrappedOperation.argNames, |
| | )) |
| | self.cConverters[i] = function |
| | return self |
| | def setCResolver( self, argName, function=NULL ): |
| | """Set C-argument converter for a given argument""" |
| | if not hasattr( self, 'cResolvers' ): |
| | self.cResolvers = [None]*len( self.wrappedOperation.argNames ) |
| | try: |
| | if not isinstance(self.wrappedOperation.argNames, list): |
| | self.wrappedOperation.argNames = list( self.wrappedOperation.argNames ) |
| | i = asList( self.wrappedOperation.argNames).index( argName ) |
| | except ValueError: |
| | raise AttributeError( """No argument named %r left in cConverters: %s"""%( |
| | argName, self.wrappedOperation.argNames, |
| | )) |
| | if function is NULL: |
| | del self.cResolvers[i] |
| | else: |
| | self.cResolvers[i] = function |
| | return self |
| | def setStoreValues( self, function=NULL ): |
| | """Set the storage-of-arguments function for the whole wrapper""" |
| | if function is NULL or ERROR_ON_COPY and not STORE_POINTERS: |
| | try: |
| | del self.storeValues |
| | except Exception as err: |
| | pass |
| | else: |
| | self.storeValues = function |
| | return self |
| | def setReturnValues( self, function=NULL ): |
| | """Set the return-of-results function for the whole wrapper""" |
| | if function is NULL: |
| | try: |
| | del self.returnValues |
| | except Exception as err: |
| | pass |
| | else: |
| | self.returnValues = function |
| | return self |
| | |
| | def finalise( self ): |
| | """Finalise our various elements into simple index-based operations""" |
| | for attribute in ('pyConverters','cConverters','cResolvers' ): |
| | value = getattr( self, attribute, None ) |
| | if value is not None: |
| | for i,item in enumerate(value): |
| | if hasattr( item, 'finalise' ): |
| | try: |
| | item.finalise( self ) |
| | except Exception as err: |
| | raise error.Error( |
| | """Error finalising item %s in %s for %s (%r): %s"""%( |
| | i,attribute,self,item,err, |
| | ) |
| | ) |
| | if hasattr( self, 'cConverters' ): |
| | for i,converter in enumerate( self.cConverters ): |
| | if isinstance( converter, (type(None),DefaultCConverter )): |
| | self.cConverters[i] = DefaultCConverter( self.pyArgIndex( self.argNames[i]) ) |
| | for attribute in ('storeValues','returnValues',): |
| | item = getattr( self, attribute, None ) |
| | if hasattr( item, 'finalise' ): |
| | item.finalise( self ) |
| | callFunction = self.finaliseCall() |
| | if not callFunction: |
| | raise RuntimeError( """Missing finalised call type for %s"""%( self, )) |
| | else: |
| | |
| | |
| | |
| | |
| | |
| | |
| | self.setFinalCall( callFunction ) |
| | return callFunction |
| | |
| | def finaliseCall( self ): |
| | """Produce specialised versions of call for finalised wrapper object |
| | |
| | This returns a version of __call__ that only does that work which is |
| | required by the particular wrapper object |
| | |
| | This is essentially a huge set of expanded nested functions, very |
| | inelegant... |
| | """ |
| | pyConverters = getattr( self, 'pyConverters', None ) |
| | cConverters = getattr( self, 'cConverters', None ) |
| | cResolvers = getattr( self, 'cResolvers', None ) |
| | wrappedOperation = self.wrappedOperation |
| | storeValues = getattr( self, 'storeValues', None ) |
| | returnValues = getattr( self, 'returnValues', None ) |
| | if pyConverters: |
| | if cWrapper: |
| | calculate_pyArgs = PyArgCalculator( |
| | self,pyConverters, |
| | ) |
| | else: |
| | pyConverters_mapped = [ |
| | (i,converter,(converter is None)) |
| | for (i,converter) in enumerate( pyConverters ) |
| | ] |
| | pyConverters_length = len([p for p in pyConverters if not getattr( p, 'optional', False)]) |
| | def calculate_pyArgs( args ): |
| | if pyConverters_length > len(args): |
| | raise ValueError( |
| | """%s requires %r arguments (%s), received %s: %r"""%( |
| | wrappedOperation.__name__, |
| | pyConverters_length, |
| | ", ".join( self.pyConverterNames ), |
| | len(args), |
| | args |
| | ) |
| | ) |
| | for index,converter,isNone in pyConverters_mapped: |
| | if isNone: |
| | yield args[index] |
| | else: |
| | try: |
| | yield converter(args[index], self, args) |
| | except IndexError as err: |
| | yield NULL |
| | except Exception as err: |
| | if hasattr( err, 'args' ): |
| | err.args += ( converter, ) |
| | raise |
| | else: |
| | calculate_pyArgs = None |
| | if cConverters: |
| | if cWrapper: |
| | calculate_cArgs = CArgCalculator( self, cConverters ) |
| | else: |
| | cConverters_mapped = [ |
| | (i,converter,hasattr(converter,'__call__')) |
| | for (i,converter) in enumerate( cConverters ) |
| | ] |
| | def calculate_cArgs( pyArgs ): |
| | for index,converter,canCall in cConverters_mapped: |
| | if canCall: |
| | try: |
| | yield converter( pyArgs, index, self ) |
| | except Exception as err: |
| | if hasattr( err, 'args' ): |
| | err.args += ( |
| | """Failure in cConverter %r"""%(converter), |
| | pyArgs, index, self, |
| | ) |
| | raise |
| | else: |
| | yield converter |
| | else: |
| | calculate_cArgs = None |
| | if cResolvers: |
| | if cWrapper: |
| | calculate_cArguments = CArgumentCalculator( cResolvers ) |
| | else: |
| | cResolvers_mapped = list(enumerate(cResolvers)) |
| | def calculate_cArguments( cArgs ): |
| | for i,converter in cResolvers_mapped: |
| | if converter is None: |
| | yield cArgs[i] |
| | else: |
| | try: |
| | yield converter( cArgs[i] ) |
| | except Exception as err: |
| | err.args += (converter,) |
| | raise |
| | else: |
| | calculate_cArguments = None |
| | if cWrapper: |
| | return cWrapper( |
| | wrappedOperation, |
| | calculate_pyArgs=calculate_pyArgs, |
| | calculate_cArgs=calculate_cArgs, |
| | calculate_cArguments=calculate_cArguments, |
| | storeValues=storeValues, |
| | returnValues=returnValues, |
| | ) |
| | if pyConverters: |
| | if cConverters: |
| | |
| | if cResolvers: |
| | if storeValues: |
| | if returnValues: |
| | def wrapperCall( *args ): |
| | """Wrapper with all possible operations""" |
| | pyArgs = tuple( calculate_pyArgs( args )) |
| | cArgs = tuple(calculate_cArgs( pyArgs )) |
| | cArguments = tuple(calculate_cArguments( cArgs )) |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | |
| | storeValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | return returnValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | return wrapperCall |
| | else: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save returnValues""" |
| | pyArgs = tuple( calculate_pyArgs( args )) |
| | cArgs = tuple(calculate_cArgs( pyArgs )) |
| | cArguments = tuple(calculate_cArguments( cArgs )) |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | |
| | storeValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | return result |
| | return wrapperCall |
| | else: |
| | if returnValues: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save storeValues""" |
| | pyArgs = tuple( calculate_pyArgs( args )) |
| | cArgs = tuple(calculate_cArgs( pyArgs )) |
| | cArguments = tuple(calculate_cArguments( cArgs )) |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | return returnValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | return wrapperCall |
| | else: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save returnValues and storeValues""" |
| | pyArgs = tuple( calculate_pyArgs( args )) |
| | cArgs = tuple(calculate_cArgs( pyArgs )) |
| | cArguments = tuple(calculate_cArguments( cArgs )) |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | return result |
| | return wrapperCall |
| | else: |
| | |
| | if storeValues: |
| | if returnValues: |
| | def wrapperCall( *args ): |
| | """Wrapper with all possible operations""" |
| | pyArgs = tuple( calculate_pyArgs( args )) |
| | cArgs = tuple(calculate_cArgs( pyArgs )) |
| | cArguments = cArgs |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | |
| | storeValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | return returnValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | return wrapperCall |
| | else: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save returnValues""" |
| | pyArgs = tuple( calculate_pyArgs( args )) |
| | cArgs = tuple(calculate_cArgs( pyArgs )) |
| | cArguments = cArgs |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | |
| | storeValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | return result |
| | return wrapperCall |
| | else: |
| | if returnValues: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save storeValues""" |
| | pyArgs = tuple( calculate_pyArgs( args )) |
| | cArgs = tuple(calculate_cArgs( pyArgs )) |
| | cArguments = cArgs |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | return returnValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | return wrapperCall |
| | else: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save returnValues and storeValues""" |
| | pyArgs = tuple( calculate_pyArgs( args )) |
| | cArgs = tuple(calculate_cArgs( pyArgs )) |
| | cArguments = cArgs |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | return result |
| | return wrapperCall |
| | else: |
| | |
| | if cResolvers: |
| | if storeValues: |
| | if returnValues: |
| | def wrapperCall( *args ): |
| | """Wrapper with all possible operations""" |
| | pyArgs = tuple( calculate_pyArgs( args )) |
| | cArgs = pyArgs |
| | cArguments = tuple(calculate_cArguments( cArgs )) |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | |
| | storeValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | return returnValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | return wrapperCall |
| | else: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save returnValues""" |
| | pyArgs = tuple( calculate_pyArgs( args )) |
| | cArgs = pyArgs |
| | cArguments = tuple(calculate_cArguments( cArgs )) |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | |
| | storeValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | return result |
| | return wrapperCall |
| | else: |
| | if returnValues: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save storeValues""" |
| | pyArgs = tuple( calculate_pyArgs( args )) |
| | cArgs = pyArgs |
| | cArguments = tuple(calculate_cArguments( cArgs )) |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | return returnValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | return wrapperCall |
| | else: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save returnValues and storeValues""" |
| | pyArgs = tuple( calculate_pyArgs( args )) |
| | cArgs = pyArgs |
| | cArguments = tuple(calculate_cArguments( cArgs )) |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | return result |
| | return wrapperCall |
| | else: |
| | |
| | if storeValues: |
| | if returnValues: |
| | def wrapperCall( *args ): |
| | """Wrapper with all possible operations""" |
| | pyArgs = tuple( calculate_pyArgs( args )) |
| | cArguments = pyArgs |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArguments |
| | err.pyArgs = pyArgs |
| | raise err |
| | |
| | storeValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArguments, |
| | ) |
| | return returnValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArguments, |
| | ) |
| | return wrapperCall |
| | else: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save returnValues""" |
| | pyArgs = tuple( calculate_pyArgs( args )) |
| | cArguments = pyArgs |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArguments |
| | err.pyArgs = pyArgs |
| | raise err |
| | |
| | storeValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArguments, |
| | ) |
| | return result |
| | return wrapperCall |
| | else: |
| | if returnValues: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save storeValues""" |
| | pyArgs = tuple( calculate_pyArgs( args )) |
| | cArguments = pyArgs |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArguments |
| | err.pyArgs = pyArgs |
| | raise err |
| | return returnValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArguments, |
| | ) |
| | return wrapperCall |
| | else: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save returnValues and storeValues""" |
| | pyArgs = tuple( calculate_pyArgs( args )) |
| | cArguments = pyArgs |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArguments |
| | err.pyArgs = pyArgs |
| | raise err |
| | return result |
| | return wrapperCall |
| | else: |
| | |
| | if cConverters: |
| | if cResolvers: |
| | if storeValues: |
| | if returnValues: |
| | def wrapperCall( *args ): |
| | """Wrapper with all possible operations""" |
| | pyArgs = args |
| | cArgs = [] |
| | for (index,converter) in enumerate( cConverters ): |
| | |
| | if not hasattr(converter,'__call__'): |
| | cArgs.append( converter ) |
| | else: |
| | try: |
| | cArgs.append( |
| | converter( pyArgs, index, self ) |
| | ) |
| | except Exception as err: |
| | if hasattr( err, 'args' ): |
| | err.args += ( |
| | """Failure in cConverter %r"""%(converter), |
| | pyArgs, index, |
| | ) |
| | raise |
| | cArguments = tuple(calculate_cArguments( cArgs )) |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | |
| | storeValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | return returnValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | return wrapperCall |
| | else: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save returnValues""" |
| | pyArgs = args |
| | cArgs = [] |
| | for (index,converter) in enumerate( cConverters ): |
| | |
| | if not hasattr(converter,'__call__'): |
| | cArgs.append( converter ) |
| | else: |
| | try: |
| | cArgs.append( |
| | converter( pyArgs, index, self ) |
| | ) |
| | except Exception as err: |
| | if hasattr( err, 'args' ): |
| | err.args += ( |
| | """Failure in cConverter %r"""%(converter), |
| | pyArgs, index, |
| | ) |
| | raise |
| | cArguments = tuple(calculate_cArguments( cArgs )) |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | |
| | storeValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | return result |
| | return wrapperCall |
| | else: |
| | if returnValues: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save storeValues""" |
| | pyArgs = args |
| | cArgs = [] |
| | for (index,converter) in enumerate( cConverters ): |
| | |
| | if not hasattr(converter,'__call__'): |
| | cArgs.append( converter ) |
| | else: |
| | try: |
| | cArgs.append( |
| | converter( pyArgs, index, self ) |
| | ) |
| | except Exception as err: |
| | if hasattr( err, 'args' ): |
| | err.args += ( |
| | """Failure in cConverter %r"""%(converter), |
| | pyArgs, index, |
| | ) |
| | raise |
| | cArguments = tuple(calculate_cArguments( cArgs )) |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | return returnValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | return wrapperCall |
| | else: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save returnValues and storeValues""" |
| | pyArgs = args |
| | cArgs = [] |
| | for (index,converter) in enumerate( cConverters ): |
| | |
| | if not hasattr(converter,'__call__'): |
| | cArgs.append( converter ) |
| | else: |
| | try: |
| | cArgs.append( |
| | converter( pyArgs, index, self ) |
| | ) |
| | except Exception as err: |
| | if hasattr( err, 'args' ): |
| | err.args += ( |
| | """Failure in cConverter %r"""%(converter), |
| | pyArgs, index, |
| | ) |
| | raise |
| | cArguments = tuple(calculate_cArguments( cArgs )) |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | return result |
| | return wrapperCall |
| | else: |
| | |
| | if storeValues: |
| | if returnValues: |
| | def wrapperCall( *args ): |
| | """Wrapper with all possible operations""" |
| | pyArgs = args |
| | cArgs = [] |
| | for (index,converter) in enumerate( cConverters ): |
| | |
| | if not hasattr(converter,'__call__'): |
| | cArgs.append( converter ) |
| | else: |
| | try: |
| | cArgs.append( |
| | converter( pyArgs, index, self ) |
| | ) |
| | except Exception as err: |
| | if hasattr( err, 'args' ): |
| | err.args += ( |
| | """Failure in cConverter %r"""%(converter), |
| | pyArgs, index, |
| | ) |
| | raise |
| | cArguments = cArgs |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | |
| | storeValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | return returnValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | return wrapperCall |
| | else: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save returnValues""" |
| | pyArgs = args |
| | cArgs = [] |
| | for (index,converter) in enumerate( cConverters ): |
| | |
| | if not hasattr(converter,'__call__'): |
| | cArgs.append( converter ) |
| | else: |
| | try: |
| | cArgs.append( |
| | converter( pyArgs, index, self ) |
| | ) |
| | except Exception as err: |
| | if hasattr( err, 'args' ): |
| | err.args += ( |
| | """Failure in cConverter %r"""%(converter), |
| | pyArgs, index, |
| | ) |
| | raise |
| | cArguments = cArgs |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | |
| | storeValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | return result |
| | return wrapperCall |
| | else: |
| | if returnValues: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save storeValues""" |
| | pyArgs = args |
| | cArgs = [] |
| | for (index,converter) in enumerate( cConverters ): |
| | |
| | if not hasattr(converter,'__call__'): |
| | cArgs.append( converter ) |
| | else: |
| | try: |
| | cArgs.append( |
| | converter( pyArgs, index, self ) |
| | ) |
| | except Exception as err: |
| | if hasattr( err, 'args' ): |
| | err.args += ( |
| | """Failure in cConverter %r"""%(converter), |
| | pyArgs, index, |
| | ) |
| | raise |
| | cArguments = cArgs |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | return returnValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | return wrapperCall |
| | else: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save returnValues and storeValues""" |
| | pyArgs = args |
| | cArgs = [] |
| | for (index,converter) in enumerate( cConverters ): |
| | |
| | if not hasattr(converter,'__call__'): |
| | cArgs.append( converter ) |
| | else: |
| | try: |
| | cArgs.append( |
| | converter( pyArgs, index, self ) |
| | ) |
| | except Exception as err: |
| | if hasattr( err, 'args' ): |
| | err.args += ( |
| | """Failure in cConverter %r"""%(converter), |
| | pyArgs, index, |
| | ) |
| | raise |
| | cArguments = cArgs |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | return result |
| | return wrapperCall |
| | else: |
| | |
| | if cResolvers: |
| | if storeValues: |
| | if returnValues: |
| | def wrapperCall( *args ): |
| | """Wrapper with all possible operations""" |
| | cArgs = args |
| | cArguments = tuple(calculate_cArguments( cArgs )) |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = args |
| | raise err |
| | |
| | storeValues( |
| | result, |
| | self, |
| | args, |
| | cArgs, |
| | ) |
| | return returnValues( |
| | result, |
| | self, |
| | args, |
| | cArgs, |
| | ) |
| | return wrapperCall |
| | else: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save returnValues""" |
| | cArgs = args |
| | cArguments = tuple(calculate_cArguments( cArgs )) |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = args |
| | raise err |
| | |
| | storeValues( |
| | result, |
| | self, |
| | args, |
| | cArgs, |
| | ) |
| | return result |
| | return wrapperCall |
| | else: |
| | if returnValues: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save storeValues""" |
| | cArgs = args |
| | cArguments = tuple(calculate_cArguments( cArgs )) |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = args |
| | raise err |
| | return returnValues( |
| | result, |
| | self, |
| | args, |
| | cArgs, |
| | ) |
| | return wrapperCall |
| | else: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save returnValues and storeValues""" |
| | cArgs = args |
| | cArguments = tuple(calculate_cArguments( cArgs )) |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = args |
| | raise err |
| | return result |
| | return wrapperCall |
| | else: |
| | |
| | if storeValues: |
| | if returnValues: |
| | def wrapperCall( *args ): |
| | """Wrapper with all possible operations""" |
| | cArguments = args |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArguments |
| | err.pyArgs = args |
| | raise err |
| | |
| | storeValues( |
| | result, |
| | self, |
| | args, |
| | cArguments, |
| | ) |
| | return returnValues( |
| | result, |
| | self, |
| | args, |
| | cArguments, |
| | ) |
| | return wrapperCall |
| | else: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save returnValues""" |
| | cArguments = args |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArguments |
| | err.pyArgs = args |
| | raise err |
| | |
| | storeValues( |
| | result, |
| | self, |
| | args, |
| | cArguments, |
| | ) |
| | return result |
| | return wrapperCall |
| | else: |
| | if returnValues: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save storeValues""" |
| | cArguments = args |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArguments |
| | err.pyArgs = args |
| | raise err |
| | return returnValues( |
| | result, |
| | self, |
| | args, |
| | cArguments, |
| | ) |
| | return wrapperCall |
| | else: |
| | def wrapperCall( *args ): |
| | """Wrapper with all save returnValues and storeValues""" |
| | cArguments = args |
| | try: |
| | result = wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArguments |
| | err.pyArgs = args |
| | raise err |
| | return result |
| | return wrapperCall |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | def _unspecialised__call__( self, *args ): |
| | """Expand arguments, call the function, store values and check errors""" |
| | pyConverters = getattr( self, 'pyConverters', None ) |
| | if pyConverters: |
| | if len(pyConverters) != len(args): |
| | raise ValueError( |
| | """%s requires %r arguments (%s), received %s: %r"""%( |
| | self.wrappedOperation.__name__, |
| | len(pyConverters), |
| | ", ".join( self.pyConverterNames ), |
| | len(args), |
| | args |
| | ) |
| | ) |
| | pyArgs = [] |
| | for (converter,arg) in zip(pyConverters,args): |
| | if converter is None: |
| | pyArgs.append( arg ) |
| | else: |
| | pyArgs.append( converter(arg, self, args) ) |
| | else: |
| | pyArgs = args |
| | cConverters = getattr( self, 'cConverters', None ) |
| | if cConverters: |
| | cArgs = [] |
| | for (index,converter) in enumerate( cConverters ): |
| | if not hasattr(converter,'__call__'): |
| | cArgs.append( converter ) |
| | else: |
| | try: |
| | cArgs.append( |
| | converter( pyArgs, index, self ) |
| | ) |
| | except Exception as err: |
| | if hasattr( err, 'args' ): |
| | err.args += ( |
| | """Failure in cConverter %r"""%(converter), |
| | pyArgs, index, self, |
| | ) |
| | raise |
| | else: |
| | cArgs = pyArgs |
| | cResolvers = getattr( self, 'cResolvers', None ) |
| | if cResolvers: |
| | cArguments = [] |
| | for (converter, value) in zip( cResolvers, cArgs ): |
| | if converter is None: |
| | cArguments.append( value ) |
| | else: |
| | cArguments.append( converter( value ) ) |
| | else: |
| | cArguments = cArgs |
| | try: |
| | result = self.wrappedOperation( *cArguments ) |
| | except ctypes.ArgumentError as err: |
| | err.args = err.args + (cArguments,) |
| | raise err |
| | except error.GLError as err: |
| | err.cArgs = cArgs |
| | err.pyArgs = pyArgs |
| | raise err |
| | storeValues = getattr( self, 'storeValues', None ) |
| | if storeValues is not None: |
| | |
| | storeValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | returnValues = getattr( self, 'returnValues', None ) |
| | if returnValues is not None: |
| | return returnValues( |
| | result, |
| | self, |
| | pyArgs, |
| | cArgs, |
| | ) |
| | else: |
| | return result |
| |
|
| | def wrapper( wrappedOperation ): |
| | """Create a Wrapper sub-class instance for the given wrappedOperation |
| | |
| | The purpose of this function is to create a subclass of Wrapper which |
| | has the __doc__ and __name__ of the wrappedOperation so that the instance of |
| | the wrapper will show up as <functionname instance @ address> by default, |
| | and will have the docstring available naturally in pydoc and the like. |
| | """ |
| | if isinstance( wrappedOperation, Wrapper ): |
| | return wrappedOperation |
| | dict = { |
| | '__doc__': wrappedOperation.__doc__, |
| | '__slots__': ('wrappedOperation', ), |
| | } |
| | cls = type( wrappedOperation.__name__, (Wrapper,), dict ) |
| | if hasattr( wrappedOperation, '__module__' ): |
| | cls.__module__ = wrappedOperation.__module__ |
| | instance = cls(wrappedOperation) |
| | return instance |
| |
|