summaryrefslogtreecommitdiff
path: root/numpy/f2py/lib/python_wrapper.py
diff options
context:
space:
mode:
authorPearu Peterson <pearu.peterson@gmail.com>2006-10-07 08:49:08 +0000
committerPearu Peterson <pearu.peterson@gmail.com>2006-10-07 08:49:08 +0000
commit90d11ae25a5edabecc0b9e9c7a6e3de929d125f2 (patch)
treeebdf733a41b773c46af6bb00cba2a333d2a38661 /numpy/f2py/lib/python_wrapper.py
parent79f992d50ce28fa119455e0f12e428559b0ff0b8 (diff)
downloadnumpy-90d11ae25a5edabecc0b9e9c7a6e3de929d125f2.tar.gz
F2PY G3: completed test site for int,float,complex scalar support. Fixed bugs.
Diffstat (limited to 'numpy/f2py/lib/python_wrapper.py')
-rw-r--r--numpy/f2py/lib/python_wrapper.py687
1 files changed, 0 insertions, 687 deletions
diff --git a/numpy/f2py/lib/python_wrapper.py b/numpy/f2py/lib/python_wrapper.py
deleted file mode 100644
index 7f73d6fbb..000000000
--- a/numpy/f2py/lib/python_wrapper.py
+++ /dev/null
@@ -1,687 +0,0 @@
-
-__all__ = ['TypeWrapper']
-
-import re
-import os
-import sys
-
-from parser.api import *
-
-from wrapper_base import *
-
-class PythonWrapperModule(WrapperBase):
-
- main_template = '''\
-#ifdef __cplusplus
-extern \"C\" {
-#endif
-#include "Python.h"
-
-#define PY_ARRAY_UNIQUE_SYMBOL PyArray_API
-#include "numpy/arrayobject.h"
-#include "numpy/arrayscalars.h"
-
-%(header_list)s
-
-%(typedef_list)s
-
-%(extern_list)s
-
-%(c_code_list)s
-
-%(capi_code_list)s
-
-%(objdecl_list)s
-
-static PyObject *f2py_module;
-
-static PyMethodDef f2py_module_methods[] = {
- %(module_method_list)s
- {NULL,NULL,0,NULL}
-};
-
-PyMODINIT_FUNC init%(modulename)s(void) {
- f2py_module = Py_InitModule("%(modulename)s", f2py_module_methods);
- import_array();
- %(module_init_list)s
- if (PyErr_Occurred()) {
- PyErr_SetString(PyExc_ImportError, "can\'t initialize module %(modulename)s");
- return;
- }
-}
-#ifdef __cplusplus
-}
-#endif
-'''
-
- main_fortran_template = '''\
-! -*- f90 -*-
-%(fortran_code_list)s
-'''
- def __init__(self, modulename):
- WrapperBase.__init__(self)
- self.modulename = modulename
-
- self.header_list = []
- self.typedef_list = []
- self.extern_list = []
- self.objdecl_list = []
- self.c_code_list = []
- self.capi_code_list = []
-
- self.module_method_list = []
- self.module_init_list = []
-
- self.fortran_code_list = []
-
- self.list_names = ['header', 'typedef', 'extern', 'objdecl',
- 'c_code','capi_code','module_method','module_init',
- 'fortran_code']
-
- return
-
- def add(self, block):
- if isinstance(block, BeginSource):
- for name, moduleblock in block.a.module.items():
- self.add(moduleblock)
- #for name, subblock in block.a.external_subprogram.items():
- # self.add(subblock)
- elif isinstance(block, (Subroutine, Function)):
- self.info('Generating interface for %s' % (block.name))
- f = PythonCAPIFunction(self, block)
- f.fill()
- elif isinstance(block, Module):
- for name,declblock in block.a.type_decls.items():
- self.add(declblock)
- elif isinstance(block, TypeDecl):
- PythonCAPIDerivedType(self, block)
- elif isinstance(block, tuple(declaration_type_spec)):
- PythonCAPIIntrinsicType(self, block)
- else:
- raise NotImplementedError,`block.__class__.__name__`
- return
-
- def c_code(self):
- return self.apply_attributes(self.main_template)
- def fortran_code(self):
- return self.apply_attributes(self.main_fortran_template)
-
- def add_subroutine(self, block):
- raise
- f = PythonCAPIFunction(self, block)
- f.fill()
- return
-
-
-
-
-class PythonCAPIIntrinsicType(WrapperBase):
- """
- Fortran intrinsic type hooks.
- """
- _defined_types = []
- def __init__(self, parent, typedecl):
- WrapperBase.__init__(self)
- self.name = name = typedecl.name
- if name in self._defined_types:
- return
- self._defined_types.append(name)
-
- self.ctype = ctype = typedecl.get_c_type()
-
- if ctype.startswith('npy_'):
- WrapperCCode(parent, 'pyobj_from_%s' % (ctype))
- return
-
- if not ctype.startswith('f2py_type_'):
- raise NotImplementedError,`name,ctype`
-
- for n in parent.list_names:
- l = getattr(parent,n + '_list')
- l.append(self.apply_attributes(getattr(self, n+'_template','')))
-
- return
-
-class PythonCAPIDerivedType(WrapperBase):
- """
- Fortran 90 derived type hooks.
- """
-
- header_template = '''\
-#define %(oname)sObject_Check(obj) \\
- PyObject_TypeCheck((PyObject*)obj, &%(oname)sType)
-#define %(init_func)s_f \\
- F_FUNC(%(init_func)s,%(INIT_FUNC)s)
-'''
-
- typedef_template = '''\
-typedef void * %(ctype)s;
-typedef struct {
- PyObject_HEAD
- %(ptrstruct_list)s
- %(ctype)s data;
-} %(oname)sObject;
-'''
-
- extern_template = '''\
-static PyTypeObject %(oname)sType;
-'''
-
- objdecl_template = '''\
-static PyMethodDef %(oname)s_methods[] = {
- %(type_method_list)s
- {NULL} /* Sentinel */
-};
-
-static PyGetSetDef %(oname)s_getseters[] = {
- %(type_getseters_list)s
- {NULL} /* Sentinel */
-};
-
-static PyTypeObject %(oname)sType = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "%(name)s", /*tp_name*/
- sizeof(%(oname)sObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)%(oname)s_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- %(oname)s_repr, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
- "Fortran derived type %(name)s objects", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- %(oname)s_methods, /* tp_methods */
- 0 /*%(oname)s_members*/, /* tp_members */
- %(oname)s_getseters, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)%(oname)s_init, /* tp_init */
- 0, /* tp_alloc */
- %(oname)s_new, /* tp_new */
-};
-'''
-
- module_init_template = '''\
-if (PyType_Ready(&%(oname)sType) < 0)
- return;
-PyModule_AddObject(f2py_module, "%(name)s",
- (PyObject *)&%(oname)sType);
-'''
-
- c_code_template = '''\
-static void %(init_func)s_c(
- %(init_func_c_arg_clist)s) {
- %(init_func_c_body_list)s
-}
-'''
-
- capi_code_template = '''\
-static void %(oname)s_dealloc(%(oname)sObject* self) {
- if (self->data)
- PyMem_Free(self->data);
- self->ob_type->tp_free((PyObject*)self);
-}
-
-static int pyobj_to_%(ctype)s(PyObject *obj,
- %(ctype)s* value_ptr) {
- int return_value = 0;
-#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
- fprintf(stderr,"pyobj_to_%(ctype)s(type=%%s)\\n",PyString_AS_STRING(PyObject_Repr(PyObject_Type(obj))));
-#endif
- if (%(oname)sObject_Check(obj)) {
- if (!memcpy(value_ptr,((%(oname)sObject *)obj)->data, %(byte_size)s)) {
- PyErr_SetString(PyExc_MemoryError,
- "failed to copy %(name)s instance memory to %(ctype)s object.");
- } else {
- return_value = 1;
- }
- }
-#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
- fprintf(stderr,"pyobj_to_%(ctype)s: return_value=%%d, PyErr_Occurred()=%%p\\n", return_value, PyErr_Occurred());
-#endif
- return return_value;
-}
-
-static PyObject* pyobj_from_%(ctype)s(%(ctype)s* value_ptr) {
- %(oname)sObject* obj = (%(oname)sObject*)(%(oname)sType.tp_alloc(&%(oname)sType, 0));
- if (obj == NULL)
- return NULL;
- obj->data = PyMem_Malloc(%(byte_size)s);
- if (obj->data == NULL) {
- Py_DECREF(obj);
- return PyErr_NoMemory();
- }
- if (value_ptr) {
- if (!memcpy(obj->data, value_ptr, %(byte_size)s)) {
- PyErr_SetString(PyExc_MemoryError,
- "failed to copy %(ctype)s object memory to %(name)s instance.");
- }
- }
- %(init_func)s_f(%(init_func)s_c, obj, obj->data);
- return (PyObject*)obj;
-}
-
-static PyObject * %(oname)s_new(PyTypeObject *type,
- PyObject *args, PyObject *kwds)
-{
- return pyobj_from_%(ctype)s(NULL);
-}
-
-static int %(oname)s_init(%(oname)sObject *self,
- PyObject *capi_args, PyObject *capi_kwds)
-{
- int return_value = 0;
-#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
- fprintf(stderr,"%(oname)s_init()\\n");
-#endif
- if (!PyArg_ParseTuple(capi_args,"%(attr_format_elist)s"
- %(attr_init_clist)s))
- return_value = -1;
-#if defined(F2PY_DEBUG_PYOBJ_TOFROM)
- fprintf(stderr,"%(oname)s_init: return_value=%%d, PyErr_Occurred()=%%p\\n", return_value, PyErr_Occurred());
-#endif
- return return_value;
-}
-
-static PyObject * %(oname)s_as_tuple(%(oname)sObject * self) {
- return Py_BuildValue("%(as_tuple_format_elist)s"
- %(as_tuple_arg_clist)s);
-}
-
-static PyObject * %(oname)s_repr(PyObject * self) {
- PyObject* r = PyString_FromString("%(name)s(");
- PyString_ConcatAndDel(&r, PyObject_Repr(%(oname)s_as_tuple((%(oname)sObject*)self)));
- PyString_ConcatAndDel(&r, PyString_FromString(")"));
- return r;
-}
-
-%(getset_func_list)s
-'''
-
- fortran_code_template = '''\
- subroutine %(init_func)s(init_func_c, self, obj)
- %(use_stmt_list)s
- external init_func_c
-! self is %(oname)sObject
- external self
- %(ftype)s obj
- call init_func_c(%(init_func_f_arg_clist)s)
- end
-'''
-
- #module_method_template = ''''''
-
- _defined_types = []
- def __init__(self, parent, typedecl):
- WrapperBase.__init__(self)
- name = typedecl.name
- if name in self._defined_types:
- return
- self._defined_types.append(name)
-
- self.name = name
- self.oname = oname = 'f2py_' + name
- self.ctype = typedecl.get_c_type()
- self.ctype_ptrs = self.ctype + '_ptrs'
- self.ftype = typedecl.get_f_type()
- self.byte_size = byte_size = typedecl.get_bit_size() / CHAR_BIT
- WrapperCPPMacro(parent, 'F_FUNC')
-
- self.init_func_f_arg_list = ['self']
- self.init_func_c_arg_list = ['%sObject *self' % (self.oname)]
- self.init_func_c_body_list = []
- self.ptrstruct_list = []
- self.attr_decl_list = []
- self.attr_format_list = []
- self.attr_init_list = []
- self.as_tuple_format_list = []
- self.as_tuple_arg_list = []
- self.getset_func_list = []
- self.type_getseters_list = []
- for n in typedecl.a.component_names:
- v = typedecl.a.components[n]
- t = v.get_typedecl()
- ct = t.get_c_type()
- on = 'f2py_' + t.name
- parent.add(t)
- self.ptrstruct_list.append('%s* %s_ptr;' % (ct, n))
- self.init_func_f_arg_list.append('obj %% %s' % (n))
- self.init_func_c_arg_list.append('\n%s * %s_ptr' % (ct, n))
- self.init_func_c_body_list.append('''\
-if (!((void*)%(n)s_ptr >= self->data
- && (void*)%(n)s_ptr < self->data + %(byte_size)s ))
- fprintf(stderr,"INCONSISTENCY IN %(name)s WRAPPER: "
- "self->data=%%p <= %(n)s_ptr=%%p < self->data+%(byte_size)s=%%p\\n",
- self->data, %(n)s_ptr, self->data + %(byte_size)s);
-self->%(n)s_ptr = %(n)s_ptr;
-''' % (locals()))
- self.attr_format_list.append('O&')
- WrapperCCode(parent, 'pyobj_to_%s' % (ct))
- self.attr_init_list.append('\npyobj_to_%s, self->%s_ptr' % (ct,n))
- WrapperCCode(parent, 'pyobj_from_%s' % (ct))
- self.as_tuple_format_list.append('O&')
- self.as_tuple_arg_list.append('\npyobj_from_%s, self->%s_ptr' % (ct, n))
- self.getset_func_list.append('''\
-static PyObject * %(oname)s_get_%(n)s(%(oname)sObject *self,
- void *closure) {
- return pyobj_from_%(ct)s(self->%(n)s_ptr);
-}
-static int %(oname)s_set_%(n)s(%(oname)sObject *self,
- PyObject *value, void *closure)
-{
- if (value == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "Cannot delete %(name)s attribute %(n)s");
- return -1;
- }
- if (pyobj_to_%(ct)s(value, self->%(n)s_ptr))
- return 0;
- return -1;
-}
-''' % (locals()))
- self.type_getseters_list.append('{"%(n)s",(getter)%(oname)s_get_%(n)s, (setter)%(oname)s_set_%(n)s,\n "component %(n)s",NULL},' % (locals()))
- if self.attr_init_list: self.attr_init_list.insert(0,'')
- if self.as_tuple_arg_list: self.as_tuple_arg_list.insert(0,'')
- self.init_func = self.ctype + '_init'
- self.INIT_FUNC = self.init_func.upper()
-
- self.type_method_list = []
- self.type_method_list.append('{"as_tuple",(PyCFunction)%(oname)s_as_tuple,METH_NOARGS,\n "Return %(name)s components as tuple."},' % (self.__dict__))
- self.cname = typedecl.get_c_name()
-
- self.use_stmt_list = []
- if isinstance(typedecl.parent, Module):
- self.use_stmt_list.append('use %s' % (typedecl.parent.name))
-
- for n in parent.list_names:
- l = getattr(parent,n + '_list')
- l.append(self.apply_attributes(getattr(self, n+'_template','')))
- return
-
-class PythonCAPIFunction(WrapperBase):
- capi_function_template = '''
-static char f2py_doc_%(function_name)s[] = "%(function_doc)s";
-static PyObject* f2py_%(function_name)s(PyObject *capi_self, PyObject *capi_args, PyObject *capi_keywds) {
- PyObject * volatile capi_buildvalue = NULL;
- volatile int f2py_success = 1;
- %(decl_list)s
- static char *capi_kwlist[] = {%(keyword_clist+optkw_clist+extrakw_clist+["NULL"])s};
- if (!PyArg_ParseTupleAndKeywords(capi_args,capi_keywds,
- "%(pyarg_format_elist)s",
- %(["capi_kwlist"]+pyarg_obj_clist)s))
- return NULL;
- %(frompyobj_list)s
- %(call_list)s
- f2py_success = !PyErr_Occurred();
- if (f2py_success) {
- %(pyobjfrom_list)s
- capi_buildvalue = Py_BuildValue(%(buildvalue_clist)s);
- %(clean_pyobjfrom_list)s
- }
- %(clean_frompyobj_list)s
- return capi_buildvalue;
-}
-'''
-
- pymethoddef_template = '''\
-{"%(function_name)s", (PyCFunction)f2py_%(function_name)s, METH_VARARGS | METH_KEYWORDS, f2py_doc_%(function_name)s},\
-'''
-
- cppmacro_template = '''\
-#define %(function_name)s_f F_FUNC(%(function_name)s,%(FUNCTION_NAME)s)
-'''
-
- extdef_template = '''\
-extern void %(function_name)s_f();\
-'''
-
- def __init__(self, parent, block):
- WrapperBase.__init__(self)
- self.parent = parent
- self.block = block
- self.function_name = block.name
- self.FUNCTION_NAME = self.function_name.upper()
- self.function_doc = ''
- self.args_list = block.args
- self.decl_list = []
- self.keyword_list = []
- self.optkw_list = []
- self.extrakw_list = []
- self.frompyobj_list = []
- self.call_list = []
- self.pyobjfrom_list = []
- self.buildvalue_list = []
- self.clean_pyobjfrom_list = []
- self.clean_frompyobj_list = []
- self.pyarg_format_list = []
- self.pyarg_obj_list = []
- return
-
- def fill(self):
- for argname in self.args_list:
- var = self.block.a.variables[argname]
- argwrap = ArgumentWrapper(self, var)
- argwrap.fill()
- self.call_list.append('%s_f(%s);' % (self.function_name, ', '.join(['&'+a for a in self.args_list])))
- if not self.buildvalue_list:
- self.buildvalue_list.append('""')
- self.parent.capi_function_list.append(self.apply_attributes(self.capi_function_template))
- self.parent.module_method_list.append(self.apply_attributes(self.pymethoddef_template))
- self.parent.extern_list.append(self.apply_attributes(self.extdef_template))
- self.parent.add_cppmacro('F_FUNC')
- self.parent.cppmacro_list.append(self.apply_attributes(self.cppmacro_template))
- return
-
-class ArgumentWrapper(WrapperBase):
-
- objdecl_template = '%(ctype)s %(name)s;'
- pyarg_obj_template = '\npyobj_to_%(ctype)s, &%(name)s'
-
- def __init__(self, parent, variable):
- WrapperBase.__init__(self)
- self.parent = parent
- self.grand_parent = parent.parent
- self.variable = variable
- self.typedecl = variable.typedecl
- self.name = variable.name
- self.ctype = self.typedecl.get_c_type()
-
- def fill(self):
- typename = self.grand_parent.add_type(self.typedecl)
- self.parent.decl_list.append(self.apply_attributes(self.objdecl_template))
-
- self.parent.pyarg_obj_list.append(self.apply_attributes(self.pyarg_obj_template))
- self.parent.pyarg_format_list.append('O&')
- self.parent.keyword_list.append('"%s"' % (self.name))
-
- return
-
-
-class TypeDecl2(WrapperBase):
- cppmacro_template = '''\
-#define initialize_%(typename)s_interface F_FUNC(initialize_%(typename)s_interface_f,INITIALIZE_%(TYPENAME)s_INTERFACE_F)\
-'''
- typedef_template = '''\
-typedef struct { char data[%(byte_size)s]; } %(ctype)s;
-typedef %(ctype)s (*create_%(typename)s_functype)(void);
-typedef void (*initialize_%(typename)s_interface_functype)(create_%(typename)s_functype);\
-'''
- objdecl_template = '''\
-static create_%(typename)s_functype create_%(typename)s_object;
-'''
- funcdef_template = '''\
-static void initialize_%(typename)s_interface_c(create_%(typename)s_functype create_object_f) {
- create_%(typename)s_object = create_object_f;
-}
-'''
- extdef_template = '''\
-extern void initialize_%(typename)s_interface(initialize_%(typename)s_interface_functype);\
-'''
- initcall_template = '''\
-initialize_%(typename)s_interface(initialize_%(typename)s_interface_c);\
-'''
- fortran_code_template = '''\
- function create_%(typename)s_object_f() result (obj)
- %(typedecl_list)s
- %(typedecl)s obj
-! %(initexpr)s
- end
- subroutine initialize_%(typename)s_interface_f(init_c)
- external create_%(typename)s_object_f
- call init_c(create_%(typename)s_object_f)
- end
-'''
- pyobj_to_type_template = '''
- static int pyobj_to_%(ctype)s(PyObject *obj, %(ctype)s* value) {
- if (PyTuple_Check(obj)) {
- return 0;
- }
- return 0;
- }
-'''
-
- def __init__(self, parent, typedecl):
- WrapperBase.__init__(self)
- self.parent = parent
- self.typedecl = typedecl.astypedecl()
- self.typedecl_list = []
- self.ctype = self.typedecl.get_c_type()
- self.byte_size = self.typedecl.get_byte_size()
- self.typename = self.typedecl.name.lower()
- self.TYPENAME = self.typedecl.name.upper()
- self.initexpr = self.typedecl.assign_expression('obj',self.typedecl.get_zero_value())
- return
-
- def fill(self):
- ctype =self.typedecl.get_c_type()
- if ctype.startswith('npy_') or ctype.startswith('f2py_string'):
- # wrappers are defined via pyobj_to_* functions
- self.parent.add_c_function('pyobj_to_%s' % (self.ctype))
- return
- if ctype.startswith('f2py_type'):
- return
- self.parent.add_typedef(ctype,
- self.apply_attributes('typedef struct { char data[%(byte_size)s]; } %(ctype)s;'))
- self.parent.add_c_function(self.apply_attributes('pyobj_to_%(ctype)s'),
- self.apply_attributes(self.pyobj_to_type_template)
- )
- else:
- self.parent.typedef_list.append(self.apply_attributes(self.typedef_template))
- self.parent.objdecl_list.append(self.apply_attributes(self.objdecl_template))
- self.parent.c_function_list.append(self.apply_attributes(self.funcdef_template))
- self.parent.extern_list.append(self.apply_attributes(self.extdef_template))
- self.parent.initialize_interface_list.append(self.apply_attributes(self.initcall_template))
- self.parent.fortran_code_list.append(self.apply_attributes(self.fortran_code_template))
- self.parent.add_cppmacro('F_FUNC')
- self.parent.cppmacro_list.append(self.apply_attributes(self.cppmacro_template))
- return
-
-
-
-
-if __name__ == '__main__':
-
- foo_code = """! -*- f90 -*-
- module rat
- type info
- complex*8 flag
- end type info
- type rational
- !integer n,d
- type(info) i
- end type rational
- end module rat
- subroutine foo(a,b)
- use rat
- integer a
- !character*5 b
- type(rational) b
- print*,'a=',a,b
- end
-"""
-
- wm = PythonWrapperModule('foo')
- wm.add(parse(foo_code))
- #wm.add_fortran_code(foo_code)
- #wm.add_subroutine(str2stmt(foo_code))
- #print wm.c_code()
-
- c_code = wm.c_code()
- f_code = wm.fortran_code()
-
- f = open('foomodule.c','w')
- f.write(c_code)
- f.close()
- f = open('foo.f','w')
- f.write(foo_code)
- f.close()
- f = open('foo_wrap.f','w')
- f.write(f_code)
- f.close()
- f = open('foo_setup.py','w')
- f.write('''\
-def configuration(parent_package='',top_path=None):
- from numpy.distutils.misc_util import Configuration
- config = Configuration('foopack',parent_package,top_path)
- config.add_library('foolib',
- sources = ['foo.f','foo_wrap.f'])
- config.add_extension('foo',
- sources=['foomodule.c'],
- libraries = ['foolib'],
- define_macros = [('F2PY_DEBUG_PYOBJ_TOFROM',None)]
- )
- return config
-if __name__ == '__main__':
- from numpy.distutils.core import setup
- setup(configuration=configuration)
-''')
- f.close()
- #print get_char_bit()
- os.system('python foo_setup.py config_fc --fcompiler=gnu95 build build_ext --inplace')
- import foo
- #print foo.__doc__
- #print dir(foo)
- #print foo.info.__doc__
- #print foo.rational.__doc__
- #print dir(foo.rational)
- i = foo.info(2)
- print 'i=',i
- #print i #,i.as_tuple()
- #print 'i.flag=',i.flag
- r = foo.rational(2)
- print r
- j = r.i
- print 'r.i.flag=',(r.i).flag
- print 'j.flag=',type(j.flag)
- #print 'r=',r
- sys.exit()
- n,d,ii = r.as_tuple()
- n += 1
- print n,d
- print r
- #foo.foo(2,r)
- print r.n, r.d
- r.n = 5
- print r
- r.n -= 1
- print r