scrapy / scrapy
1
"""This module provides some functions and classes to record and report
2
references to live object instances.
3

4
If you want live objects for a particular class to be tracked, you only have to
5
subclass from object_ref (instead of object).
6

7
About performance: This library has a minimal performance impact when enabled,
8
and no performance penalty at all when disabled (as object_ref becomes just an
9
alias to object in that case).
10
"""
11

12 7
from collections import defaultdict
13 7
from operator import itemgetter
14 7
from time import time
15 7
from typing import DefaultDict
16 7
from weakref import WeakKeyDictionary
17

18

19 7
NoneType = type(None)
20 7
live_refs: DefaultDict[type, WeakKeyDictionary] = defaultdict(WeakKeyDictionary)
21

22

23 7
class object_ref:
24
    """Inherit from this class to a keep a record of live instances"""
25

26 7
    __slots__ = ()
27

28 7
    def __new__(cls, *args, **kwargs):
29 7
        obj = object.__new__(cls)
30 7
        live_refs[cls][obj] = time()
31 7
        return obj
32

33

34 7
def format_live_refs(ignore=NoneType):
35
    """Return a tabular representation of tracked objects"""
36 7
    s = "Live References\n\n"
37 7
    now = time()
38 7
    for cls, wdict in sorted(live_refs.items(),
39
                             key=lambda x: x[0].__name__):
40 7
        if not wdict:
41 0
            continue
42 7
        if issubclass(cls, ignore):
43 7
            continue
44 7
        oldest = min(wdict.values())
45 7
        s += f"{cls.__name__:<30} {len(wdict):6}   oldest: {int(now - oldest)}s ago\n"
46 7
    return s
47

48

49 7
def print_live_refs(*a, **kw):
50
    """Print tracked objects"""
51 7
    print(format_live_refs(*a, **kw))
52

53

54 7
def get_oldest(class_name):
55
    """Get the oldest object for a specific class name"""
56 7
    for cls, wdict in live_refs.items():
57 7
        if cls.__name__ == class_name:
58 7
            if not wdict:
59 0
                break
60 7
            return min(wdict.items(), key=itemgetter(1))[0]
61

62

63 7
def iter_all(class_name):
64
    """Iterate over all objects of the same class by its class name"""
65 7
    for cls, wdict in live_refs.items():
66 7
        if cls.__name__ == class_name:
67 7
            return wdict.keys()

Read our documentation on viewing source code .

Loading