Hi,

I'm using cython to wrap DJB's primegen library (
http://cr.yp.to/primegen.html).

Here's my pyx file:

cdef extern from "primegen.h":
    ctypedef unsigned long uint32
    ctypedef unsigned long long uint64

    ctypedef struct primegen:
        uint32 buf[16][2048]
        uint64 p[512]
        int num
        int pos
        uint64 base
        uint64 L

    void primegen_init(primegen* pg)
    uint64 primegen_next(primegen* pg)
    uint64 primegen_peek(primegen* pg)
    uint64 primegen_count(primegen* pg, uint64 to)
    void primegen_skipto(primegen* pg, uint64 to)

cdef class PrimeGen:
    cdef primegen pg

    def __new__(self):
        primegen_init(&self.pg)

    def next(self):
        return primegen_next(&self.pg)

    def peek(self):
        return primegen_peek(&self.pg)

    def count(self, uint64 to):
        return primegen_count(&self.pg, to)

    def skipto(self, uint64 to):
        primegen_skipto(&self.pg, to)

Notice that the class has a method called "next".  This means that it should
be usable as an iterator.  Here's what happens if I try to do that:

Python 2.5.1 (r251:54863, Jan 17 2008, 19:35:17)
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from primegen import PrimeGen
>>> class C:
...   def __iter__(self):
...     return PrimeGen()
...
>>> for i in C():
...   print i
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __iter__ returned non-iterator of type 'primegen.PrimeGen'

How come this doesn't work?  The generated class definitely has the "next"
method required by the iterator protocol.

>>> p = PrimeGen()
>>> dir(p)
['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__',
'__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__str__', 'count', 'next', 'peek', 'skipto']

Thanks,
Alex
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to