Search code examples
pythonc++type-conversionpython-c-api

Force type conversions using Python C-API


I'm wondering whether it is possible to use Python's C-API to convert e.g. Float -> String, or Bool -> Int, or Int -> Bool etc

Not every conversion makes sense, for example Dict -> List -- it would be hard to imagine what this would look like.

However, most conversions DO make sense.

Float -> Int     would just round to the nearest integer
Float -> Bool    would evaluate True non-zero
Float -> String  would give a string representation (but to what precision?)
Float -> Dict    probably doesn't make sense

So my question is, is there any way to force these type conversions using the C-API?

I understand that Python's preferred way of doing things is to handle the type internally. So you do:

x = 1 + 2.5

And it is smart enough to know that Long + Float -> Float

However, I'm writing a Python/C++ bridge where I have Long Float Complex Dict etc types, and I want to be able to do:

// initialise a Float object with an object of unknown type
Float myFloat = somePyObjectPointer; 

So initialising it with an integer would work, a string "3.14" would work, "foo" wouldn't, a Dict wouldn't, etc.

I would like to use Python's machinery for "what plugs into what" rather than build a large amount of C++ machinery to do it manually. Rationale is (1) less C++, (2) if CPython changes functionality I don't want to be out of sync.


Solution

  • Float -> Int

    PyNumber_Int()

    Float -> Bool

    No direct conversion, but PyObject_IsTrue() and PyBool_FromLong()

    Float -> String

    PyObject_Repr() or PyObject_Str()

    Dict -> List

    PyObject_CallMethod(..., "keys"/"values"/"items", NULL)

    x = 1 + 2.5

    PyNumber_Add()

    Float -> Dict

    Yeah... no.

    Anything you could care about, it's in there... somewhere.