Derakon, 03.07.2013 22:36:
> I'm working on a game project; specifically, right now I'm working on game
> state serialization. And before you ask, I'm not using pickle or any
> similar third-party serialization library because they invariably allow for
> serialization of code or bytecode. As a result, deserializing a file could
> potentially do anything; I want my users to be able to share savefiles
> without worrying that they might be doing something nasty.
You'll still have to take care what you deserialise if you allow for
arbitrary function/method references.
> Anyway, I have a system built up that can, among other things,
> automatically recognize method and object references and [de]serialize
> them. When it encounters a method reference, it:
>
> 1) Accesses the im_self property of the method to get the object that the
> method is bound to (e.g. foo.func.im_self is foo)
> 2) Ensures that that object is serialized
> 3) Records a special string that allows me to decode the method reference
> later
>
> This works fine for pure-Python methods, but now I've run into some Cython
> objects I have kicking around. These don't pass the "isinstance(value,
> types.MethodType)" test
Yep, CPython makes this really tricky. Patching the types module works in
some cases.
Eventually, I'd like to see this supported via the ABC framework.
http://www.python.org/dev/peps/pep-3119/#overloading-isinstance-and-issubclass
You can give it a try if you want.
> because their type is cython_function_or_method,
> which is completely different. They also don't have an im_self property. So
> I have the following questions:
>
> 1) How can I recognize that an object I am working with is a Cython method?
By type name? Or by testing for
type(some_obj) is type(definitely_a_cython_function)
as long as you stay inside of the same module. The latter doesn't currently
work across module boundaries, which is considered a bug (but is unlikely
to get fixed tomorrow).
> 2) Can I go from a Cython method to the object that the method is bound to?
> If so, how?
Have you tried func.__self__ ?
Stefan