Search code examples
pythonpython-c-apipython-decimal

How to construct a decimal.Decimal object using the C API?


I'm interested in creating decimal.Decimal objects in an extension in C. I cannot find any documentation about this in the docs

Does documentation for this exist? Are there any examples anywhere?

I've found the source code that implements the object in the Python git repository so I'm sure I could do some trial and error, and muddle through working out the header file imports, but documentation is preferred (if it exists).


Solution

  • In Python 3.10, there's going to be a C API for this. You'll need to supply your own libmpdec and mpdecimal.h header, and initialize the decimal API with import_decimal(). (Note that the C-level import_decimal() call is completely different from and unrelated to the Python-level statement import decimal.)

    After setup, you can allocate an uninitialized Decimal object with

    PyObject *dec = PyDec_Alloc();
    

    and then get a pointer to the internal mpd_t with

    mpd_t *dec_internal = PyDec_Get(dec);
    

    and initialize the mpd_t with libmpdec functions. (Note that decimal objects are logically immutable, so you should refrain from mutating any Decimal object other than one you have just allocated with PyDec_Alloc.)

    To work with the mpd_t of an existing Decimal object, you can do

    const mpd_t *dec_internal = PyDec_GetConst(some_existing_decimal);
    

    and then use non-mutative libmpdec functions.


    As for pre-3.10 code, there is no Decimal C API. You'll just have to do the C-level equivalent of import decimal; d = Decimal(whatever) using functions like PyImport_ImportModule, PyObject_GetAttrString, and PyObject_Call.