The problem is that in Python code you can pass to a function that
requests a function(pointer), types.FunctionType (Maybe other types
too, didn't try though) which is in fact a type-type.
And then the PyCallable_Check won't *detect* that it's not a real
function(pointer) passed...then later when you intend to run that
function, you get an error.
Python:
import types
func(types.FunctionType)
# instead of
def f():
print "bug?!"
func(f)
C:
PyObject* module_func(PyObject* pSelf, PyObject* pArgs)
{
PyObject* CallbackFunction = NULL;
if (!PyArg_ParseTuple(pArgs, "O", &CallbackFunction)) return NULL;
// FLAW: NEXT IF STATEMENT WON'T DETECT IT'S A TYPE-TYPE AND NOT A
REAL FUNCTION!
if (!PyCallable_Check(CallbackFunction)) ...
...
...
...
}
I hope I made myself clear with this point.
Let me know what you think.
Arkon,
http://www.ragestorm.net
> Hello,
> I encountered in a bug (or so I think) in the function
> PyCallable_Check, Python C API.
>
> The problem is that in Python code you can pass to a function that
> requests a function(pointer), types.FunctionType (Maybe other types
> too, didn't try though) which is in fact a type-type.
>
> And then the PyCallable_Check won't *detect* that it's not a real
> function(pointer) passed...then later when you intend to run that
> function, you get an error.
FunctionType _is_ callable - in fact it can be used as a constructor:
>>> import types
>>> co = compile("print 1", "<string>", "exec")
>>> f = types.FunctionType(co, locals())
>>> f()
1
>>>
So basically PyCallable_Check works properly. And as python is a
dynamically typed language, I don't see how you can actually restrict the
type of values passed beyond that callable-check.
--
Regards,
Diez B. Roggisch
PyCallable_Check does as it is told, it checks whether the argument can be
called.
There are loads of callable things in Python, method references being just one
of them. A class is callable (instantiation or overridden __metaclass__ or
the like), an instance is callable (using the __call__ method of the class),
and many other things too. What you're seeing (complaining about) is that
types are nothing else than classes, and so they are callable too.
If you really have to check that it is a function, you'll have to check the
type of the reference for types.FunctionType.
HTH!
Heiko.
Well, I wasn't sure from the beginning,
but thanks for making it clear to me, I haven't thought of it in that way!
As for Diez B. Roggisch example
I get "TypeError: cannot create 'function' instances"...
Arkon
> As for Diez B. Roggisch example
> I get "TypeError: cannot create 'function' instances"...
Maybe its a version issue - it works for me with Python 2.2.3+ and Python
2.3.3.