Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #19002

Re: Extension module question

Path csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!ecngs!feeder2.ecngs.de!newsfeed.freenet.ag!news2.euro.net!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail
Return-Path <python-python-list@m.gmane.org>
X-Original-To python-list@python.org
Delivered-To python-list@mail.python.org
X-Spam-Status OK 0.000
X-Spam-Evidence '*H*': 1.00; '*S*': 0.00; 'example:': 0.03; 'python.': 0.04; 'sorts': 0.04; 'subject:module': 0.04; 'pointer': 0.05; 'attribute': 0.07; 'imports': 0.07; 'nasty': 0.07; 'raises': 0.07; 'something,': 0.07; 'python': 0.08; 'block.': 0.09; 'const': 0.09; 'pointers': 0.09; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:80.91.229.12': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'received:lo.gmane.org': 0.09; 'size_t': 0.09; 'def': 0.13; 'this:': 0.15; '"with': 0.16; '*c*': 0.16; 'build.': 0.16; 'dirname': 0.16; 'from:addr:behnel.de': 0.16; 'from:addr:stefan_ml': 0.16; 'from:name:stefan behnel': 0.16; 'pyobject': 0.16; 'pyobject*': 0.16; 'runtime.': 0.16; 'self,': 0.16; 'subject:question': 0.16; 'simpler': 0.18; 'wrap': 0.18; 'suggest': 0.20; 'extension': 0.21; 'appropriate': 0.22; 'header :In-Reply-To:1': 0.22; 'interface': 0.23; 'calls.': 0.23; 'conversions': 0.23; 'hopefully': 0.24; 'static': 0.24; 'stefan': 0.24; 'code': 0.25; 'module': 0.26; 'stuff': 0.26; "i'm": 0.27; 'putting': 0.28; 'separate': 0.28; 'earlier': 0.28; 'pass': 0.28; 'module.': 0.28; 'yield': 0.28; 'class': 0.29; '(and': 0.29; 'handling': 0.30; 'args)': 0.30; 'null;': 0.30; 'url:src': 0.30; 'error': 0.30; 'pretty': 0.30; "i've": 0.31; 'do.': 0.31; 'skip:( 20': 0.31; 'skip:l 30': 0.32; 'does': 0.32; 'modules': 0.32; 'idea': 0.32; 'implement': 0.32; 'header:User-Agent:1': 0.33; 'instead': 0.33; 'to:addr:python-list': 0.33; 'received:84': 0.34; 'calling': 0.34; 'here,': 0.34; 'header:X-Complaints-To:1': 0.34; 'things': 0.35; 'two': 0.37; 'but': 0.37; 'received:org': 0.37; 'using': 0.37; 'skip:_ 10': 0.37; 'allows': 0.38; 'e.g.': 0.38; 'url:docs': 0.39; 'url:org': 0.39; 'subject:: ': 0.39; 'might': 0.40; 'to:addr:python.org': 0.40; 'got': 0.40; 'type': 0.60; 'custom': 0.61; 'here': 0.64; 'details': 0.65; 'here:': 0.67; 'directly.': 0.68; 'failure': 0.74; 'bridge': 0.80; 'skip:h 50': 0.84; 'skip:n 40': 0.85; 'safety.': 0.91
X-Injected-Via-Gmane http://gmane.org/
To python-list@python.org
From Stefan Behnel <stefan_ml@behnel.de>
Subject Re: Extension module question
Date Sun, 15 Jan 2012 11:48:22 +0100
References <4F128232.8020801@wisc.edu>
Mime-Version 1.0
Content-Type text/plain; charset=UTF-8
Content-Transfer-Encoding 7bit
X-Gmane-NNTP-Posting-Host dslb-084-056-000-204.pools.arcor-ip.net
User-Agent Mozilla/5.0 (X11; Linux x86_64; rv:9.0) Gecko/20111220 Thunderbird/9.0
In-Reply-To <4F128232.8020801@wisc.edu>
X-BeenThere python-list@python.org
X-Mailman-Version 2.1.12
Precedence list
List-Id General discussion list for the Python programming language <python-list.python.org>
List-Unsubscribe <http://mail.python.org/mailman/options/python-list>, <mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive <http://mail.python.org/pipermail/python-list>
List-Post <mailto:python-list@python.org>
List-Help <mailto:python-list-request@python.org?subject=help>
List-Subscribe <http://mail.python.org/mailman/listinfo/python-list>, <mailto:python-list-request@python.org?subject=subscribe>
Newsgroups comp.lang.python
Message-ID <mailman.4765.1326624517.27778.python-list@python.org> (permalink)
Lines 73
NNTP-Posting-Host 2001:888:2000:d::a6
X-Trace 1326624517 news.xs4all.nl 6905 [2001:888:2000:d::a6]:52642
X-Complaints-To abuse@xs4all.nl
Xref x330-a1.tempe.blueboxinc.net comp.lang.python:19002

Show key headers only | View raw


Evan Driscoll, 15.01.2012 08:37:
> As I hinted at in an earlier email, I'm working on a module which will
> allow calling readdir() (and FindFirstFile on Windows, hopefully pretty
> uniformly) from Python. The responses I got convinced me that it was a
> good idea to write a C-to-Python bridge as an extension module.

An even better idea is to write an extension module in Cython. Much faster
and simpler to learn and do.


> What I'm not sure about is how to store pointers to *C* stuff between
> calls. In particular, opendir() returns a DIR* which you then need to
> pass to calls to readdir() in the future (and closedir()).
> 
> So I've got this:
> 
>     static PyObject*
>     py_opendir(PyObject* self, PyObject* args)
>     {
>         const char* dirname = 0;
>         if (!PyArg_ParseTuple(args, "s", &dirname)) {
>             return NULL;
>         }
>         // Eventually want to Py_BEGIN_ALLOW_THREADS here

Cython allows you to do that by simply putting it into a "with nogil" block.


>         DIR* directory = opendir(dirname);
> 
>         PyObject out = PyBuildValue( ???, directory );
>         return out;
>     }
> 
> but I don't know what to build. (I might want to wrap it in a custom
> handle class or something, but I still need to know how to build the
> value I eventually store in an attribute of that class.)

I suggest you write an extension type and store the pointer in it directly.

Untested Cython code example:

    filesystem_encoding = sys.getfilesystemencoding()

    cdef class Directory:
        cdef DIR* c_directory
        def __cinit__(self, directory):
            if isinstance(directory, unicode):
                 directory = directory.encode(filesystem_encoding)
            cdef char* c_dirname = directory # raises TypeError on failure
            with nogil:
                self.c_directory = opendir(c_dirname)

        def __iter__(self):
            cdef char* name
            cdef size_t name_length
            for name in however_you_list_the_content_of(self.c_directory):
                name_length = length_which_you_may_know_of(name)
                yield name[:name_length].decode(filesystem_encoding)

and so on. Note how Cython does all sorts of things automatically for you
here, e.g. type conversions and the corresponding error handling as well as
all those nasty details of the C-level extension type implementation. Also
note that I'm using __cinit__() instead of __init__() for safety. See here:

http://docs.cython.org/src/userguide/special_methods.html#initialisation-methods-cinit-and-init

To implement the same interface for Unices and Windows, I suggest you write
two separate extension modules and hide them in a Python package that does
the appropriate platform specific imports at runtime.

Stefan

Back to comp.lang.python | Previous | Next | Find similar | Unroll thread


Thread

Re: Extension module question Stefan Behnel <stefan_ml@behnel.de> - 2012-01-15 11:48 +0100

csiph-web