1# Copyright 2021, Kay Hayen, mailto:kay.hayen@gmail.com 2# 3# Part of "Nuitka", an optimizing Python compiler that is compatible and 4# integrates with CPython, but also works on its own. 5# 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17# 18""" Instance counter primitives 19 20We don't use a meta class as it's unnecessary complex, and portable meta classes 21have their difficulties, and want to count classes, who already have a meta 22class. 23 24This is going to expanded with time. 25 26""" 27from nuitka.Options import isShowMemory 28from nuitka.Tracing import printIndented, printLine 29 30counted_inits = {} 31counted_dels = {} 32 33 34def isCountingInstances(): 35 return isShowMemory() 36 37 38def counted_init(init): 39 if isShowMemory(): 40 41 def wrapped_init(self, *args, **kw): 42 name = self.__class__.__name__ 43 assert type(name) is str 44 45 if name not in counted_inits: 46 counted_inits[name] = 0 47 48 counted_inits[name] += 1 49 50 init(self, *args, **kw) 51 52 return wrapped_init 53 else: 54 return init 55 56 57def _wrapped_del(self): 58 # This cannot be necessary, because in program finalization, the 59 # global variables were assign to None. 60 if counted_dels is None: 61 return 62 63 name = self.__class__.__name__ 64 assert type(name) is str 65 66 if name not in counted_dels: 67 counted_dels[name] = 0 68 69 counted_dels[name] += 1 70 71 72def counted_del(): 73 assert isShowMemory() 74 75 return _wrapped_del 76 77 78def printStats(): 79 printLine("Init/del/alive calls:") 80 81 for name, count in sorted(counted_inits.items()): 82 dels = counted_dels.get(name, 0) 83 printIndented(1, name, count, dels, count - dels) 84