Skip to content

Commit c2cc946

Browse files
committed
added basic project
0 parents  commit c2cc946

File tree

6 files changed

+240
-0
lines changed

6 files changed

+240
-0
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.DS_Store
2+
build/*
3+
di.so
4+
*.pyc

LICENSE.txt

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License
2+
3+
Copyright (c) 2007 Bill Bumgarner <[email protected]>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.rst

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
Copyright 2007 Bill Bumgarner All Rights Reserved.
2+
Copyright 2014 Christopher Barker All Rights Reserved.
3+
4+
MIT License -- Free as in "free".
5+
6+
7+
This is a verison of Bill Bumgarner's "di" module.
8+
9+
http://www.friday.com/bbum/2007/08/24/python-di/
10+
http://svn.red-bean.com/bbum/trunk/hacques/di/
11+
12+
This is the di module as is, with the addition of another function::
13+
14+
ref_by_id()
15+
16+
``di(i)`` returns an object given its id ( as returned by ``id(obj)`` ).
17+
18+
``ref_by_id(i)`` returns the reference count of the the object by its id.
19+
20+
This is useful for debugging memory leaks, reference counting errors, etc.
21+
For instance, if you have a circular reference, objects can never have
22+
their reference count reduced to zero, and thsu will never be deleted.
23+
But all references to them maybe have been, so there is no way to get
24+
their reference count info in the usual way.
25+
26+
Note that both of these functions are very dangerous -- if you pass in
27+
an invalid id, you can (will!) get a segmentation fault and a hard crash.
28+
29+
Usage::
30+
31+
>>> obj = {'a' : 'b', 1 : 2}
32+
>>> from di import di, ref_by_id
33+
>>> id(obj)
34+
681856
35+
>>> di(681856)
36+
{'a': 'b', 1: 2}
37+
38+
>>> obj = ['a', 'list', 'of', 'stuff']
39+
>>> obj_id = id(obj)
40+
>>> ref_by_id(obj_id)
41+
1
42+
>>> a = b = c = obj
43+
>>> ref_by_id(obj_id)
44+
4
45+
>>> del obj
46+
>>> ref_by_id(obj_id)
47+
3
48+
>>> del b,c
49+
>>> ref_by_id(obj_id)
50+
1
51+
>>> del a
52+
>>> ref_by_id(obj_id)
53+
0
54+
55+
56+
Don't use this in production code. That would be stupid.
57+
This is, however, very useful for debugging purposes.
58+
59+
Building
60+
---------
61+
62+
The usual setup.py dance::
63+
64+
python setup.py build_ext --inplace
65+
66+
will build it in place.
67+
68+
To install::
69+
70+
python setup.py install
71+
72+
Or in develop mode:
73+
74+
python setup.py develop
75+

di.c

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#include <Python/Python.h>
2+
#include <stdio.h> /* for printf*/
3+
4+
PyDoc_STRVAR(di_di_doc,
5+
"Given the result of id(), returns a Python object reference.");
6+
7+
static PyObject *
8+
di_di(PyObject *self, PyObject *args)
9+
{
10+
PyObject *obj;
11+
if (!PyArg_ParseTuple(args, "l:di", &obj))
12+
return NULL;
13+
14+
Py_INCREF(obj);
15+
return obj;
16+
}
17+
18+
PyDoc_STRVAR(di_ref_by_id_doc,
19+
"returns the refcount of the python object with the given id.");
20+
21+
static PyObject *
22+
di_ref_by_id(PyObject *self, PyObject *args)
23+
{
24+
PyObject *obj;
25+
PyObject *refcount;
26+
27+
if (!PyArg_ParseTuple(args, "l:di", &obj))
28+
return NULL;
29+
30+
refcount = PyInt_FromLong(Py_REFCNT(obj));
31+
32+
Py_INCREF(refcount); /* Is this required? */
33+
return refcount;
34+
}
35+
36+
37+
static PyMethodDef di_methods[] = {
38+
{"di", di_di, METH_VARARGS, di_di_doc},
39+
{"ref_by_id", di_ref_by_id, METH_VARARGS, di_ref_by_id_doc},
40+
{NULL, NULL}
41+
};
42+
43+
PyDoc_STRVAR(di_doc, "Convert id() back to an object.");
44+
45+
PyMODINIT_FUNC
46+
initdi(void)
47+
{
48+
PyObject *m;
49+
50+
m = Py_InitModule3("di", di_methods, di_doc);
51+
if (m == NULL) return;
52+
}
53+
54+
/*
55+
56+
The MIT License
57+
58+
Copyright (c) 2007 Bill Bumgarner <[email protected]>
59+
60+
Permission is hereby granted, free of charge, to any person obtaining a copy
61+
of this software and associated documentation files (the "Software"), to deal
62+
in the Software without restriction, including without limitation the rights
63+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
64+
copies of the Software, and to permit persons to whom the Software is
65+
furnished to do so, subject to the following conditions:
66+
67+
The above copyright notice and this permission notice shall be included in
68+
all copies or substantial portions of the Software.
69+
70+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
71+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
72+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
73+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
74+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
75+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
76+
THE SOFTWARE.
77+
78+
*/

setup.py

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from distutils.core import setup
2+
from distutils.extension import Extension
3+
setup(
4+
name = 'di',
5+
version = '0.1',
6+
description = 'Turn an id() back into a Python object reference.',
7+
long_description = 'Turn an id() back into a Python object reference. Kind of like running with scissors.',
8+
maintainer = 'Bill Bumgarner',
9+
maintainer_email = '[email protected]',
10+
license = 'MIT',
11+
ext_modules=[
12+
Extension(
13+
'di',
14+
['di.c'],
15+
),
16+
],
17+
)
18+

test_di.py

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/vn python
2+
3+
"""
4+
some really simple test code
5+
6+
mostly to assure you that it compiled
7+
"""
8+
9+
from di import di, ref_by_id
10+
11+
12+
def test_di_1():
13+
14+
obj = {'a': 'b', 1: 2}
15+
obj_id = id(obj)
16+
assert di(obj_id) == obj
17+
18+
19+
def test_ref_by_id_1():
20+
obj = ['a', 'list', 'of', 'stuff']
21+
obj_id = id(obj)
22+
assert ref_by_id(obj_id) == 1
23+
24+
25+
def test_ref_by_id_2():
26+
""" does a few more counts """
27+
obj = ['a', 'list', 'of', 'stuff']
28+
obj_id = id(obj)
29+
30+
assert ref_by_id(obj_id) == 1
31+
32+
a = b = c = obj
33+
assert ref_by_id(obj_id) == 4
34+
35+
del obj
36+
assert ref_by_id(obj_id) == 3
37+
38+
del b,c
39+
assert ref_by_id(obj_id) == 1
40+
41+
del a
42+
assert ref_by_id(obj_id) == 0 # note: dangerous!
43+
## if that memory location gets re-used, this will break!
44+
## and could segfault hard.

0 commit comments

Comments
 (0)