asizeof.py (41873B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\pympler\asizeof.py 2 from __future__ import print_function 3 from inspect import isbuiltin, isclass, iscode, isframe, isfunction, ismethod, ismodule, stack 4 from math import log 5 from os import curdir, linesep 6 from struct import calcsize 7 import sys 8 import types as Types 9 import warnings 10 import weakref as Weakref 11 __all__ = ['adict', 12 'asized', 13 'asizeof', 14 'asizesof', 15 'Asized', 16 'Asizer', 17 'basicsize', 18 'flatsize', 19 'itemsize', 20 'leng', 21 'refs'] 22 if __name__ == '__main__': 23 _builtin_modules = (int.__module__, 'types', Exception.__module__) 24 else: 25 _builtin_modules = (int.__module__, 26 'types', 27 Exception.__module__, 28 __name__) 29 _sizeof_Cbyte = calcsize('c') 30 _sizeof_Clong = calcsize('l') 31 _sizeof_Cvoidp = calcsize('P') 32 33 def _calcsize(fmt): 34 if _sizeof_Clong < _sizeof_Cvoidp: 35 z = 'P' 36 else: 37 z = 'L' 38 return calcsize(fmt.replace('z', z)) 39 40 41 _sizeof_CPyCodeObject = _calcsize('Pz10P5i0P') 42 _sizeof_CPyFrameObject = _calcsize('Pzz13P63i0P') 43 _sizeof_CPyModuleObject = _calcsize('PzP0P') 44 _sizeof_CPyDictEntry = _calcsize('z2P') 45 _sizeof_Csetentry = _calcsize('lP') 46 try: 47 _sizeof_Cdigit = long.__itemsize__ 48 except NameError: 49 _sizeof_Cdigit = int.__itemsize__ 50 51 if _sizeof_Cdigit < 2: 52 raise AssertionError('sizeof(%s) bad: %d' % ('digit', _sizeof_Cdigit)) 53 try: 54 u = unicode('\x00') 55 except NameError: 56 u = '\x00' 57 58 u = u.encode('unicode-internal') 59 _sizeof_Cunicode = len(u) 60 del u 61 try: 62 import _testcapi as t 63 _sizeof_CPyGC_Head = t.SIZEOF_PYGC_HEAD 64 except (ImportError, AttributeError): 65 t = calcsize('2d') - 1 66 _sizeof_CPyGC_Head = _calcsize('2Pz') + t & ~t 67 68 del t 69 if hasattr(sys, 'gettotalrefcount'): 70 _sizeof_Crefcounts = _calcsize('2z') 71 else: 72 _sizeof_Crefcounts = 0 73 try: 74 from abc import ABCMeta 75 except ImportError: 76 77 class ABCMeta(type): 78 pass 79 80 81 _Py_TPFLAGS_HEAPTYPE = 1 << 9 82 _Py_TPFLAGS_HAVE_GC = 1 << 14 83 _Type_type = type(type) 84 85 def _items(obj): 86 return getattr(obj, 'iteritems', obj.items)() 87 88 89 def _keys(obj): 90 return getattr(obj, 'iterkeys', obj.keys)() 91 92 93 def _values(obj): 94 return getattr(obj, 'itervalues', obj.values)() 95 96 97 try: 98 _callable = callable 99 except NameError: 100 101 def _callable(obj): 102 return hasattr(obj, '__call__') 103 104 105 try: 106 from gc import get_referents as _getreferents 107 except ImportError: 108 109 def _getreferents(unused): 110 return () 111 112 113 _getsizeof = getattr(sys, 'getsizeof', None) 114 version = sys.version_info 115 _getsizeof_bugs = getattr(sys, 'getsizeof', None) and (version[0] == 2 and version < (2, 7, 4) or version[0] == 3 and version < (3, 2, 4)) 116 117 def _getsizeof_exclude(getsizeof, exclude): 118 119 def _getsizeof_wrapper(obj, default): 120 if isinstance(obj, exclude): 121 return default 122 else: 123 return getsizeof(obj, default) 124 125 return _getsizeof_wrapper 126 127 128 try: 129 _intern = intern 130 except NameError: 131 132 def _intern(val): 133 return val 134 135 136 def _basicsize(t, base = 0, heap = False, obj = None): 137 s = max(getattr(t, '__basicsize__', 0), base) 138 if t != _Type_type: 139 h = getattr(t, '__flags__', 0) & _Py_TPFLAGS_HAVE_GC 140 elif heap: 141 h = True 142 else: 143 h = getattr(obj, '__flags__', 0) & _Py_TPFLAGS_HEAPTYPE 144 if h: 145 s += _sizeof_CPyGC_Head 146 return s + _sizeof_Crefcounts 147 148 149 def _derive_typedef(typ): 150 v = [ v for v in _values(_typedefs) if _issubclass(typ, v.type) ] 151 if len(v) == 1: 152 return v[0] 153 154 155 def _dir2(obj, pref = '', excl = (), slots = None, itor = ''): 156 if slots: 157 if hasattr(obj, slots): 158 s = {} 159 for c in type(obj).mro(): 160 for a in getattr(c, slots, ()): 161 if a.startswith('__'): 162 a = '_' + c.__name__ + a 163 if hasattr(obj, a): 164 s.setdefault(a, getattr(obj, a)) 165 166 yield (slots, _Slots(s)) 167 for t in _items(s): 168 yield t 169 170 elif itor: 171 for o in obj: 172 yield (itor, o) 173 174 else: 175 for a in dir(obj): 176 if a.startswith(pref) and a not in excl and hasattr(obj, a): 177 yield (a, getattr(obj, a)) 178 179 180 def _infer_dict(obj): 181 for ats in (('__len__', 'get', 'has_key', 'items', 'keys', 'values'), ('__len__', 'get', 'has_key', 'iteritems', 'iterkeys', 'itervalues')): 182 if all((_callable(getattr(obj, a, None)) for a in ats)): 183 return True 184 185 return False 186 187 188 def _isdictclass(obj): 189 c = getattr(obj, '__class__', None) 190 return c and c.__name__ in _dict_classes.get(c.__module__, ()) 191 192 193 def _issubclass(sub, sup): 194 if sup is not object: 195 try: 196 return issubclass(sub, sup) 197 except TypeError: 198 pass 199 200 return False 201 202 203 closure = (lambda x: lambda : x)(None) 204 try: 205 cell_type = type(closure.__closure__[0]) 206 except AttributeError: 207 cell_type = type(closure.__closure__[0]) 208 209 def _iscell(obj): 210 return isinstance(obj, cell_type) 211 212 213 def _isnamedtuple(obj): 214 return isinstance(obj, tuple) and hasattr(obj, '_fields') 215 216 217 def _itemsize(t, item = 0): 218 return getattr(t, '__itemsize__', 0) or item 219 220 221 def _kwdstr(**kwds): 222 return ', '.join(sorted(('%s=%r' % kv for kv in _items(kwds)))) 223 224 225 def _lengstr(obj): 226 n = leng(obj) 227 if n is None: 228 r = '' 229 elif n > _len(obj): 230 r = ' leng %d!' % n 231 else: 232 r = ' leng %d' % n 233 return r 234 235 236 def _nameof(obj, dflt = ''): 237 return getattr(obj, '__name__', dflt) 238 239 240 def _objs_opts(objs, all = None, **opts): 241 if objs: 242 t = objs 243 elif all in (False, None): 244 t = () 245 elif all is True: 246 t = tuple(_values(sys.modules)) + (globals(), stack(sys.getrecursionlimit())[2:]) 247 else: 248 raise ValueError('invalid option: %s=%r' % ('all', all)) 249 return (t, opts) 250 251 252 def _p100(part, total, prec = 1): 253 r = float(total) 254 if r: 255 r = part * 100.0 / r 256 return '%.*f%%' % (prec, r) 257 return 'n/a' 258 259 260 def _plural(num): 261 if num == 1: 262 s = '' 263 else: 264 s = 's' 265 return s 266 267 268 def _power2(n): 269 p2 = 16 270 while n > p2: 271 p2 += p2 272 273 return p2 274 275 276 def _prepr(obj, clip = 0): 277 return _repr(obj, clip=clip).strip('<>').replace("'", '') 278 279 280 def _printf(fmt, *args, **print3opts): 281 if print3opts: 282 f = print3opts.get('file', None) or sys.stdout 283 if args: 284 f.write(fmt % args) 285 else: 286 f.write(fmt) 287 f.write(print3opts.get('end', linesep)) 288 elif args: 289 print(fmt % args) 290 else: 291 print(fmt) 292 293 294 def _refs(obj, named, *ats, **kwds): 295 if named: 296 for a in ats: 297 if hasattr(obj, a): 298 yield _NamedRef(a, getattr(obj, a)) 299 300 if kwds: 301 for a, o in _dir2(obj, **kwds): 302 yield _NamedRef(a, o) 303 304 else: 305 for a in ats: 306 if hasattr(obj, a): 307 yield getattr(obj, a) 308 309 if kwds: 310 for _, o in _dir2(obj, **kwds): 311 yield o 312 313 314 def _repr(obj, clip = 80): 315 try: 316 r = repr(obj) 317 except Exception: 318 r = 'N/A' 319 320 if 0 < clip < len(r): 321 h = clip // 2 - 2 322 if h > 0: 323 r = r[:h] + '....' + r[-h:] 324 return r 325 326 327 def _SI(size, K = 1024, i = 'i'): 328 if 1 < K < size: 329 f = float(size) 330 for si in iter('KMGPTE'): 331 f /= K 332 if f < K: 333 return ' or %.1f %s%sB' % (f, si, i) 334 335 return '' 336 337 338 def _SI2(size, **kwds): 339 return str(size) + _SI(size, **kwds) 340 341 342 def _class_refs(obj, named): 343 return _refs(obj, named, '__class__', '__dict__', '__doc__', '__mro__', '__name__', '__slots__', '__weakref__') 344 345 346 def _co_refs(obj, named): 347 return _refs(obj, named, pref='co_') 348 349 350 def _dict_refs(obj, named): 351 if named: 352 for k, v in _items(obj): 353 s = str(k) 354 yield _NamedRef('[K] ' + s, k) 355 yield _NamedRef('[V] ' + s + ': ' + _repr(v), v) 356 357 else: 358 try: 359 for k, v in _items(obj): 360 yield k 361 yield v 362 363 except ReferenceError: 364 warnings.warn("Reference error while iterating over '%s'" % str(obj.__class__)) 365 366 367 def _enum_refs(obj, named): 368 return _refs(obj, named, '__doc__') 369 370 371 def _exc_refs(obj, named): 372 return _refs(obj, named, 'args', 'filename', 'lineno', 'msg', 'text') 373 374 375 def _file_refs(obj, named): 376 return _refs(obj, named, 'mode', 'name') 377 378 379 def _frame_refs(obj, named): 380 return _refs(obj, named, pref='f_') 381 382 383 def _func_refs(obj, named): 384 return _refs(obj, named, '__doc__', '__name__', '__code__', '__closure__', pref='func_', excl=('func_globals',)) 385 386 387 def _cell_refs(obj, named): 388 return _refs(obj, named, 'cell_contents') 389 390 391 def _namedtuple_refs(obj, named): 392 return _refs(obj, named, '__class__', slots='__slots__') 393 394 395 def _gen_refs(obj, named): 396 f = getattr(obj, 'gi_frame', None) 397 return _refs(f, named, 'f_locals', 'f_code') 398 399 400 def _im_refs(obj, named): 401 return _refs(obj, named, '__doc__', '__name__', '__code__', pref='im_') 402 403 404 def _inst_refs(obj, named): 405 return _refs(obj, named, '__dict__', '__class__', slots='__slots__') 406 407 408 def _iter_refs(obj, named): 409 r = _getreferents(obj) 410 return _refs(r, named, itor=_nameof(obj) or 'iteref') 411 412 413 def _module_refs(obj, named): 414 if obj.__name__ == __name__: 415 return () 416 return _dict_refs(obj.__dict__, named) 417 418 419 def _prop_refs(obj, named): 420 return _refs(obj, named, '__doc__', pref='f') 421 422 423 def _seq_refs(obj, unused): 424 return obj 425 426 427 def _stat_refs(obj, named): 428 return _refs(obj, named, pref='st_') 429 430 431 def _statvfs_refs(obj, named): 432 return _refs(obj, named, pref='f_') 433 434 435 def _tb_refs(obj, named): 436 return _refs(obj, named, pref='tb_') 437 438 439 def _type_refs(obj, named): 440 return _refs(obj, named, '__dict__', '__doc__', '__mro__', '__name__', '__slots__', '__weakref__') 441 442 443 def _weak_refs(obj, unused): 444 try: 445 return (obj(),) 446 except: 447 return () 448 449 450 _all_refs = (None, 451 _cell_refs, 452 _class_refs, 453 _co_refs, 454 _dict_refs, 455 _enum_refs, 456 _exc_refs, 457 _file_refs, 458 _frame_refs, 459 _func_refs, 460 _gen_refs, 461 _im_refs, 462 _inst_refs, 463 _iter_refs, 464 _module_refs, 465 _namedtuple_refs, 466 _prop_refs, 467 _seq_refs, 468 _stat_refs, 469 _statvfs_refs, 470 _tb_refs, 471 _type_refs, 472 _weak_refs) 473 474 def _len(obj): 475 try: 476 return len(obj) 477 except TypeError: 478 return 0 479 480 481 def _len_array(obj): 482 return len(obj) * obj.itemsize 483 484 485 def _len_bytearray(obj): 486 return obj.__alloc__() 487 488 489 def _len_code(obj): 490 return obj.co_stacksize + obj.co_nlocals + _len(obj.co_freevars) + _len(obj.co_cellvars) - 1 491 492 493 def _len_dict(obj): 494 n = len(obj) 495 if n < 6: 496 n = 0 497 else: 498 n = _power2(n + 1) 499 return n 500 501 502 def _len_frame(obj): 503 c = getattr(obj, 'f_code', None) 504 if c: 505 n = _len_code(c) 506 else: 507 n = 0 508 return n 509 510 511 _digit2p2 = 1 << (_sizeof_Cdigit << 3) 512 _digitmax = _digit2p2 - 1 513 _digitlog = 1.0 / log(_digit2p2) 514 515 def _len_int(obj): 516 if obj: 517 n, i = 1, abs(obj) 518 if i > _digitmax: 519 n += int(log(i) * _digitlog) 520 else: 521 n = 0 522 return n 523 524 525 def _len_iter(obj): 526 n = getattr(obj, '__length_hint__', None) 527 if n: 528 n = n() 529 else: 530 n = _len(obj) 531 return n 532 533 534 def _len_list(obj): 535 n = len(obj) 536 if n > 8: 537 n += 6 + (n >> 3) 538 elif n: 539 n += 4 540 return n 541 542 543 def _len_module(obj): 544 return _len(obj.__dict__) 545 546 547 def _len_set(obj): 548 n = len(obj) 549 if n > 8: 550 n = _power2(n + n - 2) 551 elif n: 552 n = 8 553 return n 554 555 556 def _len_slice(obj): 557 try: 558 return (obj.stop - obj.start + 1) // obj.step 559 except (AttributeError, TypeError): 560 return 0 561 562 563 def _len_slots(obj): 564 return len(obj) - 1 565 566 567 def _len_struct(obj): 568 try: 569 return obj.size 570 except AttributeError: 571 return 0 572 573 574 def _len_unicode(obj): 575 return len(obj) + 1 576 577 578 _all_lengs = (None, 579 _len, 580 _len_array, 581 _len_bytearray, 582 _len_code, 583 _len_dict, 584 _len_frame, 585 _len_int, 586 _len_iter, 587 _len_list, 588 _len_module, 589 _len_set, 590 _len_slice, 591 _len_slots, 592 _len_struct, 593 _len_unicode) 594 _old_style = '*' 595 _new_style = '' 596 597 class _Claskey(object): 598 __slots__ = ('_obj', '_sty') 599 600 def __init__(self, obj, style): 601 self._obj = obj 602 self._sty = style 603 604 def __str__(self): 605 r = str(self._obj) 606 if r.endswith('>'): 607 r = '%s%s def>' % (r[:-1], self._sty) 608 elif self._sty is _old_style and not r.startswith('class '): 609 r = 'class %s%s def' % (r, self._sty) 610 else: 611 r = '%s%s def' % (r, self._sty) 612 return r 613 614 __repr__ = __str__ 615 616 617 _claskeys = {} 618 619 def _claskey(obj, style): 620 i = id(obj) 621 k = _claskeys.get(i, None) 622 if not k: 623 _claskeys[i] = k = _Claskey(obj, style) 624 return k 625 626 627 try: 628 _Types_ClassType = Types.ClassType 629 _Types_InstanceType = Types.InstanceType 630 631 class _Instkey(object): 632 __slots__ = ('_obj',) 633 634 def __init__(self, obj): 635 self._obj = obj 636 637 def __str__(self): 638 return '<class %s.%s%s>' % (self._obj.__module__, self._obj.__name__, _old_style) 639 640 __repr__ = __str__ 641 642 643 _instkeys = {} 644 645 def _instkey(obj): 646 i = id(obj) 647 k = _instkeys.get(i, None) 648 if not k: 649 _instkeys[i] = k = _Instkey(obj) 650 return k 651 652 653 def _keytuple(obj): 654 t = type(obj) 655 if t is _Types_InstanceType: 656 t = obj.__class__ 657 return (_claskey(t, _old_style), _instkey(t)) 658 if t is _Types_ClassType: 659 return (_claskey(obj, _old_style), _instkey(obj)) 660 if t is _Type_type: 661 return (_claskey(obj, _new_style), obj) 662 return (None, None) 663 664 665 def _objkey(obj): 666 k = type(obj) 667 if k is _Types_InstanceType: 668 k = _instkey(obj.__class__) 669 elif k is _Types_ClassType: 670 k = _claskey(obj, _old_style) 671 elif k is _Type_type: 672 k = _claskey(obj, _new_style) 673 return k 674 675 676 except AttributeError: 677 678 def _keytuple(obj): 679 if type(obj) is _Type_type: 680 return (_claskey(obj, _new_style), obj) 681 return (None, None) 682 683 684 def _objkey(obj): 685 k = type(obj) 686 if k is _Type_type: 687 k = _claskey(obj, _new_style) 688 return k 689 690 691 class _NamedRef(object): 692 __slots__ = ('name', 'ref') 693 694 def __init__(self, name, ref): 695 self.name = name 696 self.ref = ref 697 698 699 class _Slots(tuple): 700 pass 701 702 703 _i = _intern 704 _all_kinds = _kind_static, _kind_dynamic, _kind_derived, _kind_ignored, _kind_inferred = (_i('static'), 705 _i('dynamic'), 706 _i('derived'), 707 _i('ignored'), 708 _i('inferred')) 709 del _i 710 711 class _Typedef(object): 712 __slots__ = {'base': 0, 713 'item': 0, 714 'leng': None, 715 'refs': None, 716 'both': None, 717 'kind': None, 718 'type': None} 719 720 def __init__(self, **kwds): 721 self.reset(**kwds) 722 723 def __lt__(self, unused): 724 return True 725 726 def __repr__(self): 727 return repr(self.args()) 728 729 def __str__(self): 730 t = [str(self.base), str(self.item)] 731 for f in (self.leng, self.refs): 732 if f: 733 t.append(f.__name__) 734 else: 735 t.append('n/a') 736 737 if not self.both: 738 t.append('(code only)') 739 return ', '.join(t) 740 741 def args(self): 742 return (self.base, 743 self.item, 744 self.leng, 745 self.refs, 746 self.both, 747 self.kind, 748 self.type) 749 750 def dup(self, other = None, **kwds): 751 if other is None: 752 d = _dict_typedef.kwds() 753 else: 754 d = other.kwds() 755 d.update(kwds) 756 self.reset(**d) 757 758 def flat(self, obj, mask = 0): 759 s = self.base 760 if self.leng and self.item > 0: 761 s += self.leng(obj) * self.item 762 if _getsizeof: 763 s = _getsizeof(obj, s) 764 if mask: 765 s = s + mask & ~mask 766 return s 767 768 def format(self): 769 c = n = '' 770 if not self.both: 771 c = ' (code only)' 772 if self.leng: 773 n = ' (%s)' % _nameof(self.leng) 774 return dict(base=self.base, item=self.item, leng=n, code=c, kind=self.kind) 775 776 def kwds(self): 777 return dict(base=self.base, item=self.item, leng=self.leng, refs=self.refs, both=self.both, kind=self.kind, type=self.type) 778 779 def save(self, t, base = 0, heap = False): 780 c, k = _keytuple(t) 781 if k and k not in _typedefs: 782 _typedefs[k] = self 783 if c and c not in _typedefs: 784 if t.__module__ in _builtin_modules: 785 k = _kind_ignored 786 else: 787 k = self.kind 788 _typedefs[c] = _Typedef(base=_basicsize(type(t), base=base, heap=heap), refs=_type_refs, both=False, kind=k, type=t) 789 elif isbuiltin(t) and t not in _typedefs: 790 _typedefs[t] = _Typedef(base=_basicsize(t, base=base), both=False, kind=_kind_ignored, type=t) 791 else: 792 raise KeyError('asizeof typedef %r bad: %r %r' % (self, (c, k), self.both)) 793 794 def set(self, safe_len = False, **kwds): 795 if kwds: 796 d = self.kwds() 797 d.update(kwds) 798 self.reset(**d) 799 if safe_len and self.item: 800 self.leng = _len 801 802 def reset(self, base = 0, item = 0, leng = None, refs = None, both = True, kind = None, type = None): 803 if base < 0: 804 raise ValueError('invalid option: %s=%r' % ('base', base)) 805 else: 806 self.base = base 807 if item < 0: 808 raise ValueError('invalid option: %s=%r' % ('item', item)) 809 else: 810 self.item = item 811 if leng in _all_lengs: 812 self.leng = leng 813 else: 814 raise ValueError('invalid option: %s=%r' % ('leng', leng)) 815 if refs in _all_refs: 816 self.refs = refs 817 else: 818 raise ValueError('invalid option: %s=%r' % ('refs', refs)) 819 if both in (False, True): 820 self.both = both 821 else: 822 raise ValueError('invalid option: %s=%r' % ('both', both)) 823 if kind in _all_kinds: 824 self.kind = kind 825 else: 826 raise ValueError('invalid option: %s=%r' % ('kind', kind)) 827 self.type = type 828 829 830 _typedefs = {} 831 832 def _typedef_both(t, base = 0, item = 0, leng = None, refs = None, kind = _kind_static, heap = False): 833 v = _Typedef(base=_basicsize(t, base=base), item=_itemsize(t, item), refs=refs, leng=leng, both=True, kind=kind, type=t) 834 v.save(t, base=base, heap=heap) 835 return v 836 837 838 def _typedef_code(t, base = 0, refs = None, kind = _kind_static, heap = False): 839 v = _Typedef(base=_basicsize(t, base=base), refs=refs, both=False, kind=kind, type=t) 840 v.save(t, base=base, heap=heap) 841 return v 842 843 844 _typedef_both(complex) 845 _typedef_both(float) 846 _typedef_both(list, refs=_seq_refs, leng=_len_list, item=_sizeof_Cvoidp) 847 _typedef_both(tuple, refs=_seq_refs, leng=_len, item=_sizeof_Cvoidp) 848 _typedef_both(property, refs=_prop_refs) 849 _typedef_both(type(Ellipsis)) 850 _typedef_both(type(None)) 851 _typedef_both(_Slots, item=_sizeof_Cvoidp, leng=_len_slots, refs=None, heap=True) 852 _dict_typedef = _typedef_both(dict, item=_sizeof_CPyDictEntry, leng=_len_dict, refs=_dict_refs) 853 try: 854 _typedef_both(Types.DictProxyType, item=_sizeof_CPyDictEntry, leng=_len_dict, refs=_dict_refs) 855 except AttributeError: 856 _typedef_both(type(_Typedef.__dict__), item=_sizeof_CPyDictEntry, leng=_len_dict, refs=_dict_refs) 857 858 _dict_classes = {'UserDict': ('IterableUserDict', 'UserDict'), 859 'weakref': ('WeakKeyDictionary', 'WeakValueDictionary')} 860 try: 861 _typedef_both(Types.ModuleType, base=_dict_typedef.base, item=_dict_typedef.item + _sizeof_CPyModuleObject, leng=_len_module, refs=_module_refs) 862 except AttributeError: 863 pass 864 865 try: 866 from array import array 867 _typedef_both(array, leng=_len_array, item=_sizeof_Cbyte) 868 if _getsizeof_bugs: 869 _getsizeof = _getsizeof_exclude(_getsizeof, array) 870 except ImportError: 871 pass 872 873 try: 874 _typedef_both(bool) 875 except NameError: 876 pass 877 878 try: 879 _typedef_both(basestring, leng=None) 880 except NameError: 881 pass 882 883 try: 884 if isbuiltin(buffer): 885 _typedef_both(type(buffer('')), item=_sizeof_Cbyte, leng=_len) 886 else: 887 _typedef_both(buffer, item=_sizeof_Cbyte, leng=_len) 888 except NameError: 889 pass 890 891 try: 892 _typedef_both(bytearray, item=_sizeof_Cbyte, leng=_len_bytearray) 893 except NameError: 894 pass 895 896 try: 897 if type(bytes) is not type(str): 898 _typedef_both(bytes, item=_sizeof_Cbyte, leng=_len) 899 except NameError: 900 pass 901 902 try: 903 _typedef_both(str8, item=_sizeof_Cbyte, leng=_len) 904 except NameError: 905 pass 906 907 try: 908 _typedef_both(enumerate, refs=_enum_refs) 909 except NameError: 910 pass 911 912 try: 913 _typedef_both(Exception, refs=_exc_refs) 914 except: 915 pass 916 917 try: 918 _typedef_both(file, refs=_file_refs) 919 except NameError: 920 pass 921 922 try: 923 _typedef_both(frozenset, item=_sizeof_Csetentry, leng=_len_set, refs=_seq_refs) 924 except NameError: 925 pass 926 927 try: 928 _typedef_both(set, item=_sizeof_Csetentry, leng=_len_set, refs=_seq_refs) 929 except NameError: 930 pass 931 932 try: 933 _typedef_both(Types.GetSetDescriptorType) 934 except AttributeError: 935 pass 936 937 try: 938 _typedef_both(long, item=_sizeof_Cdigit, leng=_len_int) 939 _typedef_both(int) 940 except NameError: 941 _typedef_both(int, item=_sizeof_Cdigit, leng=_len_int) 942 943 try: 944 _typedef_both(Types.MemberDescriptorType) 945 except AttributeError: 946 pass 947 948 try: 949 _typedef_both(type(NotImplemented)) 950 except NameError: 951 pass 952 953 try: 954 _typedef_both(range) 955 except NameError: 956 pass 957 958 try: 959 _typedef_both(xrange) 960 except NameError: 961 pass 962 963 try: 964 _typedef_both(reversed, refs=_enum_refs) 965 except NameError: 966 pass 967 968 try: 969 _typedef_both(slice, item=_sizeof_Cvoidp, leng=_len_slice) 970 except NameError: 971 pass 972 973 try: 974 from os import stat 975 _typedef_both(type(stat(curdir)), refs=_stat_refs) 976 except ImportError: 977 pass 978 979 try: 980 from os import statvfs 981 _typedef_both(type(statvfs(curdir)), refs=_statvfs_refs, item=_sizeof_Cvoidp, leng=_len) 982 except ImportError: 983 pass 984 985 try: 986 from struct import Struct 987 _typedef_both(Struct, item=_sizeof_Cbyte, leng=_len_struct) 988 except ImportError: 989 pass 990 991 try: 992 _typedef_both(Types.TracebackType, refs=_tb_refs) 993 except AttributeError: 994 pass 995 996 try: 997 _typedef_both(unicode, leng=_len_unicode, item=_sizeof_Cunicode) 998 _typedef_both(str, leng=_len, item=_sizeof_Cbyte) 999 except NameError: 1000 _typedef_both(str, leng=_len_unicode, item=_sizeof_Cunicode) 1001 1002 try: 1003 _typedef_both(Weakref.KeyedRef, refs=_weak_refs, heap=True) 1004 except AttributeError: 1005 pass 1006 1007 try: 1008 _typedef_both(Weakref.ProxyType) 1009 except AttributeError: 1010 pass 1011 1012 try: 1013 _typedef_both(Weakref.ReferenceType, refs=_weak_refs) 1014 except AttributeError: 1015 pass 1016 1017 _typedef_code(object, kind=_kind_ignored) 1018 _typedef_code(super, kind=_kind_ignored) 1019 _typedef_code(_Type_type, kind=_kind_ignored) 1020 try: 1021 _typedef_code(classmethod, refs=_im_refs) 1022 except NameError: 1023 pass 1024 1025 try: 1026 _typedef_code(staticmethod, refs=_im_refs) 1027 except NameError: 1028 pass 1029 1030 try: 1031 _typedef_code(Types.MethodType, refs=_im_refs) 1032 except NameError: 1033 pass 1034 1035 try: 1036 _typedef_code(Types.GeneratorType, refs=_gen_refs) 1037 except AttributeError: 1038 pass 1039 1040 try: 1041 _typedef_code(Weakref.CallableProxyType, refs=_weak_refs) 1042 except AttributeError: 1043 pass 1044 1045 s = [_items({}), _keys({}), _values({})] 1046 try: 1047 s.extend([reversed([]), reversed(())]) 1048 except NameError: 1049 pass 1050 1051 try: 1052 s.append(xrange(1)) 1053 except NameError: 1054 pass 1055 1056 try: 1057 from re import finditer 1058 s.append(finditer('', '')) 1059 except ImportError: 1060 pass 1061 1062 for t in _values(_typedefs): 1063 if t.type and t.leng: 1064 try: 1065 s.append(t.type()) 1066 except TypeError: 1067 pass 1068 1069 for t in s: 1070 try: 1071 i = iter(t) 1072 _typedef_both(type(i), leng=_len_iter, refs=_iter_refs, item=0) 1073 except (KeyError, TypeError): 1074 pass 1075 1076 del i 1077 del s 1078 del t 1079 1080 def _typedef(obj, derive = False, infer = False): 1081 t = type(obj) 1082 v = _Typedef(base=_basicsize(t, obj=obj), kind=_kind_dynamic, type=t) 1083 if ismodule(obj): 1084 v.dup(item=_dict_typedef.item + _sizeof_CPyModuleObject, leng=_len_module, refs=_module_refs) 1085 elif isframe(obj): 1086 v.set(base=_basicsize(t, base=_sizeof_CPyFrameObject, obj=obj), item=_itemsize(t), leng=_len_frame, refs=_frame_refs) 1087 elif iscode(obj): 1088 v.set(base=_basicsize(t, base=_sizeof_CPyCodeObject, obj=obj), item=_sizeof_Cvoidp, leng=_len_code, refs=_co_refs, both=False) 1089 elif _callable(obj): 1090 if isclass(obj): 1091 v.set(refs=_class_refs, both=False) 1092 if getattr(obj, '__module__', None) in _builtin_modules: 1093 v.set(kind=_kind_ignored) 1094 elif isbuiltin(obj): 1095 v.set(both=False, kind=_kind_ignored) 1096 elif isfunction(obj): 1097 v.set(refs=_func_refs, both=False) 1098 elif ismethod(obj): 1099 v.set(refs=_im_refs, both=False) 1100 elif isclass(t): 1101 v.set(item=_itemsize(t), safe_len=True, refs=_inst_refs) 1102 else: 1103 v.set(both=False) 1104 elif _issubclass(t, dict): 1105 v.dup(kind=_kind_derived) 1106 elif _isdictclass(obj) or infer and _infer_dict(obj): 1107 v.dup(kind=_kind_inferred) 1108 elif _iscell(obj): 1109 v.set(item=_itemsize(t), refs=_cell_refs) 1110 elif _isnamedtuple(obj): 1111 v.set(refs=_namedtuple_refs) 1112 elif getattr(obj, '__module__', None) in _builtin_modules: 1113 v.set(kind=_kind_ignored) 1114 else: 1115 if derive: 1116 p = _derive_typedef(t) 1117 if p: 1118 v.dup(other=p, kind=_kind_derived) 1119 return v 1120 if _issubclass(t, Exception): 1121 v.set(item=_itemsize(t), safe_len=True, refs=_exc_refs, kind=_kind_derived) 1122 elif isinstance(obj, Exception): 1123 v.set(item=_itemsize(t), safe_len=True, refs=_exc_refs) 1124 else: 1125 v.set(item=_itemsize(t), safe_len=True, refs=_inst_refs) 1126 return v 1127 1128 1129 class _Prof(object): 1130 total = 0 1131 high = 0 1132 number = 0 1133 objref = None 1134 weak = False 1135 1136 def __cmp__(self, other): 1137 if self.total < other.total: 1138 return -1 1139 if self.total > other.total: 1140 return +1 1141 if self.number < other.number: 1142 return -1 1143 if self.number > other.number: 1144 return +1 1145 return 0 1146 1147 def __lt__(self, other): 1148 return self.__cmp__(other) < 0 1149 1150 def format(self, clip = 0, grand = None): 1151 if self.number > 1: 1152 a, p = int(self.total / self.number), 's' 1153 else: 1154 a, p = self.total, '' 1155 o = self.objref 1156 if self.weak: 1157 o = o() 1158 t = _SI2(self.total) 1159 if grand: 1160 t += ' (%s)' % _p100(self.total, grand, prec=0) 1161 return dict(avg=_SI2(a), high=_SI2(self.high), lengstr=_lengstr(o), obj=_repr(o, clip=clip), plural=p, total=t) 1162 1163 def update(self, obj, size): 1164 self.number += 1 1165 self.total += size 1166 if self.high < size: 1167 self.high = size 1168 try: 1169 self.objref, self.weak = Weakref.ref(obj), True 1170 except TypeError: 1171 self.objref, self.weak = obj, False 1172 1173 1174 class Asized(object): 1175 1176 def __init__(self, size, flat, refs = (), name = None): 1177 self.size = size 1178 self.flat = flat 1179 self.name = name 1180 self.refs = tuple(refs) 1181 1182 def __str__(self): 1183 return 'size %r, flat %r, refs[%d], name %r' % (self.size, 1184 self.flat, 1185 len(self.refs), 1186 self.name) 1187 1188 def get(self, name): 1189 for ref in self.refs: 1190 if name == ref.name: 1191 return ref 1192 1193 def format(self, format = '%(name)s size=%(size)d flat=%(flat)d', depth = -1, order_by = 'size', indent = ''): 1194 representation = indent + format % self.__dict__ 1195 if depth != 0: 1196 indent = indent + ' ' 1197 reverse = order_by in ('size', 'flat') 1198 refs = sorted(self.refs, key=lambda x: getattr(x, order_by), reverse=reverse) 1199 refs = [ ref.format(format, depth - 1, order_by, indent) for ref in refs ] 1200 representation = '\n'.join([representation] + refs) 1201 return representation 1202 1203 1204 class Asizer(object): 1205 _align_ = 8 1206 _clip_ = 80 1207 _code_ = False 1208 _derive_ = False 1209 _detail_ = 0 1210 _infer_ = False 1211 _limit_ = 100 1212 _stats_ = 0 1213 _cutoff = 0 1214 _depth = 0 1215 _duplicate = 0 1216 _excl_d = None 1217 _ign_d = _kind_ignored 1218 _incl = '' 1219 _mask = 7 1220 _missed = 0 1221 _profile = False 1222 _profs = None 1223 _seen = None 1224 _total = 0 1225 _stream = None 1226 1227 def __init__(self, **opts): 1228 self._excl_d = {} 1229 self.reset(**opts) 1230 1231 def _printf(self, *args, **kwargs): 1232 if self._stream and not kwargs.get('file'): 1233 kwargs['file'] = self._stream 1234 _printf(*args, **kwargs) 1235 1236 def _clear(self): 1237 self._depth = 0 1238 self._duplicate = 0 1239 self._incl = '' 1240 self._missed = 0 1241 self._profile = False 1242 self._profs = {} 1243 self._seen = {} 1244 self._total = 0 1245 for k in _keys(self._excl_d): 1246 self._excl_d[k] = 0 1247 1248 def _nameof(self, obj): 1249 return _nameof(obj, '') or self._repr(obj) 1250 1251 def _prepr(self, obj): 1252 return _prepr(obj, clip=self._clip_) 1253 1254 def _prof(self, key): 1255 p = self._profs.get(key, None) 1256 if not p: 1257 self._profs[key] = p = _Prof() 1258 return p 1259 1260 def _repr(self, obj): 1261 return _repr(obj, clip=self._clip_) 1262 1263 def _sizer(self, obj, deep, sized): 1264 s, f, i = 0, 0, id(obj) 1265 if i in self._seen: 1266 if deep: 1267 self._seen[i] += 1 1268 if sized: 1269 s = sized(s, f, name=self._nameof(obj)) 1270 return s 1271 else: 1272 self._seen[i] = 0 1273 try: 1274 k, rs = _objkey(obj), [] 1275 if k in self._excl_d: 1276 self._excl_d[k] += 1 1277 else: 1278 v = _typedefs.get(k, None) 1279 if not v: 1280 _typedefs[k] = v = _typedef(obj, derive=self._derive_, infer=self._infer_) 1281 if (v.both or self._code_) and v.kind is not self._ign_d: 1282 s = f = v.flat(obj, self._mask) 1283 if self._profile: 1284 self._prof(k).update(obj, s) 1285 if v.refs and deep < self._limit_ and not (deep and ismodule(obj)): 1286 r, z, d = v.refs, self._sizer, deep + 1 1287 if sized and deep < self._detail_: 1288 for o in r(obj, True): 1289 if isinstance(o, _NamedRef): 1290 t = z(o.ref, d, sized) 1291 t.name = o.name 1292 else: 1293 t = z(o, d, sized) 1294 t.name = self._nameof(o) 1295 rs.append(t) 1296 s += t.size 1297 1298 else: 1299 for o in r(obj, False): 1300 s += z(o, d, None) 1301 1302 if self._depth < d: 1303 self._depth = d 1304 self._seen[i] += 1 1305 except RuntimeError: 1306 self._missed += 1 1307 1308 if sized: 1309 s = sized(s, f, name=self._nameof(obj), refs=rs) 1310 return s 1311 1312 def _sizes(self, objs, sized = None): 1313 self.exclude_refs(*objs) 1314 s, t = {}, [] 1315 for o in objs: 1316 i = id(o) 1317 if i in s: 1318 self._seen[i] += 1 1319 self._duplicate += 1 1320 else: 1321 s[i] = self._sizer(o, 0, sized) 1322 t.append(s[i]) 1323 1324 if sized: 1325 s = sum((i.size for i in _values(s))) 1326 else: 1327 s = sum(_values(s)) 1328 self._total += s 1329 return (s, tuple(t)) 1330 1331 def asized(self, *objs, **opts): 1332 if opts: 1333 self.set(**opts) 1334 _, t = self._sizes(objs, Asized) 1335 if len(t) == 1: 1336 t = t[0] 1337 return t 1338 1339 def asizeof(self, *objs, **opts): 1340 if opts: 1341 self.set(**opts) 1342 s, _ = self._sizes(objs, None) 1343 return s 1344 1345 def asizesof(self, *objs, **opts): 1346 if opts: 1347 self.set(**opts) 1348 _, t = self._sizes(objs, None) 1349 return t 1350 1351 def exclude_refs(self, *objs): 1352 for o in objs: 1353 self._seen.setdefault(id(o), 0) 1354 1355 def exclude_types(self, *objs): 1356 for o in objs: 1357 for t in _keytuple(o): 1358 if t and t not in self._excl_d: 1359 self._excl_d[t] = 0 1360 1361 def print_profiles(self, w = 0, cutoff = 0, **print3opts): 1362 t = [ (v, k) for k, v in _items(self._profs) if v.total > 0 or v.number > 1 ] 1363 if len(self._profs) - len(t) < 9: 1364 t = [ (v, k) for k, v in _items(self._profs) ] 1365 if t: 1366 s = '' 1367 if self._total: 1368 s = ' (% of grand total)' 1369 c = max(cutoff, self._cutoff) 1370 c = int(c * 0.01 * self._total) 1371 else: 1372 c = 0 1373 self._printf('%s%*d profile%s: total%s, average, and largest flat size%s: largest object', linesep, w, len(t), _plural(len(t)), s, self._incl, **print3opts) 1374 r = len(t) 1375 for v, k in sorted(t, reverse=True): 1376 s = 'object%(plural)s: %(total)s, %(avg)s, %(high)s: %(obj)s%(lengstr)s' % v.format(self._clip_, self._total) 1377 self._printf('%*d %s %s', w, v.number, self._prepr(k), s, **print3opts) 1378 r -= 1 1379 if r > 1 and v.total < c: 1380 c = max(cutoff, self._cutoff) 1381 self._printf('%+*d profiles below cutoff (%.0f%%)', w, r, c) 1382 break 1383 1384 z = len(self._profs) - len(t) 1385 if z > 0: 1386 self._printf('%+*d %r object%s', w, z, 'zero', _plural(z), **print3opts) 1387 1388 def print_stats(self, objs = (), opts = {}, sized = (), sizes = (), stats = 3.0, **print3opts): 1389 s = min(opts.get('stats', stats) or 0, self._stats_) 1390 if s > 0: 1391 t = self._total + self._missed + sum(_values(self._seen)) 1392 w = len(str(t)) + 1 1393 t = c = '' 1394 o = _kwdstr(**opts) 1395 if o and objs: 1396 c = ', ' 1397 if sized and objs: 1398 n = len(objs) 1399 if n > 1: 1400 self._printf('%sasized(...%s%s) ...', linesep, c, o, **print3opts) 1401 for i in range(n): 1402 self._printf('%*d: %s', (w - 1), i, sized[i], **print3opts) 1403 1404 else: 1405 self._printf('%sasized(%s): %s', linesep, o, sized, **print3opts) 1406 elif sizes and objs: 1407 self._printf('%sasizesof(...%s%s) ...', linesep, c, o, **print3opts) 1408 for z, o in zip(sizes, objs): 1409 self._printf('%*d bytes%s%s: %s', w, z, _SI(z), self._incl, self._repr(o), **print3opts) 1410 1411 else: 1412 if objs: 1413 t = self._repr(objs) 1414 self._printf('%sasizeof(%s%s%s) ...', linesep, t, c, o, **print3opts) 1415 self.print_summary(w=w, objs=objs, **print3opts) 1416 if s > 1: 1417 c = int(s - int(s)) * 100 1418 self.print_profiles(w=w, cutoff=c, **print3opts) 1419 if s > 2: 1420 self.print_typedefs(w=w, **print3opts) 1421 1422 def print_summary(self, w = 0, objs = (), **print3opts): 1423 self._printf('%*d bytes%s%s', w, self._total, _SI(self._total), self._incl, **print3opts) 1424 if self._mask: 1425 self._printf('%*d byte aligned', w, (self._mask + 1), **print3opts) 1426 self._printf('%*d byte sizeof(void*)', w, _sizeof_Cvoidp, **print3opts) 1427 n = len(objs or ()) 1428 if n > 0: 1429 d = self._duplicate or '' 1430 if d: 1431 d = ', %d duplicate' % self._duplicate 1432 self._printf('%*d object%s given%s', w, n, _plural(n), d, **print3opts) 1433 t = sum((1 for t in _values(self._seen) if t != 0)) 1434 self._printf('%*d object%s sized', w, t, _plural(t), **print3opts) 1435 if self._excl_d: 1436 t = sum(_values(self._excl_d)) 1437 self._printf('%*d object%s excluded', w, t, _plural(t), **print3opts) 1438 t = sum(_values(self._seen)) 1439 self._printf('%*d object%s seen', w, t, _plural(t), **print3opts) 1440 if self._missed > 0: 1441 self._printf('%*d object%s missed', w, self._missed, _plural(self._missed), **print3opts) 1442 if self._depth > 0: 1443 self._printf('%*d recursion depth', w, self._depth, **print3opts) 1444 1445 def print_typedefs(self, w = 0, **print3opts): 1446 for k in _all_kinds: 1447 t = [ (self._prepr(a), v) for a, v in _items(_typedefs) if v.kind == k and (v.both or self._code_) ] 1448 if t: 1449 self._printf('%s%*d %s type%s: basicsize, itemsize, _len_(), _refs()', linesep, w, len(t), k, _plural(len(t)), **print3opts) 1450 for a, v in sorted(t): 1451 self._printf('%*s %s: %s', w, '', a, v, **print3opts) 1452 1453 t = sum((len(v) for v in _values(_dict_classes))) 1454 if t: 1455 self._printf('%s%*d dict/-like classes:', linesep, w, t, **print3opts) 1456 for m, v in _items(_dict_classes): 1457 self._printf('%*s %s: %s', w, '', m, self._prepr(v), **print3opts) 1458 1459 def set(self, align = None, code = None, detail = None, limit = None, stats = None): 1460 if align is not None: 1461 self._align_ = align 1462 if align > 1: 1463 self._mask = align - 1 1464 if self._mask & align != 0: 1465 raise ValueError('invalid option: %s=%r' % ('align', align)) 1466 else: 1467 self._mask = 0 1468 if code is not None: 1469 self._code_ = code 1470 if code: 1471 self._incl = ' (incl. code)' 1472 if detail is not None: 1473 self._detail_ = detail 1474 if limit is not None: 1475 self._limit_ = limit 1476 if stats is not None: 1477 self._stats_ = s = int(stats) 1478 self._cutoff = (stats - s) * 100 1479 if s > 1: 1480 self._profile = True 1481 else: 1482 self._profile = False 1483 1484 def _get_duplicate(self): 1485 return self._duplicate 1486 1487 duplicate = property(_get_duplicate, doc=_get_duplicate.__doc__) 1488 1489 def _get_missed(self): 1490 return self._missed 1491 1492 missed = property(_get_missed, doc=_get_missed.__doc__) 1493 1494 def _get_total(self): 1495 return self._total 1496 1497 total = property(_get_total, doc=_get_total.__doc__) 1498 1499 def reset(self, align = 8, clip = 80, code = False, derive = False, detail = 0, ignored = True, infer = False, limit = 100, stats = 0, stream = None): 1500 self._align_ = align 1501 self._clip_ = clip 1502 self._code_ = code 1503 self._derive_ = derive 1504 self._detail_ = detail 1505 self._infer_ = infer 1506 self._limit_ = limit 1507 self._stats_ = stats 1508 self._stream = stream 1509 if ignored: 1510 self._ign_d = _kind_ignored 1511 else: 1512 self._ign_d = None 1513 self._clear() 1514 self.set(align=align, code=code, stats=stats) 1515 1516 1517 def adict(*classes): 1518 a = True 1519 for c in classes: 1520 if isclass(c) and _infer_dict(c): 1521 t = _dict_classes.get(c.__module__, ()) 1522 if c.__name__ not in t: 1523 _dict_classes[c.__module__] = t + (c.__name__,) 1524 else: 1525 a = False 1526 1527 return a 1528 1529 1530 _asizer = Asizer() 1531 1532 def asized(*objs, **opts): 1533 if 'all' in opts: 1534 raise KeyError('invalid option: %s=%r' % ('all', opts['all'])) 1535 if objs: 1536 _asizer.reset(**opts) 1537 t = _asizer.asized(*objs) 1538 _asizer.print_stats(objs, opts=opts, sized=t) 1539 _asizer._clear() 1540 else: 1541 t = () 1542 return t 1543 1544 1545 def asizeof(*objs, **opts): 1546 t, p = _objs_opts(objs, **opts) 1547 if t: 1548 _asizer.reset(**p) 1549 s = _asizer.asizeof(*t) 1550 _asizer.print_stats(objs=t, opts=opts) 1551 _asizer._clear() 1552 else: 1553 s = 0 1554 return s 1555 1556 1557 def asizesof(*objs, **opts): 1558 if 'all' in opts: 1559 raise KeyError('invalid option: %s=%r' % ('all', opts['all'])) 1560 if objs: 1561 _asizer.reset(**opts) 1562 t = _asizer.asizesof(*objs) 1563 _asizer.print_stats(objs, opts=opts, sizes=t) 1564 _asizer._clear() 1565 else: 1566 t = () 1567 return t 1568 1569 1570 def _typedefof(obj, save = False, **opts): 1571 k = _objkey(obj) 1572 v = _typedefs.get(k, None) 1573 if not v: 1574 v = _typedef(obj, **opts) 1575 if save: 1576 _typedefs[k] = v 1577 return v 1578 1579 1580 def basicsize(obj, **opts): 1581 v = _typedefof(obj, **opts) 1582 if v: 1583 v = v.base 1584 return v 1585 1586 1587 def flatsize(obj, align = 0, **opts): 1588 v = _typedefof(obj, **opts) 1589 if v: 1590 if align > 1: 1591 m = align - 1 1592 if align & m != 0: 1593 raise ValueError('invalid option: %s=%r' % ('align', align)) 1594 else: 1595 m = 0 1596 v = v.flat(obj, m) 1597 return v 1598 1599 1600 def itemsize(obj, **opts): 1601 v = _typedefof(obj, **opts) 1602 if v: 1603 v = v.item 1604 return v 1605 1606 1607 def leng(obj, **opts): 1608 v = _typedefof(obj, **opts) 1609 if v: 1610 v = v.leng 1611 if v and _callable(v): 1612 v = v(obj) 1613 return v 1614 1615 1616 def refs(obj, **opts): 1617 v = _typedefof(obj, **opts) 1618 if v: 1619 v = v.refs 1620 if v and _callable(v): 1621 v = v(obj, False) 1622 return v 1623 1624 1625 def named_refs(obj): 1626 refs = [] 1627 v = _typedefof(obj) 1628 if v: 1629 v = v.refs 1630 if v and _callable(v): 1631 for ref in v(obj, True): 1632 try: 1633 refs.append((ref.name, ref.ref)) 1634 except AttributeError: 1635 pass 1636 1637 return refs