Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking A PyObjects C Type

I am using Python 3.2 and C++.

I need to extract what kind of C type is currently being stored in a PyObject. I have checked over the documentation and googled it as well and no one else seems to have needed to do this.

So I have a PyObject and am attempting to extract the C Value. I have the list of functions need to actually extract the value from the object, but what I need to know first is what is being stored in the object itself as to call the correct function.

Just in case this helps understand here is some example code of what I am attempting.

//Variable is a custom variant type to allow for generic functionality.
Variable ExtractArgument( PyObject * arg )
{
  Variable value;
  PyObject* result;
  //now here is the problem, I need to know which Python function to call in order to
  //extract the correct type;
  value = PyLong_FromLong( arg );
  //or 
  value = PyFloat_FromDouble( arg )
  //ect.
  return value;
}

Hopefully I could have something that looks sort of like this

Variable ExtractArgument( PyObject * arg )
{
  Variable value;
  PyObject* result;
  //PyType is not the actual variable to that holds the type_macro, GetType should be
  //replaced by the function I am trying to find 
  PyType type = GetType( arg ); 
  switch( type )
  { 
    case T_INT: value = static_cast<int>(PyLong_FromLong( arg  )); 
      break;
    case T_FLOAT: value = static_cast<float>(PyFloat_FromDouble( arg  ));
      break;
    case T_DOUBLE: value = PyDouble_FromDouble( arg );
      break;
    //ect.
  }
  return value;
} 

Sorry if this question is to long, or too much info. First time post and didn't want to leave anything out that may help. Thank you for any help or insight you can give me on this issue.

like image 554
DaneEC117 Avatar asked May 23 '11 22:05

DaneEC117


People also ask

How do you check the type of an object in Python?

To get the type of a variable in Python, you can use the built-in type() function. In Python, everything is an object. So, when you use the type() function to print the type of the value stored in a variable to the console, it returns the class type of the object.

How do you seek type information about a Python object v1 1/2 3?

type() Return Value If you need to check the type of an object, it is better to use the Python isinstance() function instead. It's because the isinstance() function also checks if the given object is an instance of the subclass.

What is PyTypeObject?

Perhaps one of the most important structures of the Python object system is the structure that defines a new type: the PyTypeObject structure. Type objects can be handled using any of the PyObject_* or PyType_* functions, but do not offer much that's interesting to most Python applications.

What is Py_INCREF?

void Py_INCREF (PyObject *o) Increment the reference count for object o. This function is usually used to convert a borrowed reference to a strong reference in-place. The Py_NewRef() function can be used to create a new strong reference.


2 Answers

Python objects don't have a C type, they have a Python type. For example, an integer can be an C long or a long integer. You can check for the type with PyInt_Check(obj), PyList_Check(obj), etc. If that returns true then you know you have an object of that type.

Note that PyLong_FromLong and such go the other way. They take a C value and turn it into a PyObject*. So you're using them backwards. I think you meant PyInt_AsLong.

like image 116
Adam Avatar answered Sep 30 '22 06:09

Adam


That's not quite how Python types work; they don't map to C types one-to-one. There is no Python C/API function that will tell you what C type a particular value will fit in. There are, however, functions like PyFloat_Check() and PyInt_Check() that check the type (and consider subclasses as well.) There are also specifiers to PyArg_ParseTuple() (and its variants) that tell Python to convert a passed-in argument appropriately.

The usual thing to use is the latter; decode the arguments passed to a C function with PyArg_ParseTuple(), and if you need different types being passed treated differently, pass them as different arguments (usually as named arguments.) It's not clear if that approach can work for you. The second most usual thing to do is try to convert the argument using different functions without doing a typecheck first, and simply try another conversion function when one fails. The explicit typecheck is generally the least common alternative.

like image 31
Thomas Wouters Avatar answered Sep 30 '22 08:09

Thomas Wouters