, label=None)` method to add
+new code idioms to containers.
+
+The `.generate()` method will call `.init_containers()` method, the
+`.generate()` methods of components, and `.update_containers()` method
+to generate code idioms and save the results to the corresponding
+containers. Finally, it returns the results of applying
+`.evaluate()` method to templates which replaces the
+replacement names with code idioms from containers as well as string
+valued attributes of the given `Base` subclass instance. One can set
+attributes inside `.initilize()` method.
+
+Here follows a simplified version of `ExtensionModule.template`::
+
+ #include "Python.h"
+
+ %(Header)s
+ %(TypeDef)s
+ %(Extern)s
+ %(CCode)s
+ %(CAPICode)s
+ %(ObjDecl)s
+
+ static PyObject* extgen_module;
+
+ static PyMethodDef extgen_module_methods[] = {
+ %(ModuleMethod)s
+ {NULL,NULL,0,NULL}
+ };
+
+ PyMODINIT_FUNC init%(modulename)s(void) {
+ extgen_module = Py_InitModule("%(modulename)s", extgen_module_methods);
+ %(ModuleInit)s
+ return;
+ capi_error:
+ if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_RuntimeError, "failed to initialize %(modulename)s module.");
+ }
+ return;
+ }
+
+Here `Header`, `TypeDef`, etc are the labels of containers which will be replaced
+during evaluation of templates.
+
+Using `Container` class
+=======================
+
+`Container` class has the following optional arguments:
+
+ - `separator='\n'`
+ - `prefix=''`
+ - `suffix=''`
+ - `skip_prefix_when_empty=False`
+ - `skip_suffix_when_empty=False`
+ - `default=''`
+ - `reverse=False`
+ - `user_defined_str=None`
+
+that can be used to change the behaviour of `Container.__str__()`
+method. By default, `Container.__str__()` method returns
+`prefix+separator.join(.list)+suffix`.
+
+One can add items to `Container` instance using `.add(,
+label=None)` method. Here `label` should contain an unique value that
+represents the content of ``. If `label` is `None` then
+`label = time.time()` will be set.
+
+If one tries to add items with the same label to the container then
+the equality of the corresponding string values will be checked. If
+they are not equal then `ValueError` is raised, otherwise adding an
+item is ignored.
+
+
+Reference manual
+================
+
+ExtGen package defines the following extension module component classes:
+
+ - `ExtensionModule(, *components, numpy=False, provides=..)` ---
+ represents an extension module,
+
+ - `PyCFunction(, *components, provides=..)` ---
+ represents an extension function.
+
+ - `CCode(*lines, provides=..)` --- represents any C code block or statement.
+
Added: trunk/numpy/f2py/lib/extgen/extension_module.py
===================================================================
--- trunk/numpy/f2py/lib/extgen/extension_module.py 2007-08-02 19:26:40 UTC (rev 3939)
+++ trunk/numpy/f2py/lib/extgen/extension_module.py 2007-08-03 19:44:53 UTC (rev 3940)
@@ -0,0 +1,137 @@
+
+from base import Base
+
+class ExtensionModule(Base):
+
+ """
+ ExtensionModule(, *components, numpy=False, provides=..)
+
+ Hello example:
+
+ >>> # in general use:
+ >>> # from numpy.f2py.lib.extgen import *
+ >>> # instead of the following import statement
+ >>> from __init__ import * #doctest: +ELLIPSIS
+ Ignoring...
+ >>> f = PyCFunction('hello')
+ >>> f.add('printf("Hello!\\\\n");')
+ >>> f.add('printf("Bye!\\\\n");')
+ >>> m = ExtensionModule('foo', f)
+ >>> foo = m.build #doctest: +ELLIPSIS
+ exec_command...
+ >>> foo.hello()
+ >>> # you should now see Hello! printed to stdout stream.
+
+ """
+
+ container_options = dict(\
+ Header=dict(default=''),
+ TypeDef=dict(default=''),
+ Extern=dict(default=''),
+ CCode=dict(default=''),
+ CAPICode=dict(default=''),
+ ObjDecl=dict(default=''),
+ ModuleMethod=dict(suffix=',', skip_suffix_when_empty=True,
+ default='', use_indent=True),
+ ModuleInit=dict(default='', use_indent=True),
+ )
+
+ component_container_map = dict(PyCFunction = 'CAPICode')
+
+ template = '''\
+/* -*- c -*- */
+/* This Python C/API extension module "%(modulename)s" is generated
+ using extgen tool. extgen is part of numpy.f2py.lib package
+ developed by Pearu Peterson .
+*/
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+%(Header)s
+%(TypeDef)s
+%(Extern)s
+%(CCode)s
+%(CAPICode)s
+%(ObjDecl)s
+
+static PyObject* extgen_module;
+
+static PyMethodDef extgen_module_methods[] = {
+ %(ModuleMethod)s
+ {NULL,NULL,0,NULL}
+};
+
+PyMODINIT_FUNC init%(modulename)s(void) {
+ extgen_module = Py_InitModule("%(modulename)s", extgen_module_methods);
+ %(ModuleInit)s
+ return;
+capi_error:
+ if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_RuntimeError, "failed to initialize %(modulename)s module.");
+ }
+ return;
+}
+
+#ifdef __cplusplus
+}
+#endif
+'''
+
+ def initialize(self, modulename, *components, **options):
+ self.modulename = modulename
+ self._provides = options.get('provides',
+ '%s_%s' % (self.__class__.__name__, modulename))
+ # all Python extension modules require Python.h
+ self.add(Base.get('Python.h'), 'Header')
+ if options.get('numpy'):
+ self.add(Base.get('arrayobject.h'), 'Header')
+ self.add(Base.get('import_array'), 'ModuleInit')
+ map(self.add, components)
+ return
+
+ @property
+ def build(self):
+ import os
+ import sys
+ import subprocess
+ extfile = self.generate()
+ srcfile = os.path.abspath('%smodule.c' % (self.modulename))
+ f = open(srcfile, 'w')
+ f.write(extfile)
+ f.close()
+ modulename = self.modulename
+ setup_py = """
+def configuration(parent_package='', top_path = ''):
+ from numpy.distutils.misc_util import Configuration
+ config = Configuration('',parent_package,top_path)
+ config.add_extension('%(modulename)s',
+ sources = ['%(srcfile)s'])
+ return config
+if __name__ == '__main__':
+ from numpy.distutils.core import setup
+ setup(configuration=configuration)
+""" % (locals())
+ setupfile = os.path.abspath('setup_extgen.py')
+ f = open(setupfile, 'w')
+ f.write(setup_py)
+ f.close()
+ setup_args = ['build_ext','--build-lib','.']
+ setup_cmd = ' '.join([sys.executable,setupfile]+setup_args)
+ build_dir = '.'
+ from numpy.distutils.exec_command import exec_command
+ sts = exec_command(setup_cmd)
+ #p = subprocess.Popen(setup_cmd, cwd=build_dir, shell=True, stdout=subprocess.PIPE,stderr=subprocess.PIPE)
+ #sts = os.waitpid(p.pid, 0)
+ if sts[0]:
+ raise "Failed to build (status=%s)." % (`sts`)
+ exec 'import %s as m' % (modulename)
+ return m
+
+def _test():
+ import doctest
+ doctest.testmod()
+
+if __name__ == "__main__":
+ _test()
Added: trunk/numpy/f2py/lib/extgen/predefined_components.py
===================================================================
--- trunk/numpy/f2py/lib/extgen/predefined_components.py 2007-08-02 19:26:40 UTC (rev 3939)
+++ trunk/numpy/f2py/lib/extgen/predefined_components.py 2007-08-03 19:44:53 UTC (rev 3940)
@@ -0,0 +1,23 @@
+
+from base import Base
+from c_code import CCode
+
+Base.register(
+
+ CCode('#include "Python.h"', provides='Python.h'),
+
+ CCode('''\
+#define PY_ARRAY_UNIQUE_SYMBOL PyArray_API
+#include "numpy/arrayobject.h"
+#include "numpy/arrayscalars.h"
+''', provides='arrayobject.h'),
+
+ CCode('''\
+import_array();
+if (PyErr_Occurred()) {
+ PyErr_SetString(PyExc_ImportError, "failed to load array module.");
+ goto capi_error;
+}
+''', provides='import_array')
+
+ )
Added: trunk/numpy/f2py/lib/extgen/pyc_function.py
===================================================================
--- trunk/numpy/f2py/lib/extgen/pyc_function.py 2007-08-02 19:26:40 UTC (rev 3939)
+++ trunk/numpy/f2py/lib/extgen/pyc_function.py 2007-08-03 19:44:53 UTC (rev 3940)
@@ -0,0 +1,77 @@
+
+from base import Base
+
+class PyCFunction(Base):
+
+ """
+ PyCFunction(, *components, provides=..)
+
+ """
+
+ container_options = dict(FuncDoc=dict(separator='"\n"', prefix='"', suffix='"'),
+ Args = dict(),
+ Decl = dict(default='', use_indent=True),
+ KWList = dict(separator=', ', suffix=', ', skip_suffix_when_empty=True),
+ PyArgFormat = dict(separator=''),
+ PyArgObj = dict(separator=', ', prefix=', ', skip_prefix_when_empty=True),
+ FromPyObj = dict(default='', use_indent=True),
+ Exec = dict(default='', use_indent=True),
+ PyObjFrom = dict(default='', use_indent=True),
+ RetFormat = dict(separator=''),
+ RetObj = dict(separator=', ', prefix=', ', skip_prefix_when_empty=True),
+ CleanPyObjFrom = dict(default='', reverse=True, use_indent=True),
+ CleanExec = dict(default='', reverse=True, use_indent=True),
+ CleanFromPyObj = dict(default='', reverse=True, use_indent=True),
+ )
+
+ component_container_map = dict(CCode = 'Exec',
+ PyCArgument = 'Args')
+
+ template = '''
+static char %(pyc_name)s_doc[] = %(FuncDoc)s;
+
+static PyObject*
+%(pyc_name)s
+(PyObject *pyc_self, PyObject *pyc_args, PyObject *pyc_keywds) {
+ PyObject * volatile pyc_buildvalue = NULL;
+ volatile int capi_success = 1;
+ %(Decl)s
+ static char *capi_kwlist[] = {%(KWList)sNULL};
+ if (PyArg_ParseTupleAndKeywords(pyc_args, pyc_keywds,"%(PyArgFormat)s", capi_kwlist%(PyArgObj)s)) {
+ %(FromPyObj)s
+ %(Exec)s
+ capi_success = !PyErr_Occurred();
+ if (capi_success) {
+ %(PyObjFrom)s
+ pyc_buildvalue = Py_BuildValue("%(RetFormat)s"%(RetObj)s);
+ %(CleanPyObjFrom)s
+ }
+ %(CleanExec)s
+ %(CleanFromPyObj)s
+ }
+ return pyc_buildvalue;
+}
+'''
+
+ def initialize(self, name, *components, **options):
+ self.name = name
+ self.pyc_name = 'pyc_function_'+name
+ self._provides = options.get('provides',
+ '%s_%s' % (self.__class__.__name__, name))
+ map(self.add, components)
+
+ def init_containers(self):
+ # set header to FuncDoc, for example.
+ FuncDoc = self.get_container('FuncDoc')
+ FuncDoc.add(self.name)
+ return
+
+ def update_containers(self, params=None):
+ ModuleMethod = self.get_container('ModuleMethod')
+ t = '{"%(name)s", (PyCFunction)%(pyc_name)s,\n METH_VARARGS | METH_KEYWORDS, %(pyc_name)s_doc}'
+ ModuleMethod.add(self.evaluate(t), self.name)
+ return
+
+
+
+
From numpy-svn at scipy.org Fri Aug 3 17:21:20 2007
From: numpy-svn at scipy.org (numpy-svn at scipy.org)
Date: Fri, 3 Aug 2007 16:21:20 -0500 (CDT)
Subject: [Numpy-svn] r3941 - trunk/numpy/doc/swig
Message-ID: <20070803212120.4C9B739C063@new.scipy.org>
Author: wfspotz at sandia.gov
Date: 2007-08-03 16:21:10 -0500 (Fri, 03 Aug 2007)
New Revision: 3941
Modified:
trunk/numpy/doc/swig/numpy_swig.html
trunk/numpy/doc/swig/numpy_swig.pdf
trunk/numpy/doc/swig/numpy_swig.txt
Log:
In documentation, removed one of the reasons for not providing (out) typemaps, which turns out not to be true.
Modified: trunk/numpy/doc/swig/numpy_swig.html
===================================================================
--- trunk/numpy/doc/swig/numpy_swig.html 2007-08-03 19:44:53 UTC (rev 3940)
+++ trunk/numpy/doc/swig/numpy_swig.html 2007-08-03 21:21:10 UTC (rev 3941)
@@ -634,13 +634,9 @@
Output Arrays
The numpy.i interface file does not support typemaps for output
-arrays, for several reasons. First, C/C++ function return arguments
-do not have names, so signatures for %typemap(out) do not include
-names. This means that if numpy.i supported them, they would
-apply to all pointer return arguments for the supported numeric
-types. This seems too dangerous. Second, C/C++ return arguments are
+arrays, for several reasons. First, C/C++ return arguments are
limited to a single value. This prevents obtaining dimension
-information in a general way. Third, arrays with hard-coded lengths
+information in a general way. Second, arrays with hard-coded lengths
are not permitted as return arguments. In other words:
double[3] newVector(double x, double y, double z);
@@ -1053,7 +1049,7 @@
Modified: trunk/numpy/doc/swig/numpy_swig.pdf
===================================================================
--- trunk/numpy/doc/swig/numpy_swig.pdf 2007-08-03 19:44:53 UTC (rev 3940)
+++ trunk/numpy/doc/swig/numpy_swig.pdf 2007-08-03 21:21:10 UTC (rev 3941)
@@ -702,23 +702,24 @@
/ProcSet [ /PDF /Text ]
>> endobj
206 0 obj <<
-/Length 3673
+/Length 3454
/Filter /FlateDecode
>>
stream
-x??[[s??~???Kf???!.??)???;??I?v2I&CQ????????b??????? ,??b??'?'?.u??'?mKcjq????S%???:??|?????'m?i?Ku??TV??w@????L?a >??l? T4?????D???
?{no????N???FTv
E?)9?u5?@?HWXp?oO??fc?^???sG~?????Mq?R?????s:??t?k]????^??U?)???N?g?z??.PES???w???.?V=?=?V?#h?G?-????!?O????vj?4J??????"??w3q???E&?c8? ???
-I?{?!z?Y]????W??A????+F??=?&???^a??,?*????p?G??{,0?????????{p?1????.??&iM&Z?h?z?2??@q=],y??9?????????NX?3????g?8sa#???hjU??|?%O???%,??(?MV?u?????4B?G|e???
?^j????R?6m+3y2_????3C)p?Lq??????RI?Tux?#r?L??????MN?OuD?F?VUM*?[?w?<.??????E?
-?0?????F??e??`?;7.[[j)?
-?m.Y??/.???????? h???????g~u???gBc?
f??!:???m??T????Z-GLQ???Z0a?%fOS(tA at g?.?????a aJYC?-yw?j?om?~%?V??K;?Kx089??_??x???+?s??????????=???????n*????_s??~?F??g?)???GT[:?d?u??m??????>Q???????s??/?{??????oL??yu???i>????';???n#????h>??4D'????p~65_i?j?1?GT[??d?5??m?????????~E????5??ec???{L???@vT???Nz????????R????5)??QZ[????Tn$g?ha???????????2??!"??????rB
/tQ???5@??dr????/>{?)|}?\?V(H??5E?4???;?qj?:?c???
A)???0&=MC? ?N???h???Q=Eb?4Q?kT?}?????=??^??5r???a?????5??j??R?;?0???Rhk??{O???????S?}mJm ??????S?b??C?q ?M??Q?'Z4??|N????,+?B????Y?i~a
?6??S?c?#i?p8?Y?????,?;]???/Y?*?pk??F????r
???$????A??????]?.??3?r"Fn?D??}???????Dr???V????
?K0a]??B=??????????v??'??yv~eGbtYY?N??uX>6??I?9U6????[?U?X?????????-J???_???????62?"?m??H?Z??2&?zinI3??8????R3??
-?-/??[.?D?????5??Bh^1,?x(??aUW&??)????>??+???#???w1?L?3?Ot??????O?m? *??[,??????????w.??????h?tG???r&oC?#=p ?????'???????vZ??Kf??s?>D5?e?)?P????????{?9e?f??????$?e?????E?
-????mkn?$u ???????pI?G??Z?}y????,8??? ??????p?TI?????x?ed???,??????#??yir?F??n????????8,h?rj??a??VM?Z??+x?~"?=]?m1??F?[???f? STB???V??"z?????af?bXMc??????s????????e?
-??+??????D????_m?w?~????M?????j??@n?l???D?a???w??"%l??US??9
n?!P?b?7_?T?x????]???-+??|vXm ??3?-
9u?????{??m?xn?d??????????D?+?p?e0?N?t|,??~???&t2?\I??+ ????>??z~\????????g??g??!Y???K??Yhv?? ???s???]DglH???t7N??u??]~2??zS??\??}?&>????r7M S.?oK?1?Vnu??n???"
-?n???????H$Df?
-6??x
-????????V??8??h???8|D.?d?|
J*??&???:??q9-E?,J??r?#??=?o`-?N??????R?T??D?_?Q????6zm??d"?Y??????@??-?o?C??:??h?? ??????kp@?????d??E@%?/J??T????K??4????Xl?????As??yrb5??tS?+%??|24}P ??nGHK?????Rm?Y?Z??Q?C??>z???0??????/Z?s&?U? '???,C?????w??????? ~????2M
?O??????jU???Jyd??pY?h.'?o???#9BR"??)????*??(?Y?h?Z ?RA??Ox??v?],?Q]??z??0?}7??^
??????F??????Mmr3K?E
??R?0(B??????aXSi?9???v?u??.RO???(???{I???????O??Rx?Oc?g????t?b8hU???????9o????9???????NI??f???"?????h?>::??h??'J -?JD??? ?>?t+L?? +?[???$K)7???????F??4U{??????r?t3??v???o%??g?f?u&???x?I?m??h[L-?R?F?b?}j????5??o]??Ju?????)2T5????\x???x?q?2? ???&Y?l??@??n?x??????Lm4?"?m?H??L?0???`7??Os??B??b?]???zN?b?v
-97???l?t??
-?!6]?]KO??,?s?H?;?????R???0g????mh???!t?Rjv?!e?h?\0???A?V?3yh?q?:K.(?i?})??Sy??(??U?_?;??.?7?6?b??e#??0?????{???????9n?8?g????y?w?U%Y:-R????? ?v?e???%??a{??2'???q#?]??????????-d??[??_,'??????:?qv???%?)??%K<H5?s~u<3????B?s?T??$??u??%??
:?}?????? j?? ?gS????pMS6??T8??]??|????,rd?R?4M?{?????s?(.?|PkKY7?(,?FDs+n ??? e3yw?O*?????endstream
+x??ko????} pjt??s????????J? ???,???\??????$?q?)??????p8oRbU???jt?????V???????k????`?m??m?c?wcd]9k?j?"????g/?U??5F?.^sYQ5?mVW???8???????F5??wgJ???k???_>{?Vm?ZiK??W)'??{?????bPv?a>??l t4?c????, ?7?????wgi?;Dm7?t??3Z????$????3?hX??W?~~??/'F?
+h?~?Tn?0=s???l??^_ ?7???U?)??w??????k?> +??v??x{l6??k????=W?#r?W?#n???Cl`?0??0fj??????"??w;`??UA?G??
?????!Yz???JI]|???|????V?j???;??u??????x????vYi???!?g_]D????Rn??????^9????a?K?4?o????z??zy r>0?qA?=R????*?)?E?Z?b??8Gn?L?Z???Y???Hn=?
+?k 5 ???N?6????%) |7H???^??????????-?~??=?eO??F ?[???? o?1???w?a?w(N[$
?????L?cJ8???;Q? ?fk??mEbh????:???1?)???$A?G??K^?????]?x??e????l4??B??????)?DV1??Wh?4??G?
+??? a??z?F?~??GBx??[??????? 1?G??"???`?ojSfR4a??K????????t5e?F????F???:AuGr'4m????MDGz??Q??6?
??*On(?6?3*m??i?]Y?*+d{?VF?M:`l?FhO??
+??ZY?S???L?R?nb???r~?VJ?S????Q"=???=??????????
+???^???????xE??? }_?[?r<7BG?so?e?*-????
A?KR???????2???b?U?[ V?????B ??????`????Q?Lmx?V5?
hE1??iA@???=m??i
`?`???Q$l%
?Z?w?????+a^??r^??/?????????????HE]???5<??{???}??