On Thu, Jun 23, 2016 at 8:19 AM, Guido van Rossum <gu...@python.org> wrote:
>
> It was a long time when I wrote this, but IIRC the breakage could express
> itself as a segfault or other C-level crash due to some internal state
> invariant of the type object being violated, not just an exception. The
> existence of ctypes notwithstanding, we take C-level crashes very seriously.
>

Big digression: one can still obtain the dict if they really want to, even
without using ctypes. I suppose don't actually mutate it unless you want to
segfault.

>>> import gc
>>> class A(object): pass
>>> type(A.__dict__)
<class 'mappingproxy'>
>>> type(gc.get_referents(A.__dict__)[0])
<class 'dict'>
>>> gc.get_referents(A.__dict__)[0]['abc'] = 1
>>> A.abc
1
>>>

(One can also get it right from A, but A can have other references, so
maybe that's less reliable.)

I think I wanted this at the time so I could better measure the sizes of
objects. sys.getsizeof(A.__dict__) is very different
from sys.getsizeof(gc.get_referents(A.__dict__)[0]), and also different
from sys.getsizeof(A). For example:

>>> import gc
>>> class A(object): pass
>>> sys.getsizeof(A); sys.getsizeof(A.__dict__);
sys.getsizeof(gc.get_referents(A.__dict__)[0])
976
48
288
>>> for i in range(10000): setattr(A, 'attr_%s' % i, i)
>>> sys.getsizeof(A); sys.getsizeof(A.__dict__);
sys.getsizeof(gc.get_referents(A.__dict__)[0])
976
48
393312

(Fortunately, if you want to walk the object graph to measure memory usage
per object type, you're probably going to be using gc.get_referents already
anyway, so this is just confirmation that you're getting what you want in
one corner case.)

-- Devin
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to