PyCheck for a classes defined in python and user data in PyObject_HEAD

S

sndive

q#1:
in C I want to check if a given PyObject is a xml.dom.minidom.Node (or
a derivative).
how do i extract a PyTypeObject for such a class?

issue #2
I'm in a situation when i don't really need to extend python with any
classes of my own but
i do have extra luggage for the python data structures such as tuples,
lists, dictionaries, etc
on the c++ side. I see no place in PyObject_HEAD where i can stick a
void* to my extra data.
If i enter a feature request into bugzilla for python do you think it
will be well received?
#ifdefed of course like the prev/next extras.
I'm surprised noone else is using evil twin approach.
The reason i'm asking is because while for dictionaries i can stick
weak pointer back to my c++
object in a key with an obscure name while in lists this would change
the list size and thus
is obviously not as easy to "hide" from the client code.
a placeholder in a pyobject would've been of help here
 
G

Gabriel Genellina

nevermind, i found an instance object that will work for me
as long as i figure out where is the documentation
beyond this:
http://docs.python.org/api/instanceObjects.html
on the data attrib access and extracting PyClassObject from it.

classic_class = PyObject_GetAttrString( your_classic_instance, "__class__")

Assuming you can recompile all the extensions you use, you could insert
your void* into _PyObject_HEAD_EXTRA and _PyObject_EXTRA_INIT

I think a code patch + test suite + doc patches will be much more well
received...
 
H

Hrvoje Niksic

Note that there is a mailing list dedicated to the Python/C API,
http://mail.python.org/mailman/listinfo/capi-sig

issue #2 I'm in a situation when i don't really need to extend
python with any classes of my own but i do have extra luggage for
the python data structures such as tuples, lists, dictionaries, etc
on the c++ side. I see no place in PyObject_HEAD where i can stick a
void* to my extra data.

Adding additional luggage is a valid definition of extending. :)

Simply inherit from the desired data structure, and add the pointers
you need to the extended structure. If you must add extra data to
existing Python objects created by someone else, then you can use a
weak dictionary:

import weakref
_map = {} # can't use WeakKeyDictionary because we need
# mapping by identity

def set_extra_data(obj, data):
# use id(obj) as key to map by object identity
ident = id(obj)
ref = weakref.ref(obj, lambda x: _map.pop(ident))
_map[ident] = ref, data

def extra_data(obj):
if id(obj) not in _map:
raise TypeError("object has no extra data")
ref, data = _map[id(obj)]
assert ref() is obj
return data
 
S

sndive

classic_class = PyObject_GetAttrString( your_classic_instance, "__class__")


Assuming you can recompile all the extensions you use, you could insert
your void* into _PyObject_HEAD_EXTRA and _PyObject_EXTRA_INIT

i added two void pointers to head_extra and 0,0, to the extra_init.
For some reason i get garbage in them from PyEval_EvalCode :-(
(that's after i blew the build dir and rebuilt 2.4.4 from scratch
so i don't think i have a bad build)
 
G

Gabriel Genellina

i added two void pointers to head_extra and 0,0, to the extra_init.
For some reason i get garbage in them from PyEval_EvalCode :-(
(that's after i blew the build dir and rebuilt 2.4.4 from scratch
so i don't think i have a bad build)

Can't you use instead the other approaches suggested on this thread? Like
keeping a weakkey dictionary holding your additional attributes? Seems a
lot safer to do that way.

I've never changed that headers myself so I can't guarantee it works.
Perhaps there are some assumptions somewhere in the code about a specific
layout. But since _PyObject_HEAD_EXTRA is used in the debug build I think
you should be able to add your own fields, at least in principle...
Remember that this change invalidates ALL binaries for ANY library or
extension you may be using. An additional check might be to change the
Python release number to 2.9.9 or so, so none of your existing extensions
can inadvertidely be used.
 
S

sndive

En Fri, 16 Nov 2007 00:27:42 -0300, <[email protected]> escribió:





Can't you use instead the other approaches suggested on this thread? Like
keeping a weakkey dictionary holding your additional attributes? Seems a
lot safer to do that way.

I've never changed that headers myself so I can't guarantee it works.
Perhaps there are some assumptions somewhere in the code about a specific
layout. But since _PyObject_HEAD_EXTRA is used in the debug build I think
you should be able to add your own fields, at least in principle...

i finally found that i need to reset my fields in _Py_NewReference(op)
also.
weakref approach won't work for me because i need extra data in lists/
dictionaries/tuples in addition to instances of classes
(all instances of all classes: can't derive and essentially
make my own bloated psl to maintain)
Remember that this change invalidates ALL binaries for ANY library or
extension you may be using. An additional check might be to change the

that's not a problem since i build with a prefix other than /usr/local
and the target is an embedded system so i have full control over
the environment (until someone cracks it :)

i finally got most of the code working after i figured out that
HEAD_INIT is ignored by tuple allocation code, etc
and _Py_NewReference has to be modified.

thank all of you for all the help. you got me unstuck.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,175
Messages
2,570,945
Members
47,492
Latest member
gabbywilliam

Latest Threads

Top