Re: [Python-Dev] Feature request: better support for "wrapper" objects
Recently, "Thomas Heller" <thomas.heller@ion-tof.com> said:
Here's an outline which could work in 2.2:
This sounds very good! There's only one thing you'll have to explain to me: how would this work from C? My types are all in C, not in Python, so I'd need to do the magic in C. Where do I find examples of using metatypes from C? I could then put all this wrapper stuff in a file WrapperObject.c and it would be reusable by any object that wanted this functionality.
Create a subtype of type, having a tp_convert slot:
typedef int (*convert_func)(PyTypeObject *, void **);
typedef struct { PyTypeObject type; convert_func tp_convert; } WrapperTypeType;
and use it as metaclass (metatype?) for your WindowObj:
class WindowObj(...): __metaclass__ = WrapperTypeType
Write a function to return a conversion function:
convert_func *get_converter(PyTypeObject *type) { if (WrapperTypeType_Check(type)) return ((WrapperTypeType *)type)->tp_convert; /* code to check additional types and return their converters */ .... }
and then
if (!PyArg_ParseTuple(args, "O&", get_converter(WinObj_Type), &Window))
How does this sound?
Thomas
-- - Jack Jansen <Jack.Jansen@oratrix.com> http://www.cwi.nl/~jack - - If I can't dance I don't want to be part of your revolution -- Emma Goldman -
From: "Jack Jansen" <jack@oratrix.nl>
Recently, "Thomas Heller" <thomas.heller@ion-tof.com> said:
Here's an outline which could work in 2.2:
This sounds very good! There's only one thing you'll have to explain to me: how would this work from C? My types are all in C, not in Python, so I'd need to do the magic in C. Where do I find examples of using metatypes from C?
I don't know of any, well, except ceval.c build_class(): result = PyObject_CallFunction(metaclass, "OOO", name, bases, methods); I had no need for this, because I'm very happy to write base classes/types in C, extend them by deriving subtypes from them in Python, and plugging everything together in Python. Thomas
[Metatypes, callbacks, etc.] Wouldn't it be *much* easier to just use the copyreg/pickle API/protocol for dealing with all this ? AFAICTL, the actions needed by Jack are very similar to what pickle et al. do, and we already have all that in Python -- it's just not exposed too well at C level. Example: PyArg_ParseTuple(args, "O@", &factory, &tuple) would return a factory function and a tuple storing the data of the object passed to the function while Py_BuildValue("O@", factory, tuple) would simply call factory with tuple and use the return value as object. (Note that void* can be wrapped into PyCObjects for "use" in Python.) -- Marc-Andre Lemburg CEO eGenix.com Software GmbH ______________________________________________________________________ Company & Consulting: http://www.egenix.com/ Python Software: http://www.egenix.com/files/python/
From: "M.-A. Lemburg" <mal@lemburg.com>
[Metatypes, callbacks, etc.]
Wouldn't it be *much* easier to just use the copyreg/pickle API/protocol for dealing with all this ?
I *don't* think it's complicated (once you get used to metatypes).
AFAICTL, the actions needed by Jack are very similar to what pickle et al. do, and we already have all that in Python -- it's just not exposed too well at C level.
Example:
PyArg_ParseTuple(args, "O@", &factory, &tuple) would return a factory function and a tuple storing the data of the object passed to the function
while
Py_BuildValue("O@", factory, tuple) would simply call factory with tuple and use the return value as object.
(Note that void* can be wrapped into PyCObjects for "use" in Python.)
I'm not sure we talk about the same thing: we (at least me) do not want to serialize and reconstruct objects (what pickle does), we want to convert objects from Python to C (convert them to parameters usable in C API-calls), and back (convert them from handles, pointers, whatever into Python objects) having only the Python *type* object available in the latter case. Or am I missing something? Thomas
Thomas Heller wrote:
From: "M.-A. Lemburg" <mal@lemburg.com>
[Metatypes, callbacks, etc.]
Wouldn't it be *much* easier to just use the copyreg/pickle API/protocol for dealing with all this ?
I *don't* think it's complicated (once you get used to metatypes).
I hear heads exploding already :-)
AFAICTL, the actions needed by Jack are very similar to what pickle et al. do, and we already have all that in Python -- it's just not exposed too well at C level.
Example:
PyArg_ParseTuple(args, "O@", &factory, &tuple) would return a factory function and a tuple storing the data of the object passed to the function
while
Py_BuildValue("O@", factory, tuple) would simply call factory with tuple and use the return value as object.
(Note that void* can be wrapped into PyCObjects for "use" in Python.)
I'm not sure we talk about the same thing: we (at least me) do not want to serialize and reconstruct objects (what pickle does), we want to convert objects from Python to C (convert them to parameters usable in C API-calls), and back (convert them from handles, pointers, whatever into Python objects) having only the Python *type* object available in the latter case.
Or am I missing something?
I'm not really talking about serializing in the pickle sense (with the intent of storing the data as string), it's more about providing a way to recreate an object within the same process: given an object x, provide a factory function f and a tuple args such that x == apply(f, args). Now, the object Jack has in mind wrap C pointers, so the args would be a tuple containing one PyCObject. Getting the pointer out of a PyCObject is really easy and by using a tuple as intermediate storage form, you can also support more complex objects, e.g. objects wrapping more than one pointer or value. After you have accessed the internal values, possibily calculating new ones, you can then contruct a tuple, pass it to the factory and return the same type of input object as you received no input. Since the API would be fixed, helper functions could be added to make all this really easy at C level. The fact that a registry similar to copyreg or a new method on the input object is used to contruct the factory function and the tuple, this mechanism can easily be extended in Python as well as C. Furthermore, the existing pickle mechanisms could be reused for the existing objects, since most of these use very reasonable state tuples for storing the object state. I'm just suggesting this to make the whole wrapper idea more flexible. One C void* pointer is really only useful for very simple objects. The above easily extends to complex objects such as e.g. mxDateTime objects. -- Marc-Andre Lemburg CEO eGenix.com Software GmbH ______________________________________________________________________ Company & Consulting: http://www.egenix.com/ Python Software: http://www.egenix.com/files/python/
participants (3)
-
Jack Jansen
-
M.-A. Lemburg
-
Thomas Heller