From ac2acc347a15981d4b674b99996e68ee5231d650 Mon Sep 17 00:00:00 2001 From: "Mike C. Fletcher" Date: Tue, 1 Oct 2024 20:20:36 -0400 Subject: [PATCH] CLEANUP FORMATTING Minor cleanup and formatting from ruff --- OpenGL/EGL/debug.py | 15 +- OpenGL/GL/ARB/texture_compression.py | 64 +- OpenGL/GL/VERSION/GL_1_3.py | 136 ++-- OpenGL/arrays/_buffers.py | 131 ++-- OpenGL/arrays/arrayhelpers.py | 193 +++--- OpenGL/arrays/buffers.py | 96 +-- OpenGL/arrays/formathandler.py | 90 ++- OpenGL/arrays/lists.py | 155 +++-- OpenGL/arrays/numbers.py | 5 +- OpenGL/arrays/strings.py | 107 +-- OpenGL/arrays/vbo.py | 383 ++++++----- OpenGL/converters.py | 263 +++++--- OpenGL/platform/__init__.py | 70 +- OpenGL/platform/baseplatform.py | 3 +- OpenGL/raw/GL/_lookupint.py | 38 +- OpenGL/wrapper.py | 958 ++++++++++++++++----------- directdocs/model.py | 381 ++++++----- tests/test_core.py | 627 ++++++++++-------- 18 files changed, 2159 insertions(+), 1556 deletions(-) diff --git a/OpenGL/EGL/debug.py b/OpenGL/EGL/debug.py index c0e36466..534eec76 100644 --- a/OpenGL/EGL/debug.py +++ b/OpenGL/EGL/debug.py @@ -1,4 +1,5 @@ """Debug utilities for EGL operations""" + from OpenGL.EGL import * import itertools @@ -29,7 +30,7 @@ def eglErrorName(value): def write_ppm(buf, filename): """Write height * width * 3-component buffer as ppm to filename - + This lets us write a simple image format without using any libraries that can be viewed on most linux workstations. @@ -188,11 +189,11 @@ def render(value): def format_debug_configs(debug_configs, formats=CONFIG_FORMAT): """Format config for compact debugging display - - Produces a config summary display for a set of + + Produces a config summary display for a set of debug_configs as a text-mode table. - Uses `formats` (default `CONFIG_FORMAT`) to determine + Uses `formats` (default `CONFIG_FORMAT`) to determine which fields are extracted and how they are formatted along with the column/subcolum set to be rendered in the overall header. @@ -201,7 +202,7 @@ def format_debug_configs(debug_configs, formats=CONFIG_FORMAT): logs or utilities """ columns = [] - for (key, format, subcol, col) in formats: + for key, format, subcol, col in formats: column = [] max_width = 0 for row in debug_configs: @@ -231,8 +232,8 @@ def format_debug_configs(debug_configs, formats=CONFIG_FORMAT): headers = [] subheaders = [] rows = [headers, subheaders] - last_column = None - last_column_width = 0 + # last_column = None + # last_column_width = 0 for header, subcols in itertools.groupby(columns, lambda x: x["col"]): subcols = list(subcols) width = sum([col["width"] for col in subcols]) + (len(subcols) - 1) diff --git a/OpenGL/GL/ARB/texture_compression.py b/OpenGL/GL/ARB/texture_compression.py index 8d9fa477..b97569a7 100644 --- a/OpenGL/GL/ARB/texture_compression.py +++ b/OpenGL/GL/ARB/texture_compression.py @@ -65,6 +65,7 @@ The official definition of this extension is available here: http://www.opengl.org/registry/specs/ARB/texture_compression.txt ''' + from OpenGL import platform, constant, arrays from OpenGL import extensions, wrapper import ctypes @@ -72,45 +73,46 @@ from OpenGL.raw.GL.ARB.texture_compression import * from OpenGL.raw.GL.ARB.texture_compression import _EXTENSION_NAME + def glInitTextureCompressionARB(): '''Return boolean indicating whether this extension is available''' from OpenGL import extensions - return extensions.hasGLExtension( _EXTENSION_NAME ) + + return extensions.hasGLExtension(_EXTENSION_NAME) + # INPUT glCompressedTexImage3DARB.data size not checked against imageSize -glCompressedTexImage3DARB=wrapper.wrapper(glCompressedTexImage3DARB).setInputArraySize( - 'data', None -) +glCompressedTexImage3DARB = wrapper.wrapper( + glCompressedTexImage3DARB +).setInputArraySize('data', None) # INPUT glCompressedTexImage2DARB.data size not checked against imageSize -glCompressedTexImage2DARB=wrapper.wrapper(glCompressedTexImage2DARB).setInputArraySize( - 'data', None -) +glCompressedTexImage2DARB = wrapper.wrapper( + glCompressedTexImage2DARB +).setInputArraySize('data', None) # INPUT glCompressedTexImage1DARB.data size not checked against imageSize -glCompressedTexImage1DARB=wrapper.wrapper(glCompressedTexImage1DARB).setInputArraySize( - 'data', None -) +glCompressedTexImage1DARB = wrapper.wrapper( + glCompressedTexImage1DARB +).setInputArraySize('data', None) # INPUT glCompressedTexSubImage3DARB.data size not checked against imageSize -glCompressedTexSubImage3DARB=wrapper.wrapper(glCompressedTexSubImage3DARB).setInputArraySize( - 'data', None -) +glCompressedTexSubImage3DARB = wrapper.wrapper( + glCompressedTexSubImage3DARB +).setInputArraySize('data', None) # INPUT glCompressedTexSubImage2DARB.data size not checked against imageSize -glCompressedTexSubImage2DARB=wrapper.wrapper(glCompressedTexSubImage2DARB).setInputArraySize( - 'data', None -) +glCompressedTexSubImage2DARB = wrapper.wrapper( + glCompressedTexSubImage2DARB +).setInputArraySize('data', None) # INPUT glCompressedTexSubImage1DARB.data size not checked against imageSize -glCompressedTexSubImage1DARB=wrapper.wrapper(glCompressedTexSubImage1DARB).setInputArraySize( - 'data', None -) -# OUTPUT glGetCompressedTexImageARB.img COMPSIZE(target, level) +glCompressedTexSubImage1DARB = wrapper.wrapper( + glCompressedTexSubImage1DARB +).setInputArraySize('data', None) +# OUTPUT glGetCompressedTexImageARB.img COMPSIZE(target, level) ### END AUTOGENERATED SECTION from OpenGL.GL import images -for dimensions in (1,2,3): - for function in ('glCompressedTexImage%sDARB','glCompressedTexSubImage%sDARB'): - name = function%(dimensions,) - globals()[ name ] = images.compressedImageFunction( - globals()[ name ] - ) +for dimensions in (1, 2, 3): + for function in ('glCompressedTexImage%sDARB', 'glCompressedTexSubImage%sDARB'): + name = function % (dimensions,) + globals()[name] = images.compressedImageFunction(globals()[name]) try: del name, function except NameError as err: @@ -121,12 +123,14 @@ def glInitTextureCompressionARB(): pass if glGetCompressedTexImageARB: - def glGetCompressedTexImageARB( target, level, img=None ): + + def glGetCompressedTexImageARB(target, level, img=None): """Retrieve a compressed texture image""" if img is None: length = glget.glGetTexLevelParameteriv( - target, 0, + target, + 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, ) - img = arrays.ArrayDataType.zeros( (length,), GL_1_0.GL_UNSIGNED_BYTE ) - return glGetCompressedTexImageARB(target, 0, img); + img = arrays.ArrayDataType.zeros((length,), GL_1_0.GL_UNSIGNED_BYTE) + return glGetCompressedTexImageARB(target, 0, img) diff --git a/OpenGL/GL/VERSION/GL_1_3.py b/OpenGL/GL/VERSION/GL_1_3.py index 1e3e5dde..6f494960 100644 --- a/OpenGL/GL/VERSION/GL_1_3.py +++ b/OpenGL/GL/VERSION/GL_1_3.py @@ -7,6 +7,7 @@ The official definition of this extension is available here: http://www.opengl.org/registry/specs/VERSION/GL_1_3.txt ''' + from OpenGL import platform, constant, arrays from OpenGL import extensions, wrapper import ctypes @@ -14,114 +15,83 @@ from OpenGL.raw.GL.VERSION.GL_1_3 import * from OpenGL.raw.GL.VERSION.GL_1_3 import _EXTENSION_NAME + def glInitGl13VERSION(): '''Return boolean indicating whether this extension is available''' from OpenGL import extensions - return extensions.hasGLExtension( _EXTENSION_NAME ) + + return extensions.hasGLExtension(_EXTENSION_NAME) + # INPUT glCompressedTexImage3D.data size not checked against imageSize -glCompressedTexImage3D=wrapper.wrapper(glCompressedTexImage3D).setInputArraySize( +glCompressedTexImage3D = wrapper.wrapper(glCompressedTexImage3D).setInputArraySize( 'data', None ) # INPUT glCompressedTexImage2D.data size not checked against imageSize -glCompressedTexImage2D=wrapper.wrapper(glCompressedTexImage2D).setInputArraySize( +glCompressedTexImage2D = wrapper.wrapper(glCompressedTexImage2D).setInputArraySize( 'data', None ) # INPUT glCompressedTexImage1D.data size not checked against imageSize -glCompressedTexImage1D=wrapper.wrapper(glCompressedTexImage1D).setInputArraySize( +glCompressedTexImage1D = wrapper.wrapper(glCompressedTexImage1D).setInputArraySize( 'data', None ) # INPUT glCompressedTexSubImage3D.data size not checked against imageSize -glCompressedTexSubImage3D=wrapper.wrapper(glCompressedTexSubImage3D).setInputArraySize( - 'data', None -) +glCompressedTexSubImage3D = wrapper.wrapper( + glCompressedTexSubImage3D +).setInputArraySize('data', None) # INPUT glCompressedTexSubImage2D.data size not checked against imageSize -glCompressedTexSubImage2D=wrapper.wrapper(glCompressedTexSubImage2D).setInputArraySize( - 'data', None -) +glCompressedTexSubImage2D = wrapper.wrapper( + glCompressedTexSubImage2D +).setInputArraySize('data', None) # INPUT glCompressedTexSubImage1D.data size not checked against imageSize -glCompressedTexSubImage1D=wrapper.wrapper(glCompressedTexSubImage1D).setInputArraySize( - 'data', None -) -# OUTPUT glGetCompressedTexImage.img COMPSIZE(target, level) -glMultiTexCoord1dv=wrapper.wrapper(glMultiTexCoord1dv).setInputArraySize( - 'v', 1 -) -glMultiTexCoord1fv=wrapper.wrapper(glMultiTexCoord1fv).setInputArraySize( - 'v', 1 -) -glMultiTexCoord1iv=wrapper.wrapper(glMultiTexCoord1iv).setInputArraySize( - 'v', 1 -) -glMultiTexCoord1sv=wrapper.wrapper(glMultiTexCoord1sv).setInputArraySize( - 'v', 1 -) -glMultiTexCoord2dv=wrapper.wrapper(glMultiTexCoord2dv).setInputArraySize( - 'v', 2 -) -glMultiTexCoord2fv=wrapper.wrapper(glMultiTexCoord2fv).setInputArraySize( - 'v', 2 -) -glMultiTexCoord2iv=wrapper.wrapper(glMultiTexCoord2iv).setInputArraySize( - 'v', 2 -) -glMultiTexCoord2sv=wrapper.wrapper(glMultiTexCoord2sv).setInputArraySize( - 'v', 2 -) -glMultiTexCoord3dv=wrapper.wrapper(glMultiTexCoord3dv).setInputArraySize( - 'v', 3 -) -glMultiTexCoord3fv=wrapper.wrapper(glMultiTexCoord3fv).setInputArraySize( - 'v', 3 -) -glMultiTexCoord3iv=wrapper.wrapper(glMultiTexCoord3iv).setInputArraySize( - 'v', 3 -) -glMultiTexCoord3sv=wrapper.wrapper(glMultiTexCoord3sv).setInputArraySize( - 'v', 3 -) -glMultiTexCoord4dv=wrapper.wrapper(glMultiTexCoord4dv).setInputArraySize( - 'v', 4 -) -glMultiTexCoord4fv=wrapper.wrapper(glMultiTexCoord4fv).setInputArraySize( - 'v', 4 -) -glMultiTexCoord4iv=wrapper.wrapper(glMultiTexCoord4iv).setInputArraySize( - 'v', 4 -) -glMultiTexCoord4sv=wrapper.wrapper(glMultiTexCoord4sv).setInputArraySize( - 'v', 4 -) -glLoadTransposeMatrixf=wrapper.wrapper(glLoadTransposeMatrixf).setInputArraySize( +glCompressedTexSubImage1D = wrapper.wrapper( + glCompressedTexSubImage1D +).setInputArraySize('data', None) +# OUTPUT glGetCompressedTexImage.img COMPSIZE(target, level) +glMultiTexCoord1dv = wrapper.wrapper(glMultiTexCoord1dv).setInputArraySize('v', 1) +glMultiTexCoord1fv = wrapper.wrapper(glMultiTexCoord1fv).setInputArraySize('v', 1) +glMultiTexCoord1iv = wrapper.wrapper(glMultiTexCoord1iv).setInputArraySize('v', 1) +glMultiTexCoord1sv = wrapper.wrapper(glMultiTexCoord1sv).setInputArraySize('v', 1) +glMultiTexCoord2dv = wrapper.wrapper(glMultiTexCoord2dv).setInputArraySize('v', 2) +glMultiTexCoord2fv = wrapper.wrapper(glMultiTexCoord2fv).setInputArraySize('v', 2) +glMultiTexCoord2iv = wrapper.wrapper(glMultiTexCoord2iv).setInputArraySize('v', 2) +glMultiTexCoord2sv = wrapper.wrapper(glMultiTexCoord2sv).setInputArraySize('v', 2) +glMultiTexCoord3dv = wrapper.wrapper(glMultiTexCoord3dv).setInputArraySize('v', 3) +glMultiTexCoord3fv = wrapper.wrapper(glMultiTexCoord3fv).setInputArraySize('v', 3) +glMultiTexCoord3iv = wrapper.wrapper(glMultiTexCoord3iv).setInputArraySize('v', 3) +glMultiTexCoord3sv = wrapper.wrapper(glMultiTexCoord3sv).setInputArraySize('v', 3) +glMultiTexCoord4dv = wrapper.wrapper(glMultiTexCoord4dv).setInputArraySize('v', 4) +glMultiTexCoord4fv = wrapper.wrapper(glMultiTexCoord4fv).setInputArraySize('v', 4) +glMultiTexCoord4iv = wrapper.wrapper(glMultiTexCoord4iv).setInputArraySize('v', 4) +glMultiTexCoord4sv = wrapper.wrapper(glMultiTexCoord4sv).setInputArraySize('v', 4) +glLoadTransposeMatrixf = wrapper.wrapper(glLoadTransposeMatrixf).setInputArraySize( 'm', 16 ) -glLoadTransposeMatrixd=wrapper.wrapper(glLoadTransposeMatrixd).setInputArraySize( +glLoadTransposeMatrixd = wrapper.wrapper(glLoadTransposeMatrixd).setInputArraySize( 'm', 16 ) -glMultTransposeMatrixf=wrapper.wrapper(glMultTransposeMatrixf).setInputArraySize( +glMultTransposeMatrixf = wrapper.wrapper(glMultTransposeMatrixf).setInputArraySize( 'm', 16 ) -glMultTransposeMatrixd=wrapper.wrapper(glMultTransposeMatrixd).setInputArraySize( +glMultTransposeMatrixd = wrapper.wrapper(glMultTransposeMatrixd).setInputArraySize( 'm', 16 ) ### END AUTOGENERATED SECTION -GL_SRC0_ALPHA = GL_SOURCE0_ALPHA # alias -GL_SRC0_RGB = GL_SOURCE0_RGB # alias -GL_SRC1_ALPHA = GL_SOURCE1_ALPHA # alias -GL_SRC1_RGB = GL_SOURCE1_RGB # alias -GL_SRC2_ALPHA = GL_SOURCE2_ALPHA # alias -GL_SRC2_RGB = GL_SOURCE2_RGB # alias +GL_SRC0_ALPHA = GL_SOURCE0_ALPHA # alias +GL_SRC0_RGB = GL_SOURCE0_RGB # alias +GL_SRC1_ALPHA = GL_SOURCE1_ALPHA # alias +GL_SRC1_RGB = GL_SOURCE1_RGB # alias +GL_SRC2_ALPHA = GL_SOURCE2_ALPHA # alias +GL_SRC2_RGB = GL_SOURCE2_RGB # alias from OpenGL import wrapper from OpenGL.raw.GL.VERSION import GL_1_3 as _simple from OpenGL.GL import images, glget -for dimensions in (1,2,3): - for function in ('glCompressedTexImage%sD','glCompressedTexSubImage%sD'): - name = function%(dimensions,) - globals()[ name ] = images.compressedImageFunction( - getattr( _simple, name ) - ) +for dimensions in (1, 2, 3): + for function in ('glCompressedTexImage%sD', 'glCompressedTexSubImage%sD'): + name = function % (dimensions,) + globals()[name] = images.compressedImageFunction(getattr(_simple, name)) try: del name, function except NameError as err: @@ -132,12 +102,14 @@ def glInitGl13VERSION(): pass if _simple.glGetCompressedTexImage: - def glGetCompressedTexImage( target, level, img=None ): + + def glGetCompressedTexImage(target, level, img=None): """Retrieve a compressed texture image""" if img is None: length = glget.glGetTexLevelParameteriv( - target, 0, + target, + 0, _simple.GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, ) - img = arrays.ArrayDataType.zeros( (length,), constants.GL_UNSIGNED_BYTE ) - return _simple.glGetCompressedTexImage(target, 0, img); + img = arrays.ArrayDataType.zeros((length,), constants.GL_UNSIGNED_BYTE) + return _simple.glGetCompressedTexImage(target, 0, img) diff --git a/OpenGL/arrays/_buffers.py b/OpenGL/arrays/_buffers.py index 8d18af72..03b68aae 100644 --- a/OpenGL/arrays/_buffers.py +++ b/OpenGL/arrays/_buffers.py @@ -1,87 +1,105 @@ #! /usr/bin/env python """Python 3.x buffer-handling (currently just for bytes/bytearray types) """ -import ctypes,sys -if sys.version_info[:2] < (2,6): - raise ImportError( 'Buffer interface only usable on Python 2.6+' ) +import ctypes, sys + +if sys.version_info[:2] < (2, 6): + raise ImportError('Buffer interface only usable on Python 2.6+') from ._arrayconstants import * PyBUF_SIMPLE = 0 PyBUF_WRITABLE = PyBUF_WRITEABLE = 0x0001 PyBUF_ND = 0x0008 -PyBUF_STRIDES = (0x0010 | PyBUF_ND) -PyBUF_CONTIG = (PyBUF_ND | PyBUF_WRITABLE) -PyBUF_CONTIG_RO = (PyBUF_ND) -PyBUF_C_CONTIGUOUS = (0x0020 | PyBUF_STRIDES) +PyBUF_STRIDES = 0x0010 | PyBUF_ND +PyBUF_CONTIG = PyBUF_ND | PyBUF_WRITABLE +PyBUF_CONTIG_RO = PyBUF_ND +PyBUF_C_CONTIGUOUS = 0x0020 | PyBUF_STRIDES PyBUF_FORMAT = 0x0004 # Python 2.6 doesn't define this... -c_ssize_t = getattr( ctypes, 'c_ssize_t',ctypes.c_ulong) - +c_ssize_t = getattr(ctypes, 'c_ssize_t', ctypes.c_ulong) + _fields_ = [ - ('buf',ctypes.c_void_p), - ('obj',ctypes.c_void_p), - ('len',c_ssize_t), - ('itemsize',c_ssize_t), - - ('readonly',ctypes.c_int), - ('ndim',ctypes.c_int), - ('format',ctypes.c_char_p), - ('shape',ctypes.POINTER(c_ssize_t)), - ('strides',ctypes.POINTER(c_ssize_t)), - ('suboffsets',ctypes.POINTER(c_ssize_t)), + ('buf', ctypes.c_void_p), + ('obj', ctypes.c_void_p), + ('len', c_ssize_t), + ('itemsize', c_ssize_t), + ('readonly', ctypes.c_int), + ('ndim', ctypes.c_int), + ('format', ctypes.c_char_p), + ('shape', ctypes.POINTER(c_ssize_t)), + ('strides', ctypes.POINTER(c_ssize_t)), + ('suboffsets', ctypes.POINTER(c_ssize_t)), ] -if sys.version_info[:2] <= (2,6) or sys.version_info[:2] >= (3,3): - # Original structure was eventually restored in 3.3, so just +if sys.version_info[:2] <= (2, 6) or sys.version_info[:2] >= (3, 3): + # Original structure was eventually restored in 3.3, so just # 2.7 through 3.2 uses the "enhanced" structure below - _fields_.extend( [ - ('internal',ctypes.c_void_p), - ] ) + _fields_.extend( + [ + ('internal', ctypes.c_void_p), + ] + ) else: # Sigh, this structure seems to have changed with Python 3.x... - _fields_.extend( [ - ('smalltable',ctypes.c_size_t*2), - ('internal',ctypes.c_void_p), - ] ) + _fields_.extend( + [ + ('smalltable', ctypes.c_size_t * 2), + ('internal', ctypes.c_void_p), + ] + ) + class Py_buffer(ctypes.Structure): """Wrapper around the Python buffer structure...""" - @classmethod - def from_object( cls, object, flags=PyBUF_STRIDES|PyBUF_FORMAT|PyBUF_C_CONTIGUOUS ): + + @classmethod + def from_object( + cls, object, flags=PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_C_CONTIGUOUS + ): """Create a new Py_buffer referencing ram of object""" - if not CheckBuffer( object ): - raise TypeError( "%s type does not support Buffer Protocol"%(object.__class__,)) + if not CheckBuffer(object): + raise TypeError( + "%s type does not support Buffer Protocol" % (object.__class__,) + ) buf = cls() # deallocation of the buf causes glibc abort :( - result = GetBuffer( object, buf, flags ) + result = GetBuffer(object, buf, flags) if result != 0: - raise ValueError( "Unable to retrieve Buffer from %s"%(object,)) + raise ValueError("Unable to retrieve Buffer from %s" % (object,)) if not buf.buf: - raise ValueError( "Null pointer result from %s"%(object,) ) + raise ValueError("Null pointer result from %s" % (object,)) return buf + _fields_ = _fields_ + @property - def dims( self ): - return self.shape[:self.ndim] - def __len__( self ): + def dims(self): + return self.shape[: self.ndim] + + def __len__(self): return self.shape[0] - @property - def dim_strides( self ): + + @property + def dim_strides(self): if self.strides: - return self.strides[:self.ndim] + return self.strides[: self.ndim] return None + def __enter__(self): - pass - def __exit__( self, exc_type=None, exc_value=None, traceback=None): + pass + + def __exit__(self, exc_type=None, exc_value=None, traceback=None): if self.obj: - ReleaseBuffer( self ) - def __del__( self ): + ReleaseBuffer(self) + + def __del__(self): if self.obj: - ReleaseBuffer( self ) - -BUFFER_POINTER = ctypes.POINTER( Py_buffer ) + ReleaseBuffer(self) + + +BUFFER_POINTER = ctypes.POINTER(Py_buffer) try: @@ -90,16 +108,17 @@ def __del__( self ): CheckBuffer.restype = ctypes.c_int except AttributeError as err: # Python 2.6 doesn't appear to have CheckBuffer support... - CheckBuffer = lambda x: True + def CheckBuffer(x): + True + + +IncRef = ctypes.pythonapi.Py_IncRef +IncRef.argtypes = [ctypes.py_object] -IncRef = ctypes.pythonapi.Py_IncRef -IncRef.argtypes = [ ctypes.py_object ] - GetBuffer = ctypes.pythonapi.PyObject_GetBuffer -GetBuffer.argtypes = [ ctypes.py_object, BUFFER_POINTER, ctypes.c_int ] +GetBuffer.argtypes = [ctypes.py_object, BUFFER_POINTER, ctypes.c_int] GetBuffer.restype = ctypes.c_int ReleaseBuffer = ctypes.pythonapi.PyBuffer_Release -ReleaseBuffer.argtypes = [ BUFFER_POINTER ] +ReleaseBuffer.argtypes = [BUFFER_POINTER] ReleaseBuffer.restype = None - diff --git a/OpenGL/arrays/arrayhelpers.py b/OpenGL/arrays/arrayhelpers.py index 662e30d3..bad0b9c2 100644 --- a/OpenGL/arrays/arrayhelpers.py +++ b/OpenGL/arrays/arrayhelpers.py @@ -3,180 +3,217 @@ These are functions intended to be used in wrapping GL functions that deal with OpenGL array data-types. """ + import OpenGL import ctypes from OpenGL import _configflags from OpenGL import contextdata, error, converters from OpenGL.arrays import arraydatatype -from OpenGL._bytes import bytes,unicode +from OpenGL._bytes import bytes, unicode import logging -_log = logging.getLogger( 'OpenGL.arrays.arrayhelpers' ) + +_log = logging.getLogger('OpenGL.arrays.arrayhelpers') from OpenGL import acceleratesupport + AsArrayTypedSizeChecked = None if acceleratesupport.ACCELERATE_AVAILABLE: try: from OpenGL_accelerate.arraydatatype import AsArrayTypedSizeChecked from OpenGL_accelerate.wrapper import returnPyArgumentIndex from OpenGL_accelerate.arraydatatype import ( - AsArrayOfType,AsArrayTyped,AsArrayTypedSize + AsArrayOfType, + AsArrayTyped, + AsArrayTypedSize, ) except ImportError as err: - _log.warning( - "Unable to load arrayhelpers accelerator from OpenGL_accelerate" - ) + _log.warning("Unable to load arrayhelpers accelerator from OpenGL_accelerate") if AsArrayTypedSizeChecked is None: - def returnPointer( result,baseOperation,pyArgs,cArgs, ): + + def returnPointer( + result, + baseOperation, + pyArgs, + cArgs, + ): """Return the converted object as result of function - + Note: this is a hack that always returns pyArgs[0]! """ return pyArgs[0] - class AsArrayOfType( converters.PyConverter ): + + class AsArrayOfType(converters.PyConverter): """Given arrayName and typeName coerce arrayName to array of type typeName - + TODO: It should be possible to drop this if ERROR_ON_COPY, - as array inputs always have to be the final objects in that + as array inputs always have to be the final objects in that case. """ - argNames = ( 'arrayName','typeName' ) - indexLookups = ( - ('arrayIndex', 'arrayName','pyArgIndex'), - ('typeIndex', 'typeName','pyArgIndex'), + + argNames = ('arrayName', 'typeName') + indexLookups = ( + ('arrayIndex', 'arrayName', 'pyArgIndex'), + ('typeIndex', 'typeName', 'pyArgIndex'), ) - def __init__( self, arrayName='pointer', typeName='type' ): + + def __init__(self, arrayName='pointer', typeName='type'): self.arrayName = arrayName - self.typeName = typeName - def __call__( self, arg, wrappedOperation, args): + self.typeName = typeName + + def __call__(self, arg, wrappedOperation, args): """Get the arg as an array of the appropriate type""" - type = args[ self.typeIndex ] - arrayType = arraydatatype.GL_CONSTANT_TO_ARRAY_TYPE[ type ] - return arrayType.asArray( arg ) - class AsArrayTyped( converters.PyConverter ): + type = args[self.typeIndex] + arrayType = arraydatatype.GL_CONSTANT_TO_ARRAY_TYPE[type] + return arrayType.asArray(arg) + + class AsArrayTyped(converters.PyConverter): """Given arrayName and arrayType, convert arrayName to array of type - + TODO: It should be possible to drop this if ERROR_ON_COPY, - as array inputs always have to be the final objects in that + as array inputs always have to be the final objects in that case. """ - argNames = ( 'arrayName','arrayType' ) - indexLookups = ( - ('arrayIndex', 'arrayName','pyArgIndex'), - ) - def __init__( self, arrayName='pointer', arrayType=None ): + + argNames = ('arrayName', 'arrayType') + indexLookups = (('arrayIndex', 'arrayName', 'pyArgIndex'),) + + def __init__(self, arrayName='pointer', arrayType=None): self.arrayName = arrayName self.arrayType = arrayType - def __call__( self, arg, wrappedOperation, args): + + def __call__(self, arg, wrappedOperation, args): """Get the arg as an array of the appropriate type""" - return self.arrayType.asArray( arg ) - class AsArrayTypedSize( converters.CConverter ): - """Given arrayName and arrayType, determine size of arrayName - """ - argNames = ( 'arrayName','arrayType' ) - indexLookups = ( - ('arrayIndex', 'arrayName','pyArgIndex'), - ) - def __init__( self, arrayName='pointer', arrayType=None ): + return self.arrayType.asArray(arg) + + class AsArrayTypedSize(converters.CConverter): + """Given arrayName and arrayType, determine size of arrayName""" + + argNames = ('arrayName', 'arrayType') + indexLookups = (('arrayIndex', 'arrayName', 'pyArgIndex'),) + + def __init__(self, arrayName='pointer', arrayType=None): self.arrayName = arrayName self.arrayType = arrayType - def __call__( self, pyArgs, index, wrappedOperation ): + + def __call__(self, pyArgs, index, wrappedOperation): """Get the arg as an array of the appropriate type""" - return self.arrayType.arraySize( pyArgs[self.arrayIndex ] ) + return self.arrayType.arraySize(pyArgs[self.arrayIndex]) + else: - returnPointer = returnPyArgumentIndex( 0 ) + returnPointer = returnPyArgumentIndex(0) if not _configflags.ERROR_ON_COPY: - def asArrayType( typ, size=None ): + + def asArrayType(typ, size=None): """Create PyConverter to get first argument as array of type""" - return converters.CallFuncPyConverter( typ.asArray ) + return converters.CallFuncPyConverter(typ.asArray) + else: - def asArrayType( typ, size=None ): + + def asArrayType(typ, size=None): """No converter required""" return None + if not _configflags.ARRAY_SIZE_CHECKING: asArrayTypeSize = asArrayType else: if AsArrayTypedSizeChecked: asArrayTypeSize = AsArrayTypedSizeChecked else: - def asArrayTypeSize( typ, size ): + + def asArrayTypeSize(typ, size): """Create PyConverter function to get array as type and check size - + Produces a raw function, not a PyConverter instance """ - asArray = typ.asArray + # asArray = typ.asArray dataType = typ.typeConstant - arraySize = typ.arraySize - expectedBytes = ctypes.sizeof( typ.baseType ) * size - def asArraySize( incoming, function, args ): - handler = typ.getHandler( incoming ) - result = handler.asArray( incoming, dataType ) + # arraySize = typ.arraySize + expectedBytes = ctypes.sizeof(typ.baseType) * size + + def asArraySize(incoming, function, args): + handler = typ.getHandler(incoming) + result = handler.asArray(incoming, dataType) # check that the number of bytes expected is present... - byteSize = handler.arrayByteCount( result ) + byteSize = handler.arrayByteCount(result) if byteSize != expectedBytes: raise ValueError( - """Expected %r byte array, got %r byte array"""%( + """Expected %r byte array, got %r byte array""" + % ( expectedBytes, byteSize, ), incoming, ) return result + return asArraySize if not _configflags.ERROR_ON_COPY: - def asVoidArray( ): + + def asVoidArray(): """Create PyConverter returning incoming as an array of any type""" from OpenGL.arrays import ArrayDatatype - return converters.CallFuncPyConverter( ArrayDatatype.asArray ) + + return converters.CallFuncPyConverter(ArrayDatatype.asArray) + else: - def asVoidArray( ): + + def asVoidArray(): """If there's no copying allowed, we can use default passing""" return None -class storePointerType( object ): + +class storePointerType(object): """Store named pointer value in context indexed by constant - - pointerName -- named pointer argument + + pointerName -- named pointer argument constant -- constant used to index in the context storage - + Note: OpenGL.STORE_POINTERS can be set with ERROR_ON_COPY to ignore this storage operation. - + Stores the pyArgs (i.e. result of pyConverters) for the named pointer argument... """ - def __init__( self, pointerName, constant ): + + def __init__(self, pointerName, constant): self.pointerName = pointerName - self.constant = constant - def finalise( self, wrapper ): - self.pointerIndex = wrapper.pyArgIndex( self.pointerName ) - def __call__( self, result, baseOperation, pyArgs, cArgs ): - contextdata.setValue( self.constant, pyArgs[self.pointerIndex] ) + self.constant = constant + + def finalise(self, wrapper): + self.pointerIndex = wrapper.pyArgIndex(self.pointerName) + + def __call__(self, result, baseOperation, pyArgs, cArgs): + contextdata.setValue(self.constant, pyArgs[self.pointerIndex]) -def setInputArraySizeType( baseOperation, size, type, argName=0 ): +def setInputArraySizeType(baseOperation, size, type, argName=0): """Decorate function with vector-handling code for a single argument - - if OpenGL.ERROR_ON_COPY is False, then we return the + + 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 + + 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. """ from OpenGL import wrapper - return wrapper.wrapper( baseOperation ).setInputArraySize( argName, size ) -def arraySizeOfFirstType( typ, default ): + return wrapper.wrapper(baseOperation).setInputArraySize(argName, size) + + +def arraySizeOfFirstType(typ, default): unitSize = typ.unitSize - def arraySizeOfFirst( pyArgs, index, baseOperation ): + + def arraySizeOfFirst(pyArgs, index, baseOperation): """Return the array size of the first argument""" array = pyArgs[0] if array is None: return default else: - return unitSize( array ) + return unitSize(array) + return arraySizeOfFirst diff --git a/OpenGL/arrays/buffers.py b/OpenGL/arrays/buffers.py index 6c47a68d..308cf338 100644 --- a/OpenGL/arrays/buffers.py +++ b/OpenGL/arrays/buffers.py @@ -4,22 +4,24 @@ Will *only* work for Python 2.6+, and pretty much just works for strings under 2.6 (in terms of the common object types). """ -import sys,operator,logging,traceback +import sys, operator, logging, traceback from OpenGL.arrays import _buffers from OpenGL.raw.GL import _types -#from OpenGL.raw.GL.VERSION import GL_1_1 + +# from OpenGL.raw.GL.VERSION import GL_1_1 from OpenGL.arrays import formathandler from OpenGL import _configflags from OpenGL import acceleratesupport -_log = logging.getLogger( __name__ ) + +_log = logging.getLogger(__name__) try: - reduce + reduce except NameError as err: from functools import reduce MemoryviewHandler = BufferHandler = None -if sys.version_info[:2] > (2,6): - # Only Python 2.7+ has memoryview support, and the accelerate module +if sys.version_info[:2] > (2, 6): + # Only Python 2.7+ has memoryview support, and the accelerate module # requires memoryviews to be able to pass around the buffer structures if acceleratesupport.ACCELERATE_AVAILABLE: try: @@ -32,67 +34,87 @@ else: BufferHandler = MemoryviewHandler if not BufferHandler: - class BufferHandler( formathandler.FormatHandler ): + + class BufferHandler(formathandler.FormatHandler): """Buffer-protocol data-type handler for OpenGL""" - isOutput=False + + isOutput = False ERROR_ON_COPY = _configflags.ERROR_ON_COPY if sys.version_info[0] >= 3: + @classmethod - def from_param( cls, value, typeCode=None ): - if not isinstance( value, _buffers.Py_buffer ): - value = cls.asArray( value ) - #raise TypeError( """Can't convert value to py-buffer in from_param""" ) + def from_param(cls, value, typeCode=None): + if not isinstance(value, _buffers.Py_buffer): + value = cls.asArray(value) + # raise TypeError( """Can't convert value to py-buffer in from_param""" ) # TODO: only do this IFF value.internal is None - return _types.GLvoidp( value.buf ) -# return value + return _types.GLvoidp(value.buf) + + # return value else: + @classmethod - def from_param( cls, value, typeCode=None ): - if not isinstance( value, _buffers.Py_buffer ): - value = cls.asArray( value ) - #raise TypeError( """Can't convert value to py-buffer in from_param""" ) + def from_param(cls, value, typeCode=None): + if not isinstance(value, _buffers.Py_buffer): + value = cls.asArray(value) + # raise TypeError( """Can't convert value to py-buffer in from_param""" ) return value.buf - def dataPointer( value ): - if not isinstance( value, _buffers.Py_buffer ): - value = _buffers.Py_buffer.from_object( value ) + + def dataPointer(value): + if not isinstance(value, _buffers.Py_buffer): + value = _buffers.Py_buffer.from_object(value) return value.buf - dataPointer = staticmethod( dataPointer ) + + dataPointer = staticmethod(dataPointer) + @classmethod - def zeros( cls, dims, typeCode=None ): + def zeros(cls, dims, typeCode=None): """Currently don't allow strings as output types!""" - raise NotImplementedError( "Generic buffer type does not have output capability" ) - return cls.asArray( bytearray( b'\000'*reduce(operator.mul,dims)*BYTE_SIZES[typeCode] ) ) + raise NotImplementedError( + "Generic buffer type does not have output capability" + ) + return cls.asArray( + bytearray(b'\000' * reduce(operator.mul, dims) * BYTE_SIZES[typeCode]) + ) + @classmethod - def ones( cls, dims, typeCode=None ): + def ones(cls, dims, typeCode=None): """Currently don't allow strings as output types!""" - raise NotImplementedError( """Have not implemented ones for buffer type""" ) + raise NotImplementedError("""Have not implemented ones for buffer type""") + @classmethod - def arrayToGLType( cls, value ): + def arrayToGLType(cls, value): """Given a value, guess OpenGL type of the corresponding pointer""" - format = value.format + format = value.format if format in ARRAY_TO_GL_TYPE_MAPPING: return ARRAY_TO_GL_TYPE_MAPPING[format] - raise TypeError( 'Unknown format: %r'%(format,)) + raise TypeError('Unknown format: %r' % (format,)) + @classmethod - def arraySize( cls, value, typeCode = None ): + def arraySize(cls, value, typeCode=None): """Given a data-value, calculate ravelled size for the array""" return value.len // value.itemsize + @classmethod - def arrayByteCount( cls, value, typeCode = None ): + def arrayByteCount(cls, value, typeCode=None): """Given a data-value, calculate number of bytes required to represent""" return value.len - @classmethod - def unitSize( cls, value, default=None ): + + @classmethod + def unitSize(cls, value, default=None): return value.dims[-1] + @classmethod - def asArray( cls, value, typeCode=None ): + def asArray(cls, value, typeCode=None): """Convert given value to an array value of given typeCode""" - buf = _buffers.Py_buffer.from_object( value ) + buf = _buffers.Py_buffer.from_object(value) return buf + @classmethod - def dimensions( cls, value, typeCode=None ): + def dimensions(cls, value, typeCode=None): """Determine dimensions of the passed array value (if possible)""" return value.dims + ARRAY_TO_GL_TYPE_MAPPING = _buffers.ARRAY_TO_GL_TYPE_MAPPING BYTE_SIZES = _buffers.BYTE_SIZES diff --git a/OpenGL/arrays/formathandler.py b/OpenGL/arrays/formathandler.py index 11b72d93..2df3b307 100644 --- a/OpenGL/arrays/formathandler.py +++ b/OpenGL/arrays/formathandler.py @@ -2,16 +2,19 @@ Data-type handlers are specified using OpenGL.plugins module """ + import ctypes from OpenGL import plugins -class FormatHandler( object ): + +class FormatHandler(object): """Abstract class describing the handler interface - + Each data-type handler is responsible for providing a number of methods - which allow it to manipulate (and create) instances of the data-type + which allow it to manipulate (and create) instances of the data-type it represents. """ + LAZY_TYPE_REGISTRY = {} # more registrations HANDLER_REGISTRY = {} baseType = None @@ -19,75 +22,92 @@ class FormatHandler( object ): HANDLED_TYPES = () preferredOutput = None isOutput = False - GENERIC_OUTPUT_PREFERENCES = ['numpy','ctypesarrays'] + GENERIC_OUTPUT_PREFERENCES = ['numpy', 'ctypesarrays'] ALL_OUTPUT_HANDLERS = [] - def loadAll( cls ): - """Load all OpenGL.plugins-registered FormatHandler classes - """ + + def loadAll(cls): + """Load all OpenGL.plugins-registered FormatHandler classes""" for entrypoint in plugins.FormatHandler.all(): - cls.loadPlugin( entrypoint ) + cls.loadPlugin(entrypoint) + @classmethod - def loadPlugin( cls, entrypoint ): + def loadPlugin(cls, entrypoint): """Load a single entry-point via plugins module""" if not entrypoint.loaded: from OpenGL.arrays.arraydatatype import ArrayDatatype + try: plugin_class = entrypoint.load() except ImportError as err: from OpenGL import logs from OpenGL._configflags import WARN_ON_FORMAT_UNAVAILABLE - _log = logs.getLog( 'OpenGL.formathandler' ) + + _log = logs.getLog('OpenGL.formathandler') if WARN_ON_FORMAT_UNAVAILABLE: logFunc = _log.warn else: - logFunc = _log.info + logFunc = _log.info logFunc( - 'Unable to load registered array format handler %s:\n%s', - entrypoint.name, _log.getException( err ) + 'Unable to load registered array format handler %s:\n%s', + entrypoint.name, + _log.getException(err), ) else: handler = plugin_class() - #handler.register( handler.HANDLED_TYPES ) - ArrayDatatype.getRegistry()[ entrypoint.name ] = handler + # handler.register( handler.HANDLED_TYPES ) + ArrayDatatype.getRegistry()[entrypoint.name] = handler return handler entrypoint.loaded = True + @classmethod - def typeLookup( cls, type ): + def typeLookup(cls, type): """Lookup handler by data-type""" + from OpenGL.arrays.arraydatatype import ArrayDatatype + registry = ArrayDatatype.getRegistry() try: - return registry[ type ] + return registry[type] except KeyError as err: - key = '%s.%s'%(type.__module__,type.__name__) - plugin = cls.LAZY_TYPE_REGISTRY.get( key ) + key = '%s.%s' % (type.__module__, type.__name__) + plugin = cls.LAZY_TYPE_REGISTRY.get(key) if plugin: - cls.loadPlugin( plugin ) - return registry[ type ] - raise KeyError( """Unable to find data-format handler for %s"""%( type,)) - loadAll = classmethod( loadAll ) + cls.loadPlugin(plugin) + return registry[type] + raise KeyError("""Unable to find data-format handler for %s""" % (type,)) - def register( self, types=None ): + loadAll = classmethod(loadAll) + + def register(self, types=None): """Register this class as handler for given set of types""" from OpenGL.arrays.arraydatatype import ArrayDatatype - ArrayDatatype.getRegistry().register( self, types ) - def registerReturn( self ): + + ArrayDatatype.getRegistry().register(self, types) + + def registerReturn(self): """Register this handler as the default return-type handler""" from OpenGL.arrays.arraydatatype import ArrayDatatype - ArrayDatatype.getRegistry().registerReturn( self ) - def from_param( self, value, typeCode=None ): + ArrayDatatype.getRegistry().registerReturn(self) + + def from_param(self, value, typeCode=None): """Convert to a ctypes pointer value""" - def dataPointer( self, value ): + + def dataPointer(self, value): """return long for pointer value""" - def asArray( self, value, typeCode=None ): + + def asArray(self, value, typeCode=None): """Given a value, convert to array representation""" - def arrayToGLType( self, value ): + + def arrayToGLType(self, value): """Given a value, guess OpenGL type of the corresponding pointer""" - def arraySize( self, value, typeCode = None ): + + def arraySize(self, value, typeCode=None): """Given a data-value, calculate dimensions for the array""" - def unitSize( self, value, typeCode=None ): + + def unitSize(self, value, typeCode=None): """Determine unit size of an array (if possible)""" if self.baseType is not None: - return - def dimensions( self, value, typeCode=None ): + return + + def dimensions(self, value, typeCode=None): """Determine dimensions of the passed array value (if possible)""" diff --git a/OpenGL/arrays/lists.py b/OpenGL/arrays/lists.py index b704200d..72f4e544 100644 --- a/OpenGL/arrays/lists.py +++ b/OpenGL/arrays/lists.py @@ -6,31 +6,39 @@ C-level code there. This implementation is required to allow for usage without numpy installed. """ + REGISTRY_NAME = 'lists' import ctypes, _ctypes + # Note: these are the same definitions as for GLES, so we are not cross-polluting -from OpenGL.raw.GL import _types +from OpenGL.raw.GL import _types from OpenGL.arrays import _arrayconstants as GL_1_1 from OpenGL import constant, error from OpenGL._configflags import ERROR_ON_COPY from OpenGL.arrays import formathandler -from OpenGL._bytes import bytes,unicode,as_8_bit -HANDLED_TYPES = (list,tuple) +from OpenGL._bytes import bytes, unicode, as_8_bit + +HANDLED_TYPES = (list, tuple) import operator -def err_on_copy( func ): + +def err_on_copy(func): """Decorator which raises informative error if we try to copy while ERROR_ON_COPY""" if not ERROR_ON_COPY: - return func + return func else: - def raiseErrorOnCopy( self, value, *args, **named ): + + def raiseErrorOnCopy(self, value, *args, **named): raise error.CopyError( - """%s passed, cannot copy with ERROR_ON_COPY set, please use an array type which has native data-pointer support (e.g. numpy or ctypes arrays)"""%( value.__class__.__name__, ) + """%s passed, cannot copy with ERROR_ON_COPY set, please use an array type which has native data-pointer support (e.g. numpy or ctypes arrays)""" + % (value.__class__.__name__,) ) - raiseErrorOnCopy.__name__ = getattr(func,'__name__','raiseErrorOnCopy') + + raiseErrorOnCopy.__name__ = getattr(func, '__name__', 'raiseErrorOnCopy') return raiseErrorOnCopy -class ListHandler( formathandler.FormatHandler ): + +class ListHandler(formathandler.FormatHandler): """Storage of array data in Python lists/arrays This mechanism, unlike multi-dimensional arrays, is not necessarily @@ -44,131 +52,148 @@ class ListHandler( formathandler.FormatHandler ): arrays, not Python lists, this is done for convenience in coding the implementation, mostly. """ + @err_on_copy - def from_param( self, instance, typeCode=None ): + def from_param(self, instance, typeCode=None): try: - return ctypes.byref( instance ) - except (TypeError,AttributeError) as err: - array = self.asArray( instance, typeCode ) - pp = ctypes.c_void_p( ctypes.addressof( array ) ) + return ctypes.byref(instance) + except (TypeError, AttributeError) as err: + array = self.asArray(instance, typeCode) + pp = ctypes.c_void_p(ctypes.addressof(array)) pp._temporary_array_ = (array,) return pp - dataPointer = staticmethod( ctypes.addressof ) - HANDLED_TYPES = HANDLED_TYPES + + dataPointer = staticmethod(ctypes.addressof) + HANDLED_TYPES = HANDLED_TYPES isOutput = True + @err_on_copy @classmethod - def voidDataPointer( cls, value ): + def voidDataPointer(cls, value): """Given value in a known data-pointer type, return void_p for pointer""" - return ctypes.byref( value ) + return ctypes.byref(value) + @classmethod - def zeros( cls, dims, typeCode ): + def zeros(cls, dims, typeCode): """Return array of zeros in given size""" - type = GL_TYPE_TO_ARRAY_MAPPING[ typeCode ] + type = GL_TYPE_TO_ARRAY_MAPPING[typeCode] for dim in dims: - type *= dim - return type() # should expicitly set to 0s + type *= dim + return type() # should expicitly set to 0s + @classmethod - def dimsOf( cls, x ): + def dimsOf(cls, x): """Calculate total dimension-set of the elements in x - + This is *extremely* messy, as it has to track nested arrays - where the arrays could be different sizes on all sorts of + where the arrays could be different sizes on all sorts of levels... """ try: - dimensions = [ len(x) ] - except (TypeError,AttributeError,ValueError) as err: + _ = [len(x)] + except (TypeError, AttributeError, ValueError) as err: return [] else: childDimension = None for child in x: - newDimension = cls.dimsOf( child ) + newDimension = cls.dimsOf(child) if childDimension is not None: if newDimension != childDimension: - raise ValueError( - """Non-uniform array encountered: %s versus %s"""%( - newDimension, childDimension, - ), x + raise ValueError( + """Non-uniform array encountered: %s versus %s""" + % ( + newDimension, + childDimension, + ), + x, ) @classmethod - def arrayToGLType( cls, value ): + def arrayToGLType(cls, value): """Given a value, guess OpenGL type of the corresponding pointer""" - result = ARRAY_TO_GL_TYPE_MAPPING.get( value._type_ ) + result = ARRAY_TO_GL_TYPE_MAPPING.get(value._type_) if result is not None: return result raise TypeError( - """Don't know GL type for array of type %r, known types: %s\nvalue:%s"""%( - value._type_, list(ARRAY_TO_GL_TYPE_MAPPING.keys()), value, + """Don't know GL type for array of type %r, known types: %s\nvalue:%s""" + % ( + value._type_, + list(ARRAY_TO_GL_TYPE_MAPPING.keys()), + value, ) ) + @classmethod - def arraySize( cls, value, typeCode = None ): + def arraySize(cls, value, typeCode=None): """Given a data-value, calculate dimensions for the array""" dims = 1 - for base in cls.types( value ): - length = getattr( base, '_length_', None) + for base in cls.types(value): + length = getattr(base, '_length_', None) if length is not None: dims *= length - return dims + return dims + @classmethod - def types( cls, value ): + def types(cls, value): """Produce iterable producing all composite types""" dimObject = value while dimObject is not None: yield dimObject - dimObject = getattr( dimObject, '_type_', None ) - if isinstance( dimObject, (bytes,unicode)): - dimObject = None + dimObject = getattr(dimObject, '_type_', None) + if isinstance(dimObject, (bytes, unicode)): + dimObject = None + @classmethod - def dims( cls, value ): + def dims(cls, value): """Produce iterable of all dimensions""" - for base in cls.types( value ): - length = getattr( base, '_length_', None) + for base in cls.types(value): + length = getattr(base, '_length_', None) if length is not None: yield length + @err_on_copy @classmethod - def asArray( cls, value, typeCode=None ): + def asArray(cls, value, typeCode=None): """Convert given value to a ctypes array value of given typeCode - + This does a *lot* of work just to get the data into the correct format. It's not going to be anywhere near as fast as a numpy or similar approach! """ if typeCode is None: - raise NotImplementedError( """Haven't implemented type-inference for lists yet""" ) - arrayType = GL_TYPE_TO_ARRAY_MAPPING[ typeCode ] - if isinstance( value, (list,tuple)): - subItems = [ - cls.asArray( item, typeCode ) - for item in value - ] + raise NotImplementedError( + """Haven't implemented type-inference for lists yet""" + ) + arrayType = GL_TYPE_TO_ARRAY_MAPPING[typeCode] + if isinstance(value, (list, tuple)): + subItems = [cls.asArray(item, typeCode) for item in value] if subItems: - for dim in cls.dimensions( subItems[0] )[::-1]: + for dim in cls.dimensions(subItems[0])[::-1]: arrayType *= dim - arrayType *= len( subItems ) + arrayType *= len(subItems) result = arrayType() result[:] = subItems return result else: - return arrayType( value ) + return arrayType(value) + @err_on_copy @classmethod - def unitSize( cls, value, typeCode=None ): + def unitSize(cls, value, typeCode=None): """Determine unit size of an array (if possible)""" return tuple(cls.dims(value))[-1] + @err_on_copy @classmethod - def dimensions( cls, value, typeCode=None ): + def dimensions(cls, value, typeCode=None): """Determine dimensions of the passed array value (if possible)""" - return tuple( cls.dims(value) ) + return tuple(cls.dims(value)) + @classmethod - def arrayByteCount( cls, value, typeCode = None ): + def arrayByteCount(cls, value, typeCode=None): """Given a data-value, calculate number of bytes required to represent""" - return ctypes.sizeof( value ) + return ctypes.sizeof(value) ARRAY_TO_GL_TYPE_MAPPING = { @@ -178,7 +203,6 @@ def arrayByteCount( cls, value, typeCode = None ): _types.GLuint: GL_1_1.GL_UNSIGNED_INT, _types.GLshort: GL_1_1.GL_SHORT, _types.GLushort: GL_1_1.GL_UNSIGNED_SHORT, - _types.GLchar: GL_1_1.GL_CHAR, _types.GLbyte: GL_1_1.GL_BYTE, _types.GLubyte: GL_1_1.GL_UNSIGNED_BYTE, @@ -190,7 +214,6 @@ def arrayByteCount( cls, value, typeCode = None ): GL_1_1.GL_UNSIGNED_INT: _types.GLuint, GL_1_1.GL_SHORT: _types.GLshort, GL_1_1.GL_UNSIGNED_SHORT: _types.GLushort, - GL_1_1.GL_CHAR: _types.GLchar, GL_1_1.GL_BYTE: _types.GLbyte, GL_1_1.GL_UNSIGNED_BYTE: _types.GLubyte, diff --git a/OpenGL/arrays/numbers.py b/OpenGL/arrays/numbers.py index 2214b090..723b25db 100644 --- a/OpenGL/arrays/numbers.py +++ b/OpenGL/arrays/numbers.py @@ -1,5 +1,6 @@ """Numbers passed as array handling code for PyOpenGL """ + REGISTRY_NAME = 'numbers' from OpenGL.raw.GL import _types from OpenGL.raw.GL.VERSION import GL_1_1 @@ -40,13 +41,13 @@ def from_param(self, value, typeCode=None): def zeros(self, dims, typeCode=None): """Currently don't allow Number as output types!""" - raise NotImplemented( + raise NotImplementedError( """Number data-type not allowed as an output array format""" ) def ones(self, dims, typeCode=None): """Currently don't allow Number as output types!""" - raise NotImplemented( + raise NotImplementedError( """Number data-type not allowed as an output array format""" ) diff --git a/OpenGL/arrays/strings.py b/OpenGL/arrays/strings.py index 40aa7d97..79850ac5 100644 --- a/OpenGL/arrays/strings.py +++ b/OpenGL/arrays/strings.py @@ -1,83 +1,102 @@ """String-array-handling code for PyOpenGL """ -from OpenGL.raw.GL import _types + +from OpenGL.raw.GL import _types from OpenGL.raw.GL.VERSION import GL_1_1 from OpenGL.arrays import formathandler import ctypes from OpenGL import _bytes, error from OpenGL._configflags import ERROR_ON_COPY -def dataPointer( value, typeCode=None ): - return ctypes.cast(ctypes.c_char_p(value), - ctypes.c_void_p).value -class StringHandler( formathandler.FormatHandler ): +def dataPointer(value, typeCode=None): + return ctypes.cast(ctypes.c_char_p(value), ctypes.c_void_p).value + + +class StringHandler(formathandler.FormatHandler): """String-specific data-type handler for OpenGL""" - HANDLED_TYPES = (_bytes.bytes, ) + + HANDLED_TYPES = (_bytes.bytes,) + @classmethod - def from_param( cls, value, typeCode=None ): - return ctypes.c_void_p( dataPointer( value ) ) - dataPointer = staticmethod( dataPointer ) - def zeros( self, dims, typeCode=None ): + def from_param(cls, value, typeCode=None): + return ctypes.c_void_p(dataPointer(value)) + + dataPointer = staticmethod(dataPointer) + + def zeros(self, dims, typeCode=None): """Currently don't allow strings as output types!""" - raise NotImplemented( """Don't currently support strings as output arrays""" ) - def ones( self, dims, typeCode=None ): + raise NotImplementedError( + """Don't currently support strings as output arrays""" + ) + + def ones(self, dims, typeCode=None): """Currently don't allow strings as output types!""" - raise NotImplemented( """Don't currently support strings as output arrays""" ) - def arrayToGLType( self, value ): + raise NotImplementedError( + """Don't currently support strings as output arrays""" + ) + + def arrayToGLType(self, value): """Given a value, guess OpenGL type of the corresponding pointer""" - raise NotImplemented( """Can't guess data-type from a string-type argument""" ) - def arraySize( self, value, typeCode = None ): + raise NotImplementedError( + """Can't guess data-type from a string-type argument""" + ) + + def arraySize(self, value, typeCode=None): """Given a data-value, calculate ravelled size for the array""" # need to get bits-per-element... - byteCount = BYTE_SIZES[ typeCode ] - return len(value)//byteCount - def arrayByteCount( self, value, typeCode = None ): + byteCount = BYTE_SIZES[typeCode] + return len(value) // byteCount + + def arrayByteCount(self, value, typeCode=None): """Given a data-value, calculate number of bytes required to represent""" return len(value) - def asArray( self, value, typeCode=None ): + + def asArray(self, value, typeCode=None): """Convert given value to an array value of given typeCode""" - if isinstance( value, bytes ): + if isinstance(value, bytes): return value - elif hasattr( value, 'tostring' ): + elif hasattr(value, 'tostring'): return value.tostring() - elif hasattr( value, 'raw' ): + elif hasattr(value, 'raw'): return value.raw # could convert types to string here, but we're not registered for # anything save string types... - raise TypeError( """String handler got non-string object: %r"""%(type(value))) - def dimensions( self, value, typeCode=None ): + raise TypeError("""String handler got non-string object: %r""" % (type(value))) + + def dimensions(self, value, typeCode=None): """Determine dimensions of the passed array value (if possible)""" - raise TypeError( - """Cannot calculate dimensions for a String data-type""" - ) + raise TypeError("""Cannot calculate dimensions for a String data-type""") + -class UnicodeHandler( StringHandler ): +class UnicodeHandler(StringHandler): HANDLED_TYPES = (_bytes.unicode,) + @classmethod - def from_param( cls, value, typeCode=None ): + def from_param(cls, value, typeCode=None): # TODO: raise CopyError if the flag is set! - converted = _bytes.as_8_bit( value ) - result = StringHandler.from_param( converted ) + converted = _bytes.as_8_bit(value) + result = StringHandler.from_param(converted) if converted is not value: if ERROR_ON_COPY: raise error.CopyError( """Unicode string passed, cannot copy with ERROR_ON_COPY set, please use 8-bit strings""" ) - result._temporary_array_ = converted + result._temporary_array_ = converted return result - def asArray( self, value, typeCode=None ): - value = _bytes.as_8_bit( value ) - return StringHandler.asArray( self, value, typeCode=typeCode ) + + def asArray(self, value, typeCode=None): + value = _bytes.as_8_bit(value) + return StringHandler.asArray(self, value, typeCode=typeCode) BYTE_SIZES = { - GL_1_1.GL_DOUBLE: ctypes.sizeof( _types.GLdouble ), - GL_1_1.GL_FLOAT: ctypes.sizeof( _types.GLfloat ), - GL_1_1.GL_INT: ctypes.sizeof( _types.GLint ), - GL_1_1.GL_SHORT: ctypes.sizeof( _types.GLshort ), - GL_1_1.GL_UNSIGNED_BYTE: ctypes.sizeof( _types.GLubyte ), - GL_1_1.GL_UNSIGNED_SHORT: ctypes.sizeof( _types.GLshort ), - GL_1_1.GL_BYTE: ctypes.sizeof( _types.GLbyte ), - GL_1_1.GL_UNSIGNED_INT: ctypes.sizeof( _types.GLuint ), + GL_1_1.GL_DOUBLE: ctypes.sizeof(_types.GLdouble), + GL_1_1.GL_FLOAT: ctypes.sizeof(_types.GLfloat), + GL_1_1.GL_INT: ctypes.sizeof(_types.GLint), + GL_1_1.GL_SHORT: ctypes.sizeof(_types.GLshort), + GL_1_1.GL_UNSIGNED_BYTE: ctypes.sizeof(_types.GLubyte), + GL_1_1.GL_UNSIGNED_SHORT: ctypes.sizeof(_types.GLshort), + GL_1_1.GL_BYTE: ctypes.sizeof(_types.GLbyte), + GL_1_1.GL_UNSIGNED_INT: ctypes.sizeof(_types.GLuint), } diff --git a/OpenGL/arrays/vbo.py b/OpenGL/arrays/vbo.py index 362c2527..21188f83 100644 --- a/OpenGL/arrays/vbo.py +++ b/OpenGL/arrays/vbo.py @@ -30,29 +30,34 @@ This implementation will choose either the ARB or Core (OpenGL 1.5) implementation of the VBO functions. """ + from OpenGL.arrays.arraydatatype import ArrayDatatype from OpenGL.arrays.formathandler import FormatHandler -from OpenGL.raw.GL import _types +from OpenGL.raw.GL import _types from OpenGL import error -from OpenGL._bytes import bytes,unicode,as_8_bit -import ctypes,logging -_log = logging.getLogger( 'OpenGL.arrays.vbo' ) +from OpenGL._bytes import bytes, unicode, as_8_bit +import ctypes, logging + +_log = logging.getLogger('OpenGL.arrays.vbo') from OpenGL._bytes import long, integer_types import weakref -__all__ = ('VBO','VBOHandler','mapVBO') -class Implementation( object ): - """Abstraction point for the various implementations that can be used - """ +__all__ = ('VBO', 'VBOHandler', 'mapVBO') + + +class Implementation(object): + """Abstraction point for the various implementations that can be used""" + IMPLEMENTATION_CLASSES = [] CHOSEN = None + @classmethod - def register( cls ): - cls.IMPLEMENTATION_CLASSES.append( cls ) - - @classmethod - def get_implementation( cls, *args ): + def register(cls): + cls.IMPLEMENTATION_CLASSES.append(cls) + + @classmethod + def get_implementation(cls, *args): if cls.CHOSEN is None: for possible in cls.IMPLEMENTATION_CLASSES: implementation = possible() @@ -83,28 +88,34 @@ def get_implementation( cls, *args ): GL_TEXTURE_BUFFER GL_TRANSFORM_FEEDBACK_BUFFER'''.split() available = False - def _arbname( self, name ): + + def _arbname(self, name): return ( - (name.startswith( 'gl' ) and name.endswith( 'ARB' )) or - (name.startswith( 'GL_' ) and name.endswith( 'ARB' )) + (name.startswith('gl') and name.endswith('ARB')) + or (name.startswith('GL_') and name.endswith('ARB')) ) and (name != 'glInitVertexBufferObjectARB') - def basename( self, name ): - if name.endswith( '_ARB' ): + + def basename(self, name): + if name.endswith('_ARB'): return name[:-4] - elif name.endswith( 'ARB' ): + elif name.endswith('ARB'): return name[:-3] else: return name - def __nonzero__( self ): + + def __nonzero__(self): return self.available + __bool__ = __nonzero__ - def deleter( self, buffers, key): + + def deleter(self, buffers, key): """Produce a deleter callback to delete the given buffer""" - # these values are stored here to avoid them being cleaned up + # these values are stored here to avoid them being cleaned up # to non during module deletion and causing errors to be raised nfe = error.NullFunctionError gluint = _types.GLuint - def doBufferDeletion( *args, **named ): + + def doBufferDeletion(*args, **named): while buffers: try: buffer = buffers.pop() @@ -114,32 +125,38 @@ def doBufferDeletion( *args, **named ): try: # Note that to avoid ERROR_ON_COPY issues # we have to pass an array-compatible type here... - buf = gluint( buffer ) + buf = gluint(buffer) self.glDeleteBuffers(1, buf) except (AttributeError, nfe, TypeError) as err: pass try: - self._DELETERS_.pop( key ) + self._DELETERS_.pop(key) except KeyError as err: pass + return doBufferDeletion + _DELETERS_ = {} + get_implementation = Implementation.get_implementation from OpenGL import acceleratesupport + VBO = None if acceleratesupport.ACCELERATE_AVAILABLE: try: from OpenGL_accelerate.vbo import ( - VBO,VBOOffset,VBOHandler,VBOOffsetHandler, + VBO, + VBOOffset, + VBOHandler, + VBOOffsetHandler, ) except ImportError as err: - _log.warning( - "Unable to load VBO accelerator from OpenGL_accelerate" - ) + _log.warning("Unable to load VBO accelerator from OpenGL_accelerate") if VBO is None: - class VBO( object ): + + class VBO(object): """Instances can be passed into array-handling routines You can check for whether VBOs are supported by accessing the implementation: @@ -149,18 +166,23 @@ class VBO( object ): else: # fallback version of code """ + copied = False - _no_cache_ = True # do not cache in context data arrays + _no_cache_ = True # do not cache in context data arrays + def __init__( - self, data, usage='GL_DYNAMIC_DRAW', - target='GL_ARRAY_BUFFER', size=None, + self, + data, + usage='GL_DYNAMIC_DRAW', + target='GL_ARRAY_BUFFER', + size=None, ): - """Initialize the VBO object - + """Initialize the VBO object + data -- PyOpenGL-compatible array-data structure, numpy arrays, ctypes arrays, etc. - usage -- OpenGL usage constant describing expected data-flow patterns (this is a hint + usage -- OpenGL usage constant describing expected data-flow patterns (this is a hint to the GL about where/how to cache the data) - + GL_STATIC_DRAW_ARB GL_STATIC_READ_ARB GL_STATIC_COPY_ARB @@ -170,43 +192,48 @@ def __init__( GL_STREAM_DRAW_ARB GL_STREAM_READ_ARB GL_STREAM_COPY_ARB - - DRAW constants suggest to the card that the data will be primarily used to draw - on the card. READ that the data will be read back into the GL. COPY means that + + DRAW constants suggest to the card that the data will be primarily used to draw + on the card. READ that the data will be read back into the GL. COPY means that the data will be used both for DRAW and READ operations. - + STATIC suggests that the data will only be written once (or a small number of times). - DYNAMIC suggests that the data will be used a small number of times before being + DYNAMIC suggests that the data will be used a small number of times before being discarded. - STREAM suggests that the data will be updated approximately every time that it is + STREAM suggests that the data will be updated approximately every time that it is used (that is, it will likely only be used once). - + target -- VBO target to which to bind (array or indices) - GL_ARRAY_BUFFER -- array-data binding + GL_ARRAY_BUFFER -- array-data binding GL_ELEMENT_ARRAY_BUFFER -- index-data binding GL_UNIFORM_BUFFER -- used to pass mid-size arrays of data packed into a buffer GL_TEXTURE_BUFFER -- used to pass large arrays of data as a pseudo-texture GL_TRANSFORM_FEEDBACK_BUFFER -- used to receive transformed vertices for processing - + size -- if not provided, will use arrayByteCount to determine the size of the data-array, thus this value (number of bytes) is required when using opaque data-structures, (such as ctypes pointers) as the array data-source. """ self.usage = usage - self.set_array( data, size ) + self.set_array(data, size) self.target = target self.buffers = [] self._copy_segments = [] + _I_ = None - implementation = property( get_implementation, ) - def resolve( self, value ): + implementation = property( + get_implementation, + ) + + def resolve(self, value): """Resolve string constant to constant""" - if isinstance( value, (bytes,unicode)): - return getattr( self.implementation, self.implementation.basename( value ) ) + if isinstance(value, (bytes, unicode)): + return getattr(self.implementation, self.implementation.basename(value)) return value - def set_array( self, data, size=None ): + + def set_array(self, data, size=None): """Update our entire array with new data - + data -- PyOpenGL-compatible array-data structure, numpy arrays, ctypes arrays, etc. size -- if not provided, will use arrayByteCount to determine the size of the data-array, thus this value (number of bytes) is required when using opaque data-structures, @@ -217,8 +244,9 @@ def set_array( self, data, size=None ): if size is not None: self.size = size elif self.data is not None: - self.size = ArrayDatatype.arrayByteCount( self.data ) - def __setitem__( self, slice, array): + self.size = ArrayDatatype.arrayByteCount(self.data) + + def __setitem__(self, slice, array): """Set slice of data on the array and vbo (if copied already) slice -- the Python slice object determining how the data should @@ -234,21 +262,23 @@ def __setitem__( self, slice, array): is concerned). """ if slice.step and not slice.step == 1: - raise NotImplemented( """Don't know how to map stepped arrays yet""" ) + raise NotImplementedError( + """Don't know how to map stepped arrays yet""" + ) # TODO: handle e.g. mapping character data into an integer data-set - data = ArrayDatatype.asArray( array ) - data_length = ArrayDatatype.arrayByteCount( array ) - start = (slice.start or 0) - stop = (slice.stop or len(self.data)) + data = ArrayDatatype.asArray(array) + # data_length = ArrayDatatype.arrayByteCount(array) + start = slice.start or 0 + stop = slice.stop or len(self.data) if start < 0: start += len(self.data) - start = max((start,0)) + start = max((start, 0)) if stop < 0: stop += len(self.data) - stop = max((stop,0)) - self.data[ slice ] = data + stop = max((stop, 0)) + self.data[slice] = data if self.copied and self.buffers: - if start-stop == len(self.data): + if start - stop == len(self.data): # re-copy the whole data-set self.copied = False elif len(data): @@ -259,50 +289,65 @@ def __setitem__( self, slice, array): # multiple mappings to copy into the memory area... # find the step size from the dimensions and base size... - size = ArrayDatatype.arrayByteCount( self.data[0] ) - #baseSize = ArrayDatatype.unitSize( data ) + size = ArrayDatatype.arrayByteCount(self.data[0]) + # baseSize = ArrayDatatype.unitSize( data ) # now create the start and distance values... start *= size stop *= size # wait until the last moment (bind) to copy the data... - self._copy_segments.append( - (start,(stop-start), data) - ) - def __len__( self ): + self._copy_segments.append((start, (stop - start), data)) + + def __len__(self): """Delegate length/truth checks to our data-array""" - return len( self.data ) - def __getattr__( self, key ): + return len(self.data) + + def __getattr__(self, key): """Delegate failing attribute lookups to our data-array""" - if key not in ('data','usage','target','buffers', 'copied','_I_','implementation','_copy_segments' ): - return getattr( self.data, key ) + if key not in ( + 'data', + 'usage', + 'target', + 'buffers', + 'copied', + '_I_', + 'implementation', + '_copy_segments', + ): + return getattr(self.data, key) else: - raise AttributeError( key ) - def create_buffers( self ): + raise AttributeError(key) + + def create_buffers(self): """Create the internal buffer(s)""" assert not self.buffers, """Already created the buffer""" - self.buffers = [ long(self.implementation.glGenBuffers(1)) ] - self.target = self.resolve( self.target ) - self.usage = self.resolve( self.usage ) - self.implementation._DELETERS_[ id(self) ] = weakref.ref( self, self.implementation.deleter( self.buffers, id(self) )) + self.buffers = [long(self.implementation.glGenBuffers(1))] + self.target = self.resolve(self.target) + self.usage = self.resolve(self.usage) + self.implementation._DELETERS_[id(self)] = weakref.ref( + self, self.implementation.deleter(self.buffers, id(self)) + ) return self.buffers - def copy_data( self ): + + def copy_data(self): """Copy our data into the buffer on the GL side (if required) - - Ensures that the GL's version of the data in the VBO matches our - internal view of the data, either by copying the entire data-set - over with glBufferData or by updating the already-transferred + + Ensures that the GL's version of the data in the VBO matches our + internal view of the data, either by copying the entire data-set + over with glBufferData or by updating the already-transferred data with glBufferSubData. """ assert self.buffers, """Should do create_buffers before copy_data""" if self.copied: if self._copy_segments: while self._copy_segments: - start,size,data = self._copy_segments.pop(0) - dataptr = ArrayDatatype.voidDataPointer( data ) - self.implementation.glBufferSubData(self.target, start, size, dataptr) + start, size, data = self._copy_segments.pop(0) + dataptr = ArrayDatatype.voidDataPointer(data) + self.implementation.glBufferSubData( + self.target, start, size, dataptr + ) else: if self.data is not None and self.size is None: - self.size = ArrayDatatype.arrayByteCount( self.data ) + self.size = ArrayDatatype.arrayByteCount(self.data) self.implementation.glBufferData( self.target, self.size, @@ -310,139 +355,168 @@ def copy_data( self ): self.usage, ) self.copied = True - def delete( self ): + + def delete(self): """Delete this buffer explicitly""" if self.buffers: while self.buffers: try: self.implementation.glDeleteBuffers(1, self.buffers.pop(0)) - except (AttributeError,error.NullFunctionError) as err: + except (AttributeError, error.NullFunctionError) as err: pass - def __int__( self ): + + def __int__(self): """Get our VBO id""" if not self.buffers: self.create_buffers() return self.buffers[0] - def bind( self ): + + def bind(self): """Bind this buffer for use in vertex calls - - If we have not yet created our implementation-level VBO, then we + + If we have not yet created our implementation-level VBO, then we will create it before binding. Once bound, calls self.copy_data() """ if not self.buffers: - buffers = self.create_buffers() - self.implementation.glBindBuffer( self.target, self.buffers[0]) + self.create_buffers() + self.implementation.glBindBuffer(self.target, self.buffers[0]) self.copy_data() - def unbind( self ): + + def unbind(self): """Unbind the buffer (make normal array operations active)""" - self.implementation.glBindBuffer( self.target,0 ) + self.implementation.glBindBuffer(self.target, 0) - def __add__( self, other ): + def __add__(self, other): """Add an integer to this VBO (create a VBOOffset)""" - if hasattr( other, 'offset' ): + if hasattr(other, 'offset'): other = other.offset - assert isinstance( other, integer_types ), """Only know how to add integer/long offsets""" - return VBOOffset( self, other ) + assert isinstance( + other, integer_types + ), """Only know how to add integer/long offsets""" + return VBOOffset(self, other) __enter__ = bind - def __exit__( self, exc_type=None, exc_val=None, exc_tb=None ): + + def __exit__(self, exc_type=None, exc_val=None, exc_tb=None): """Context manager exit""" self.unbind() - return False # do not supress exceptions... + return False # do not supress exceptions... + + class VBOOffset(object): + """Offset into a VBO instance - class VBOOffset( object ): - """Offset into a VBO instance - This class is normally instantiated by doing a my_vbo + int operation, - it can be passed to VBO requiring operations and will generate the + it can be passed to VBO requiring operations and will generate the appropriate integer offset value to be passed in. """ - def __init__( self, vbo, offset ): + + def __init__(self, vbo, offset): """Initialize the offset with vbo and offset (unsigned integer)""" self.vbo = vbo self.offset = offset - def __getattr__( self, key ): + + def __getattr__(self, key): """Delegate any undefined attribute save vbo to our vbo""" if key != 'vbo': - return getattr( self.vbo, key ) - raise AttributeError( 'No %r key in VBOOffset'%(key,)) - def __add__( self, other ): - """Allow adding integers or other VBOOffset instances - + return getattr(self.vbo, key) + raise AttributeError('No %r key in VBOOffset' % (key,)) + + def __add__(self, other): + """Allow adding integers or other VBOOffset instances + returns a VBOOffset to the this VBO with other.offset + self.offset or, if other has no offset, returns VBOOffset with self.offset + other """ - if hasattr( other, 'offset' ): + if hasattr(other, 'offset'): other = other.offset - return VBOOffset( self.vbo, self.offset + other ) + return VBOOffset(self.vbo, self.offset + other) - class VBOHandler( FormatHandler ): + class VBOHandler(FormatHandler): """Handles VBO instances passed in as array data - - This FormatHandler is registered with PyOpenGL on import of this module + + This FormatHandler is registered with PyOpenGL on import of this module to provide handling of VBO objects as array data-sources """ - vp0 = ctypes.c_void_p( 0 ) - def dataPointer( self, instance ): + + vp0 = ctypes.c_void_p(0) + + def dataPointer(self, instance): """Retrieve data-pointer from the instance's data Is always NULL, to indicate use of the bound pointer """ return 0 - def from_param( self, instance, typeCode=None ): + + def from_param(self, instance, typeCode=None): """Always returns c_void_p(0)""" return self.vp0 - def zeros( self, dims, typeCode ): + + def zeros(self, dims, typeCode): """Not implemented""" - raise NotImplemented( """Don't have VBO output support yet""" ) + raise NotImplementedError("""Don't have VBO output support yet""") + ones = zeros - def asArray( self, value, typeCode=None ): + + def asArray(self, value, typeCode=None): """Given a value, convert to array representation""" return value - def arrayToGLType( self, value ): + + def arrayToGLType(self, value): """Given a value, guess OpenGL type of the corresponding pointer""" - return ArrayDatatype.arrayToGLType( value.data ) - def arrayByteCount( self, value ): - return ArrayDatatype.arrayByteCount( value.data ) - def arraySize( self, value, typeCode = None ): + return ArrayDatatype.arrayToGLType(value.data) + + def arrayByteCount(self, value): + return ArrayDatatype.arrayByteCount(value.data) + + def arraySize(self, value, typeCode=None): """Given a data-value, calculate dimensions for the array""" - return ArrayDatatype.arraySize( value.data ) - def unitSize( self, value, typeCode=None ): + return ArrayDatatype.arraySize(value.data) + + def unitSize(self, value, typeCode=None): """Determine unit size of an array (if possible)""" - return ArrayDatatype.unitSize( value.data ) - def dimensions( self, value, typeCode=None ): + return ArrayDatatype.unitSize(value.data) + + def dimensions(self, value, typeCode=None): """Determine dimensions of the passed array value (if possible)""" - return ArrayDatatype.dimensions( value.data ) + return ArrayDatatype.dimensions(value.data) - class VBOOffsetHandler( VBOHandler ): + class VBOOffsetHandler(VBOHandler): """Handles VBOOffset instances passed in as array data - - Registered on module import to provide support for VBOOffset instances + + Registered on module import to provide support for VBOOffset instances as sources for array data. """ - def dataPointer( self, instance ): + + def dataPointer(self, instance): """Retrieve data-pointer from the instance's data returns instance' offset """ return instance.offset - def from_param( self, instance, typeCode=None ): + + def from_param(self, instance, typeCode=None): """Returns a c_void_p( instance.offset )""" - return ctypes.c_void_p( instance.offset ) + return ctypes.c_void_p(instance.offset) + _cleaners = {} -def _cleaner( vbo ): + + +def _cleaner(vbo): """Construct a mapped-array cleaner function to unmap vbo.target""" - def clean( ref ): + + def clean(ref): try: - _cleaners.pop( vbo ) + _cleaners.pop(vbo) except Exception as err: pass else: - vbo.implementation.glUnmapBuffer( vbo.target ) + vbo.implementation.glUnmapBuffer(vbo.target) + return clean -def mapVBO( vbo, access=0x88BA ): # GL_READ_WRITE + +def mapVBO(vbo, access=0x88BA): # GL_READ_WRITE """Map the given buffer into a numpy array... Method taken from: @@ -451,15 +525,16 @@ def mapVBO( vbo, access=0x88BA ): # GL_READ_WRITE This should be considered an *experimental* API, it is not guaranteed to be available in future revisions of this library! - + Simplification to use ctypes cast from comment by 'sashimi' on my blog... """ from numpy import frombuffer - vp = vbo.implementation.glMapBuffer( vbo.target, access ) - # TODO: obviously this is not the right way to do this should allow each format + + vp = vbo.implementation.glMapBuffer(vbo.target, access) + # TODO: obviously this is not the right way to do this should allow each format # handler to convert the pointer in their own way... - vp_array = ctypes.cast(vp, ctypes.POINTER(ctypes.c_byte*vbo.size) ) + vp_array = ctypes.cast(vp, ctypes.POINTER(ctypes.c_byte * vbo.size)) # Note: we could have returned the raw ctypes.c_byte array instead... - array = frombuffer( vp_array, 'B' ) - _cleaners[vbo] = weakref.ref( array, _cleaner( vbo )) + array = frombuffer(vp_array, 'B') + _cleaners[vbo] = weakref.ref(array, _cleaner(vbo)) return array diff --git a/OpenGL/converters.py b/OpenGL/converters.py index 91d34db2..57e6560c 100644 --- a/OpenGL/converters.py +++ b/OpenGL/converters.py @@ -1,10 +1,13 @@ """Implementations for common converter types""" -import ctypes,logging + +import ctypes, logging from OpenGL._bytes import bytes, unicode, as_8_bit from OpenGL._null import NULL -_log = logging.getLogger( 'OpenGL.converters' ) -class Converter( object ): +_log = logging.getLogger('OpenGL.converters') + + +class Converter(object): """Base class for Converter types Converter objects are callable objects used with the @@ -24,9 +27,11 @@ class Converter( object ): Converters can be any of the Wrapper API helper functions, so the callable interface can vary among Converter classes. """ - argNames = ( ) - indexLookups = ( ) - def __init__( self, *args, **named ): + + argNames = () + indexLookups = () + + def __init__(self, *args, **named): """Store arguments in attributes *args -- mapped to self.argNames in order to set attributes @@ -35,26 +40,28 @@ def __init__( self, *args, **named ): argNames = list(self.argNames) for a in self.argNames: if a in named: - setattr( self, a, named[a] ) - argNames.remove( a ) - for a,value in zip( argNames, args ): - setattr( self, a, value ) - def finalise( self, wrapper ): + setattr(self, a, named[a]) + argNames.remove(a) + for a, value in zip(argNames, args): + setattr(self, a, value) + + def finalise(self, wrapper): """Look up our indices (where appropriate)""" - for indexname,argName,methodName in self.indexLookups: + for indexname, argName, methodName in self.indexLookups: setattr( - self, indexname, - getattr(wrapper,methodName)(getattr( self, argName )) + self, indexname, getattr(wrapper, methodName)(getattr(self, argName)) ) + # Definitions of the abstract interfaces... -class PyConverter( Converter ): +class PyConverter(Converter): """Converter sub-class for use in Wrapper.pyConverters This class just defines the interface for a pyConverter-style Converter object """ - def __call__( self, incoming, function, arguments ): + + def __call__(self, incoming, function, arguments): """Convert incoming argument into compatable data-types incoming -- the Python argument for this parameter @@ -64,17 +71,19 @@ def __call__( self, incoming, function, arguments ): """ - raise NotImplemented( """%s class doesn't implement __call__"""%( - self.__class__.__name__, - )) + raise NotImplementedError( + """%s class doesn't implement __call__""" % (self.__class__.__name__,) + ) + -class CConverter( Converter ): +class CConverter(Converter): """Converter sub-class for use in Wrapper.cConverters This class just defines the interface for a cConverter-style Converter object """ - def __call__( self, pyArgs, index, baseOperation ): + + def __call__(self, pyArgs, index, baseOperation): """Calculate C-compatible Python object from Python arguments pyArgs -- set of Python argument objects converted by @@ -82,16 +91,19 @@ def __call__( self, pyArgs, index, baseOperation ): index -- our index in baseOperation.cConverters baseOperation -- the Wrapper object which we are supporting """ - raise NotImplemented( """%s class doesn't implement __call__"""%( - self.__class__.__name__, - )) -class ReturnValues( Converter ): + raise NotImplementedError( + """%s class doesn't implement __call__""" % (self.__class__.__name__,) + ) + + +class ReturnValues(Converter): """Converter sub-class for use as Wrapper.returnValues This class just defines the interface for a returnValues-style Converter object """ - def __call__( self, result, baseOperation, pyArgs, cArgs ): + + def __call__(self, result, baseOperation, pyArgs, cArgs): """Return a final value to the caller result -- the raw ctypes result value @@ -101,23 +113,31 @@ def __call__( self, result, baseOperation, pyArgs, cArgs ): return the Python object for the final result """ - raise NotImplemented( """%s class doesn't implement __call__"""%( - self.__class__.__name__, - )) + raise NotImplementedError( + """%s class doesn't implement __call__""" % (self.__class__.__name__,) + ) + # Now the concrete classes... from OpenGL import acceleratesupport + CallFuncPyConverter = None if acceleratesupport.ACCELERATE_AVAILABLE: try: from OpenGL_accelerate.wrapper import ( - CallFuncPyConverter, DefaultCConverter, getPyArgsName, + CallFuncPyConverter, + DefaultCConverter, + getPyArgsName, ) from OpenGL_accelerate.arraydatatype import ( - Output,SizedOutput,OutputOrInput,SizedOutputOrInput + Output, + SizedOutput, + OutputOrInput, + SizedOutputOrInput, ) from OpenGL_accelerate.wrapper import ( - returnCArgument, returnPyArgument, + returnCArgument, + returnPyArgument, ) except ImportError as err: _log.warning( @@ -125,15 +145,19 @@ def __call__( self, result, baseOperation, pyArgs, cArgs ): ) CallFuncPyConverter = None if CallFuncPyConverter is None: - class CallFuncPyConverter( PyConverter ): + + class CallFuncPyConverter(PyConverter): """PyConverter that takes a callable and calls it on incoming""" - def __init__( self, function ): + + def __init__(self, function): """Store the function""" self.function = function - def __call__( self, incoming, function, argument ): + + def __call__(self, incoming, function, argument): """Call our function on incoming""" - return self.function( incoming ) - class DefaultCConverter( CConverter ): + return self.function(incoming) + + class DefaultCConverter(CConverter): """NULL or Default CConverter, returns same-named Python argument Used primarily to allow for specifying a converter that explicitly @@ -143,36 +167,44 @@ class DefaultCConverter( CConverter ): Raises informative errors if the index cannot be resolved in pyArgs """ - def __init__( self, index ): + + def __init__(self, index): """Just store index for future access""" self.index = index - def __call__( self, pyArgs, index, wrapper ): + + def __call__(self, pyArgs, index, wrapper): """Return pyArgs[self.index] or raise a ValueError""" try: - return pyArgs[ self.index ] + return pyArgs[self.index] except IndexError: raise ValueError( - """Expected parameter index %r, but pyArgs only length %s"""%( - self.index, - len(pyArgs ) - )) - class getPyArgsName( CConverter ): + """Expected parameter index %r, but pyArgs only length %s""" + % (self.index, len(pyArgs)) + ) + + class getPyArgsName(CConverter): """CConverter returning named Python argument Intended for use in cConverters, the function returned retrieves the named pyArg and returns it when called. """ + argNames = ('name',) - indexLookups = [ ('index','name', 'pyArgIndex' ), ] - __slots__ = ( 'index', 'name') - def __call__( self, pyArgs, index, baseOperation ): + indexLookups = [ + ('index', 'name', 'pyArgIndex'), + ] + __slots__ = ('index', 'name') + + def __call__(self, pyArgs, index, baseOperation): """Return pyArgs[ self.index ]""" try: - return pyArgs[ self.index ] + return pyArgs[self.index] except AttributeError: - raise RuntimeError( """"Did not resolve parameter index for %r"""%(self.name)) + raise RuntimeError( + """"Did not resolve parameter index for %r""" % (self.name) + ) - class Output( CConverter ): + class Output(CConverter): """CConverter generating static-size typed output arrays Produces an output array of given type (arrayType) and @@ -186,89 +218,115 @@ class Output( CConverter ): PyOpenGL compatability mode, where result arrays of size (1,) are returned as scalar values. """ - argNames = ('name','size','arrayType' ) + + argNames = ('name', 'size', 'arrayType') indexLookups = [ - ('outIndex','name', 'cArgIndex' ), + ('outIndex', 'name', 'cArgIndex'), ] - __slots__ = ('index','size','arrayType','outIndex','inIndex') - def __call__( self, pyArgs, index, baseOperation ): + __slots__ = ('index', 'size', 'arrayType', 'outIndex', 'inIndex') + + def __call__(self, pyArgs, index, baseOperation): """Return pyArgs[ self.index ]""" - return self.arrayType.zeros( self.getSize(pyArgs) ) - def getSize( self, pyArgs ): + return self.arrayType.zeros(self.getSize(pyArgs)) + + def getSize(self, pyArgs): """Retrieve the array size for this argument""" return self.size - def oldStyleReturn( self, result, baseOperation, pyArgs, cArgs ): + + def oldStyleReturn(self, result, baseOperation, pyArgs, cArgs): """Retrieve cArgs[ self.index ]""" - result = cArgs[ self.outIndex ] + result = cArgs[self.outIndex] try: thisSize = self.getSize(pyArgs) except KeyError: - return result + return result if thisSize == (1,): try: return result[0] - except (IndexError,TypeError): + except (IndexError, TypeError): return result else: return result - class OutputOrInput( Output ): - DO_OUTPUT = (None,NULL) - def __call__( self, pyArgs, index, baseOperation ): + + class OutputOrInput(Output): + DO_OUTPUT = (None, NULL) + + def __call__(self, pyArgs, index, baseOperation): for do_output in self.DO_OUTPUT: if pyArgs[index] is do_output: - return super( OutputOrInput,self ).__call__( pyArgs, index, baseOperation ) - return self.arrayType.asArray( pyArgs[index] ) + return super(OutputOrInput, self).__call__( + pyArgs, index, baseOperation + ) + return self.arrayType.asArray(pyArgs[index]) - class SizedOutput( Output ): + class SizedOutput(Output): """Output generating dynamically-sized typed output arrays Takes an extra parameter "specifier", which is the name of a Python argument to be passed to the lookup function in order to determine the appropriate size for the output array. """ - argNames = ('name','specifier','lookup','arrayType' ) + + argNames = ('name', 'specifier', 'lookup', 'arrayType') indexLookups = [ - ('outIndex','name', 'cArgIndex' ), - ('index','specifier', 'pyArgIndex' ), + ('outIndex', 'name', 'cArgIndex'), + ('index', 'specifier', 'pyArgIndex'), ] - __slots__ = ('index','outIndex','specifier','lookup','arrayType') - def getSize( self, pyArgs ): + __slots__ = ('index', 'outIndex', 'specifier', 'lookup', 'arrayType') + + def getSize(self, pyArgs): """Retrieve the array size for this argument""" try: - specifier = pyArgs[ self.index ] + specifier = pyArgs[self.index] except AttributeError: - raise RuntimeError( """"Did not resolve parameter index for %r"""%(self.name)) + raise RuntimeError( + """"Did not resolve parameter index for %r""" % (self.name) + ) else: try: - return self.lookup( specifier ) + return self.lookup(specifier) except KeyError: - raise KeyError( """Unknown specifier %s"""%( specifier )) - class SizedOutputOrInput( SizedOutput ): - DO_OUTPUT = (None,NULL) - def __call__( self, pyArgs, index, baseOperation ): + raise KeyError("""Unknown specifier %s""" % (specifier)) + + class SizedOutputOrInput(SizedOutput): + DO_OUTPUT = (None, NULL) + + def __call__(self, pyArgs, index, baseOperation): for do_output in self.DO_OUTPUT: if pyArgs[index] is do_output: - return super( SizedOutputOrInput,self ).__call__( pyArgs, index, baseOperation ) - return self.arrayType.asArray( pyArgs[index] ) - class returnCArgument( ReturnValues ): + return super(SizedOutputOrInput, self).__call__( + pyArgs, index, baseOperation + ) + return self.arrayType.asArray(pyArgs[index]) + + class returnCArgument(ReturnValues): """ReturnValues returning the named cArgs value""" + argNames = ('name',) - indexLookups = [ ('index','name', 'cArgIndex' ), ] - __slots__ = ( 'index', 'name' ) - def __call__( self, result, baseOperation, pyArgs, cArgs ): + indexLookups = [ + ('index', 'name', 'cArgIndex'), + ] + __slots__ = ('index', 'name') + + def __call__(self, result, baseOperation, pyArgs, cArgs): """Retrieve cArgs[ self.index ]""" return cArgs[self.index] - class returnPyArgument( ReturnValues ): + class returnPyArgument(ReturnValues): """ReturnValues returning the named pyArgs value""" + argNames = ('name',) - indexLookups = [ ('index','name', 'pyArgIndex' ), ] - __slots__ = ( 'index', 'name' ) - def __call__( self, result, baseOperation, pyArgs, cArgs ): + indexLookups = [ + ('index', 'name', 'pyArgIndex'), + ] + __slots__ = ('index', 'name') + + def __call__(self, result, baseOperation, pyArgs, cArgs): """Retrieve pyArgs[ self.index ]""" return pyArgs[self.index] -class StringLengths( CConverter ): + +class StringLengths(CConverter): """CConverter for processing array-of-pointers-to-strings data-type Converter is a CConverter for the array-of-lengths for a @@ -286,29 +344,38 @@ class StringLengths( CConverter ): totalCount -- CConverter callable giving count of string pointers (that is, length of the pointer array) """ + argNames = ('name',) - indexLookups = [ ('index','name', 'pyArgIndex' ), ] + indexLookups = [ + ('index', 'name', 'pyArgIndex'), + ] __slots__ = () - def __call__( self, pyArgs, index, baseOperation ): + + def __call__(self, pyArgs, index, baseOperation): """Get array of length integers for string contents""" from OpenGL.raw.GL import _types + tmp = [len(x) for x in pyArgs[self.index]] a_type = _types.GLint * len(tmp) - return a_type( *tmp ) - def totalCount( self, pyArgs, index, baseOperation ): + return a_type(*tmp) + + def totalCount(self, pyArgs, index, baseOperation): """Get array of length integers for string contents""" return len(pyArgs[self.index]) - def stringArray( self, arg, baseOperation, args ): + + def stringArray(self, arg, baseOperation, args): """Create basic array-of-strings object from pyArg""" - if isinstance( arg, (bytes,unicode) ): + if isinstance(arg, (bytes, unicode)): arg = [arg] value = [as_8_bit(x) for x in arg] return value - def stringArrayForC( self, strings ): + + def stringArrayForC(self, strings): """Create a ctypes pointer to char-pointer set""" from OpenGL import arrays + result = (ctypes.c_char_p * len(strings))() - for i,s in enumerate(strings): + for i, s in enumerate(strings): result[i] = ctypes.cast( arrays.GLcharARBArray.dataPointer(s), ctypes.c_char_p, diff --git a/OpenGL/platform/__init__.py b/OpenGL/platform/__init__.py index 0d621556..11675d15 100644 --- a/OpenGL/platform/__init__.py +++ b/OpenGL/platform/__init__.py @@ -16,6 +16,7 @@ of a platform implementation. See the various platform specific modules for examples to use when porting. """ + import os, sys from OpenGL.plugins import PlatformPlugin from OpenGL import _configflags @@ -23,27 +24,28 @@ XDG = 'XDG_SESSION_TYPE' WAYLAND_DISPLAY = 'WAYLAND_DISPLAY' -def _load( ): +PLATFORM = None +nullFunction = None + + +def _load(): """Load the os.name plugin for the platform functionality""" # Linux override keys... guessing_key = None - if ( - sys.platform in ('linux','linux2') - and not 'PYOPENGL_PLATFORM' in os.environ - ): + if sys.platform in ('linux', 'linux2') and 'PYOPENGL_PLATFORM' not in os.environ: if 'WAYLAND_DISPLAY' in os.environ: guessing_key = 'wayland' elif 'DISPLAY' in os.environ: guessing_key = 'linux' key = ( - os.environ.get( 'PYOPENGL_PLATFORM'), - os.environ.get( 'XDG_SESSION_TYPE','').lower(), + os.environ.get('PYOPENGL_PLATFORM'), + os.environ.get('XDG_SESSION_TYPE', '').lower(), guessing_key, sys.platform, os.name, ) - plugin = PlatformPlugin.match( key ) + plugin = PlatformPlugin.match(key) plugin_class = plugin.load() plugin.loaded = True # create instance of this platform implementation @@ -53,15 +55,18 @@ def _load( ): plugin.install(globals()) return plugin + _load() -def types(resultType,*argTypes): + +def types(resultType, *argTypes): """Decorator to add returnType, argTypes and argNames to a function""" - def add_types( function ): + + def add_types(function): """Adds the given metadata to the function, introspects var names from declaration""" function.resultType = resultType - function.argTypes = argTypes - if hasattr( function, 'func_code' ): # python 2.x + function.argTypes = argTypes + if hasattr(function, 'func_code'): # python 2.x function.argNames = function.func_code.co_varnames else: function.argNames = function.__code__.co_varnames @@ -69,30 +74,43 @@ def add_types( function ): function.__annotations__ = { 'return': resultType, } - for name,typ in zip(function.argNames,argTypes): + for name, typ in zip(function.argNames, argTypes): function.__annotations__[name] = typ - return function + return function + return add_types -def unpack_constants( constants, namespace ): + +def unpack_constants(constants, namespace): """Create constants and add to the namespace""" from OpenGL.constant import Constant + for line in constants.splitlines(): if line and line.split(): - name,value = line.split() - namespace[name] = Constant( name, int(value,16) ) + name, value = line.split() + namespace[name] = Constant(name, int(value, 16)) + -def createFunction( function, dll,extension, deprecated=False, error_checker=None, force_extension=False ): +def createFunction( + function, + dll, + extension, + deprecated=False, + error_checker=None, + force_extension=False, +): """Allows the more compact declaration format to use the old-style constructor""" return nullFunction( function.__name__, dll or PLATFORM.GL, - resultType = function.resultType, - argTypes = function.argTypes, - doc = None, argNames = function.argNames, - extension = extension, - deprecated = deprecated, - module = function.__module__, - error_checker = error_checker, - force_extension = force_extension or getattr(function,'force_extension',force_extension), + resultType=function.resultType, + argTypes=function.argTypes, + doc=None, + argNames=function.argNames, + extension=extension, + deprecated=deprecated, + module=function.__module__, + error_checker=error_checker, + force_extension=force_extension + or getattr(function, 'force_extension', force_extension), ) diff --git a/OpenGL/platform/baseplatform.py b/OpenGL/platform/baseplatform.py index f7450ec3..ac1740e8 100644 --- a/OpenGL/platform/baseplatform.py +++ b/OpenGL/platform/baseplatform.py @@ -1,5 +1,6 @@ """Base class for platform implementations """ + import ctypes from OpenGL.platform import ctypesloader from OpenGL._bytes import as_8_bit @@ -54,7 +55,7 @@ def _find_module(exclude=(__name__,)): frame = sys._getframe() while frame and '__name__' in frame.f_globals: if exclude: - if not frame.f_globals['__name__'] in exclude: + if frame.f_globals['__name__'] not in exclude: return frame.f_globals['__name__'] else: diff --git a/OpenGL/raw/GL/_lookupint.py b/OpenGL/raw/GL/_lookupint.py index 2df4d817..c30fe38d 100644 --- a/OpenGL/raw/GL/_lookupint.py +++ b/OpenGL/raw/GL/_lookupint.py @@ -1,28 +1,48 @@ """Integer values looked up via glGetIntegerv( constant )""" + import ctypes + _get = None _get_float = None -class LookupInt( object ): - def __init__( self, lookup, format=ctypes.c_int, calculation=None ): - self.lookup = lookup + +class LookupInt(object): + def __init__(self, lookup, format=ctypes.c_int, calculation=None): + self.lookup = lookup self.format = format self.calculation = calculation - def __int__( self ): + + def __int__(self): global _get if _get is None: from OpenGL.GL import glGetIntegerv + _get = glGetIntegerv output = self.format() - _get( self.lookup, output ) + _get(self.lookup, output) if self.calculation: - return self.calculation( output.value ) + return self.calculation(output.value) return output.value + __long__ = __int__ - def __eq__( self, other ): + + def __eq__(self, other): return int(self) == other - def __cmp__( self, other ): - return cmp( int(self), other ) + + def __cmp__(self, other): + test = int(self) + return (test > other) - (test < other) + + def __lt__(self, other): + return int(self) < other + + def __gt__(self, other): + return int(self) > other + + def __eq__(self, other): + return int(self) == other + def __str__(self): return str(int(self)) + __repr__ = __str__ diff --git a/OpenGL/wrapper.py b/OpenGL/wrapper.py index 44a6f467..dcc68688 100644 --- a/OpenGL/wrapper.py +++ b/OpenGL/wrapper.py @@ -1,17 +1,19 @@ """The wrapping code for providing natural ctypes-based OpenGL interface""" + import ctypes, logging from OpenGL import platform, error -assert platform 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.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 + +_log = logging.getLogger('OpenGL.wrapper') +assert platform cWrapper = None if acceleratesupport.ACCELERATE_AVAILABLE: try: @@ -24,25 +26,33 @@ MultiReturn, ) except ImportError as err: - _log.warning( """OpenGL_accelerate seems to be installed, but unable to import expected wrapper entry points!""" ) + _log.warning( + """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""" ) + _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 ): +def asList(o): """Convert to a list if not already one""" - if not isinstance( o, list ): + if not isinstance(o, list): return list(o) return o -def none_or_pass( incoming, function, arguments ): + +def none_or_pass(incoming, function, arguments): return incoming -none_or_pass.optional=True -class Wrapper( LateBind ): + +none_or_pass.optional = True + + +class Wrapper(LateBind): """Wrapper around a ctypes cFunction object providing SWIG-like hooks Attributes: @@ -72,6 +82,7 @@ class Wrapper( LateBind ): output value from the value of ARG2, provided for documentation/reference """ + localProperties = ( 'wrappedOperation', '__file__', @@ -83,50 +94,62 @@ class Wrapper( LateBind ): 'returnValues', '_finalCall', ) - def __init__( self, wrappedOperation ): + + def __init__(self, wrappedOperation): """Initialise the wrapper, storing wrappedOperation""" - if isinstance( wrappedOperation, Wrapper ): + if isinstance(wrappedOperation, Wrapper): wrappedOperation = wrappedOperation.wrappedOperation self.wrappedOperation = wrappedOperation - def __getattr__( self, key ): + + def __getattr__(self, key): """Delegate attribute lookup to our wrappedOperation""" if key != 'wrappedOperation': - return getattr( self.wrappedOperation, key ) - raise AttributeError( key ) - def __nonzero__( self ): + return getattr(self.wrappedOperation, key) + raise AttributeError(key) + + def __nonzero__(self): """Is this function/wrapper available?""" - return bool( self.wrappedOperation ) + return bool(self.wrappedOperation) + __bool__ = __nonzero__ - def __setattr__( self, key, value ): + + def __setattr__(self, key, value): """Forward attribute setting to our wrappedOperation""" if key in self.localProperties: - super( Wrapper, self ).__setattr__( key, value ) + super(Wrapper, self).__setattr__(key, value) else: - return setattr( self.wrappedOperation, key, value ) - def pyArgIndex( self, argName ): + 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 ) + argNames = getattr(self, 'pyConverterNames', None) if argNames is None: argNames = self.wrappedOperation.argNames try: - return asList( argNames ).index( argName ) - except (ValueError,IndexError): - raise KeyError( """No argument %r in argument list %r"""%( - argName, argNames - )) - def cArgIndex( self, argName ): + return asList(argNames).index(argName) + except (ValueError, IndexError): + 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): - raise KeyError( """No argument %r in argument list %r"""%( - argName, argNames - )) + return asList(argNames).index(argName) + except (ValueError, IndexError): + 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, + self, + outArg, + size=(1,), + pnameArg=None, + arrayType=None, + oldStyleReturn=SIZE_1_ARRAY_UNPACK, + orPassIn=False, ): """Set the given argName to be an output array @@ -141,34 +164,40 @@ def setOutput( """ if arrayType is None: # figure out from self.wrappedOperation's argtypes - index = self.cArgIndex( outArg ) - arrayType = self.wrappedOperation.argtypes[ index ] - if not hasattr( arrayType, 'asArray' ): + 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 %s on %s is %r"%( - outArg, self.wrappedOperation.__name__, arrayType, - ) ) + else: + raise TypeError( + "Should only have array types for output parameters %s on %s is %r" + % ( + outArg, + self.wrappedOperation.__name__, + arrayType, + ) + ) if pnameArg is None: - assert not hasattr(size,'__call__' ) + assert not hasattr(size, '__call__') if orPassIn: cls = converters.OutputOrInput else: - cls = converters.Output + cls = converters.Output conv = cls( name=outArg, size=size, arrayType=arrayType, ) else: - if isinstance( size, dict ): - setattr( self, '%s_LOOKUP_%s'%(outArg,pnameArg), size ) + 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__' ) + setattr(self, '%s_FROM_%s' % (outArg, pnameArg), size) + assert hasattr(size, '__call__') if orPassIn: cls = converters.SizedOutputOrInput else: @@ -182,80 +211,90 @@ def setOutput( if oldStyleReturn: returnObject = conv.oldStyleReturn else: - returnObject = converters.returnCArgument( outArg ) + returnObject = converters.returnCArgument(outArg) if orPassIn: - self.setPyConverter( - outArg, none_or_pass - ) + self.setPyConverter(outArg, none_or_pass) else: - self.setPyConverter( outArg ) + self.setPyConverter(outArg) return self.setCConverter( - outArg, conv, - ).setReturnValues( - returnObject - ) - def typeOfArg( self, outArg ): + 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 ] - + index = self.cArgIndex(outArg) + return self.wrappedOperation.argtypes[index] + if not ERROR_ON_COPY: - def setInputArraySize( self, argName, size=None ): + + 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 + + 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 + + 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' ): + arrayType = self.typeOfArg(argName) + if not hasattr(arrayType, 'asArray'): if arrayType == ctypes.c_void_p: # special case, we will convert to a void * array... - self.setPyConverter( + self.setPyConverter( argName, - converters.CallFuncPyConverter( arraydatatype.ArrayDatatype.asArray ) + converters.CallFuncPyConverter( + arraydatatype.ArrayDatatype.asArray + ), ) - self.setCConverter( argName, converters.getPyArgsName( argName ) ) + self.setCConverter(argName, converters.getPyArgsName(argName)) return self - elif hasattr( arrayType, '_type_' ) and hasattr(arrayType._type_, '_type_' ): + elif hasattr(arrayType, '_type_') and hasattr( + arrayType._type_, '_type_' + ): # is a ctypes array-of-pointers data-type... # requires special handling no matter what... return self - else: - raise TypeError( "Should only have array types for output parameters: got %s"%(arrayType,) ) + 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) ) + self.setPyConverter( + argName, arrayhelpers.asArrayTypeSize(arrayType, size) + ) else: - self.setPyConverter( argName, arrayhelpers.asArrayType(arrayType) ) - self.setCConverter( argName, converters.getPyArgsName( argName ) ) + self.setPyConverter(argName, arrayhelpers.asArrayType(arrayType)) + self.setCConverter(argName, converters.getPyArgsName(argName)) return self + else: - def setInputArraySize( self, argName, size=None ): + + 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 + + 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 + + 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 ) + arrayType = self.typeOfArg(argName) # return value is always the source array... - if hasattr( arrayType, 'asArray' ): - self.setPyConverter( argName, arrayhelpers.asArrayTypeSize(arrayType, size) ) - self.setCConverter( argName, - converters.getPyArgsName( 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 ): + + 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 @@ -273,22 +312,28 @@ def setPyConverter( self, argName, function = NULL ): 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 ) + 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 ) + 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, - )) + 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 ): + + def setCConverter(self, argName, function): """Set C-argument converter for a given argument argName -- the argument name whose C-compatible representation will @@ -309,40 +354,51 @@ def setCConverter( self, argName, function ): 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 ) + 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 ) + 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, - )) + raise AttributeError( + """No argument named %r left in cConverters: %s""" + % ( + argName, + self.wrappedOperation.argNames, + ) + ) if self.cConverters[i] is not None: - raise RuntimeError("Double wrapping of output parameter: %r on %s"%( - argName, self.__name__ - )) + raise RuntimeError( + "Double wrapping of output parameter: %r on %s" + % (argName, self.__name__) + ) self.cConverters[i] = function return self - def setCResolver( self, argName, function=NULL ): + + 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 ) + 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 ) + 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, - )) + 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 ): + + 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: @@ -352,7 +408,8 @@ def setStoreValues( self, function=NULL ): else: self.storeValues = function return self - def setReturnValues( self, function=NULL ): + + def setReturnValues(self, function=NULL): """Set the return-of-results function for the whole wrapper""" if function is NULL: try: @@ -360,52 +417,63 @@ def setReturnValues( self, function=NULL ): except Exception: pass else: - if hasattr(self,'returnValues'): - if isinstance(self.returnValues,MultiReturn): - self.returnValues.append( function ) + if hasattr(self, 'returnValues'): + if isinstance(self.returnValues, MultiReturn): + self.returnValues.append(function) else: - self.returnValues = MultiReturn( self.returnValues, function ) + self.returnValues = MultiReturn(self.returnValues, function) else: self.returnValues = function return self - - def finalise( self ): + + def finalise(self): """Finalise our various elements into simple index-based operations""" - for attribute in ('pyConverters','cConverters','cResolvers' ): - value = getattr( self, attribute, None ) + 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' ): + for i, item in enumerate(value): + if hasattr(item, 'finalise'): try: - item.finalise( self ) + 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, + """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 ) + 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, )) + raise RuntimeError("""Missing finalised call type for %s""" % (self,)) else: - #self.__class__.finalize = lambda *args: callFunction - #self.__call__ = callFunction - #self.__class__.__call__ = callFunction - #self.__class__.set_call( callFunction ) - #self.__class__.__dict__[ '__call__' ] = callFunction - #print 'setting class call', callFunction - self.setFinalCall( callFunction ) + # self.__class__.finalize = lambda *args: callFunction + # self.__call__ = callFunction + # self.__class__.__call__ = callFunction + # self.__class__.set_call( callFunction ) + # self.__class__.__dict__[ '__call__' ] = callFunction + # print 'setting class call', callFunction + self.setFinalCall(callFunction) return callFunction - #return self - def finaliseCall( self ): + # return self + + 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 @@ -414,35 +482,40 @@ def finaliseCall( self ): 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 ) + 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 ) + storeValues = getattr(self, 'storeValues', None) + returnValues = getattr(self, 'returnValues', None) if pyConverters: if cWrapper: calculate_pyArgs = PyArgCalculator( - self,pyConverters, + self, + pyConverters, ) else: pyConverters_mapped = [ - (i,converter,(converter is None)) - for (i,converter) in enumerate( pyConverters ) + (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 ): + 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"""%( + """%s requires %r arguments (%s), received %s: %r""" + % ( wrappedOperation.__name__, pyConverters_length, - ", ".join( self.pyConverterNames ), + ", ".join(self.pyConverterNames), len(args), - args + args, ) ) - for index,converter,isNone in pyConverters_mapped: + for index, converter, isNone in pyConverters_mapped: if isNone: yield args[index] else: @@ -451,50 +524,57 @@ def calculate_pyArgs( args ): except IndexError as err: yield NULL except Exception as err: - if hasattr( err, 'args' ): - err.args += ( converter, ) + if hasattr(err, 'args'): + err.args += (converter,) raise + else: calculate_pyArgs = None if cConverters: if cWrapper: - calculate_cArgs = CArgCalculator( self, cConverters ) + calculate_cArgs = CArgCalculator(self, cConverters) else: cConverters_mapped = [ - (i,converter,hasattr(converter,'__call__')) - for (i,converter) in enumerate( cConverters ) + (i, converter, hasattr(converter, '__call__')) + for (i, converter) in enumerate(cConverters) ] - def calculate_cArgs( pyArgs ): - for index,converter,canCall in cConverters_mapped: + + def calculate_cArgs(pyArgs): + for index, converter, canCall in cConverters_mapped: if canCall: try: - yield converter( pyArgs, index, self ) + yield converter(pyArgs, index, self) except Exception as err: - if hasattr( err, 'args' ): + if hasattr(err, 'args'): err.args += ( - """Failure in cConverter %r"""%(converter), - pyArgs, index, self, + """Failure in cConverter %r""" % (converter), + pyArgs, + index, + self, ) raise else: yield converter + else: calculate_cArgs = None if cResolvers: if cWrapper: - calculate_cArguments = CArgumentCalculator( cResolvers ) + calculate_cArguments = CArgumentCalculator(cResolvers) else: cResolvers_mapped = list(enumerate(cResolvers)) - def calculate_cArguments( cArgs ): - for i,converter in cResolvers_mapped: + + def calculate_cArguments(cArgs): + for i, converter in cResolvers_mapped: if converter is None: yield cArgs[i] else: try: - yield converter( cArgs[i] ) + yield converter(cArgs[i]) except Exception as err: err.args += (converter,) raise + else: calculate_cArguments = None if cWrapper: @@ -512,13 +592,14 @@ def calculate_cArguments( cArgs ): if cResolvers: if storeValues: if returnValues: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all possible operations""" - pyArgs = tuple( calculate_pyArgs( args )) - cArgs = tuple(calculate_cArgs( pyArgs )) - cArguments = tuple(calculate_cArguments( cArgs )) + pyArgs = tuple(calculate_pyArgs(args)) + cArgs = tuple(calculate_cArgs(pyArgs)) + cArguments = tuple(calculate_cArguments(cArgs)) try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -539,15 +620,17 @@ def wrapperCall( *args ): pyArgs, cArgs, ) + return wrapperCall else: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save returnValues""" - pyArgs = tuple( calculate_pyArgs( args )) - cArgs = tuple(calculate_cArgs( pyArgs )) - cArguments = tuple(calculate_cArguments( cArgs )) + pyArgs = tuple(calculate_pyArgs(args)) + cArgs = tuple(calculate_cArgs(pyArgs)) + cArguments = tuple(calculate_cArguments(cArgs)) try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -563,16 +646,18 @@ def wrapperCall( *args ): cArgs, ) return result + return wrapperCall - else: # null storeValues + else: # null storeValues if returnValues: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save storeValues""" - pyArgs = tuple( calculate_pyArgs( args )) - cArgs = tuple(calculate_cArgs( pyArgs )) - cArguments = tuple(calculate_cArguments( cArgs )) + pyArgs = tuple(calculate_pyArgs(args)) + cArgs = tuple(calculate_cArgs(pyArgs)) + cArguments = tuple(calculate_cArguments(cArgs)) try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -586,15 +671,17 @@ def wrapperCall( *args ): pyArgs, cArgs, ) + return wrapperCall else: - def wrapperCall( *args ): + + 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 )) + pyArgs = tuple(calculate_pyArgs(args)) + cArgs = tuple(calculate_cArgs(pyArgs)) + cArguments = tuple(calculate_cArguments(cArgs)) try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -603,18 +690,20 @@ def wrapperCall( *args ): err.pyArgs = pyArgs raise err return result + return wrapperCall else: # null cResolvers if storeValues: if returnValues: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all possible operations""" - pyArgs = tuple( calculate_pyArgs( args )) - cArgs = tuple(calculate_cArgs( pyArgs )) + pyArgs = tuple(calculate_pyArgs(args)) + cArgs = tuple(calculate_cArgs(pyArgs)) cArguments = cArgs try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -635,15 +724,17 @@ def wrapperCall( *args ): pyArgs, cArgs, ) + return wrapperCall else: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save returnValues""" - pyArgs = tuple( calculate_pyArgs( args )) - cArgs = tuple(calculate_cArgs( pyArgs )) + pyArgs = tuple(calculate_pyArgs(args)) + cArgs = tuple(calculate_cArgs(pyArgs)) cArguments = cArgs try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -659,16 +750,18 @@ def wrapperCall( *args ): cArgs, ) return result + return wrapperCall - else: # null storeValues + else: # null storeValues if returnValues: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save storeValues""" - pyArgs = tuple( calculate_pyArgs( args )) - cArgs = tuple(calculate_cArgs( pyArgs )) + pyArgs = tuple(calculate_pyArgs(args)) + cArgs = tuple(calculate_cArgs(pyArgs)) cArguments = cArgs try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise @@ -682,15 +775,17 @@ def wrapperCall( *args ): pyArgs, cArgs, ) + return wrapperCall else: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save returnValues and storeValues""" - pyArgs = tuple( calculate_pyArgs( args )) - cArgs = tuple(calculate_cArgs( pyArgs )) + pyArgs = tuple(calculate_pyArgs(args)) + cArgs = tuple(calculate_cArgs(pyArgs)) cArguments = cArgs try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise @@ -699,19 +794,21 @@ def wrapperCall( *args ): err.pyArgs = pyArgs raise err return result + return wrapperCall else: # null cConverters if cResolvers: if storeValues: if returnValues: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all possible operations""" - pyArgs = tuple( calculate_pyArgs( args )) + pyArgs = tuple(calculate_pyArgs(args)) cArgs = pyArgs - cArguments = tuple(calculate_cArguments( cArgs )) + cArguments = tuple(calculate_cArguments(cArgs)) try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -732,15 +829,17 @@ def wrapperCall( *args ): pyArgs, cArgs, ) + return wrapperCall else: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save returnValues""" - pyArgs = tuple( calculate_pyArgs( args )) + pyArgs = tuple(calculate_pyArgs(args)) cArgs = pyArgs - cArguments = tuple(calculate_cArguments( cArgs )) + cArguments = tuple(calculate_cArguments(cArgs)) try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -756,16 +855,18 @@ def wrapperCall( *args ): cArgs, ) return result + return wrapperCall - else: # null storeValues + else: # null storeValues if returnValues: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save storeValues""" - pyArgs = tuple( calculate_pyArgs( args )) + pyArgs = tuple(calculate_pyArgs(args)) cArgs = pyArgs - cArguments = tuple(calculate_cArguments( cArgs )) + cArguments = tuple(calculate_cArguments(cArgs)) try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -779,15 +880,17 @@ def wrapperCall( *args ): pyArgs, cArgs, ) + return wrapperCall else: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save returnValues and storeValues""" - pyArgs = tuple( calculate_pyArgs( args )) + pyArgs = tuple(calculate_pyArgs(args)) cArgs = pyArgs - cArguments = tuple(calculate_cArguments( cArgs )) + cArguments = tuple(calculate_cArguments(cArgs)) try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -796,17 +899,19 @@ def wrapperCall( *args ): err.pyArgs = pyArgs raise err return result + return wrapperCall else: # null cResolvers if storeValues: if returnValues: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all possible operations""" - pyArgs = tuple( calculate_pyArgs( args )) + pyArgs = tuple(calculate_pyArgs(args)) cArguments = pyArgs try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -827,14 +932,16 @@ def wrapperCall( *args ): pyArgs, cArguments, ) + return wrapperCall else: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save returnValues""" - pyArgs = tuple( calculate_pyArgs( args )) + pyArgs = tuple(calculate_pyArgs(args)) cArguments = pyArgs try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -850,15 +957,17 @@ def wrapperCall( *args ): cArguments, ) return result + return wrapperCall - else: # null storeValues + else: # null storeValues if returnValues: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save storeValues""" - pyArgs = tuple( calculate_pyArgs( args )) + pyArgs = tuple(calculate_pyArgs(args)) cArguments = pyArgs try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -872,14 +981,16 @@ def wrapperCall( *args ): pyArgs, cArguments, ) + return wrapperCall else: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save returnValues and storeValues""" - pyArgs = tuple( calculate_pyArgs( args )) + pyArgs = tuple(calculate_pyArgs(args)) cArguments = pyArgs try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -888,6 +999,7 @@ def wrapperCall( *args ): err.pyArgs = pyArgs raise err return result + return wrapperCall else: # null pyConverters @@ -895,29 +1007,30 @@ def wrapperCall( *args ): if cResolvers: if storeValues: if returnValues: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all possible operations""" pyArgs = args cArgs = [] - for (index,converter) in enumerate( cConverters ): + for index, converter in enumerate(cConverters): # move enumerate out... - if not hasattr(converter,'__call__'): - cArgs.append( converter ) + if not hasattr(converter, '__call__'): + cArgs.append(converter) else: try: - cArgs.append( - converter( pyArgs, index, self ) - ) + cArgs.append(converter(pyArgs, index, self)) except Exception as err: - if hasattr( err, 'args' ): + if hasattr(err, 'args'): err.args += ( - """Failure in cConverter %r"""%(converter), - pyArgs, index, + """Failure in cConverter %r""" + % (converter), + pyArgs, + index, ) raise - cArguments = tuple(calculate_cArguments( cArgs )) + cArguments = tuple(calculate_cArguments(cArgs)) try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -938,31 +1051,33 @@ def wrapperCall( *args ): pyArgs, cArgs, ) + return wrapperCall else: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save returnValues""" pyArgs = args cArgs = [] - for (index,converter) in enumerate( cConverters ): + for index, converter in enumerate(cConverters): # move enumerate out... - if not hasattr(converter,'__call__'): - cArgs.append( converter ) + if not hasattr(converter, '__call__'): + cArgs.append(converter) else: try: - cArgs.append( - converter( pyArgs, index, self ) - ) + cArgs.append(converter(pyArgs, index, self)) except Exception as err: - if hasattr( err, 'args' ): + if hasattr(err, 'args'): err.args += ( - """Failure in cConverter %r"""%(converter), - pyArgs, index, + """Failure in cConverter %r""" + % (converter), + pyArgs, + index, ) raise - cArguments = tuple(calculate_cArguments( cArgs )) + cArguments = tuple(calculate_cArguments(cArgs)) try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -978,32 +1093,34 @@ def wrapperCall( *args ): cArgs, ) return result + return wrapperCall - else: # null storeValues + else: # null storeValues if returnValues: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save storeValues""" pyArgs = args cArgs = [] - for (index,converter) in enumerate( cConverters ): + for index, converter in enumerate(cConverters): # move enumerate out... - if not hasattr(converter,'__call__'): - cArgs.append( converter ) + if not hasattr(converter, '__call__'): + cArgs.append(converter) else: try: - cArgs.append( - converter( pyArgs, index, self ) - ) + cArgs.append(converter(pyArgs, index, self)) except Exception as err: - if hasattr( err, 'args' ): + if hasattr(err, 'args'): err.args += ( - """Failure in cConverter %r"""%(converter), - pyArgs, index, + """Failure in cConverter %r""" + % (converter), + pyArgs, + index, ) raise - cArguments = tuple(calculate_cArguments( cArgs )) + cArguments = tuple(calculate_cArguments(cArgs)) try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -1017,31 +1134,33 @@ def wrapperCall( *args ): pyArgs, cArgs, ) + return wrapperCall else: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save returnValues and storeValues""" pyArgs = args cArgs = [] - for (index,converter) in enumerate( cConverters ): + for index, converter in enumerate(cConverters): # move enumerate out... - if not hasattr(converter,'__call__'): - cArgs.append( converter ) + if not hasattr(converter, '__call__'): + cArgs.append(converter) else: try: - cArgs.append( - converter( pyArgs, index, self ) - ) + cArgs.append(converter(pyArgs, index, self)) except Exception as err: - if hasattr( err, 'args' ): + if hasattr(err, 'args'): err.args += ( - """Failure in cConverter %r"""%(converter), - pyArgs, index, + """Failure in cConverter %r""" + % (converter), + pyArgs, + index, ) raise - cArguments = tuple(calculate_cArguments( cArgs )) + cArguments = tuple(calculate_cArguments(cArgs)) try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -1050,34 +1169,36 @@ def wrapperCall( *args ): err.pyArgs = pyArgs raise err return result + return wrapperCall else: # null cResolvers if storeValues: if returnValues: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all possible operations""" pyArgs = args cArgs = [] - for (index,converter) in enumerate( cConverters ): + for index, converter in enumerate(cConverters): # move enumerate out... - if not hasattr(converter,'__call__'): - cArgs.append( converter ) + if not hasattr(converter, '__call__'): + cArgs.append(converter) else: try: - cArgs.append( - converter( pyArgs, index, self ) - ) + cArgs.append(converter(pyArgs, index, self)) except Exception as err: - if hasattr( err, 'args' ): + if hasattr(err, 'args'): err.args += ( - """Failure in cConverter %r"""%(converter), - pyArgs, index, + """Failure in cConverter %r""" + % (converter), + pyArgs, + index, ) raise cArguments = cArgs try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -1098,31 +1219,33 @@ def wrapperCall( *args ): pyArgs, cArgs, ) + return wrapperCall else: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save returnValues""" pyArgs = args cArgs = [] - for (index,converter) in enumerate( cConverters ): + for index, converter in enumerate(cConverters): # move enumerate out... - if not hasattr(converter,'__call__'): - cArgs.append( converter ) + if not hasattr(converter, '__call__'): + cArgs.append(converter) else: try: - cArgs.append( - converter( pyArgs, index, self ) - ) + cArgs.append(converter(pyArgs, index, self)) except Exception as err: - if hasattr( err, 'args' ): + if hasattr(err, 'args'): err.args += ( - """Failure in cConverter %r"""%(converter), - pyArgs, index, + """Failure in cConverter %r""" + % (converter), + pyArgs, + index, ) raise cArguments = cArgs try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -1138,32 +1261,34 @@ def wrapperCall( *args ): cArgs, ) return result + return wrapperCall - else: # null storeValues + else: # null storeValues if returnValues: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save storeValues""" pyArgs = args cArgs = [] - for (index,converter) in enumerate( cConverters ): + for index, converter in enumerate(cConverters): # move enumerate out... - if not hasattr(converter,'__call__'): - cArgs.append( converter ) + if not hasattr(converter, '__call__'): + cArgs.append(converter) else: try: - cArgs.append( - converter( pyArgs, index, self ) - ) + cArgs.append(converter(pyArgs, index, self)) except Exception as err: - if hasattr( err, 'args' ): + if hasattr(err, 'args'): err.args += ( - """Failure in cConverter %r"""%(converter), - pyArgs, index, + """Failure in cConverter %r""" + % (converter), + pyArgs, + index, ) raise cArguments = cArgs try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -1177,31 +1302,33 @@ def wrapperCall( *args ): pyArgs, cArgs, ) + return wrapperCall else: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save returnValues and storeValues""" pyArgs = args cArgs = [] - for (index,converter) in enumerate( cConverters ): + for index, converter in enumerate(cConverters): # move enumerate out... - if not hasattr(converter,'__call__'): - cArgs.append( converter ) + if not hasattr(converter, '__call__'): + cArgs.append(converter) else: try: - cArgs.append( - converter( pyArgs, index, self ) - ) + cArgs.append(converter(pyArgs, index, self)) except Exception as err: - if hasattr( err, 'args' ): + if hasattr(err, 'args'): err.args += ( - """Failure in cConverter %r"""%(converter), - pyArgs, index, + """Failure in cConverter %r""" + % (converter), + pyArgs, + index, ) raise cArguments = cArgs try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -1210,18 +1337,20 @@ def wrapperCall( *args ): err.pyArgs = pyArgs raise err return result + return wrapperCall else: # null cConverters if cResolvers: if storeValues: if returnValues: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all possible operations""" cArgs = args - cArguments = tuple(calculate_cArguments( cArgs )) + cArguments = tuple(calculate_cArguments(cArgs)) try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -1242,14 +1371,16 @@ def wrapperCall( *args ): args, cArgs, ) + return wrapperCall else: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save returnValues""" cArgs = args - cArguments = tuple(calculate_cArguments( cArgs )) + cArguments = tuple(calculate_cArguments(cArgs)) try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -1265,15 +1396,17 @@ def wrapperCall( *args ): cArgs, ) return result + return wrapperCall - else: # null storeValues + else: # null storeValues if returnValues: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save storeValues""" cArgs = args - cArguments = tuple(calculate_cArguments( cArgs )) + cArguments = tuple(calculate_cArguments(cArgs)) try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -1287,14 +1420,16 @@ def wrapperCall( *args ): args, cArgs, ) + return wrapperCall else: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save returnValues and storeValues""" cArgs = args - cArguments = tuple(calculate_cArguments( cArgs )) + cArguments = tuple(calculate_cArguments(cArgs)) try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -1303,16 +1438,18 @@ def wrapperCall( *args ): err.pyArgs = args raise err return result + return wrapperCall else: # null cResolvers if storeValues: if returnValues: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all possible operations""" cArguments = args try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -1333,13 +1470,15 @@ def wrapperCall( *args ): args, cArguments, ) + return wrapperCall else: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save returnValues""" cArguments = args try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -1355,14 +1494,16 @@ def wrapperCall( *args ): cArguments, ) return result + return wrapperCall - else: # null storeValues + else: # null storeValues if returnValues: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save storeValues""" cArguments = args try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -1376,13 +1517,15 @@ def wrapperCall( *args ): args, cArguments, ) + return wrapperCall else: - def wrapperCall( *args ): + + def wrapperCall(*args): """Wrapper with all save returnValues and storeValues""" cArguments = args try: - result = wrappedOperation( *cArguments ) + result = wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -1391,68 +1534,71 @@ def wrapperCall( *args ): err.pyArgs = args raise err return result + return wrapperCall -# def __call__( self, *args, **named ): -# """Finalise the wrapper before calling it""" -# try: -# return self._finalCall( *args, **named ) -# except AttributeError, err: -# return self.finalise()( *args, **named ) - - def _unspecialised__call__( self, *args ): + + # def __call__( self, *args, **named ): + # """Finalise the wrapper before calling it""" + # try: + # return self._finalCall( *args, **named ) + # except AttributeError, err: + # return self.finalise()( *args, **named ) + + def _unspecialised__call__(self, *args): """Expand arguments, call the function, store values and check errors""" - pyConverters = getattr( self, 'pyConverters', None ) + pyConverters = getattr(self, 'pyConverters', None) if pyConverters: if len(pyConverters) != len(args): raise ValueError( - """%s requires %r arguments (%s), received %s: %r"""%( + """%s requires %r arguments (%s), received %s: %r""" + % ( self.wrappedOperation.__name__, len(pyConverters), - ", ".join( self.pyConverterNames ), + ", ".join(self.pyConverterNames), len(args), - args + args, ) ) pyArgs = [] - for (converter,arg) in zip(pyConverters,args): + for converter, arg in zip(pyConverters, args): if converter is None: - pyArgs.append( arg ) + pyArgs.append(arg) else: - pyArgs.append( converter(arg, self, args) ) + pyArgs.append(converter(arg, self, args)) else: pyArgs = args - cConverters = getattr( self, 'cConverters', None ) + cConverters = getattr(self, 'cConverters', None) if cConverters: cArgs = [] - for (index,converter) in enumerate( cConverters ): - if not hasattr(converter,'__call__'): - cArgs.append( converter ) + for index, converter in enumerate(cConverters): + if not hasattr(converter, '__call__'): + cArgs.append(converter) else: try: - cArgs.append( - converter( pyArgs, index, self ) - ) + cArgs.append(converter(pyArgs, index, self)) except Exception as err: - if hasattr( err, 'args' ): + if hasattr(err, 'args'): err.args += ( - """Failure in cConverter %r"""%(converter), - pyArgs, index, self, + """Failure in cConverter %r""" % (converter), + pyArgs, + index, + self, ) raise else: cArgs = pyArgs - cResolvers = getattr( self, 'cResolvers', None ) + cResolvers = getattr(self, 'cResolvers', None) if cResolvers: cArguments = [] - for (converter, value) in zip( cResolvers, cArgs ): + for converter, value in zip(cResolvers, cArgs): if converter is None: - cArguments.append( value ) + cArguments.append(value) else: - cArguments.append( converter( value ) ) + cArguments.append(converter(value)) else: cArguments = cArgs try: - result = self.wrappedOperation( *cArguments ) + result = self.wrappedOperation(*cArguments) except ctypes.ArgumentError as err: err.args = err.args + (cArguments,) raise err @@ -1460,7 +1606,7 @@ def _unspecialised__call__( self, *args ): err.cArgs = cArgs err.pyArgs = pyArgs raise err - storeValues = getattr( self, 'storeValues', None ) + storeValues = getattr(self, 'storeValues', None) if storeValues is not None: # handle storage of persistent argument values... storeValues( @@ -1469,7 +1615,7 @@ def _unspecialised__call__( self, *args ): pyArgs, cArgs, ) - returnValues = getattr( self, 'returnValues', None ) + returnValues = getattr(self, 'returnValues', None) if returnValues is not None: return returnValues( result, @@ -1480,22 +1626,26 @@ def _unspecialised__call__( self, *args ): else: return result + class MultiReturn(object): - def __init__(self,*children): + def __init__(self, *children): self.children = list(children) - def append(self, child ): - self.children.append( child ) - def __call__(self,*args,**named): + + def append(self, child): + self.children.append(child) + + def __call__(self, *args, **named): result = [] for child in self.children: try: - result.append( child(*args,**named) ) + result.append(child(*args, **named)) except Exception as err: - err.args += ( child, args, named ) + err.args += (child, args, named) raise return result -def wrapper( wrappedOperation ): + +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 @@ -1503,14 +1653,14 @@ def wrapper( wrappedOperation ): the wrapper will show up as by default, and will have the docstring available naturally in pydoc and the like. """ - if isinstance( wrappedOperation, Wrapper ): + if isinstance(wrappedOperation, Wrapper): return wrappedOperation dict = { '__doc__': wrappedOperation.__doc__, - '__slots__': ('wrappedOperation', ), + '__slots__': ('wrappedOperation',), } - cls = type( wrappedOperation.__name__, (Wrapper,), dict ) - if hasattr( wrappedOperation, '__module__' ): + cls = type(wrappedOperation.__name__, (Wrapper,), dict) + if hasattr(wrappedOperation, '__module__'): cls.__module__ = wrappedOperation.__module__ instance = cls(wrappedOperation) return instance diff --git a/directdocs/model.py b/directdocs/model.py index ae4f5846..a3f17649 100644 --- a/directdocs/model.py +++ b/directdocs/model.py @@ -1,87 +1,114 @@ """Modelling objects for the documentation generator""" + from __future__ import absolute_import import logging, types, inspect from six.moves import zip -log = logging.getLogger( 'directdocs.model' ) + +log = logging.getLogger('directdocs.model') from OpenGL import __version__ -MAJOR_VERSION = '.'.join(__version__.split('.')[:2] ) +MAJOR_VERSION = '.'.join(__version__.split('.')[:2]) -class NotDefined( object ): - def __nonzero__( self ): + +class NotDefined(object): + def __nonzero__(self): return False + NOT_DEFINED = NotDefined() -class Reference( object ): + +class Reference(object): """Overall reference text""" - def __init__( self ): + + def __init__(self): self.sections = {} self.section_titles = {} self.functions = {} self.constants = {} - def append( self, section ): + + def append(self, section): """Add the given section to our tables""" if section.id != section.title: if not section.id: - log.warn( 'Null section id in %s', section.title ) - elif '.' in section.id and section.id.split('.')[0] == section.title and section.id.split('.')[1].startswith( '3' ): + log.warn('Null section id in %s', section.title) + elif ( + '.' in section.id + and section.id.split('.')[0] == section.title + and section.id.split('.')[1].startswith('3') + ): pass else: - log.warn( "Unmatched id/title: %s (title) %s (id)", section.title, section.id ) + log.warn( + "Unmatched id/title: %s (title) %s (id)", section.title, section.id + ) if section.id in self.sections: - log.warn( "Duplicate section id: %s", section.id ) + log.warn("Duplicate section id: %s", section.id) if section.title in self.sections: - log.warn( "Duplicate section title: %s", section.title ) + log.warn("Duplicate section title: %s", section.title) self.sections[section.id] = section - self.section_titles[section.title]= section + self.section_titles[section.title] = section for function in section.functions.values(): - self.functions[ function.name ] = function + self.functions[function.name] = function - def suffixed_name( self, a,b ): + def suffixed_name(self, a, b): """Is b a with a suffix?""" - if b.startswith( a ): - for char in b[len(a):]: + if b.startswith(a): + for char in b[len(a) :]: if char not in self.suffix_chars: return False return True return False - def get_crossref( self, title, volume=None,section=None ): - raise NotImplemented( """Need a get_crossref method""" ) - def package_names( self ): - raise NotImplemented( """Need a package_names method""" ) - def modules( self ): - raise NotImplemented( """Need a modules method""" ) + + def get_crossref(self, title, volume=None, section=None): + raise NotImplementedError("""Need a get_crossref method""") + + def package_names(self): + raise NotImplementedError("""Need a package_names method""") + + def modules(self): + raise NotImplementedError("""Need a modules method""") suffix_chars = 'iufs1234v' - def check_crossrefs( self ): + + def check_crossrefs(self): sections = sorted(self.sections.items()) - for i,(name,section) in enumerate(sections): + for i, (name, section) in enumerate(sections): list(section.get_crossrefs(self)) if i > 0: - section.previous = sections[i-1][1] - if i < len(sections)-1: - section.next = sections[i+1][1] + section.previous = sections[i - 1][1] + if i < len(sections) - 1: + section.next = sections[i + 1][1] section.find_python_functions() - def packages( self ): + def packages(self): result = [] for source in self.package_names(): - result.append( (source,sorted([ - (name,section) for name,section in self.section_titles.items() - if section.package == source - ]))) + result.append( + ( + source, + sorted( + [ + (name, section) + for name, section in self.section_titles.items() + if section.package == source + ] + ), + ) + ) return result -class RefSect( object ): + +class RefSect(object): id = None title = None purpose = None next = None previous = None deprecated = False - def __init__( self, package='GL', reference=None ): + + def __init__(self, package='GL', reference=None): self.package = package self.reference = reference self.functions = {} @@ -91,222 +118,245 @@ def __init__( self, package='GL', reference=None ): self.discussions = [] self.samples = [] self.constants = {} - def set_deprecation( self, value ): + + def set_deprecation(self, value): """Set our deprecated flag""" self.deprecated = value - def has_function( self, name ): + + def has_function(self, name): """Ask whether we have this name defined""" - return ( - name in self.functions or - name in self.py_functions - ) - def get_module( self ): + return name in self.functions or name in self.py_functions + + def get_module(self): """Retrieve our module""" return self.reference.modules()[ - self.reference.package_names().index( self.package ) + self.reference.package_names().index(self.package) ] - def get_crossrefs( self, reference ): + + def get_crossrefs(self, reference): """Retrieve all cross-references from reference""" result = [] - for (title,volume) in self.see_also: - target = reference.get_crossref( title, volume, self ) + for title, volume in self.see_also: + target = reference.get_crossref(title, volume, self) if target is not None: - result.append( target ) + result.append(target) return result # should also look for mentions in the description sections - def find_python_functions( self ): + + def find_python_functions(self): """Find our functions, aliases and the like in python module""" # TODO this is a very inefficient scan... source = self.get_module() - for name,function in sorted(self.functions.items()): - if hasattr( source, function.name ): + for name, function in sorted(self.functions.items()): + if hasattr(source, function.name): function.python[name] = PyFunction( - root_function = function, - py_function = getattr( source,name ), - alias = name, + root_function=function, + py_function=getattr(source, name), + alias=name, ) for name in sorted(dir(source)): - if ( - self.reference.suffixed_name( name, function.name ) or - self.reference.suffixed_name( function.name, name ) - ): - if not self.has_function( name ): + if self.reference.suffixed_name( + name, function.name + ) or self.reference.suffixed_name(function.name, name): + if not self.has_function(name): function.python[name] = PyFunction( - root_function = function, - py_function = getattr( source,name ), - alias = name, + root_function=function, + py_function=getattr(source, name), + alias=name, ) self.py_functions[name] = function if name not in self.reference.functions: - self.reference.functions[ name ] = function - def get_samples( self, sample_set ): + self.reference.functions[name] = function + + def get_samples(self, sample_set): """Populate our sample-set for all of the available samples""" - names = ( - sorted(self.functions.keys()) + - sorted(self.py_functions.keys()) - ) + names = sorted(self.functions.keys()) + sorted(self.py_functions.keys()) filtered = [] filter_set = {} for name in names: if name not in filter_set: - filtered.append( name ) + filtered.append(name) for name in filtered: if name in sample_set: - self.samples.append( (name,Sample.joined(sample_set[name]))) + self.samples.append((name, Sample.joined(sample_set[name]))) self.samples.sort() -class Function( object ): + +class Function(object): """Function description produced from docs Each function represents an original OpenGL function, which may have many Python-level functions associated with it. """ + return_value = None varargs = varnamed = False docstring = None deprecated = False NOT_DEFINED = NOT_DEFINED - def __init__( self,name, section ): + + def __init__(self, name, section): self.name = name self.section = section - self.python = {} # name to python function... + self.python = {} # name to python function... self.parameters = [] -# if section.package == 'GL': -# from OpenGL.platform import entrypoint31 -# self.deprecated = entrypoint31.deprecated( self.name ) -# if self.deprecated: -# self.section.set_deprecation( True ) - def __repr__( self ): - return '%s( %s ) -> %s'%( + + # if section.package == 'GL': + # from OpenGL.platform import entrypoint31 + # self.deprecated = entrypoint31.deprecated( self.name ) + # if self.deprecated: + # self.section.set_deprecation( True ) + def __repr__(self): + return '%s( %s ) -> %s' % ( self.name, self.parameters, self.return_value, ) -class PyFunction( Function ): + +class PyFunction(Function): """Python-implemented function produced via introspection""" - def __init__( self, root_function, py_function, alias=None ): + + def __init__(self, root_function, py_function, alias=None): self.root_function = root_function self.py_function = py_function self.alias = alias + @property - def alternates( self ): + def alternates(self): """Yield any alternate definitions""" - if hasattr( self.py_function, '_alternatives' ): + if hasattr(self.py_function, '_alternatives'): return [ - PyFunction( self.root_function, alternate ) + PyFunction(self.root_function, alternate) for alternate in self.py_function._alternatives ] return [] + @property - def name( self ): + def name(self): """Introspect to get a name for our function""" if self.alias: return self.alias # okay, so do some introspection... - if hasattr( self.py_function, '__name__' ): + if hasattr(self.py_function, '__name__'): return self.py_function.__name__ - raise ValueError( """Don't know how to get name for %r type"""%( - self.py_function.__class__, - )) + raise ValueError( + """Don't know how to get name for %r type""" % (self.py_function.__class__,) + ) + @property - def target( self ): + def target(self): function = self.py_function - function = getattr( function, '__func__', function ) + function = getattr(function, '__func__', function) return function + @property - def docstring( self ): + def docstring(self): """Retrieve docstring for pure-python objects""" - if hasattr( self.target, '__doc__' ): + if hasattr(self.target, '__doc__'): return self.target.__doc__ return None + @property - def section( self ): + def section(self): return self.root_function.section + @property - def python( self ): + def python(self): return {} + _parameters = None + @property - def parameters( self ): + def parameters(self): """Calculate (and store) parameter-list for the function""" if self._parameters is None: - self._parameters = self.get_parameters( self.target ) + self._parameters = self.get_parameters(self.target) return self._parameters - def get_parameters( self, target ): + + def get_parameters(self, target): names = None - if hasattr( target, 'pyConverterNames' ): + if hasattr(target, 'pyConverterNames'): names = target.pyConverterNames - elif hasattr( target, 'argNames' ): + elif hasattr(target, 'argNames'): names = target.argNames - elif hasattr( target, 'wrapperFunction' ): + elif hasattr(target, 'wrapperFunction'): # only values *past* the first for lazy-wrapped operations - return self.get_parameters( target.wrapperFunction )[1:] - elif hasattr( target, 'wrappedOperation' ): - return self.get_parameters( target.wrappedOperation ) - elif isinstance( target, (types.FunctionType,types.MethodType) ): - args,varargs,varkw,defaults = inspect.getargspec( - target - ) + return self.get_parameters(target.wrapperFunction)[1:] + elif hasattr(target, 'wrappedOperation'): + return self.get_parameters(target.wrappedOperation) + elif isinstance(target, (types.FunctionType, types.MethodType)): + args, varargs, varkw, defaults = inspect.getargspec(target) defaults = defaults or () - default_dict = dict([ - (arg,default) - for (arg,default) in zip(args[-len(defaults):],defaults) - ]) + default_dict = dict( + [ + (arg, default) + for (arg, default) in zip(args[-len(defaults) :], defaults) + ] + ) try: parameters = [] for name in args: - if isinstance( name, list ): + if isinstance(name, list): name = tuple(name) - parameters.append( Parameter( - name, default=default_dict.get( name, NOT_DEFINED ), - function = self, - )) + parameters.append( + Parameter( + name, + default=default_dict.get(name, NOT_DEFINED), + function=self, + ) + ) except Exception as err: import pdb + pdb.set_trace() if varargs: parameters.append( Parameter( varargs, - function = self, - varargs = True, + function=self, + varargs=True, ) ) if varkw: parameters.append( Parameter( varkw, - function = self, - varnamed = True, + function=self, + varnamed=True, ) ) return parameters else: - if hasattr( target, 'argtypes' ) and target.argtypes is None: + if hasattr(target, 'argtypes') and target.argtypes is None: return [] - log.warn( """No parameters for type: %r""", target.__class__ ) + log.warn("""No parameters for type: %r""", target.__class__) names = [] - return [ - Parameter( name, data_type=None, function = self ) - for name in names - ] + return [Parameter(name, data_type=None, function=self) for name in names] + @property - def return_value( self ): + def return_value(self): """Determine (if possible) whether we have a return-value type""" - if hasattr( self.py_function, 'restype' ): + if hasattr(self.py_function, 'restype'): return self.py_function.restype return None -class Parameter( object ): + +class Parameter(object): """Description of a parameter to a function""" + NOT_DEFINED = NOT_DEFINED + def __init__( - self, name, description=None, - data_type=None,function=None, + self, + name, + description=None, + data_type=None, + function=None, default=NOT_DEFINED, - varargs=False, varnamed=False + varargs=False, + varnamed=False, ): """Initialize with the values for the parameter""" self.function = function @@ -316,50 +366,69 @@ def __init__( self.default = default self.varargs = varargs self.varnamed = varnamed + @property - def has_default( self ): - return not( self.default is NOT_DEFINED ) + def has_default(self): + return not (self.default is NOT_DEFINED) + -class ParameterReference( object ): - def __init__( self, names, description ): +class ParameterReference(object): + def __init__(self, names, description): self.names = names self.description = description - def __repr__( self ): + + def __repr__(self): result = [] - return '\t\t%s -- %s'%( ', '.join(self.names), self.description ) + return '\t\t%s -- %s' % (', '.join(self.names), self.description) + -class Sample( object ): +class Sample(object): def __init__( - self, url, - projectName, deltaPath, + self, + url, + projectName, + deltaPath, tokenString=None, - sourceRow=None, sourceCol=None, - endRow=None,endCol=None, + sourceRow=None, + sourceCol=None, + endRow=None, + endCol=None, lineText=None, ): self.positions = [] ( - self.url, self.projectName, self.deltaPath, - self.tokenString,self.lineText, + self.url, + self.projectName, + self.deltaPath, + self.tokenString, + self.lineText, ) = ( - url, projectName, deltaPath, - tokenString, lineText, + url, + projectName, + deltaPath, + tokenString, + lineText, ) if sourceRow: - self.positions.append( (sourceRow, sourceCol,endRow,endCol) ) + self.positions.append((sourceRow, sourceCol, endRow, endCol)) + @classmethod - def joined( cls, instances ): + def joined(cls, instances): """Compress same-file references to a single instance""" result = [] if instances: set = {} for instance in instances: - key = instance.projectName,instance.deltaPath - current = set.get( key ) + key = instance.projectName, instance.deltaPath + current = set.get(key) if current is None: - current = cls( instance.url, instance.projectName, instance.deltaPath, instance.tokenString ) + current = cls( + instance.url, + instance.projectName, + instance.deltaPath, + instance.tokenString, + ) set[key] = current - result.append( current ) - current.positions.extend( instance.positions ) + result.append(current) + current.positions.extend(instance.positions) return result - diff --git a/tests/test_core.py b/tests/test_core.py index 5c9b8606..2bbe2ff7 100755 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -2,10 +2,12 @@ from __future__ import print_function import pygame, pygame.display import logging, time, traceback, unittest, os + logging.basicConfig(level=logging.INFO) log = logging.getLogger(__name__) -HERE = os.path.dirname( __file__ ) +HERE = os.path.dirname(__file__) import pickle + try: import cPickle except ImportError as err: @@ -17,24 +19,26 @@ array = None pygame.display.init() -import OpenGL -if os.environ.get( 'TEST_NO_ACCELERATE' ): +import OpenGL + +if os.environ.get('TEST_NO_ACCELERATE'): OpenGL.USE_ACCELERATE = False -#OpenGL.FULL_LOGGING = True +# OpenGL.FULL_LOGGING = True OpenGL.CONTEXT_CHECKING = True OpenGL.FORWARD_COMPATIBLE_ONLY = False OpenGL.UNSIGNED_BYTE_IMAGES_AS_STRING = True -#from OpenGL._bytes import bytes, _NULL_8_BYTE, unicode, as_8_bit +# from OpenGL._bytes import bytes, _NULL_8_BYTE, unicode, as_8_bit from OpenGL.GL import * + try: glGetError() except error.NoContext as err: - # good, should have got this error + # good, should have got this error pass else: - print( 'WARNING: Failed to catch invalid context' ) - #raise RuntimeError( """Did not catch invalid context!""" ) + print('WARNING: Failed to catch invalid context') + # raise RuntimeError( """Did not catch invalid context!""" ) from OpenGL import error from OpenGL.GLU import * import OpenGL @@ -44,22 +48,24 @@ from OpenGL.GL.ARB.imaging import * from OpenGL._bytes import _NULL_8_BYTE -glMultiDrawElements = alternate( - glMultiDrawElementsEXT, glMultiDrawElements, +glMultiDrawElements = alternate( + glMultiDrawElementsEXT, + glMultiDrawElements, ) import basetestcase -class TestCore( basetestcase.BaseTest ): - def test_errors( self ): + +class TestCore(basetestcase.BaseTest): + def test_errors(self): """Test for error catching/checking""" try: - glClear( GL_INVALID_VALUE ) + glClear(GL_INVALID_VALUE) except Exception as err: assert err.err == 1281, ("""Expected invalid value (1281)""", err.err) else: assert not OpenGL.ERROR_CHECKING, """No error on invalid glClear""" try: - glColorPointer(GL_INVALID_VALUE,GL_BYTE,0,None) + glColorPointer(GL_INVALID_VALUE, GL_BYTE, 0, None) except Exception as err: assert err.err == 1281, ("""Expected invalid value (1281)""", err.err) assert err.baseOperation, err.baseOperation @@ -68,173 +74,207 @@ def test_errors( self ): else: assert not OpenGL.ERROR_CHECKING, """No error on invalid glColorPointer""" try: - glBitmap(-1,-1,0,0,0,0,as_8_bit("")) + glBitmap(-1, -1, 0, 0, 0, 0, as_8_bit("")) except Exception as err: - assert err.err in (1281,1282), ("""Expected invalid value (1281) or invalid operation (1282)""", err.err) + assert err.err in (1281, 1282), ( + """Expected invalid value (1281) or invalid operation (1282)""", + err.err, + ) else: assert not OpenGL.ERROR_CHECKING, """No error on invalid glBitmap""" + if not OpenGL.ERROR_ON_COPY: - def test_simple( self ): + + def test_simple(self): """Test for simple vertex-based drawing""" - glDisable( GL_LIGHTING ) - glBegin( GL_TRIANGLES ) + glDisable(GL_LIGHTING) + glBegin(GL_TRIANGLES) try: try: - glVertex3f( 0.,1.,0. ) + glVertex3f(0.0, 1.0, 0.0) except Exception: traceback.print_exc() - glVertex3fv( [-1,0,0] ) - glVertex3dv( [1,0,0] ) + glVertex3fv([-1, 0, 0]) + glVertex3dv([1, 0, 0]) try: - glVertex3dv( [1,0,4,5] ) + glVertex3dv([1, 0, 4, 5]) except ValueError: - #Got expected value error (good) - assert OpenGL.ARRAY_SIZE_CHECKING, """Should have raised ValueError when doing array size checking""" + # Got expected value error (good) + assert ( + OpenGL.ARRAY_SIZE_CHECKING + ), """Should have raised ValueError when doing array size checking""" else: - assert not OpenGL.ARRAY_SIZE_CHECKING, """Should not have raised ValueError when not doing array size checking""" + assert ( + not OpenGL.ARRAY_SIZE_CHECKING + ), """Should not have raised ValueError when not doing array size checking""" finally: glEnd() - a = glGenTextures( 1 ) + a = glGenTextures(1) assert a - b = glGenTextures( 2 ) + b = glGenTextures(2) assert len(b) == 2 - def test_arbwindowpos( self ): + + def test_arbwindowpos(self): """Test the ARB window_pos extension will load if available""" from OpenGL.GL.ARB.window_pos import glWindowPos2dARB + if glWindowPos2dARB: - glWindowPos2dARB( 0.0, 3.0 ) - def test_getstring( self ): - assert glGetString( GL_EXTENSIONS ) - def test_constantPickle( self ): + glWindowPos2dARB(0.0, 3.0) + + def test_getstring(self): + assert glGetString(GL_EXTENSIONS) + + def test_constantPickle(self): """Test that our constants can be pickled/unpickled properly""" - for p in pickle,cPickle: - v = p.loads( p.dumps( GL_VERTEX_ARRAY )) - assert v == GL_VERTEX_ARRAY, (v,GL_VERTEX_ARRAY) - assert v.name == GL_VERTEX_ARRAY.name, v.name - - - def test_nonFloatColor( self ): + for p in pickle, cPickle: + v = p.loads(p.dumps(GL_VERTEX_ARRAY)) + assert v == GL_VERTEX_ARRAY, (v, GL_VERTEX_ARRAY) + assert v.name == GL_VERTEX_ARRAY.name, v.name + + def test_nonFloatColor(self): """Test that we handle non-floating-point colour inputs""" - for notFloat,shouldWork in ((0,True), (object(),False), (object,False)): + for notFloat, shouldWork in ((0, True), (object(), False), (object, False)): try: - glColor4f( 0,1,1,notFloat ) + glColor4f(0, 1, 1, notFloat) except Exception: if shouldWork: - raise + raise else: if not shouldWork: - raise RuntimeError( """Expected failure for non-float value %s, succeeded"""%( notFloat, )) + raise RuntimeError( + """Expected failure for non-float value %s, succeeded""" + % (notFloat,) + ) + if array: - def test_arrayTranspose( self ): - m = glGetFloatv( GL_MODELVIEW_MATRIX ) - glMatrixMode( GL_MODELVIEW ) + + def test_arrayTranspose(self): + m = glGetFloatv(GL_MODELVIEW_MATRIX) + glMatrixMode(GL_MODELVIEW) glLoadIdentity() t = eye(4) - t[3,0] = 20.0 + t[3, 0] = 20.0 # the following glMultMatrixf call ignored this transpose t = t.T if OpenGL.ERROR_ON_COPY: - t = ascontiguousarray( t ) - - glMultMatrixd( t ) + t = ascontiguousarray(t) + + glMultMatrixd(t) + + m = glGetFloatv(GL_MODELVIEW_MATRIX) + assert allclose(m[-1], [0, 0, 0, 1]), m - m = glGetFloatv( GL_MODELVIEW_MATRIX ) - assert allclose( m[-1], [0,0,0,1] ), m - if array: - # currently crashes in py_buffer operation, so reverted to raw numpy + # currently crashes in py_buffer operation, so reverted to raw numpy # api - def test_mmap_data( self ): + def test_mmap_data(self): """Test that we can use mmap data array - + If we had a reasonable lib that dumped raw image data to a shared-mem file - we might be able to use this for movie display :) + we might be able to use this for movie display :) """ - fh = open( 'mmap-test-data.dat', 'wb+' ) - fh.write( _NULL_8_BYTE*(32*32*3+1)) + fh = open('mmap-test-data.dat', 'wb+') + fh.write(_NULL_8_BYTE * (32 * 32 * 3 + 1)) fh.flush() fh.close() # using memmap here... - data = memmap( 'mmap-test-data.dat' ) - for i in range( 0,255,2 ): - glDrawPixels( 32,32, GL_RGB, GL_UNSIGNED_BYTE, data, ) + data = memmap('mmap-test-data.dat') + for i in range(0, 255, 2): + glDrawPixels( + 32, + 32, + GL_RGB, + GL_UNSIGNED_BYTE, + data, + ) glFlush() pygame.display.flip() data[::2] = i - time.sleep( 0.001 ) - + time.sleep(0.001) + if array: - def test_vbo( self ): + + def test_vbo(self): """Test utility vbo wrapper""" from OpenGL.arrays import vbo + if not vbo.get_implementation(): return if not glVertexPointerd or not glDrawElements: return - points = array( [ - [0,0,0], - [0,1,0], - [1,.5,0], - [1,0,0], - [1.5,.5,0], - [1.5,0,0], - ], dtype='d') + points = array( + [ + [0, 0, 0], + [0, 1, 0], + [1, 0.5, 0], + [1, 0, 0], + [1.5, 0.5, 0], + [1.5, 0, 0], + ], + dtype='d', + ) indices = array( range(len(points)), - ['i','I'][bool(OpenGL.ERROR_ON_COPY)], # test coercion if we can + ['i', 'I'][int(bool(OpenGL.ERROR_ON_COPY))], # test coercion if we can ) d = vbo.VBO(points) - glDisable( GL_CULL_FACE ) - glNormal3f( 0,0,1 ) - glColor3f( 1,1,1 ) + glDisable(GL_CULL_FACE) + glNormal3f(0, 0, 1) + glColor3f(1, 1, 1) glEnableClientState(GL_VERTEX_ARRAY) try: - for x in range( 1, 255, 10 ): + for x in range(1, 255, 10): d.bind() try: - glVertexPointerd( d ) - glDrawElements( GL_LINE_LOOP, len(indices), GL_UNSIGNED_INT, indices ) + glVertexPointerd(d) + glDrawElements( + GL_LINE_LOOP, len(indices), GL_UNSIGNED_INT, indices + ) finally: d.unbind() - lastPoint = array( [[1.5,(1/255.) * float(x),0]] ) + lastPoint = array([[1.5, (1 / 255.0) * float(x), 0]]) d[-2:-1] = lastPoint glFlush() pygame.display.flip() - glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT ) - time.sleep( 0.001 ) + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) + time.sleep(0.001) finally: - glDisableClientState( GL_VERTEX_ARRAY ) - # bug report from Dan Helfman, delete shouldn't cause + glDisableClientState(GL_VERTEX_ARRAY) + # bug report from Dan Helfman, delete shouldn't cause # errors if called explicitly d.delete() + def test_glgetbufferparameter(self): if not glGenBuffers or not glGenVertexArrays: return None buffer = glGenBuffers(1) - vertex_array = glGenVertexArrays(1,buffer) + vertex_array = glGenVertexArrays(1, buffer) glBindBuffer(GL_ARRAY_BUFFER, buffer) try: mapped = glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_MAPPED) - assert mapped == (GL_FALSE if OpenGL.SIZE_1_ARRAY_UNPACK else [GL_FALSE]), mapped + assert mapped == ( + GL_FALSE if OpenGL.SIZE_1_ARRAY_UNPACK else [GL_FALSE] + ), mapped finally: glBindBuffer(GL_ARRAY_BUFFER, 0) - glDeleteVertexArrays(1,vertex_array) - glDeleteBuffers(1,buffer) + glDeleteVertexArrays(1, vertex_array) + glDeleteBuffers(1, buffer) + def test_glbufferparameter_create(self): if not glGenBuffers or not glGenVertexArrays: return None - for create in [True,False]: + for create in [True, False]: buffer = glGenBuffers(1) - vertex_array = glGenVertexArrays(1,buffer) + vertex_array = glGenVertexArrays(1, buffer) glBindBuffer(GL_ARRAY_BUFFER, buffer) try: for param, expected in [ - (GL_BUFFER_SIZE,0), - (GL_BUFFER_MAPPED,GL_FALSE), - (GL_BUFFER_STORAGE_FLAGS,0), - (GL_BUFFER_USAGE,GL_STATIC_DRAW), + (GL_BUFFER_SIZE, 0), + (GL_BUFFER_MAPPED, GL_FALSE), + (GL_BUFFER_STORAGE_FLAGS, 0), + (GL_BUFFER_USAGE, GL_STATIC_DRAW), ]: if create: mapped = GLint(-1) @@ -248,360 +288,405 @@ def test_glbufferparameter_create(self): if OpenGL.SIZE_1_ARRAY_UNPACK: assert mapped == expected, (param, mapped, expected) else: - assert mapped[0] == expected, (param, mapped[0], expected) + assert mapped[0] == expected, ( + param, + mapped[0], + expected, + ) finally: glBindBuffer(GL_ARRAY_BUFFER, 0) - glDeleteVertexArrays(1,vertex_array) - glDeleteBuffers(1,buffer) - def test_fbo( self ): + glDeleteVertexArrays(1, vertex_array) + glDeleteBuffers(1, buffer) + + def test_fbo(self): """Test that we support framebuffer objects - + http://www.gamedev.net/reference/articles/article2331.asp """ if not glGenFramebuffers: - print( 'No Frame Buffer Support!' ) + print('No Frame Buffer Support!') return False width = height = 128 fbo = glGenFramebuffers(1) glBindFramebuffer(GL_FRAMEBUFFER, fbo) - depthbuffer = glGenRenderbuffers(1 ) + depthbuffer = glGenRenderbuffers(1) glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer) glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height) glFramebufferRenderbuffer( - GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, - depthbuffer + GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuffer ) img = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, img) # NOTE: these lines are *key*, without them you'll likely get an unsupported format error, # ie. GL_FRAMEBUFFER_UNSUPPORTED - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexImage2D( - GL_TEXTURE_2D, 0, GL_RGB8, - width, height, 0, GL_RGB, - GL_INT, - None # no data transferred - ) + GL_TEXTURE_2D, + 0, + GL_RGB8, + width, + height, + 0, + GL_RGB, + GL_INT, + None, # no data transferred + ) glFramebufferTexture2D( - GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, - img, - 0 # mipmap level, normally 0 + GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + img, + 0, # mipmap level, normally 0 ) status = glCheckFramebufferStatus(GL_FRAMEBUFFER) assert status == GL_FRAMEBUFFER_COMPLETE, status glBindFramebuffer(GL_FRAMEBUFFER, fbo) - glPushAttrib(GL_VIEWPORT_BIT) # viewport is shared with the main context + glPushAttrib(GL_VIEWPORT_BIT) # viewport is shared with the main context try: - glViewport(0,0,width, height) - + glViewport(0, 0, width, height) + # rendering to the texture here... - glColor3f( 1,0,0 ) - glNormal3f( 0,0,1 ) - glBegin( GL_QUADS ) - for v in [[0,0,0],[0,1,0],[1,1,0],[1,0,0]]: - glColor3f( *v ) - glVertex3d( *v ) + glColor3f(1, 0, 0) + glNormal3f(0, 0, 1) + glBegin(GL_QUADS) + for v in [[0, 0, 0], [0, 1, 0], [1, 1, 0], [1, 0, 0]]: + glColor3f(*v) + glVertex3d(*v) glEnd() finally: - glPopAttrib(); # restore viewport - glBindFramebuffer(GL_FRAMEBUFFER, 0) # unbind - + glPopAttrib() + # restore viewport + glBindFramebuffer(GL_FRAMEBUFFER, 0) # unbind + glBindTexture(GL_TEXTURE_2D, img) - - glEnable( GL_TEXTURE_2D ) - + + glEnable(GL_TEXTURE_2D) + # rendering with the texture here... - glColor3f( 1,1,1 ) - glNormal3f( 0,0,1 ) - glDisable( GL_LIGHTING ) - glBegin( GL_QUADS ) + glColor3f(1, 1, 1) + glNormal3f(0, 0, 1) + glDisable(GL_LIGHTING) + glBegin(GL_QUADS) try: - for v in [[0,0,0],[0,1,0],[1,1,0],[1,0,0]]: - glTexCoord2f( *v[:2] ) - glVertex3d( *v ) + for v in [[0, 0, 0], [0, 1, 0], [1, 1, 0], [1, 0, 0]]: + glTexCoord2f(*v[:2]) + glVertex3d(*v) finally: glEnd() - def test_gl_1_2_support( self ): + + def test_gl_1_2_support(self): if glBlendColor: - glBlendColor( .3, .4, 1.0, .3 ) + glBlendColor(0.3, 0.4, 1.0, 0.3) print('OpenGL 1.2 support') + if array: - def test_glmultidraw( self ): + + def test_glmultidraw(self): """Test that glMultiDrawElements works, uses glDrawElements""" if glMultiDrawElements: - points = array([ - (i,0,0) for i in range( 8 ) - ] + [ - (i,1,0) for i in range( 8 ) - ], 'd') - indices = array([ - [0,8,9,1, 2,10,11,3,], - [4,12,13,5,6,14,15,7], - ],'B') - index_pointers = arrays.GLvoidpArray.zeros( (2,)) - index_pointers[0] = arrays.GLbyteArray.dataPointer( indices ) - index_pointers[1] = arrays.GLbyteArray.dataPointer( indices[1] ) - counts = [ len(x) for x in indices ] + points = array( + [(i, 0, 0) for i in range(8)] + [(i, 1, 0) for i in range(8)], 'd' + ) + indices = array( + [ + [ + 0, + 8, + 9, + 1, + 2, + 10, + 11, + 3, + ], + [4, 12, 13, 5, 6, 14, 15, 7], + ], + 'B', + ) + index_pointers = arrays.GLvoidpArray.zeros((2,)) + index_pointers[0] = arrays.GLbyteArray.dataPointer(indices) + index_pointers[1] = arrays.GLbyteArray.dataPointer(indices[1]) + counts = [len(x) for x in indices] if OpenGL.ERROR_ON_COPY: - counts = (GLuint*len(counts))(*counts) - glEnableClientState( GL_VERTEX_ARRAY ) - glDisableClientState( GL_COLOR_ARRAY ) - glDisableClientState( GL_NORMAL_ARRAY ) + counts = (GLuint * len(counts))(*counts) + glEnableClientState(GL_VERTEX_ARRAY) + glDisableClientState(GL_COLOR_ARRAY) + glDisableClientState(GL_NORMAL_ARRAY) try: - glVertexPointerd( points ) - glDisable( GL_LIGHTING ) + glVertexPointerd(points) + glDisable(GL_LIGHTING) try: - glMultiDrawElements(GL_QUAD_STRIP, counts, GL_UNSIGNED_BYTE, index_pointers, 2) + glMultiDrawElements( + GL_QUAD_STRIP, counts, GL_UNSIGNED_BYTE, index_pointers, 2 + ) finally: - glEnable( GL_LIGHTING ) + glEnable(GL_LIGHTING) finally: - glDisableClientState( GL_VERTEX_ARRAY ) + glDisableClientState(GL_VERTEX_ARRAY) else: print('No multi_draw_arrays support') - def test_glDrawBuffers_list( self ): + + def test_glDrawBuffers_list(self): """Test that glDrawBuffers with list argument doesn't crash""" if not glDrawBuffers: return - a_type = GLenum*2 + a_type = GLenum * 2 args = a_type( GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, ) try: - glDrawBuffers( 2, args ) + glDrawBuffers(2, args) except GLError as err: assert err.err == GL_INVALID_OPERATION, err - def test_glDrawBuffers_list_valid( self ): + + def test_glDrawBuffers_list_valid(self): """Test that glDrawBuffers with list argument where value is set""" if not glGenFramebuffers: return if not glDrawBuffers: return - previous = glGetIntegerv( GL_READ_BUFFER ) + previous = glGetIntegerv(GL_READ_BUFFER) fbo = glGenFramebuffers(1) glBindFramebuffer(GL_FRAMEBUFFER, fbo) try: - img1,img2 = glGenTextures(2) - for img in img1,img2: - glBindTexture( GL_TEXTURE_2D, img ) + img1, img2 = glGenTextures(2) + for img in img1, img2: + glBindTexture(GL_TEXTURE_2D, img) glTexImage2D( - GL_TEXTURE_2D, 0, GL_RGB8, - 300, 300, 0, GL_RGB, - GL_INT, - None # no data transferred - ) - + GL_TEXTURE_2D, + 0, + GL_RGB8, + 300, + 300, + 0, + GL_RGB, + GL_INT, + None, # no data transferred + ) glFramebufferTexture2D( - GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, img1, 0 + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, img1, 0 ) glFramebufferTexture2D( - GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT1, - GL_TEXTURE_2D, img2, 0 + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, img2, 0 ) - a_type = GLenum*2 + a_type = GLenum * 2 drawingBuffers = a_type( - GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, ) - glDrawBuffers(2, drawingBuffers ) + glDrawBuffers(2, drawingBuffers) try: checkFramebufferStatus() except error.GLError: pass else: - glReadBuffer( GL_COLOR_ATTACHMENT1 ) - pixels = glReadPixels( 0,0, 10,10, GL_RGB, GL_UNSIGNED_BYTE ) + glReadBuffer(GL_COLOR_ATTACHMENT1) + pixels = glReadPixels(0, 0, 10, 10, GL_RGB, GL_UNSIGNED_BYTE) assert len(pixels) == 300, len(pixels) finally: - glBindFramebuffer( GL_FRAMEBUFFER, 0 ) - - glReadBuffer( previous ) - - def test_get_version( self ): + glBindFramebuffer(GL_FRAMEBUFFER, 0) + + glReadBuffer(previous) + + def test_get_version(self): from OpenGL.extensions import hasGLExtension - if hasGLExtension( 'GL_VERSION_GL_2_0' ): + + if hasGLExtension('GL_VERSION_GL_2_0'): assert glShaderSource assert glUniform1f else: assert not glShaderSource assert not glUniform1f - - def test_lookupint( self ): - from OpenGL.raw.GL import _lookupint + + def test_lookupint(self): + from OpenGL.raw.GL import _lookupint + if GLQuerier.pullVersion() < [2]: return - l = _lookupint.LookupInt( GL_NUM_COMPRESSED_TEXTURE_FORMATS, GLint ) + l = _lookupint.LookupInt(GL_NUM_COMPRESSED_TEXTURE_FORMATS, GLint) result = int(l) if not os.environ.get('TRAVIS'): - assert result, "No compressed textures on this platform? that seems unlikely" + assert ( + result + ), "No compressed textures on this platform? that seems unlikely" else: "Travis xvfb doesn't normally have compressed textures, possible upgrade?" - - def test_glget( self ): + + def test_glget(self): """Test that we can run glGet... on registered constants without crashing...""" from OpenGL.raw.GL import _glgets + get_items = sorted(_glgets._glget_size_mapping.items()) - for key,value in get_items: + for key, value in get_items: # There are glGet values that will cause a crash during cleanup # GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92c1 crashes/segfaults - if key >= 0x8df9 and key <= 0x8e23: + if key >= 0x8DF9 and key <= 0x8E23: continue - if key >= 0x92be and key <= 0x92c9: + if key >= 0x92BE and key <= 0x92C9: continue # print( 'Trying glGetFloatv( 0x%x )'%(key,)) try: - result = glGetFloatv( key ) + result = glGetFloatv(key) except error.GLError as err: if err.err == GL_INVALID_ENUM: pass elif err.err == GL_INVALID_OPERATION: - if key == 0x882d: # gl draw buffer + if key == 0x882D: # gl draw buffer pass else: - raise + raise else: if value == (1,) and OpenGL.SIZE_1_ARRAY_UNPACK: try: result = float(result) except TypeError as err: - err.args += (result,key) + err.args += (result, key) raise else: - assert ArrayDatatype.dimensions( result ) == value, (result,ArrayDatatype.dimensions( result ), value) + assert ArrayDatatype.dimensions(result) == value, ( + result, + ArrayDatatype.dimensions(result), + value, + ) + def test_max_compute_work_group_invocations(self): from OpenGL.extensions import hasGLExtension - if hasGLExtension( 'GL_ARB_compute_shader' ): - assert glGetIntegerv( GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS ) - - - def test_glCallLists_twice2( self ): + + if hasGLExtension('GL_ARB_compute_shader'): + assert glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS) + + def test_glCallLists_twice2(self): """SF#2829309 report that glCallLists doubles operation""" - glRenderMode (GL_RENDER) + glRenderMode(GL_RENDER) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(40.0, 1.0, 1.0, 10.0) - glMatrixMode (GL_MODELVIEW) - glLoadIdentity () - glTranslatef (0, 0, -3) - first = glGenLists( 2 ) - second = first+1 + glMatrixMode(GL_MODELVIEW) + glLoadIdentity() + glTranslatef(0, 0, -3) + first = glGenLists(2) + second = first + 1 glNewList(first, GL_COMPILE_AND_EXECUTE) - glInitNames () + glInitNames() if not OpenGL.ERROR_ON_COPY: - glCallLists([second]) # replace with gCallList(2) + glCallLists([second]) # replace with gCallList(2) else: lists = (GLuint * 1)() lists[0] = second glCallLists(lists) - #glCallList(second) - glEndList () + # glCallList(second) + glEndList() glNewList(second, GL_COMPILE) - glPushName (1) - glBegin (GL_POINTS) - glVertex3f (0, 0, 0) - glEnd () - glEndList () - glCallList( second ) + glPushName(1) + glBegin(GL_POINTS) + glVertex3f(0, 0, 0) + glEnd() + glEndList() + glCallList(second) glPopName() - depth = glGetIntegerv( GL_NAME_STACK_DEPTH ) - assert depth in (0,(0,)), depth # have popped, but even then, were' not in the mode... + depth = glGetIntegerv(GL_NAME_STACK_DEPTH) + assert depth in ( + 0, + (0,), + ), depth # have popped, but even then, were' not in the mode... - glSelectBuffer (100) - glRenderMode (GL_SELECT) + glSelectBuffer(100) + glRenderMode(GL_SELECT) glCallList(1) - depth = glGetIntegerv( GL_NAME_STACK_DEPTH ) - assert depth in (1,(1,)), depth # should have a single record + depth = glGetIntegerv(GL_NAME_STACK_DEPTH) + assert depth in (1, (1,)), depth # should have a single record glPopName() - records = glRenderMode (GL_RENDER) + records = glRenderMode(GL_RENDER) # reporter says sees two records, Linux sees none, Win32 sees 1 :( assert len(records) == 1, records - - - def test_orinput_handling( self ): + + def test_orinput_handling(self): if not glGenVertexArrays: return None x = glGenVertexArrays(1) - x = int(x) # check that we got x as an integer-compatible value + x = int(x) # check that we got x as an integer-compatible value x2 = GLuint() - r_value = glGenVertexArrays( 1, x2 ) + r_value = glGenVertexArrays(1, x2) assert x2.value, x2.value assert r_value - - color = glGetFloatv( GL_FOG_COLOR ) - color2 = (GLfloat *4)() - glGetFloatv( GL_FOG_COLOR, color2 ) - for a,b in zip( color,color2 ): - assert a==b, (color,color2) - - - def test_get_read_fb_binding( self ): + + color = glGetFloatv(GL_FOG_COLOR) + color2 = (GLfloat * 4)() + glGetFloatv(GL_FOG_COLOR, color2) + for a, b in zip(color, color2): + assert a == b, (color, color2) + + def test_get_read_fb_binding(self): if GLQuerier.pullVersion() < [3]: return glGetInteger(GL_READ_FRAMEBUFFER_BINDING) - - def test_shader_compile_string( self ): + + def test_shader_compile_string(self): if not glCreateShader: return None shader = glCreateShader(GL_VERTEX_SHADER) - + def glsl_version(): """Parse GL_SHADING_LANGUAGE_VERSION into [int(major),int(minor)]""" - version = glGetString( GL_SHADING_LANGUAGE_VERSION ) + version = glGetString(GL_SHADING_LANGUAGE_VERSION) version = version.split(as_8_bit(' '))[0] version = [int(x) for x in version.split(as_8_bit('.'))[:2]] - return version - if glsl_version() < [3,3]: + return version + + if glsl_version() < [3, 3]: return SAMPLE_SHADER = '''#version 330 void main() { gl_Position = vec4(0,0,0,0);}''' if OpenGL.ERROR_ON_COPY: - SAMPLE_SHADER = as_8_bit( SAMPLE_SHADER ) + SAMPLE_SHADER = as_8_bit(SAMPLE_SHADER) glShaderSource(shader, SAMPLE_SHADER) glCompileShader(shader) if not bool(glGetShaderiv(shader, GL_COMPILE_STATUS)) == True: print('Info log:') print(glGetShaderInfoLog(shader)) assert False, """Failed to compile""" - - def test_gen_framebuffers_twice( self ): + + def test_gen_framebuffers_twice(self): if not glGenFramebuffersEXT: return glGenFramebuffersEXT(1) f1 = glGenFramebuffersEXT(1) f2 = glGenFramebuffersEXT(1) - assert f1 != f2, (f1,f2) + assert f1 != f2, (f1, f2) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, f2) glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0) - + def test_compressed_data(self): from OpenGL.extensions import hasGLExtension - if hasGLExtension( 'GL_EXT_texture_compression_s3tc' ): + + if hasGLExtension('GL_EXT_texture_compression_s3tc'): from OpenGL.GL.EXT import texture_compression_s3tc as s3tc + texture = glGenTextures(1) - glEnable( GL_TEXTURE_2D ) - image_type = GLubyte *256*256 + glEnable(GL_TEXTURE_2D) + image_type = GLubyte * 256 * 256 image = image_type() glCompressedTexImage2D( - GL_TEXTURE_2D, 0, - s3tc.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, - 256, 256, 0, + GL_TEXTURE_2D, + 0, + s3tc.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, + 256, + 256, + 0, # 256*256*1, image, ) assert texture - - - + + if __name__ == "__main__": - logging.basicConfig( level=logging.INFO ) + logging.basicConfig(level=logging.INFO) unittest.main() pygame.display.quit() pygame.quit()