def test_long_typename_with_no_module(self): x = type('MyClass', (), {'__module__': None})() self.assertEqual('MyClass', objgraph._long_typename(x))
def get_new_ids(skip_update=False, limit=10, sortby='deltas', # pylint: disable=dangerous-default-value shortnames=None, ignore_thresholds=IGNORE_THRESHOLDS, output=None, _state={}): """Find and display new objects allocated since last call. Shows the increase in object counts since last call to this function and returns the memory address ids for new objects. Returns a dictionary mapping object type names to sets of object IDs that have been created since the last time this function was called. ``skip_update`` (bool): If True, returns the same dictionary that was returned during the previous call without updating the internal state or examining the objects currently in memory. ``limit`` (int): The maximum number of rows that you want to print data for. Use 0 to suppress the printing. Use None to print everything. ``sortby`` (str): This is the column that you want to sort by in descending order. Possible values are: 'old', 'current', 'new', 'deltas' ``shortnames`` (bool): If True, classes with the same name but defined in different modules will be lumped together. If False, all type names will be qualified with the module name. If None (default), ``get_new_ids`` will remember the value from previous calls, so it's enough to prime this once. By default the primed value is True. ``_state`` (dict): Stores old, current, and new_ids in memory. It is used by the function to store the internal state between calls. Never pass in this argument unless you know what you're doing. The caveats documented in :func:`growth` apply. When one gets new_ids from :func:`get_new_ids`, one can use :func:`at_addrs` to get a list of those objects. Then one can iterate over the new objects, print out what they are, and call :func:`show_backrefs` or :func:`show_chain` to see where they are referenced. Example: >>> _ = get_new_ids() # store current objects in _state >>> _ = get_new_ids() # current_ids become old_ids in _state >>> a = [0, 1, 2] # list we don't know about >>> b = [3, 4, 5] # list we don't know about >>> new_ids = get_new_ids(limit=3) # we see new lists ====================================================================== Type Old_ids Current_ids New_ids Count_Deltas ====================================================================== list 324 326 +3 +2 dict 1125 1125 +0 +0 wrapper_descriptor 1001 1001 +0 +0 ====================================================================== >>> new_lists = at_addrs(new_ids['list']) >>> a in new_lists True >>> b in new_lists True """ if ignore_thresholds is None: ignore_thresholds = IGNORE_THRESHOLDS _initialize_state(_state) new_ids = _state['new'] if skip_update: return new_ids old_ids = _state['old'] current_ids = _state['current'] if shortnames is None: shortnames = _state['shortnames'] else: _state['shortnames'] = shortnames gc.collect() objects = gc.get_objects() for class_name in old_ids: old_ids[class_name].clear() for class_name, ids_set in current_ids.items(): old_ids[class_name].update(ids_set) for class_name in current_ids: current_ids[class_name].clear() for o in objects: if shortnames: class_name = _short_typename(o) else: class_name = _long_typename(o) id_number = id(o) current_ids[class_name].add(id_number) for class_name in new_ids: new_ids[class_name].clear() rows = [] keys_to_remove = [] for class_name in current_ids: num_old = len(old_ids[class_name]) num_current = len(current_ids[class_name]) if num_old == 0 and num_current == 0: # remove the key from our dicts if we don't have any old or # current class_name objects keys_to_remove.append(class_name) continue new_ids_set = current_ids[class_name] - old_ids[class_name] new_ids[class_name].update(new_ids_set) num_new = len(new_ids_set) num_delta = num_current - num_old if num_delta < 1 or (class_name in ignore_thresholds and num_current < ignore_thresholds[class_name]): # ignore types with no net increase or whose overall count isn't large enough to worry us if class_name in new_ids: del new_ids[class_name] continue row = (class_name, num_old, num_current, num_new, num_delta) rows.append(row) for key in keys_to_remove: del old_ids[key] del current_ids[key] if key in new_ids: del new_ids[key] index_by_sortby = {'old': 1, 'current': 2, 'new': 3, 'deltas': 4} rows.sort(key=operator.itemgetter(index_by_sortby[sortby], 0), reverse=True) _show_results(rows, limit, output) return new_ids