Easy questions from a python beginner

Thomas Jollans thomas at jollans.com
Fri Jul 23 13:13:45 EDT 2010


On 07/23/2010 12:34 AM, wheres pythonmonks wrote:
> 2.  Is there a better way to loopup by id?  I'm not very familiar with
> sys.exc_info, but creating the id->name hash each time seems like
> overkill.

I just had the most horrendous idea. Really, looking up objects by ID,
or even swapping two objects, isn't that difficult if you do some C
black magic. Don't try this in front of the kids.

I wrote a little module, called "hell":

Python 3.1.2 (release31-maint, Jul  8 2010, 09:18:08)
[GCC 4.4.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> from hell import swap, getptr
>>> dir
<built-in function dir>
>>> len
<built-in function len>
>>> swap(dir, len)
>>> dir
<built-in function len>
>>> len
<built-in function dir>
>>> a = "this was a"
>>> b = "this was b, hell yeah"
>>> (a, b, id(a), id(b))
('this was a', 'this was b, hell yeah', 32417752, 32418144)
>>> tpl = (a, b, id(a), id(b))
>>> tpl
('this was a', 'this was b, hell yeah', 32417752, 32418144)
>>> swap(a, b)
>>> tpl
('this was b, hell yeah', 'this was a', 32417752, 32418144)
>>> getptr(32417752)
'this was b, hell yeah'
>>>


The code is below. Use it under the terms of the WTFPL version 2.
(http://sam.zoy.org/wtfpl/)

 -- Thomas

PS: all of this is a very BAD IDEA. But interesting, in a way.


################# setup.py ############
from distutils.core import setup, Extension

hellmodule = Extension('hell',
                       sources = ['hellmodule.c'])

setup (name = 'hellmodule',
       version = '0.1-apocalypse',
       description = 'Functions from hell. Never ever use.',
       ext_modules = [hellmodule])



################# hellmodule.c ##############
#define PY_SSIZE_T_CLEAN
#include <Python.h>

static PyObject *swap(PyObject *self, PyObject *args);
static PyObject *getptr(PyObject *self, PyObject *args);

static PyMethodDef hell_methods[] = {
    {"swap",  &swap,  METH_VARARGS, ""},
    {"getptr", &getptr, METH_VARARGS, ""},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef hell_module = {
    PyModuleDef_HEAD_INIT,
    "hell",                            /* module name */
    "functions from hell. never use.", /* doc */
    -1,
    hell_methods
};

PyMODINIT_FUNC
PyInit_hell(void)
{
    return PyModule_Create(&hell_module);
}

static PyObject *
swap(PyObject *self, PyObject *args)
{
    PyObject *obj1, *obj2;
    Py_ssize_t len;

    PyObject *temp;


    if (!PyArg_ParseTuple(args, "OO", &obj1, &obj2)) {
        return NULL;
    }

    len = obj1->ob_type->tp_basicsize;
    if (obj2->ob_type->tp_basicsize != len) {
        PyErr_SetString(PyExc_TypeError,
            "types have different sizes (incompatible)");
        return NULL;
    }

    temp = PyMem_Malloc(len);
    memcpy(temp, obj1, len);
    memcpy(obj1, obj2, len);
    memcpy(obj2, temp, len);
    obj2->ob_refcnt = obj1->ob_refcnt;
    obj1->ob_refcnt = temp->ob_refcnt;

    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject *
getptr(PyObject *self, PyObject *args)
{
    unsigned long lId;
    PyObject *retv;

    if (!PyArg_ParseTuple(args, "k", &lId)) {
        return NULL;
    }

    retv = (PyObject*) lId;
    Py_INCREF(retv);
    return retv;
}





More information about the Python-list mailing list