py_support.py :  » Business-Application » PDB2PQR » pdb2pqr-1.6 » contrib » numpy-1.1.0 » numpy » f2py » lib » extgen » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Business Application » PDB2PQR 
PDB2PQR » pdb2pqr 1.6 » contrib » numpy 1.1.0 » numpy » f2py » lib » extgen » py_support.py

__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()
ww_w_.__j_a_v_a__2_s___.___c__o_m_ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.