def __new__(mcs, class_name, parents, attributes): if "socket.socket" in str(attributes): print(f'Найден атрибут сокета в классе {class_name}') else: print(f'Атрибут сокета в классе {class_name} не найден') for key, value in attributes.items(): try: if 'socket' in code_info(value): print(f'Найден сокет в функции {key}') if 'SOCK_STREAM' in code_info(value): print('Задан тип соединения TCP') else: print('TCP соединение не задано') if 'accept' and 'listen' not in code_info(value): print('Отсутствуют методы accept и listen') print("---------------------") else: print('Методы accept и listen заданы') print("---------------------") else: print(f'Сокет не задан в функции {key}') print("---------------------") except: print(f'{key} атрибут не подлежит разбору') print("--------------------------------------------------") return type.__new__(mcs, class_name, parents, attributes)
def getByteCode(): #https://docs.python.org/3.7/library/dis.html#analysis-functions dis.dis( test ) print('-'*25) dis.code_info( test ) print('-'*25) dis.show_code( test ) print('-'*25) # dis.disco( test ) print('-'*25) dis.get_instructions( test )
def info(self, arguments): """Print information about the current frame's code. Usage: info """ f = self._obj.curframe self._ui.print(dis.code_info(f.f_code))
def __new__(mcs, class_name, parents, attributes): for key, value in attributes.items(): try: if 'socket' in code_info(value): print(f'Найден сокет в функции {key}') if 'SOCK_STREAM' in code_info(value): print('Задан тип соединения TCP') else: print('TCP соединение не задано') if 'connect' not in code_info(value): print('Отсутствует метод connect') print("---------------------") else: print('Метод connect задан') print("---------------------") else: print(f'Сокет не задан в функции {key}') print("---------------------") except: print(f'{key} атрибут не подлежит разбору') print("--------------------------------------------------") return type.__new__(mcs, class_name, parents, attributes)
def notation(func, debug=False): """ Get the asymptotic notation for a Python code object. :param func: The code object to analyse :type func: ``types.CodeType`` :param debug: Show debug information :type debug: ``bool`` :return: Return the notation for a given code object :rtype: :class:`NOTATION_TYPES` """ if debug: print(dis.code_info(func)) bytecode = dis.Bytecode(func) _nested_func = None # Nested functions, e.g. lambdas and comprehensions max_loop_stack_depth = 0 extra_stacks = 0 # setup the loop stacks as a deque loop_stacks = deque() for i in bytecode: if i.opname == FOR_ITER: # basic for loop loop_stacks.append(i.argval) elif i.opname == LOAD_CONST and isinstance(i.argval, types.CodeType): # Load code objects onto the stacks, evaluate the notation of the object # and store locally if that function is loaded. _nested_notation = notation(i.argval, debug=debug) elif i.opname == MAKE_FUNCTION: # Where there is a dynamically-generated function, add the loop-stack-depth of it. if _nested_func: extra_stacks += int(_nested_func) elif i.opname == POP_BLOCK: # pop back up the stack. offset = loop_stacks.pop() if offset != i.offset: # Check the popped value is the offset of the pop_block raise ValueError( "Not implemented, maybe. Or maybe this is a bug.") else: if debug: print(i) if len(loop_stacks) > max_loop_stack_depth: max_loop_stack_depth = len(loop_stacks) return NOTATION_TYPES(max_loop_stack_depth + extra_stacks)
def test_code_info(self): self.maxDiff = 1000 for x, expected in self.test_pairs: self.assertRegex(dis.code_info(x), expected)
from numpy import * from inspect import getsourcefile, getsource, getmodule import dis getsource(sum) getsourcefile(sum) def f(x, y): x, y = y, x dis.dis(f) dis.disassemble(f) dis.show_code(f) dis.code_info(f) f(1, 2) help(dis) str(getmodule(sum)).split('\\')[-3] import sympy as sp x, y, z, t = sp.symbols('x y z t') sp.init_printing() print(sp.Integral(sp.sqrt(1 / x), x))
def myfunc(alist): return len(alist) print(dis.dis(myfunc)) from dis import dis, code_info dis(compile('(1,2,3, "a")', 'string', 'eval')) print('===' * 15) dis(compile('[1,2,3, "a"]', 'string', 'eval')) print('===' * 15) print(code_info(myfunc)) # Name: myfunc # Filename: C:/proj/deepdive/03_Section/dis_simple.py # Argument count: 1 # Positional-only arguments: 0 # Kw-only arguments: 0 # Number of locals: 1 # Stack size: 2 # Flags: OPTIMIZED, NEWLOCALS, NOFREE # Constants: # 0: None # Names: # 0: len # Variable names: # 0: alist
for item in code.co_consts: if isinstance(item, types.CodeType): if item.co_name == name: items.append(item) return items def dis_func(code,name): items=find_code(code,name) for item in items: dis.dis(item) code=marshal.load(open('draw.code','rb')) if(len(sys.argv)>1): if(sys.argv[1]=='-f'): dis_func(code,sys.argv[2]) if(sys.argv[1]=='-i'): if(len(sys.argv)==2): print(dis.code_info(code)) else: print(dis.code_info(find_code(code,sys.argv[2])[0])) if(sys.argv[1]=='-l'): ols=dis.findlinestarts(code) for ol in ols: print(ol) if(sys.argv[1]=='-o'): sys.stdout=open(sys.argv[2],"w") print('main:') dis.dis(code) for item in code.co_consts: if isinstance(item, types.CodeType): print(item.co_name+':') dis.dis(item) if(sys.argv[1]=='-c'):
def compileBytecode(self, code): """ recursively compiles bytecode to min assembly """ btc = dis.get_instructions(code) print(dis.code_info(code)) dis.dis(code) level_name = code.co_name env = Env(code) # if we are not at the toplevel we setup the function prologue if level_name != "<module>": csts = env.getConsts() # Emit const strings before function definition for i, v in enumerate(csts): if v.type == ConstVal.Addr: self.emitter.emitString(env.getStringRef(i), v.value) self.emitter.emitLabel(level_name) self.emitter.emitPrologue(code.co_nlocals) # Copy args into slot for i in range(code.co_argcount): self.emitter.emitStoreSlot(REGS[i], i) for ins in btc: if ins.opname == "MAKE_FUNCTION": name = env.popEvent().value code = env.popEvent().value if not isinstance(code, type(self.compileBytecode.__code__)): raise Exception( "MAKE_FUNCTION instruction with no code object") self.compileBytecode(code) if ins.opname == "CALL_FUNCTION": arg_count = ins.argval if arg_count >= len(REGS) - 1: raise Exception( "Functions must have at most {} arguments".format( len(REGS) - 1)) # TODO: Emit movs of variables into regs env.setupArgs(arg_count, self.emitter) func = env.popEvent().value self.emitter.emitRaw("call #{}".format(func)) env.pushEvent(StackEvent(StackEvent.MAKE_FUNCTION_DUMMY, 0, 0)) if ins.opname == "LOAD_FAST": env.pushEvent( StackEvent(StackEvent.LOAD_FAST, ins.argval, ins.arg)) if ins.opname == "LOAD_CONST": env.pushEvent( StackEvent(StackEvent.LOAD_CONST, ins.argval, ins.arg)) if ins.opname == "LOAD_GLOBAL": env.pushEvent( StackEvent(StackEvent.LOAD_GLOBAL, ins.argval, ins.arg)) if ins.opname == "STORE_FAST": evt = env.popEvent() # We returned from a function if evt.type == StackEvent.MAKE_FUNCTION_DUMMY: self.emitter.emitStoreSlot(REGS[0], evt.index) if evt.type == StackEvent.LOAD_CONST: cstval = env.getConsts()[evt.index] if cstval.type == ConstVal.Imm: self.emitter.emitMovImm(REGS[0], cstval.value) if cstval.type == ConstVal.Addr: self.emitter.emitMovRef(REGS[0], cstval.value) self.emitter.emitStoreSlot(REGS[0], ins.arg) if ins.opname == "RETURN_VALUE": evt = env.popEvent() if evt.type == StackEvent.LOAD_FAST: self.emitter.emitLoadSlot(REGS[0], evt.index) if evt.type == StackEvent.LOAD_CONST: cstval = env.getConsts()[evt.index] if cstval.type == ConstVal.Imm: self.emitter.emitMovImm(REGS[0], cstval.value) if cstval.type == ConstVal.Addr: self.emitter.emitMovAddr(REGS[0], env.getStringRef(evt.index)) if ins.opname.startswith("BINARY") or ins.opname.startswith( "INPLACE"): env.setupArgs(2, self.emitter) if ins.opname == "BINARY_ADD" or ins.opname == "INPLACE_ADD": self.emitter.emitRaw("add $A $B") if ins.opname == "BINARY_MULTIPLY" or ins.opname == "INPLACE_MULTIPLY": self.emitter.emitRaw("mul $A $B") if ins.opname == "BINARY_SUBSTRACT" or ins.opname == "INPLACE_SUBSTRACT": self.emitter.emitRaw("sub $A $B") if ins.opname == "BINARY_LSHIFT": self.emitter.emitRaw("shl $A $B") if ins.opname == "BINARY_RSHIFT": self.emitter.emitRaw("shr $A $B") if ins.opname == "BINARY_AND": self.emitter.emitRaw("and $A $B") if ins.opname == "BINARY_XOR": self.emitter.emitRaw("xor $A $B") if ins.opname == "BINARY_OR": self.emitter.emitRaw("or $A $B") env.pushEvent(StackEvent(StackEvent.MAKE_FUNCTION_DUMMY, 0, 0)) if ins.opname == "SETUP_LOOP": self.emitter.emitLabel(env.addLoop()) if ins.opname == "JUMP_ABSOLUTE": self.emitter.emitRaw("jmp #{}".format(env.getLoopTop())) if ins.opname == "POP_BLOCK": self.emitter.emitRaw(env.popLoop()) if ins.opname == "COMPARE_OP": env.setupArgs(2, self.emitter) env.addComparison(ins.argval) self.emitter.emitRaw("cmp $A $B") env.pushEvent(StackEvent(StackEvent.MAKE_FUNCTION_DUMMY, 0, 0)) if ins.opname == "POP_JUMP_IF_TRUE": cmp = env.popComparison() dest = env.getLoopTop() + "_end" if cmp == '>': self.emitter.emitRaw("jbe #{}".format(dest)) if cmp == '<': self.emitter.emitRaw("jle #{}".format(dest)) if cmp == "==": self.emitter.emitRaw("je #{}".format(dest)) if cmp == "!=": self.emitter.emitRaw("jne #{}".format(dest)) if ins.opname == "POP_JUMP_IF_FALSE": cmp = env.popComparison() dest = env.getLoopTop() + "_end" if cmp == '>': self.emitter.emitRaw("jle #{}".format(dest)) if cmp == '<': self.emitter.emitRaw("jbe #{}".format(dest)) if cmp == "==": self.emitter.emitRaw("jne #{}".format(dest)) if cmp == "!=": self.emitter.emitRaw("je #{}".format(dest)) if level_name != "<module>": self.emitter.emitEpilogue()
def python_code_details(code_text: str): """Get details about the given code_text. This is a wrapper for `dis.code_info`""" import dis return dis.code_info(code_text)
return items def dis_func(code, name): items = find_code(code, name) for item in items: dis.dis(item) code = marshal.load(open('draw.code', 'rb')) if (len(sys.argv) > 1): if (sys.argv[1] == '-f'): dis_func(code, sys.argv[2]) if (sys.argv[1] == '-i'): if (len(sys.argv) == 2): print(dis.code_info(code)) else: print(dis.code_info(find_code(code, sys.argv[2])[0])) if (sys.argv[1] == '-l'): ols = dis.findlinestarts(code) for ol in ols: print(ol) if (sys.argv[1] == '-o'): sys.stdout = open(sys.argv[2], "w") print('main:') dis.dis(code) for item in code.co_consts: if isinstance(item, types.CodeType): print(item.co_name + ':') dis.dis(item) if (sys.argv[1] == '-c'):
""" Based on a question in Freenode #python on March 6th, 2019 about computing the effect of code on the size of the stack """ import dis from pprint import pprint from codetransformer import Code def example(arg): try: arg.x except: return print(dis.code_info(example)) instr = list(dis.get_instructions(example)) sfx = [dis.stack_effect(op.opcode, op.arg) for op in instr] for i, s in zip(instr, sfx): opline = '\t'.join([ f"{thing:<15}" for thing in ('>>' if i.is_jump_target else '', i.offset, i.opname, i.argrepr, f'{s:>5d}') ]) print(opline) c = Code.from_pyfunc(example)
# Looking at python bytecode import dis def byte_cookinator(name): "byte_cookinator function" honorary_title = f"{name}: The Food Cookinator" return f"{honorary_title} is your name." print("\n\nPython dissassembly:") dis.dis(byte_cookinator) code_info = dis.code_info(byte_cookinator) print("\n\n", "Python code_info:", "\n", code_info) bytecode = dis.Bytecode(byte_cookinator) print("\n\n", "Python bytecode info:", "\n", bytecode, "\n\n") for i in bytecode: print(i)
print( '---------------------------------------------------------------------------' ) obj = C() print(dir(obj)) print() print(dir(my_func)) print() print(sorted(set(dir(my_func)) - set(dir(obj)))) print( '---------------------------------------------------------------------------' ) print(dis.dis(my_func.__code__)) print(dis.code_info(my_func.__code__)) print( '---------------------------------------------------------------------------' ) print(tag('br')) print(tag('p', 'hello')) print(tag('p', 'hello', 'world')) print(tag('p', 'hello', id=33)) print(tag('p', 'hello', 'world', cls='sidebar')) print(tag(content='testing', name="img")) my_tag = { 'name': 'img', 'title': 'Sunset Boulevard', 'src': 'sunset.jpg',
def get_code_metadata(f): """ f - function, generator, coroutine, method, source code string, code object return - string """ return " Byte code instructions {0} and {1}".format( dis.dis(f), dis.code_info(f))
def update_event(self, inp=-1): self.set_output_val(0, dis.code_info(self.input(0)))
t = 10 for f_name, op, im in ( ('reduce', f'list(reduce(list(range({arr_size}))))', 'from reduce import reduce'), ('reduce2', f'list(reduce2(list(range({arr_size}))))', 'from reduce2 import reduce2'), ('get_reduced_list', f'get_reduced_list(list(range({arr_size})))', 'from get_reduced_list import get_reduced_list'), ('get_reduced_list2', f'get_reduced_list2(list(range({arr_size})))', 'from get_reduced_list2 import get_reduced_list2'), ('get_reduced_list3', f'get_reduced_list3(list(range({arr_size})))', 'from get_reduced_list3 import get_reduced_list3'), ): print(f'{f_name}: {round(Timer(op, im).timeit(t), 3)}[s]') elif MODE == 'DIS': from dis import dis, code_info from reduce import reduce print(code_info(reduce)) # print(code_info(reduce2)) # print(code_info(get_reduced_list)) # print(code_info(get_reduced_list2)) # print(code_info(get_reduced_list3)) # print(dis(reduced)) print(dis(reduce)) # print(dis(get_reduced_list)) # print(dis(get_reduced_list2)) # print(dis(get_reduced_list3))
return list(filter(lambda item: item > limit, l)) def filter2(l): limit = 5 return [y for y in l if y > limit] import dis dis.dis(filter1) print("-------") dis.dis(filter2) print("CODE INFO") print(dis.code_info(filter2)) # more closures def create_filter(threshold): def filter_it(iterable): return [x for x in iterable if x > threshold] return filter_it t = (1, 2, 3, 4, 5, 6, 7) f = create_filter(2) print(f(t)) f = create_filter(5)