Re: C function in a Python context

2008-02-19 Thread castironpi
 #include string
 #include vector

This modification required:

compilercommand='c:/programs/mingw/bin/g++'

and

strctypes= { 'i': 'int', 's': 'const char*',
 'O': 'PyObject*' }

The output is:

#include c:/programs/python/include/Python.h

[ user code ]

static PyObject *
extcode_enumfactors(PyObject *self, PyObject *args) {
PyObject* result;
int arg0;
const char* arg1;
PyArg_ParseTuple(args, is, arg0, arg1 );
result= enumfactors( arg0, arg1 );
return Py_BuildValue( O, result );
}

static PyMethodDef ExtcodeMethods[] = {
{ enumfactors, extcode_enumfactors, METH_VARARGS,  },
{NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
initextcode(void) {
(void) Py_InitModule(extcode, ExtcodeMethods);
}

The benefits are automatic parameter parsing and automatic method
table construction.  The costs are portability and parameter parsing
flexibility.  Add up.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C function in a Python context

2008-02-12 Thread castironpi
On Feb 9, 3:04 pm, [EMAIL PROTECTED] wrote:
 On Feb 9, 1:48 pm, [EMAIL PROTECTED] wrote:





  To write quick C things that Python won't do up to speed.  So it's got
  a redundancy.

  import ext
  extA= ext.Ext()
  extA[ 'enumfactors' ]= r
      int enumfactors( int a, const char* sep ) {
          int ret= 0, i;
          for( i= 1; i= a; i++ ) {
              if( a% i== 0 ) {
                  ret+= 1;
                  if( i 1 ) {
                      printf( %s, sep );
                  }
                  printf( %i, i );
              }
          }
          printf( \n );
          return ret;
      }
      , (i,i,s)

  factorsn= extA.enumfactors( 209677683, ', ' )
  print( %i factors total.% factorsn )

  import sys
  sys.exit()

  1, 3, 23, 69, 131, 393, 3013, 9039, 23197, 69591, 533531, 1600593,
  3038807, 9116
  421, 69892561, 209677683
  16 factors total.

 '''Prototype implementation, slightly rigid.  If anyone knows how to
 compile and link without intermediate object file, and from a string,
 memory, or stdin, let me know.  Change first four lines.  If you are
 not using gcc, look at regenpyd().'''

 compilercommand=    'c:/programs/mingw/bin/gcc'
 pythondll=          'python30'
 pythonpathinclude=  'c:/programs/python/include'
 pythonpathlibs=     'c:/programs/python/libs'

 class Ext:
     strctypes= { 'i': 'int', 's': 'const char*' }
     class ExtElem:
         def __init__( self, name, code, types ):
             self.name, self.code= name, code
             self.types= types
     def __init__( self ):
         self.__dict__[ 'exts' ]= []
     def regenc( self ):
         extcode= open( 'extcode.c', 'w' )
         wr= extcode.write
         wr( '#include %s'% pythonpathinclude )
         wr( '/Python.h\n\n' )
         for ext in self.exts:
             wr( ext.code )
             wr( '\n' )
         for ext in self.exts:
             wr( 'static PyObject *\n' )
             wr( 'extcode_%s'% ext.name )
             wr( '(PyObject *self, ' )
             wr( 'PyObject *args) {\n' )
             wr( '\t%s result;\n'%
                 Ext.strctypes[ext.types[0]] )
             for i, type in enumerate( ext.types[1:] ):
                 wr( '\t%s arg%i;\n'%
                     ( Ext.strctypes[type], i ) )
             wr( '\tPyArg_ParseTuple(args, ' )
             wr( ''.join( ext.types[1:] ) )
             wr( '' )
             for i, type in enumerate( ext.types[1:] ):
                 wr( ', arg%i'% i )
             wr( ' );\n' )
             wr( '\tresult= %s( '% ext.name )
             wr( ', '.join( [ 'arg%i'% i for i
                 in range( len( ext.types[1:] ) ) ] ) )
             wr( ' );\n' )
             wr( '\treturn Py_BuildValue' )
             wr( '( %s, result );\n'% ext.types[0] )
             wr( '}\n\n' )
         wr( 'static PyMethodDef ExtcodeMethods[] = {\n' )
         for ext in self.exts:
             wr( '\t{ %s, extcode_%s, '%
                             ( ext.name, ext.name ) )
             wr( 'METH_VARARGS,  },\n' )
         wr( '\t{NULL, NULL, 0, NULL}\n' )
         wr( '};\n\n' )
         wr( 'PyMODINIT_FUNC\n' )
         wr( 'initextcode(void) {\n' )
         wr( '\t(void) Py_InitModule' )
         wr( '(extcode, ExtcodeMethods);\n' )
         wr( '}\n\n' )
         extcode.close()
     def regenpyd( self ):
         import os, os.path
         if os.path.exists( 'extcode.pyd' ):
             os.remove( 'extcode.pyd' )
         import subprocess
         retcompile= subprocess.call(
             '%s extcode.c -c -I%s'%
             ( compilercommand, pythonpathinclude ) )
         assert not retcompile, 'Compiler error'
         retlink= subprocess.call(
             '%s -shared extcode.o -o extcode.pyd -L%s -l%s'
             % ( compilercommand, pythonpathlibs,
             pythondll ) )
         assert not retlink, 'Linker error'
         os.remove( 'extcode.o' )
         os.remove( 'extcode.c' )
     def __setitem__( self, key, value ):
         code, types= value
         self.exts.append( Ext.ExtElem( key, code, types ) )
         self.regenc()
         self.regenpyd()
         import extcode
         setattr( self, key, getattr( extcode, key ) )- Hide quoted text -

 - Show quoted text -

This is- and returns a list, of the enumerated factors.  Is it
starting to get bulky.


import ext
extA= ext.Ext()
extA[ 'enumfactors' ]= r
#include string
#include vector
using namespace std;
PyObject* enumfactors( int a, const char* sep ) {
string fmt= [;
vector long  resv;
for( int i= 1; i= a; i++ ) {
if( a% i== 0 ) {
resv.push_back( i );
fmt.append( i );
if( i 1 ) {
printf( %s, sep );
}
printf( %i, i );
}
}
printf( \n );
fmt.append( ] );
PyObject* res= PyList_New( resv.size() );
for( int i= 0; i resv.size(); i++ ) {
PyObject* v= PyLong_FromLong( resv[i] );

C function in a Python context

2008-02-09 Thread castironpi
To write quick C things that Python won't do up to speed.  So it's got
a redundancy.

import ext
extA= ext.Ext()
extA[ 'enumfactors' ]= r
int enumfactors( int a, const char* sep ) {
int ret= 0, i;
for( i= 1; i= a; i++ ) {
if( a% i== 0 ) {
ret+= 1;
if( i 1 ) {
printf( %s, sep );
}
printf( %i, i );
}
}
printf( \n );
return ret;
}
, (i,i,s)

factorsn= extA.enumfactors( 209677683, ', ' )
print( %i factors total.% factorsn )

import sys
sys.exit()


1, 3, 23, 69, 131, 393, 3013, 9039, 23197, 69591, 533531, 1600593,
3038807, 9116
421, 69892561, 209677683
16 factors total.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C function in a Python context

2008-02-09 Thread castironpi
On Feb 9, 1:48 pm, [EMAIL PROTECTED] wrote:
 To write quick C things that Python won't do up to speed.  So it's got
 a redundancy.

 import ext
 extA= ext.Ext()
 extA[ 'enumfactors' ]= r
     int enumfactors( int a, const char* sep ) {
         int ret= 0, i;
         for( i= 1; i= a; i++ ) {
             if( a% i== 0 ) {
                 ret+= 1;
                 if( i 1 ) {
                     printf( %s, sep );
                 }
                 printf( %i, i );
             }
         }
         printf( \n );
         return ret;
     }
     , (i,i,s)

 factorsn= extA.enumfactors( 209677683, ', ' )
 print( %i factors total.% factorsn )

 import sys
 sys.exit()

 1, 3, 23, 69, 131, 393, 3013, 9039, 23197, 69591, 533531, 1600593,
 3038807, 9116
 421, 69892561, 209677683
 16 factors total.

'''Prototype implementation, slightly rigid.  If anyone knows how to
compile and link without intermediate object file, and from a string,
memory, or stdin, let me know.  Change first four lines.  If you are
not using gcc, look at regenpyd().'''

compilercommand='c:/programs/mingw/bin/gcc'
pythondll=  'python30'
pythonpathinclude=  'c:/programs/python/include'
pythonpathlibs= 'c:/programs/python/libs'

class Ext:
strctypes= { 'i': 'int', 's': 'const char*' }
class ExtElem:
def __init__( self, name, code, types ):
self.name, self.code= name, code
self.types= types
def __init__( self ):
self.__dict__[ 'exts' ]= []
def regenc( self ):
extcode= open( 'extcode.c', 'w' )
wr= extcode.write
wr( '#include %s'% pythonpathinclude )
wr( '/Python.h\n\n' )
for ext in self.exts:
wr( ext.code )
wr( '\n' )
for ext in self.exts:
wr( 'static PyObject *\n' )
wr( 'extcode_%s'% ext.name )
wr( '(PyObject *self, ' )
wr( 'PyObject *args) {\n' )
wr( '\t%s result;\n'%
Ext.strctypes[ext.types[0]] )
for i, type in enumerate( ext.types[1:] ):
wr( '\t%s arg%i;\n'%
( Ext.strctypes[type], i ) )
wr( '\tPyArg_ParseTuple(args, ' )
wr( ''.join( ext.types[1:] ) )
wr( '' )
for i, type in enumerate( ext.types[1:] ):
wr( ', arg%i'% i )
wr( ' );\n' )
wr( '\tresult= %s( '% ext.name )
wr( ', '.join( [ 'arg%i'% i for i
in range( len( ext.types[1:] ) ) ] ) )
wr( ' );\n' )
wr( '\treturn Py_BuildValue' )
wr( '( %s, result );\n'% ext.types[0] )
wr( '}\n\n' )
wr( 'static PyMethodDef ExtcodeMethods[] = {\n' )
for ext in self.exts:
wr( '\t{ %s, extcode_%s, '%
( ext.name, ext.name ) )
wr( 'METH_VARARGS,  },\n' )
wr( '\t{NULL, NULL, 0, NULL}\n' )
wr( '};\n\n' )
wr( 'PyMODINIT_FUNC\n' )
wr( 'initextcode(void) {\n' )
wr( '\t(void) Py_InitModule' )
wr( '(extcode, ExtcodeMethods);\n' )
wr( '}\n\n' )
extcode.close()
def regenpyd( self ):
import os, os.path
if os.path.exists( 'extcode.pyd' ):
os.remove( 'extcode.pyd' )
import subprocess
retcompile= subprocess.call(
'%s extcode.c -c -I%s'%
( compilercommand, pythonpathinclude ) )
assert not retcompile, 'Compiler error'
retlink= subprocess.call(
'%s -shared extcode.o -o extcode.pyd -L%s -l%s'
% ( compilercommand, pythonpathlibs,
pythondll ) )
assert not retlink, 'Linker error'
os.remove( 'extcode.o' )
os.remove( 'extcode.c' )
def __setitem__( self, key, value ):
code, types= value
self.exts.append( Ext.ExtElem( key, code, types ) )
self.regenc()
self.regenpyd()
import extcode
setattr( self, key, getattr( extcode, key ) )
-- 
http://mail.python.org/mailman/listinfo/python-list