mdornfe1
mdornfe1

Reputation: 2160

How can I use the Python Decimal object in cython code?

Naively I try

from decimal cimport Decimal

cpdef Decimal to_decimal(str value):
    return Decimal(value)

However when I try to compile this I get the following error

Error compiling Cython file:
------------------------------------------------------------
...
from decimal cimport Decimal
^
------------------------------------------------------------

helloworld.pyx:1:0: 'decimal.pxd' not found

Error compiling Cython file:
------------------------------------------------------------
...
from decimal cimport Decimal
^
------------------------------------------------------------

helloworld.pyx:1:0: 'decimal/Decimal.pxd' not found

Error compiling Cython file:
------------------------------------------------------------
...
from decimal cimport Decimal

cpdef Decimal to_decimal(str value):
     ^
------------------------------------------------------------

helloworld.pyx:3:6: 'Decimal' is not a type identifier

Error compiling Cython file:
------------------------------------------------------------
...
from decimal cimport Decimal

cpdef Decimal to_decimal(str value):
    return Decimal(value)
          ^
------------------------------------------------------------

helloworld.pyx:4:11: 'Decimal' is not a constant, variable or function identifier

I know the Decimal class is created from this c extension file https://github.com/python/cpython/blob/master/Modules/_decimal/_decimal.c. So it seems like it should be usable in cython code. Anyone know how?

Upvotes: 3

Views: 976

Answers (2)

Pau Kou
Pau Kou

Reputation: 41

gmpy2 exports native API that can be used in Cython code.

Provided minimal example is written in C-style cython code, so your code is going to be less readable. Or alternatively you can write your own idiomatic OOP wrapper in Cython.

Please, correct me if such wrapper already exists.

Upvotes: 0

oz1
oz1

Reputation: 998

Do you mean the standard library module decimal ?

If that, you cannot cimport Decimal since it's not a cython extension type declared in a pxd file(like a C header). Also, you cannot type your function return value as Decimal for the same reason. Indeed, Decimal is implemented in C, but it's not a cython extension type or cython has not built-in support for it as a type identifier currently.

What you want to do looks like:

class Foo:
    pass

cpdef Foo func():   # the same compile error
    pass

However, the following works:

cdef class Foo:
    pass

cpdef Foo func():
    pass

In a word, you can use cdef class as a type identifier, not a pure python class. You can modify your code like:

from decimal import Decimal

cpdef to_decimal(str value):
    return Decimal(value)

You may wonder why this works: cdef list my_list = [] since list is not a cdef class. Well, cython has built-in support for it!

You may also interested in the standard headers provided by cython, usually in site-packages/Cython/Includes, make sure have a look at the cpython subfolder.

Upvotes: 2

Related Questions