[Numpy-svn] r3950 - trunk/numpy/f2py/lib/extgen
numpy-svn at scipy.org
numpy-svn at scipy.org
Mon Aug 6 09:07:18 EDT 2007
Author: pearu
Date: 2007-08-06 08:07:03 -0500 (Mon, 06 Aug 2007)
New Revision: 3950
Modified:
trunk/numpy/f2py/lib/extgen/base.py
trunk/numpy/f2py/lib/extgen/c_type.py
trunk/numpy/f2py/lib/extgen/doc.txt
Log:
Added numpy array and scalar support to PyCTypePython.
Modified: trunk/numpy/f2py/lib/extgen/base.py
===================================================================
--- trunk/numpy/f2py/lib/extgen/base.py 2007-08-06 12:42:58 UTC (rev 3949)
+++ trunk/numpy/f2py/lib/extgen/base.py 2007-08-06 13:07:03 UTC (rev 3950)
@@ -54,6 +54,9 @@
# map(self.add, components)
return self
+ def __repr__(self):
+ return '%s(%s)' % (self.__class__.__name__, ', '.join([repr(c) for (c,l) in self.components]))
+
@property
def provides(self):
"""
@@ -72,9 +75,6 @@
def info(message):
print >> sys.stderr, message
- def __repr__(self):
- return '%s(%s)' % (self.__class__.__name__, `self.containers`)
-
def __getattr__(self, attr):
if attr.startswith('container_'): # convenience feature
return self.get_container(attr[10:])
Modified: trunk/numpy/f2py/lib/extgen/c_type.py
===================================================================
--- trunk/numpy/f2py/lib/extgen/c_type.py 2007-08-06 12:42:58 UTC (rev 3949)
+++ trunk/numpy/f2py/lib/extgen/c_type.py 2007-08-06 13:07:03 UTC (rev 3950)
@@ -24,6 +24,9 @@
self.name = name
map(self.add, components)
return self
+
+ def __repr__(self):
+ return '%s(%s)' % (self.__class__.__name__, ', '.join([repr(self.name)]+[repr(c) for (c,l) in self.components]))
def update_containers(self):
self.container_TypeDef += self.evaluate(self.template_typedef)
@@ -31,19 +34,28 @@
def __str__(self):
return self.name
- def get_pyret_fmt(self, input_intent_hide = True):
- if input_intent_hide: return 'O'
- return 'N'
+ def set_pyarg_decl(self, arg):
+ if arg.input_intent=='return':
+ arg += CDecl(self, '%s = Py_None' % (arg.pycvar))
+ else:
+ arg += CDecl(self, '%s = NULL' % (arg.pycvar))
+
+ def get_pyarg_fmt(self, arg):
+ if arg.input_intent=='hide': return None
+ return 'O'
- def get_pyret_arg(self, cname):
- return cname
-
- def get_pyarg_fmt(self):
+ def get_pyarg_obj(self, arg):
+ if arg.input_intent=='hide': return None
+ return '&' + arg.pycvar
+
+ def get_pyret_fmt(self, arg):
+ if arg.output_intent=='hide': return None
return 'O'
+
+ def get_pyret_obj(self, arg):
+ if arg.output_intent=='hide': return None
+ return arg.pycvar
- def get_pyarg_arg(self, cname):
- return '&%s' % (cname)
-
class _CatchTypeDef(Component): # for doctest
template = '%(TypeDef)s'
default_container_label = '<IGNORE>'
@@ -68,7 +80,7 @@
def initialize(self, name):
if isinstance(name, CTypeBase):
return name
- if isinstance(name, type) or name in ['cell', 'generator', 'cobject']:
+ if isinstance(name, type) or name in ['cell', 'generator', 'cobject', 'instance']:
return CTypePython(name)
try:
return Component.get(name)
@@ -79,6 +91,11 @@
def update_containers(self):
pass
+ def set_pyarg_decl(self, arg):
+ pass
+ def set_titles(self, arg):
+ pass
+
class CTypeAlias(CTypeBase):
""" CTypeAlias(<name>, <ctype>)
@@ -247,81 +264,201 @@
>>> b.func(23, 23l, 1.2, 1+2j, 'hello', u'hei', (2,'a'), [-2], {3:4}, set([1,2]), 2, '15')
(23, 23L, 1.2, (1+2j), 'hello', u'hei', (2, 'a'), [-2], {3: 4}, set([1, 2]), 2, '15')
- #>>> print b.func.__doc__
+ >>> print b.func.__doc__
+ func(i, l, f, c, s, u, t, lst, d, set, o1, o2) -> (i, l, f, c, s, u, t, lst, d, set, o1, o2)
+ <BLANKLINE>
+ Required arguments:
+ i - a python int object
+ l - a python long object
+ f - a python float object
+ c - a python complex object
+ s - a python str object
+ u - a python unicode object
+ t - a python tuple object
+ lst - a python list object
+ d - a python dict object
+ set - a python set object
+ o1 - a python object
+ o2 - a python object
+ <BLANKLINE>
+ Return values:
+ i - a python int object
+ l - a python long object
+ f - a python float object
+ c - a python complex object
+ s - a python str object
+ u - a python unicode object
+ t - a python tuple object
+ lst - a python list object
+ d - a python dict object
+ set - a python set object
+ o1 - a python object
+ o2 - a python object
+
+ >>> import numpy
+ >>> m = ExtensionModule('test_CTypePython_numpy')
+ >>> f = PyCFunction('func_int')
+ >>> f += PyCArgument('i1', numpy.int8, output_intent='return')
+ >>> f += PyCArgument('i2', numpy.int16, output_intent='return')
+ >>> f += PyCArgument('i3', numpy.int32, output_intent='return')
+ >>> f += PyCArgument('i4', numpy.int64, output_intent='return')
+ >>> m += f
+ >>> f = PyCFunction('func_uint')
+ >>> f += PyCArgument('i1', numpy.uint8, output_intent='return')
+ >>> f += PyCArgument('i2', numpy.uint16, output_intent='return')
+ >>> f += PyCArgument('i3', numpy.uint32, output_intent='return')
+ >>> f += PyCArgument('i4', numpy.uint64, output_intent='return')
+ >>> m += f
+ >>> f = PyCFunction('func_float')
+ >>> f += PyCArgument('f1', numpy.float32, output_intent='return')
+ >>> f += PyCArgument('f2', numpy.float64, output_intent='return')
+ >>> f += PyCArgument('f3', numpy.float128, output_intent='return')
+ >>> m += f
+ >>> f = PyCFunction('func_complex')
+ >>> f += PyCArgument('c1', numpy.complex64, output_intent='return')
+ >>> f += PyCArgument('c2', numpy.complex128, output_intent='return')
+ >>> f += PyCArgument('c3', numpy.complex256, output_intent='return')
+ >>> m += f
+ >>> f = PyCFunction('func_array')
+ >>> f += PyCArgument('a1', numpy.ndarray, output_intent='return')
+ >>> m += f
+ >>> #f = PyCFunction('func_c_int')
+ >>> #f += PyCArgument('i1', 'c_int', output_intent='return')
+ >>> #m += f
+ >>> b = m.build() #doctest: +ELLIPSIS
+ exec_command...
+ >>> b.func_int(numpy.int8(-2), numpy.int16(-3), numpy.int32(-4), numpy.int64(-5))
+ (-2, -3, -4, -5)
+ >>> b.func_uint(numpy.uint8(-1), numpy.uint16(-1), numpy.uint32(-1), numpy.uint64(-1))
+ (255, 65535, 4294967295, 18446744073709551615)
+ >>> b.func_float(numpy.float32(1.2),numpy.float64(1.2),numpy.float128(1.2))
+ (1.20000004768, 1.2, 1.19999999999999995559)
+ >>> b.func_complex(numpy.complex64(1+2j),numpy.complex128(1+2j),numpy.complex256(1+2j))
+ ((1+2j), (1+2j), (1.0+2.0j))
+ >>> b.func_array(numpy.array([1,2]))
+ array([1, 2])
+ >>> b.func_array(numpy.array(2))
+ array(2)
+ >>> b.func_array(2)
+ Traceback (most recent call last):
+ ...
+ TypeError: argument 1 must be numpy.ndarray, not int
+ >>> b.func_array(numpy.int8(2))
+ Traceback (most recent call last):
+ ...
+ TypeError: argument 1 must be numpy.ndarray, not numpy.int8
+ >>> #b.func_c_int(2)
+ """
+
+ typeinfo_map = dict(
+ # <key>: (<type object in C>, <C type>, <PyArgFmt>)
+ int = ('PyInt_Type', 'PyIntObject*', 'O!'),
+ long = ('PyLong_Type', 'PyLongObject*', 'O!'),
+ float = ('PyFloat_Type', 'PyFloatObject*', 'O!'),
+ complex = ('PyComplex_Type', 'PyComplexObject*', 'O!'),
+ str = ('PyString_Type', 'PyStringObject*', 'S'),
+ unicode = ('PyUnicode_Type', 'PyUnicodeObject*', 'U'),
+ buffer = ('PyBuffer_Type', 'PyBufferObject*', 'O!'),
+ tuple = ('PyTuple_Type', 'PyTupleObject*', 'O!'),
+ list = ('PyList_Type', 'PyListObject*', 'O!'),
+ dict = ('PyDict_Type', 'PyDictObject*', 'O!'),
+ file = ('PyFile_Type', 'PyFileObject*', 'O!'),
+ instance = ('PyInstance_Type', 'PyObject*', 'O!'),
+ function = ('PyFunction_Type', 'PyFunctionObject*', 'O!'),
+ method = ('PyMethod_Type', 'PyObject*', 'O!'),
+ module = ('PyModule_Type', 'PyObject*', 'O!'),
+ iter = ('PySeqIter_Type', 'PyObject*', 'O!'),
+ property = ('PyProperty_Type', 'PyObject*', 'O!'),
+ slice = ('PySlice_Type', 'PyObject*', 'O!'),
+ cell = ('PyCell_Type', 'PyCellObject*', 'O!'),
+ generator = ('PyGen_Type', 'PyGenObject*', 'O!'),
+ set = ('PySet_Type', 'PySetObject*', 'O!'),
+ frozenset = ('PyFrozenSet_Type', 'PySetObject*', 'O!'),
+ cobject = (None, 'PyCObject*', 'O'),
+ type = ('PyType_Type', 'PyTypeObject*', 'O!'),
+ object = (None, 'PyObject*', 'O'),
+ numpy_ndarray = ('PyArray_Type', 'PyArrayObject*', 'O!'),
+ numpy_descr = ('PyArrayDescr_Type','PyArray_Descr', 'O!'),
+ numpy_ufunc = ('PyUFunc_Type', 'PyUFuncObject*', 'O!'),
+ numpy_iter = ('PyArrayIter_Type', 'PyArrayIterObject*', 'O!'),
+ numpy_multiiter = ('PyArrayMultiIter_Type', 'PyArrayMultiIterObject*', 'O!'),
+ numpy_int8 = ('PyInt8ArrType_Type', 'PyInt8ScalarObject*', 'O!'),
+ numpy_int16 = ('PyInt16ArrType_Type', 'PyInt16ScalarObject*', 'O!'),
+ numpy_int32 = ('PyInt32ArrType_Type', 'PyInt32ScalarObject*', 'O!'),
+ numpy_int64 = ('PyInt64ArrType_Type', 'PyInt64ScalarObject*', 'O!'),
+ numpy_int128 = ('PyInt128ArrType_Type', 'PyInt128ScalarObject*', 'O!'),
+ numpy_uint8 = ('PyUInt8ArrType_Type', 'PyUInt8ScalarObject*', 'O!'),
+ numpy_uint16 = ('PyUInt16ArrType_Type', 'PyUInt16ScalarObject*', 'O!'),
+ numpy_uint32 = ('PyUInt32ArrType_Type', 'PyUInt32ScalarObject*', 'O!'),
+ numpy_uint64 = ('PyUInt64ArrType_Type', 'PyUInt64ScalarObject*', 'O!'),
+ numpy_uint128 = ('PyUInt128ArrType_Type', 'PyUInt128ScalarObject*', 'O!'),
+ numpy_float16 = ('PyFloat16ArrType_Type', 'PyFloat16ScalarObject*', 'O!'),
+ numpy_float32 = ('PyFloat32ArrType_Type', 'PyFloat32ScalarObject*', 'O!'),
+ numpy_float64 = ('PyFloat64ArrType_Type', 'PyFloat64ScalarObject*', 'O!'),
+ numpy_float80 = ('PyFloat80ArrType_Type', 'PyFloat80ScalarObject*', 'O!'),
+ numpy_float96 = ('PyFloat96ArrType_Type', 'PyFloat96ScalarObject*', 'O!'),
+ numpy_float128 = ('PyFloat128ArrType_Type', 'PyFloat128ScalarObject*', 'O!'),
+ numpy_complex32 = ('PyComplex32ArrType_Type', 'PyComplex32ScalarObject*', 'O!'),
+ numpy_complex64 = ('PyComplex64ArrType_Type', 'PyComplex64ScalarObject*', 'O!'),
+ numpy_complex128 = ('PyComplex128ArrType_Type', 'PyComplex128ScalarObject*', 'O!'),
+ numpy_complex160 = ('PyComplex160ArrType_Type', 'PyComplex160ScalarObject*', 'O!'),
+ numpy_complex192 = ('PyComplex192ArrType_Type', 'PyComplex192ScalarObject*', 'O!'),
+ numpy_complex256 = ('PyComplex256ArrType_Type', 'PyComplex256ScalarObject*', 'O!'),
+ numeric_array = ('PyArray_Type', 'PyArrayObject*', 'O!'),
+ c_int = (None, 'int', 'i')
+ )
- """
- @property
- def provides(self):
- return self.typeobj_name
def initialize(self, typeobj):
+ m = self.typeinfo_map
+
+ key = None
if isinstance(typeobj, type):
- self.typeobj_name = typeobj.__name__
+ if typeobj.__module__=='__builtin__':
+ key = typeobj.__name__
+ if key=='array':
+ key = 'numeric_array'
+ elif typeobj.__module__=='numpy':
+ key = 'numpy_' + typeobj.__name__
elif isinstance(typeobj, str):
- self.typeobj_name = typeobj
- else:
- raise ValueError('%s: unexpected input type %r' \
- % (self.__class__.__name__, type(typeobj)))
- self.ctypeobj = dict(int='PyInt_Type',
- long='PyLong_Type',
- float='PyFloat_Type',
- complex='PyComplex_Type',
- str='PyString_Type',
- unicode='PyUnicode_Type',
- buffer='PyBuffer_Type',
- tuple='PyTuple_Type',
- list='PyList_Type',
- dict='PyDict_Type',
- file='PyFile_Type',
- instance='PyInstance_Type',
- function='PyFunction_Type',
- method='PyMethod_Type',
- module='PyModule_Type',
- iter='PySeqIter_Type',
- property='PyProperty_Type',
- slice='PySlice_Type',
- cell='PyCell_Type',
- generator='PyGen_Type',
- set='PySet_Type',
- frozenset='PyFrozenSet_Type',
- type='PyType_Type',
- ).get(self.typeobj_name)
- pyctypes = dict(int='PyIntObject',
- long='PyLongObject',
- float='PyFloatObject',
- complex='PyComplexObject',
- str='PyStringObject',
- unicode='PyUnicodeObject',
- buffer='PyBufferObject',
- tuple='PyTupleObject',
- list='PyListObject',
- dict='PyDictObject',
- file='PyFileObject',
- instance='PyObject',
- function='PyFunctionObject',
- method='PyObject',
- module='PyObject',
- iter='PyObject',
- property='PyObject',
- slice='PyObject',
- cobject='PyCObject', # XXX: check key
- cell='PyCellObject',
- type='PyTypeObject',
- generator='PyGenObject',
- set='PySetObject',
- frozenset='PySetObject',
- object='PyObject',
- )
- try:
- self.name = pyctypes[self.typeobj_name] + '*'
+ key = typeobj
+ if key.startswith('numpy_'):
+ k = key[6:]
+ named_scalars = ['byte','short','int','long','longlong',
+ 'ubyte','ushort','uint','ulong','ulonglong',
+ 'intp','uintp',
+ 'float_','double',
+ 'longfloat','longdouble',
+ 'complex_',
+ ]
+ if k in named_scalars:
+ import numpy
+ key = 'numpy_' + getattr(numpy, k).__name__
+
+ try: item = m[key]
except KeyError:
raise NotImplementedError('%s: need %s support' % (self.__class__.__name__, typeobj))
+
+ self.typeobj_name = key
+ self.ctypeobj = item[0]
+ self.name = item[1]
+ self.pyarg_fmt = item[2]
+
+ if key.startswith('numpy_'):
+ self.add(Component.get('arrayobject.h'), 'Header')
+ self.add(Component.get('import_array'), 'ModuleInit')
+
+ if key.startswith('numeric_'):
+ raise NotImplementedError(self.__class__.__name__ + ': Numeric support')
return self
def set_titles(self, arg):
if self.typeobj_name == 'object':
tn = 'a python ' + self.typeobj_name
else:
- tn = 'a python ' + self.typeobj_name + ' object'
+ if self.typeobj_name.startswith('numpy_'):
+ tn = 'a numpy.' + self.typeobj_name[6:] + ' object'
+ else:
+ tn = 'a python ' + self.typeobj_name + ' object'
if arg.input_intent!='hide':
r = ''
if arg.input_title: r = ', ' + arg.input_title
@@ -338,22 +475,18 @@
arg += CDecl(self, '%s = NULL' % (arg.pycvar))
def get_pyarg_fmt(self, arg):
- return dict(object='O', str='S', unicode='U', cobject='O'
- ).get(self.typeobj_name, 'O!') # XXX: check cobject
+ if arg.input_intent=='hide': return None
+ return self.pyarg_fmt
def get_pyarg_obj(self, arg):
- if self.typeobj_name in ['object', 'str', 'unicode', 'cobject']: # XXX: check cobject
- return '&' + arg.pycvar
- return '&%s, &%s' % (self.ctypeobj, arg.pycvar)
-
- def get_pyret_fmt(self, arg):
- if arg.input_intent=='hide':
- return 'O'
- # return 'N' if arg is constructed inside PyCFunction
- return 'O'
- def get_pyret_obj(self, arg): return arg.pycvar
+ if arg.input_intent=='hide': return None
+ if self.pyarg_fmt=='O!':
+ return '&%s, &%s' % (self.ctypeobj, arg.pycvar)
+ return '&' + arg.pycvar
+
+
class CInt(CType):
name = provides = 'int'
def initialize(self): return self
Modified: trunk/numpy/f2py/lib/extgen/doc.txt
===================================================================
--- trunk/numpy/f2py/lib/extgen/doc.txt 2007-08-06 12:42:58 UTC (rev 3949)
+++ trunk/numpy/f2py/lib/extgen/doc.txt 2007-08-06 13:07:03 UTC (rev 3950)
@@ -266,7 +266,7 @@
- `CCode(*lines, provides=..)` --- represents any C code block or
statement component.
- - `CType(<name>)` --- represents a predefined or intrinsic C type
+ - `CType(<name or python type obj>)` --- represents a predefined or intrinsic C type
with a given name.
- `CTypeAlias(<name>, <ctype>)` --- represents `typedef ctype name;`
@@ -286,7 +286,7 @@
- `CDecl(<ctype>, *names)` --- represents `ctype name1, name2, ..;`
declaration. Use `.add()` method to add more names.
- -`CTypePython(<python type object or 'cell' or 'generator' or 'cobject'>)`
+ - `CTypePython(<python type object or 'cell' or 'generator' or 'cobject' or 'instance'>)`
--- represents python type object in C.
More information about the Numpy-svn
mailing list