diff options
author | Robert Kern <robert.kern@gmail.com> | 2008-07-03 19:57:24 +0000 |
---|---|---|
committer | Robert Kern <robert.kern@gmail.com> | 2008-07-03 19:57:24 +0000 |
commit | 484c100392601f4942ceecbedf32e6df0201d473 (patch) | |
tree | 5e5a58b30a39bd1b5481333ae4a4b9c34e466841 /numpy/f2py/lib/extgen/py_support.py | |
parent | 0c817a5d51c2c16db9df5c015ff846002d991d74 (diff) | |
download | numpy-484c100392601f4942ceecbedf32e6df0201d473.tar.gz |
Removing G3 f2py code. Development has moved to https://launchpad.net/f2py/
Diffstat (limited to 'numpy/f2py/lib/extgen/py_support.py')
-rw-r--r-- | numpy/f2py/lib/extgen/py_support.py | 1104 |
1 files changed, 0 insertions, 1104 deletions
diff --git a/numpy/f2py/lib/extgen/py_support.py b/numpy/f2py/lib/extgen/py_support.py deleted file mode 100644 index 9f0057133..000000000 --- a/numpy/f2py/lib/extgen/py_support.py +++ /dev/null @@ -1,1104 +0,0 @@ - -__all__ = ['PySource', 'PyCFunction', 'PyCModule', 'PyCTypeSpec', 'PyCArgument', 'PyCReturn'] - -import os -import sys -from base import Component -from utils import * -from c_support import * - -class PySource(FileSource): - - template_py_header = '''\ -#!/usr/bin/env python -# This file %(path)r is generated using ExtGen tool -# from NumPy version %(numpy_version)s. -# ExtGen is developed by Pearu Peterson <pearu.peterson@gmail.com>. -# For more information see http://www.scipy.org/ExtGen/ .''' - - container_options = dict( - Content = dict(default='', - prefix = template_py_header + '\n', - suffix = '\n', - use_indent=True) - ) - - pass - -class PyCModule(CSource): - - """ - >>> m = PyCModule('PyCModule_test', title='This is first line.\\nSecond line.', description='This is a module.\\nYes, it is.') - >>> mod = m.build() - >>> print mod.__doc__ #doctest: +ELLIPSIS - This module 'PyCModule_test' is generated with ExtGen from NumPy version ... - <BLANKLINE> - This is first line. - Second line. - <BLANKLINE> - This is a module. - Yes, it is. - """ - - template = CSource.template_c_header + ''' -#ifdef __cplusplus -extern \"C\" { -#endif -#include "Python.h" -%(CHeader)s -%(CTypeDef)s -%(CProto)s -%(CDefinition)s -%(CAPIDefinition)s -%(CDeclaration)s -%(PyCModuleCDeclaration)s -%(CMainProgram)s -#ifdef __cplusplus -} -#endif -''' - - container_options = CSource.container_options.copy() - container_options.update(CAPIDefinition=container_options['CDefinition'], - PyCModuleCDeclaration=dict(default='<KILLLINE>', - ignore_empty_content=True), - ) - - component_container_map = dict( - PyCModuleInitFunction = 'CMainProgram', - PyCModuleCDeclaration = 'PyCModuleCDeclaration', - PyCFunction = 'CAPIDefinition', - ) - - def initialize(self, pyname, *components, **options): - self.pyname = pyname - self.title = options.pop('title', None) - self.description = options.pop('description', None) - - self = CSource.initialize(self, '%smodule.c' % (pyname), **options) - self.need_numpy_support = False - - self.cdecl = PyCModuleCDeclaration(pyname) - self += self.cdecl - - self.main = PyCModuleInitFunction(pyname) - self += self.main - map(self.add, components) - return self - - def update_parent(self, parent): - if isinstance(parent, Component.SetupPy): - self.update_SetupPy(parent) - - def update_SetupPy(self, parent): - parent.setup_py += self.evaluate(' config.add_extension(%(pyname)r, sources = ["%(extmodulesrc)s"])', - extmodulesrc = self.path) - parent.init_py += 'import %s' % (self.pyname) - - def finalize(self): - if self.need_numpy_support: - self.add(CCode(''' -#define PY_ARRAY_UNIQUE_SYMBOL PyArray_API -#include "numpy/arrayobject.h" -#include "numpy/arrayscalars.h" -'''), 'CHeader') - self.main.add(CCode(''' -import_array(); -if (PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "failed to load NumPy array module."); - goto capi_error; -} -'''),'CBody') - CSource.finalize(self) - - def build(self, build_dir=None, clean_at_exit=None): - """ build(build_dir=None, clean_at_exit=None) - - A convenience function to build, import, an return - an extension module object. - """ - if build_dir is None: - import tempfile - import time - packagename = 'extgen_' + str(hex(int(time.time()*10000000)))[2:] - build_dir = os.path.join(tempfile.gettempdir(), packagename) - clean_at_exit = True - - setup = Component.SetupPy(build_dir) - setup += self - s,o = setup.execute('build_ext','--inplace') - if s: - self.info('return status=%s' % (s)) - self.info(o) - raise RuntimeError('failed to build extension module %r,'\ - ' the build is located in %r directory'\ - % (self.pyname, build_dir)) - - if clean_at_exit: - import atexit - import shutil - atexit.register(lambda d=build_dir: shutil.rmtree(d)) - self.info('directory %r will be removed at exit from python.' % (build_dir)) - - sys.path.insert(0, os.path.dirname(build_dir)) - packagename = os.path.basename(build_dir) - try: - p = __import__(packagename) - m = getattr(p, self.pyname) - except: - del sys.path[0] - raise - else: - del sys.path[0] - return m - -class PyCModuleCDeclaration(Component): - - template = '''\ -static PyObject* extgen_module; -static -PyMethodDef extgen_module_methods[] = { - %(PyMethodDef)s - {NULL,NULL,0,NULL} -}; -static -char extgen_module_doc[] = -"This module %(pyname)r is generated with ExtGen from NumPy version %(numpy_version)s." -%(Title)s -%(Description)s -%(FunctionSignature)s -;''' - container_options = dict( - PyMethodDef = dict(suffix=',', skip_suffix_when_empty=True,separator=',\n', - default='<KILLLINE>', use_indent=True, ignore_empty_content=True), - FunctionSignature = dict(prefix='"\\n\\n:Functions:\\n"\n" ', skip_prefix_when_empty=True, use_indent=True, - ignore_empty_content=True, default='<KILLLINE>', - separator = '"\n" ', suffix='"', skip_suffix_when_empty=True, - ), - Title = dict(default='<KILLLINE>',prefix='"\\n\\n',suffix='"',separator='\\n"\n"', - skip_prefix_when_empty=True, skip_suffix_when_empty=True, - use_firstline_indent=True, replace_map={'\n':'\\n'}), - Description = dict(default='<KILLLINE>',prefix='"\\n\\n"\n"', - suffix='"',separator='\\n"\n"', - skip_prefix_when_empty=True, skip_suffix_when_empty=True, - use_firstline_indent=True, replace_map={'\n':'\\n'}), - ) - - default_component_class_name = 'Line' - - def initialize(self, pyname): - self.pyname = pyname - return self - - def update_parent(self, parent): - if isinstance(parent, PyCModule): - self.update_PyCModule(parent) - - def update_PyCModule(self, parent): - if parent.title: - self.add(parent.title, 'Title') - if parent.description: - self.add(parent.description, 'Description') - - -class PyCModuleInitFunction(CFunction): - - """ - >>> f = PyCModuleInitFunction('test_PyCModuleInitFunction') - >>> print f.generate() - PyMODINIT_FUNC - inittest_PyCModuleInitFunction(void) { - PyObject* extgen_module_dict = NULL; - PyObject* extgen_str_obj = NULL; - extgen_module = Py_InitModule(\"test_PyCModuleInitFunction\", extgen_module_methods); - if ((extgen_module_dict = PyModule_GetDict(extgen_module))==NULL) goto capi_error; - if ((extgen_str_obj = PyString_FromString(extgen_module_doc))==NULL) goto capi_error; - PyDict_SetItemString(extgen_module_dict, \"__doc__\", extgen_str_obj); - Py_DECREF(extgen_str_obj); - if ((extgen_str_obj = PyString_FromString(\"restructuredtext\"))==NULL) goto capi_error; - PyDict_SetItemString(extgen_module_dict, \"__docformat__\", extgen_str_obj); - Py_DECREF(extgen_str_obj); - return; - capi_error: - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_RuntimeError, \"failed to initialize 'test_PyCModuleInitFunction' module.\"); - } - return; - } - """ - - template = '''\ -%(CSpecifier)s -%(CTypeSpec)s -%(name)s(void) { - PyObject* extgen_module_dict = NULL; - PyObject* extgen_str_obj = NULL; - %(CDeclaration)s - extgen_module = Py_InitModule("%(pyname)s", extgen_module_methods); - if ((extgen_module_dict = PyModule_GetDict(extgen_module))==NULL) goto capi_error; - if ((extgen_str_obj = PyString_FromString(extgen_module_doc))==NULL) goto capi_error; - PyDict_SetItemString(extgen_module_dict, "__doc__", extgen_str_obj); - Py_DECREF(extgen_str_obj); - if ((extgen_str_obj = PyString_FromString("restructuredtext"))==NULL) goto capi_error; - PyDict_SetItemString(extgen_module_dict, "__docformat__", extgen_str_obj); - Py_DECREF(extgen_str_obj); - %(CBody)s - return; -capi_error: - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_RuntimeError, "failed to initialize %(pyname)r module."); - } - return; -}''' - - def initialize(self, pyname, *components, **options): - self.pyname = pyname - self.title = options.pop('title', None) - self.description = options.pop('description', None) - self = CFunction.initialize(self, 'init'+pyname, 'PyMODINIT_FUNC', *components, **options) - return self - -#helper classes for PyCFunction -class KWListBase(Word): parent_container_options = dict(separator=', ', suffix=', ', skip_suffix_when_empty=True) -class ReqKWList(KWListBase): pass -class OptKWList(KWListBase): pass -class ExtKWList(KWListBase): pass -class ArgBase(Word): parent_container_options = dict(separator=', ') -class ReqArg(ArgBase): pass -class OptArg(ArgBase): pass -class ExtArg(ArgBase): pass -class RetArg(ArgBase): - parent_container_options = dict(separator=', ', prefix='(', suffix=')', default = 'None', - skip_prefix_when_empty=True, skip_suffix_when_empty=True, - skip_prefix_suffix_when_single=True) -class OptExtArg(ArgBase): - parent_container_options = dict(separator=', ', prefix=' [, ', skip_prefix_when_empty=True, - suffix=']', skip_suffix_when_empty=True) -class ArgDocBase(Word): - parent_container_options = dict(default='<KILLLINE>', prefix='"\\n\\nArguments:\\n"\n" ', - separator='\\n"\n" ', suffix='"', - skip_prefix_when_empty=True, skip_suffix_when_empty=True, - use_firstline_indent=True, replace_map={'\n':'\\n'}) -class ReqArgDoc(ArgDocBase): - parent_container_options = ArgDocBase.parent_container_options.copy() - parent_container_options.update(prefix='"\\n\\n:Parameters:\\n"\n" ') -class OptArgDoc(ArgDocBase): - parent_container_options = ArgDocBase.parent_container_options.copy() - parent_container_options.update(prefix='"\\n\\n:Optional parameters:\\n"\n" ') -class ExtArgDoc(ArgDocBase): - parent_container_options = ArgDocBase.parent_container_options.copy() - parent_container_options.update(prefix='"\\n\\n:Extra parameters:\\n"\n" ') -class RetArgDoc(ArgDocBase): - parent_container_options = ArgDocBase.parent_container_options.copy() - parent_container_options.update(prefix='"\\n\\n:Returns:\\n"\n" ', - default='"\\n\\n:Returns:\\n None"') -class ArgFmtBase(Word): parent_container_options = dict(separator='') -class ReqArgFmt(ArgFmtBase): pass -class OptArgFmt(ArgFmtBase): pass -class ExtArgFmt(ArgFmtBase): pass -class RetArgFmt(ArgFmtBase): pass -class OptExtArgFmt(ArgFmtBase): - parent_container_options = dict(separator='', prefix='|', skip_prefix_when_empty=True) -class ArgObjBase(Word): parent_container_options = dict(separator=', ', prefix=', ', skip_prefix_when_empty=True) -class ReqArgObj(ArgObjBase): pass -class OptArgObj(ArgObjBase): pass -class ExtArgObj(ArgObjBase): pass -class RetArgObj(ArgObjBase): pass - -class FunctionSignature(Component): - template = '%(name)s(%(ReqArg)s%(OptExtArg)s) -> %(RetArg)s' - parent_container_options = dict() - container_options = dict( - ReqArg = ReqArg.parent_container_options, - OptArg = OptArg.parent_container_options, - ExtArg = ExtArg.parent_container_options, - RetArg = RetArg.parent_container_options, - OptExtArg = OptExtArg.parent_container_options, - ) - def initialize(self, name, *components, **options): - self.name = name - map(self.add, components) - return self - def update_containers(self): - self.container_OptExtArg += self.container_OptArg + self.container_ExtArg - -class PyCFunction(CFunction): - - """ - >>> from __init__ import * - >>> f = PyCFunction('foo') - >>> print f.generate() - static - char pyc_function_foo_doc[] = - \" foo() -> None\" - \"\\n\\n:Returns:\\n None\" - ; - static - PyObject* - pyc_function_foo(PyObject *pyc_self, PyObject *pyc_args, PyObject *pyc_keywds) { - PyObject * volatile pyc_buildvalue = NULL; - volatile int capi_success = 1; - static char *capi_kwlist[] = {NULL}; - if (PyArg_ParseTupleAndKeywords(pyc_args, pyc_keywds,"", - capi_kwlist)) { - capi_success = !PyErr_Occurred(); - if (capi_success) { - pyc_buildvalue = Py_BuildValue(""); - } - } - return pyc_buildvalue; - } - >>> f = PyCFunction('foo', title=' Function title.\\nSecond line.', description=' This is a function.\\n2nd line.') - >>> e = PyCModule('PyCFunction_test', f) - >>> mod = e.build() - >>> print mod.foo.__doc__ - foo() -> None - <BLANKLINE> - Function title. - Second line. - <BLANKLINE> - This is a function. - 2nd line. - <BLANKLINE> - :Returns: - None - """ - - template = '''\ -static -char %(name)s_doc[] = -" %(FunctionSignature)s" -%(Title)s -%(Description)s -%(ReqArgDoc)s -%(RetArgDoc)s -%(OptArgDoc)s -%(ExtArgDoc)s -; -static -PyObject* -%(name)s(PyObject *pyc_self, PyObject *pyc_args, PyObject *pyc_keywds) { - PyObject * volatile pyc_buildvalue = NULL; - volatile int capi_success = 1; - %(CDeclaration)s - static char *capi_kwlist[] = {%(ReqKWList)s%(OptKWList)s%(ExtKWList)sNULL}; - if (PyArg_ParseTupleAndKeywords(pyc_args, pyc_keywds,"%(ReqArgFmt)s%(OptExtArgFmt)s", - capi_kwlist%(ReqArgObj)s%(OptArgObj)s%(ExtArgObj)s)) { - %(FromPyObj)s - %(CBody)s - capi_success = !PyErr_Occurred(); - if (capi_success) { - %(PyObjFrom)s - pyc_buildvalue = Py_BuildValue("%(RetArgFmt)s"%(RetArgObj)s); - %(CleanPyObjFrom)s - } - %(CleanCBody)s - %(CleanFromPyObj)s - } - return pyc_buildvalue; -}''' - - container_options = CFunction.container_options.copy() - - container_options.update(\ - - TMP = dict(), - - ReqArg = ReqArg.parent_container_options, - OptArg = OptArg.parent_container_options, - ExtArg = ExtArg.parent_container_options, - RetArg = RetArg.parent_container_options, - - FunctionSignature = FunctionSignature.parent_container_options, - - OptExtArg = OptExtArg.parent_container_options, - - Title = dict(default='<KILLLINE>',prefix='"\\n\\n',suffix='"',separator='\\n"\n"', - skip_prefix_when_empty=True, skip_suffix_when_empty=True, - use_firstline_indent=True, replace_map={'\n':'\\n'}), - Description = dict(default='<KILLLINE>',prefix='"\\n\\n"\n"', - suffix='"',separator='\\n"\n"', - skip_prefix_when_empty=True, skip_suffix_when_empty=True, - use_firstline_indent=True, replace_map={'\n':'\\n'}), - - ReqArgDoc = ReqArgDoc.parent_container_options, - OptArgDoc = OptArgDoc.parent_container_options, - ExtArgDoc = ExtArgDoc.parent_container_options, - RetArgDoc = RetArgDoc.parent_container_options, - - ReqKWList = ReqKWList.parent_container_options, - OptKWList = OptKWList.parent_container_options, - ExtKWList = ExtKWList.parent_container_options, - - ReqArgFmt = ReqArgFmt.parent_container_options, - OptArgFmt = OptArgFmt.parent_container_options, - ExtArgFmt = ExtArgFmt.parent_container_options, - OptExtArgFmt = OptExtArgFmt.ExtArgFmt.parent_container_options, - RetArgFmt = ExtArgFmt.parent_container_options, - - ReqArgObj = ReqArgObj.parent_container_options, - OptArgObj = OptArgObj.parent_container_options, - ExtArgObj = ExtArgObj.parent_container_options, - RetArgObj = RetArgObj.parent_container_options, - - FromPyObj = CCode.parent_container_options, - PyObjFrom = CCode.parent_container_options, - - CleanPyObjFrom = dict(default='<KILLLINE>', reverse=True, use_indent=True, ignore_empty_content=True), - CleanCBody = dict(default='<KILLLINE>', reverse=True, use_indent=True, ignore_empty_content=True), - CleanFromPyObj = dict(default='<KILLLINE>', reverse=True, use_indent=True, ignore_empty_content=True), - - ) - - default_component_class_name = 'CCode' - - component_container_map = CFunction.component_container_map.copy() - component_container_map.update( - PyCArgument = 'TMP', - CCode = 'CBody', - ) - - def initialize(self, pyname, *components, **options): - self.pyname = pyname - self.title = options.pop('title', None) - self.description = options.pop('description', None) - self = CFunction.initialize(self, 'pyc_function_'+pyname, 'PyObject*', **options) - self.signature = FunctionSignature(pyname) - self += self.signature - if self.title: - self.add(self.title, 'Title') - if self.description: - self.add(self.description, 'Description') - map(self.add, components) - return self - - def __repr__(self): - return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,[self.pyname]+[c for (c,l) in self.components]))) - - def update_parent(self, parent): - if isinstance(parent, PyCModule): - self.update_PyCModule(parent) - - def update_PyCModule(self, parent): - t = ' {"%(pyname)s", (PyCFunction)%(name)s, METH_VARARGS | METH_KEYWORDS, %(name)s_doc}' - parent.cdecl.add(self.evaluate(t),'PyMethodDef') - parent.cdecl.add(self.signature,'FunctionSignature') - - def update_containers(self): - self.container_OptExtArg += self.container_OptArg + self.container_ExtArg - self.container_OptExtArgFmt += self.container_OptArgFmt + self.container_ExtArgFmt - - # resolve dependencies - sorted_arguments = [] - sorted_names = [] - comp_map = {} - dep_map = {} - for (c,l) in self.components: - if not isinstance(c, Component.PyCArgument): - continue - d = [n for n in c.depends if n not in sorted_names] - if not d: - sorted_arguments.append((c,l)) - sorted_names.append(c.name) - else: - comp_map[c.name] = (c,l) - dep_map[c.name] = d - - while dep_map: - dep_map_copy = dep_map.copy() - for name, deps in dep_map.items(): - d = [n for n in deps if n in dep_map] - if not d: - sorted_arguments.append(comp_map[name]) - del dep_map[name] - else: - dep_map[name] = d - if dep_map_copy==dep_map: - self.warnign('%s: detected cyclic dependencies in %r, incorrect behavior is expected.\n'\ - % (self.provides, dep_map)) - sorted_arguments += dep_map.values() - break - - for c, l in sorted_arguments: - old_parent = c.parent - c.parent = self - c.ctype.set_converters(c) - c.parent = old_parent - - -class PyCArgument(Component): - - """ - >>> from __init__ import * - >>> a = PyCArgument('a') - >>> print a - PyCArgument('a', PyCTypeSpec('object')) - >>> print a.generate() - a - >>> f = PyCFunction('foo') - >>> f += a - >>> f += PyCArgument('b') - >>> m = PyCModule('PyCArgument_test') - >>> m += f - >>> #print m.generate() - >>> mod = m.build() - >>> print mod.__doc__ #doctest: +ELLIPSIS - This module 'PyCArgument_test' is generated with ExtGen from NumPy version ... - <BLANKLINE> - :Functions: - foo(a, b) -> None - - """ - - container_options = dict( - TMP = dict() - ) - - component_container_map = dict( - PyCTypeSpec = 'TMP' - ) - - template = '%(name)s' - - def initialize(self, name, ctype = object, *components, **options): - self.input_intent = options.pop('input_intent','required') # 'optional', 'extra', 'hide' - self.output_intent = options.pop('output_intent','hide') # 'return' - self.input_title = options.pop('input_title', None) - self.output_title = options.pop('output_title', None) - self.input_description = options.pop('input_description', None) - self.output_description = options.pop('output_description', None) - self.depends = options.pop('depends', []) - title = options.pop('title', None) - description = options.pop('description', None) - if title is not None: - if self.input_intent!='hide': - if self.input_title is None: - self.input_title = title - elif self.output_intent!='hide': - if self.output_title is None: - self.output_title = title - if description is not None: - if self.input_intent!='hide': - if self.input_description is None: - self.input_description = description - elif self.output_intent!='hide': - if self.output_description is None: - self.output_description = description - if options: self.warning('%s unused options: %s\n' % (self.__class__.__name__, options)) - - self.name = name - self.ctype = ctype = PyCTypeSpec(ctype) - self += ctype - - self.cvar = name - self.pycvar = None - self.retpycvar = None - - retfmt = ctype.get_pyret_fmt(self) - if isinstance(ctype, PyCTypeSpec): - if retfmt and retfmt in 'SON': - if self.output_intent == 'return': - if self.input_intent=='hide': - self.retpycvar = name - else: - self.pycvar = name - self.retpycvar = name + '_return' - elif self.input_intent!='hide': - self.pycvar = name - else: - self.pycvar = name - self.retpycvar = name - else: - self.pycvar = name + '_pyc' - self.retpycvar = name + '_pyc_r' - - ctype.set_titles(self) - - map(self.add, components) - return self - - def __repr__(self): - return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,[self.name]+[c for (c,l) in self.components]))) - - def update_parent(self, parent): - if isinstance(parent, PyCFunction): - self.update_PyCFunction(parent) - - def update_PyCFunction(self, parent): - ctype = self.ctype - - input_doc_title = '%s : %s' % (self.name, self.input_title) - output_doc_title = '%s : %s' % (self.name, self.output_title) - if self.input_description is not None: - input_doc_descr = ' %s' % (self.input_description) - else: - input_doc_descr = None - if self.output_description is not None: - output_doc_descr = ' %s' % (self.output_description) - else: - output_doc_descr = None - - # add components to parent: - parent += ctype.get_decl(self, parent) - if self.input_intent=='required': - parent += ReqArg(self.name) - parent.signature += ReqArg(self.name) - parent += ReqKWList('"' + self.name + '"') - parent += ReqArgFmt(ctype.get_pyarg_fmt(self)) - parent += ReqArgObj(ctype.get_pyarg_obj(self)) - parent += ReqArgDoc(input_doc_title) - parent += ReqArgDoc(input_doc_descr) - elif self.input_intent=='optional': - parent += OptArg(self.name) - parent.signature += OptArg(self.name) - parent += OptKWList('"' + self.name + '"') - parent += OptArgFmt(ctype.get_pyarg_fmt(self)) - parent += OptArgObj(ctype.get_pyarg_obj(self)) - parent += OptArgDoc(input_doc_title) - parent += OptArgDoc(input_doc_descr) - elif self.input_intent=='extra': - parent += ExtArg(self.name) - parent.signature += ExtArg(self.name) - parent += ExtKWList('"' + self.name + '"') - parent += ExtArgFmt(ctype.get_pyarg_fmt(self)) - parent += ExtArgObj(ctype.get_pyarg_obj(self)) - parent += ExtArgDoc(input_doc_title) - parent += ExtArgDoc(input_doc_descr) - elif self.input_intent=='hide': - pass - else: - raise NotImplementedError('input_intent=%r' % (self.input_intent)) - - if self.output_intent=='return': - parent += RetArg(self.name) - parent.signature += RetArg(self.name) - parent += RetArgFmt(ctype.get_pyret_fmt(self)) - parent += RetArgObj(ctype.get_pyret_obj(self)) - parent += RetArgDoc(output_doc_title) - parent += RetArgDoc(output_doc_descr) - elif self.output_intent=='hide': - pass - else: - raise NotImplementedError('output_intent=%r' % (self.output_intent)) - -class PyCReturn(PyCArgument): - - def initialize(self, name, ctype = object, *components, **options): - return PyCArgument(name, ctype, input_intent='hide', output_intent='return', *components, **options) - -class PyCTypeSpec(CTypeSpec): - - """ - >>> s = PyCTypeSpec(object) - >>> print s - PyCTypeSpec('object') - >>> print s.generate() - PyObject* - - >>> from __init__ import * - >>> m = PyCModule('test_PyCTypeSpec') - >>> f = PyCFunction('func') - >>> f += PyCArgument('i', int, output_intent='return') - >>> f += PyCArgument('l', long, output_intent='return') - >>> f += PyCArgument('f', float, output_intent='return') - >>> f += PyCArgument('c', complex, output_intent='return') - >>> f += PyCArgument('s', str, output_intent='return') - >>> f += PyCArgument('u', unicode, output_intent='return') - >>> f += PyCArgument('t', tuple, output_intent='return') - >>> f += PyCArgument('lst', list, output_intent='return') - >>> f += PyCArgument('d', dict, output_intent='return') - >>> f += PyCArgument('set', set, output_intent='return') - >>> f += PyCArgument('o1', object, output_intent='return') - >>> f += PyCArgument('o2', object, output_intent='return') - >>> m += f - >>> b = m.build() #doctest: +ELLIPSIS - >>> 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__ - 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> - :Parameters: - 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> - :Returns: - 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 - - >>> m = PyCModule('test_PyCTypeSpec_c') - >>> f = PyCFunction('func_c_int') - >>> f += PyCArgument('i1', 'c_char', output_intent='return') - >>> f += PyCArgument('i2', 'c_short', output_intent='return') - >>> f += PyCArgument('i3', 'c_int', output_intent='return') - >>> f += PyCArgument('i4', 'c_long', output_intent='return') - >>> f += PyCArgument('i5', 'c_long_long', output_intent='return') - >>> m += f - >>> f = PyCFunction('func_c_unsigned_int') - >>> f += PyCArgument('i1', 'c_unsigned_char', output_intent='return') - >>> f += PyCArgument('i2', 'c_unsigned_short', output_intent='return') - >>> f += PyCArgument('i3', 'c_unsigned_int', output_intent='return') - >>> f += PyCArgument('i4', 'c_unsigned_long', output_intent='return') - >>> f += PyCArgument('i5', 'c_unsigned_long_long', output_intent='return') - >>> m += f - >>> f = PyCFunction('func_c_float') - >>> f += PyCArgument('f1', 'c_float', output_intent='return') - >>> f += PyCArgument('f2', 'c_double', output_intent='return') - >>> m += f - >>> f = PyCFunction('func_c_complex') - >>> f += PyCArgument('c1', 'c_Py_complex', output_intent='return') - >>> m += f - >>> f = PyCFunction('func_c_string') - >>> f += PyCArgument('s1', 'c_const_char_ptr', output_intent='return') - >>> f += PyCArgument('s2', 'c_const_char_ptr', output_intent='return') - >>> f += PyCArgument('s3', 'c_Py_UNICODE', output_intent='return') - >>> f += PyCArgument('s4', 'c_char1', output_intent='return') - >>> m += f - >>> b = m.build() - >>> b.func_c_int(2,3,4,5,6) - (2, 3, 4, 5, 6L) - >>> b.func_c_unsigned_int(-1,-1,-1,-1,-1) - (255, 65535, 4294967295, 18446744073709551615L, 18446744073709551615L) - >>> b.func_c_float(1.2,1.2) - (1.2000000476837158, 1.2) - >>> b.func_c_complex(1+2j) - (1+2j) - >>> b.func_c_string('hei', None, u'tere', 'b') - ('hei', None, u'tere', 'b') - - >>> import numpy - >>> m = PyCModule('test_PyCTypeSpec_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 - >>> b = m.build() - >>> 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 - """ - - typeinfo_map = dict( - int = ('PyInt_Type', 'PyIntObject*', 'O!', 'N', 'NULL'), - long = ('PyLong_Type', 'PyLongObject*', 'O!', 'N', 'NULL'), - float = ('PyFloat_Type', 'PyFloatObject*', 'O!', 'N', 'NULL'), - complex = ('PyComplex_Type', 'PyComplexObject*', 'O!', 'N', 'NULL'), - str = ('PyString_Type', 'PyStringObject*', 'S', 'N', 'NULL'), - unicode = ('PyUnicode_Type', 'PyUnicodeObject*', 'U', 'N', 'NULL'), - buffer = ('PyBuffer_Type', 'PyBufferObject*', 'O!', 'N', 'NULL'), - tuple = ('PyTuple_Type', 'PyTupleObject*', 'O!', 'N', 'NULL'), - list = ('PyList_Type', 'PyListObject*', 'O!', 'N', 'NULL'), - dict = ('PyDict_Type', 'PyDictObject*', 'O!', 'N', 'NULL'), - file = ('PyFile_Type', 'PyFileObject*', 'O!', 'N', 'NULL'), - instance = ('PyInstance_Type', 'PyObject*', 'O!', 'N', 'NULL'), - function = ('PyFunction_Type', 'PyFunctionObject*', 'O!', 'N', 'NULL'), - method = ('PyMethod_Type', 'PyObject*', 'O!', 'N', 'NULL'), - module = ('PyModule_Type', 'PyObject*', 'O!', 'N', 'NULL'), - iter = ('PySeqIter_Type', 'PyObject*', 'O!', 'N', 'NULL'), - property = ('PyProperty_Type', 'PyObject*', 'O!', 'N', 'NULL'), - slice = ('PySlice_Type', 'PyObject*', 'O!', 'N', 'NULL'), - cell = ('PyCell_Type', 'PyCellObject*', 'O!', 'N', 'NULL'), - generator = ('PyGen_Type', 'PyGenObject*', 'O!', 'N', 'NULL'), - set = ('PySet_Type', 'PySetObject*', 'O!', 'N', 'NULL'), - frozenset = ('PyFrozenSet_Type', 'PySetObject*', 'O!', 'N', 'NULL'), - cobject = (None, 'PyCObject*', 'O', 'N', 'NULL'), - type = ('PyType_Type', 'PyTypeObject*', 'O!', 'N', 'NULL'), - object = (None, 'PyObject*', 'O', 'N', 'NULL'), - numpy_ndarray = ('PyArray_Type', 'PyArrayObject*', 'O!', 'N', 'NULL'), - numpy_descr = ('PyArrayDescr_Type','PyArray_Descr', 'O!', 'N', 'NULL'), - numpy_ufunc = ('PyUFunc_Type', 'PyUFuncObject*', 'O!', 'N', 'NULL'), - numpy_iter = ('PyArrayIter_Type', 'PyArrayIterObject*', 'O!', 'N', 'NULL'), - numpy_multiiter = ('PyArrayMultiIter_Type', 'PyArrayMultiIterObject*', 'O!', 'N', 'NULL'), - numpy_int8 = ('PyInt8ArrType_Type', 'PyInt8ScalarObject*', 'O!', 'N', 'NULL'), - numpy_int16 = ('PyInt16ArrType_Type', 'PyInt16ScalarObject*', 'O!', 'N', 'NULL'), - numpy_int32 = ('PyInt32ArrType_Type', 'PyInt32ScalarObject*', 'O!', 'N', 'NULL'), - numpy_int64 = ('PyInt64ArrType_Type', 'PyInt64ScalarObject*', 'O!', 'N', 'NULL'), - numpy_int128 = ('PyInt128ArrType_Type', 'PyInt128ScalarObject*', 'O!', 'N', 'NULL'), - numpy_uint8 = ('PyUInt8ArrType_Type', 'PyUInt8ScalarObject*', 'O!', 'N', 'NULL'), - numpy_uint16 = ('PyUInt16ArrType_Type', 'PyUInt16ScalarObject*', 'O!', 'N', 'NULL'), - numpy_uint32 = ('PyUInt32ArrType_Type', 'PyUInt32ScalarObject*', 'O!', 'N', 'NULL'), - numpy_uint64 = ('PyUInt64ArrType_Type', 'PyUInt64ScalarObject*', 'O!', 'N', 'NULL'), - numpy_uint128 = ('PyUInt128ArrType_Type', 'PyUInt128ScalarObject*', 'O!', 'N', 'NULL'), - numpy_float16 = ('PyFloat16ArrType_Type', 'PyFloat16ScalarObject*', 'O!', 'N', 'NULL'), - numpy_float32 = ('PyFloat32ArrType_Type', 'PyFloat32ScalarObject*', 'O!', 'N', 'NULL'), - numpy_float64 = ('PyFloat64ArrType_Type', 'PyFloat64ScalarObject*', 'O!', 'N', 'NULL'), - numpy_float80 = ('PyFloat80ArrType_Type', 'PyFloat80ScalarObject*', 'O!', 'N', 'NULL'), - numpy_float96 = ('PyFloat96ArrType_Type', 'PyFloat96ScalarObject*', 'O!', 'N', 'NULL'), - numpy_float128 = ('PyFloat128ArrType_Type', 'PyFloat128ScalarObject*', 'O!', 'N', 'NULL'), - numpy_complex32 = ('PyComplex32ArrType_Type', 'PyComplex32ScalarObject*', 'O!', 'N', 'NULL'), - numpy_complex64 = ('PyComplex64ArrType_Type', 'PyComplex64ScalarObject*', 'O!', 'N', 'NULL'), - numpy_complex128 = ('PyComplex128ArrType_Type', 'PyComplex128ScalarObject*', 'O!', 'N', 'NULL'), - numpy_complex160 = ('PyComplex160ArrType_Type', 'PyComplex160ScalarObject*', 'O!', 'N', 'NULL'), - numpy_complex192 = ('PyComplex192ArrType_Type', 'PyComplex192ScalarObject*', 'O!', 'N', 'NULL'), - numpy_complex256 = ('PyComplex256ArrType_Type', 'PyComplex256ScalarObject*', 'O!', 'N', 'NULL'), - numeric_array = ('PyArray_Type', 'PyArrayObject*', 'O!', 'N', 'NULL'), - c_char = (None, 'char', 'b', 'b', '0'), - c_unsigned_char = (None, 'unsigned char', 'B', 'B', '0'), - c_short = (None, 'short int', 'h', 'h', '0'), - c_unsigned_short = (None, 'unsigned short int', 'H', 'H', '0'), - c_int = (None,'int', 'i', 'i', '0'), - c_unsigned_int = (None,'unsigned int', 'I', 'I', '0'), - c_long = (None,'long', 'l', 'l', '0'), - c_unsigned_long = (None,'unsigned long', 'k', 'k', '0'), - c_long_long = (None,'PY_LONG_LONG', 'L', 'L', '0'), - c_unsigned_long_long = (None,'unsigned PY_LONG_LONG', 'K', 'K', '0'), - c_Py_ssize_t = (None,'Py_ssize_t', 'n', 'n', '0'), - c_char1 = (None,'char', 'c', 'c', '"\\0"'), - c_float = (None,'float', 'f', 'f', '0.0'), - c_double = (None,'double', 'd', 'd', '0.0'), - c_Py_complex = (None,'Py_complex', 'D', 'D', '{0.0, 0.0}'), - c_const_char_ptr = (None,'const char *', 'z', 'z', 'NULL'), - c_Py_UNICODE = (None,'Py_UNICODE*','u','u', 'NULL'), - ) - - def initialize(self, typeobj): - if isinstance(typeobj, self.__class__): - return typeobj - - m = self.typeinfo_map - - key = None - if isinstance(typeobj, type): - 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): - 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.line = item[1] - self.arg_fmt = item[2] - self.ret_fmt = item[3] - self.cinit_value = item[4] - - self.need_numpy_support = False - if key.startswith('numpy_'): - self.need_numpy_support = True - #self.add(Component.get('arrayobject.h'), 'CHeader') - #self.add(Component.get('import_array'), 'ModuleInit') - if key.startswith('numeric_'): - raise NotImplementedError(self.__class__.__name__ + ': Numeric support') - - return self - - def finalize(self): - if self.need_numpy_support: - self.component_PyCModule.need_numpy_support = True - - def __repr__(self): - return '%s(%s)' % (self.__class__.__name__, ', '.join([repr(self.typeobj_name)]+[repr(c) for (c,l) in self.components])) - - def get_pyarg_fmt(self, arg): - if arg.input_intent=='hide': return None - return self.arg_fmt - - def get_pyarg_obj(self, arg): - if arg.input_intent=='hide': return None - if self.arg_fmt=='O!': - return '&%s, &%s' % (self.ctypeobj, arg.pycvar) - return '&' + arg.pycvar - - def get_pyret_fmt(self, arg): - if arg.output_intent=='hide': return None - return self.ret_fmt - - def get_pyret_obj(self, arg): - if arg.output_intent=='return': - if self.get_pyret_fmt(arg)=='D': - return '&' + arg.retpycvar - return arg.retpycvar - return - - def get_init_value(self, arg): - return self.cinit_value - - def set_titles(self, arg): - if self.typeobj_name == 'object': - tn = 'a python ' + self.typeobj_name - else: - if self.typeobj_name.startswith('numpy_'): - tn = 'a numpy.' + self.typeobj_name[6:] + ' object' - elif self.typeobj_name.startswith('c_'): - n = self.typeobj_name[2:] - if not n.startswith('Py_'): - n = ' '.join(n.split('_')) - tn = 'a to C ' + n + ' convertable object' - else: - tn = 'a python ' + self.typeobj_name + ' object' - if arg.input_intent!='hide': - r = '' - if arg.input_title: r = ', ' + arg.input_title - arg.input_title = tn + r - if arg.output_intent!='hide': - r = '' - if arg.output_title: r = ', ' + arg.output_title - arg.output_title = tn + r - - def get_decl(self, arg, func): - init_value = self.get_init_value(arg) - if init_value: - init = ' = %s' % (init_value) - else: - init = '' - if arg.pycvar and arg.pycvar==arg.retpycvar: - func += CDeclaration(self, '%s%s' % (arg.pycvar, init)) - else: - if self.get_pyret_obj(arg) is None: - if self.get_pyret_obj(arg) is not None: - func += CDeclaration(self, '%s%s' % (arg.pycvar, init)) - elif self.get_pyarg_obj(arg) is not None: - func += CDeclaration(self, '%s%s' % (arg.pycvar, init)) - func += CDeclaration(self,'%s%s' % (arg.retpycvar, init)) - else: - func += CDeclaration(self, '%s%s' % (arg.retpycvar, init)) - return - - def set_converters(self, arg): - """ - Notes for user: - if arg is intent(optional, in, out) and not specified - as function argument then function may created but - it must then have *new reference* (ie use Py_INCREF - unless it is a new reference already). - """ - # this method is called from PyCFunction.update_containers(), - # note that self.parent is None put arg.parent is PyCFunction - # instance. - eval_a = arg.evaluate - FromPyObj = arg.container_FromPyObj - PyObjFrom = arg.container_PyObjFrom - - argfmt = self.get_pyarg_fmt(arg) - retfmt = self.get_pyret_fmt(arg) - if arg.output_intent=='return': - if arg.input_intent in ['optional', 'extra']: - if retfmt in 'SON': - FromPyObj += eval_a('''\ -if (!(%(pycvar)s==NULL)) { - /* make %(pycvar)r a new reference */ - %(retpycvar)s = %(pycvar)s; - Py_INCREF((PyObject*)%(retpycvar)s); -} -''') - PyObjFrom += eval_a('''\ -if (%(retpycvar)s==NULL) { - /* %(pycvar)r was not specified */ - if (%(pycvar)s==NULL) { - %(retpycvar)s = Py_None; - Py_INCREF((PyObject*)%(retpycvar)s); - } else { - %(retpycvar)s = %(pycvar)s; - /* %(pycvar)r must be a new reference or expect a core dump. */ - } -} elif (!(%(retpycvar)s == %(pycvar)s)) { - /* a new %(retpycvar)r was created, undoing %(pycvar)s new reference */ - Py_DECREF((PyObject*)%(pycvar)s); -} -''') - elif arg.input_intent=='hide': - if retfmt in 'SON': - PyObjFrom += eval_a('''\ -if (%(retpycvar)s==NULL) { - %(retpycvar)s = Py_None; - Py_INCREF((PyObject*)%(retpycvar)s); -} /* else %(retpycvar)r must be a new reference or expect a core dump. */ -''') - elif arg.input_intent=='required': - if retfmt in 'SON': - FromPyObj += eval_a('''\ -/* make %(pycvar)r a new reference */ -%(retpycvar)s = %(pycvar)s; -Py_INCREF((PyObject*)%(retpycvar)s); -''') - PyObjFrom += eval_a('''\ -if (!(%(retpycvar)s==%(pycvar)s)) { - /* a new %(retpycvar)r was created, undoing %(pycvar)r new reference */ - /* %(retpycvar)r must be a new reference or expect a core dump. */ - Py_DECREF((PyObject*)%(pycvar)s); -} -''') - - -def _test(): - import doctest - doctest.testmod() - -if __name__ == "__main__": - _test() |