Esempio n. 1
0
    def as_traceback(self):
        if tproxy:
            return tproxy(TracebackType, self.__tproxy_handler)
        elif tb_set_next:
            f_code = self.tb_frame.f_code
            code = compile(
                '\n' * (self.tb_lineno - 1) + 'raise __traceback_maker',
                self.tb_frame.f_code.co_filename, 'exec')
            if PY3:
                code = CodeType(0, 0, f_code.co_nlocals, f_code.co_stacksize,
                                f_code.co_flags, code.co_code, code.co_consts,
                                code.co_names, code.co_varnames,
                                f_code.co_filename, f_code.co_name,
                                code.co_firstlineno, b"", (), ())
            else:
                code = CodeType(0, f_code.co_nlocals, f_code.co_stacksize,
                                f_code.co_flags, code.co_code, code.co_consts,
                                code.co_names, code.co_varnames,
                                f_code.co_filename.encode(),
                                f_code.co_name.encode(), code.co_firstlineno,
                                b"", (), ())

            try:
                exec(code, self.tb_frame.f_globals, {})
            except:
                tb = sys.exc_info()[2].tb_next
                tb_set_next(tb, self.tb_next and self.tb_next.as_traceback())
                try:
                    return tb
                finally:
                    del tb
        else:
            raise RuntimeError("Cannot re-create traceback !")
Esempio n. 2
0
def recreate_code(code, codes_offsets, codes_lines):
    """Recreate code with new lnotab


    Arguments:
    code -- original code object
    codes_offsets -- updated list of offsets
    codes_lines -- updated list of lines
    """
    offsets = codes_offsets[id(code)]
    lines = codes_lines[id(code)]
    new_lnotab = reconstruct_lnotab(code.co_firstlineno, offsets, lines)
    new_consts = []
    for const in code.co_consts:
        if isinstance(const, CodeType):
            new_consts.append(recreate_code(const, codes_offsets, codes_lines))
        else:
            new_consts.append(const)

    if PY3:
        new_code = CodeType(code.co_argcount, code.co_kwonlyargcount,
                            code.co_nlocals,
                            code.co_stacksize, code.co_flags, code.co_code,
                            tuple(new_consts), code.co_names, code.co_varnames,
                            code.co_filename, code.co_name,
                            code.co_firstlineno, new_lnotab, code.co_freevars,
                            code.co_cellvars)
    else:
        new_code = CodeType(code.co_argcount, code.co_nlocals,
                            code.co_stacksize, code.co_flags, code.co_code,
                            tuple(new_consts), code.co_names, code.co_varnames,
                            code.co_filename, code.co_name,
                            code.co_firstlineno, new_lnotab, code.co_freevars,
                            code.co_cellvars)
    return new_code
Esempio n. 3
0
 def rename(f):
     if not isinstance(f, (LambdaType, FunctionType)):
         # TODO: Can't raise TypeError; @fploop et al. do-it-now-and-replace-def-with-result
         # TODO: decorators need to do this.
         return f
     f = copy(f)
     # __name__ for tools like pydoc; __qualname__ for repr(); __code__.co_name for stack traces
     #     https://stackoverflow.com/questions/40661758/name-of-a-python-function-in-a-stack-trace
     #     https://stackoverflow.com/questions/16064409/how-to-create-a-code-object-in-python
     f.__name__ = name
     j = f.__qualname__.rfind('.')
     f.__qualname__ = "{}.{}".format(f.__qualname__[:j],
                                     name) if j != -1 else name
     # __code__.co_name is read-only, but there's a types.CodeType constructor
     # that we can use to re-create the code object with the new name.
     # (This is no worse than what the stdlib's Lib/modulefinder.py already does.)
     co = f.__code__
     # https://github.com/ipython/ipython/blob/master/IPython/core/interactiveshell.py
     # https://www.python.org/dev/peps/pep-0570/
     if version_info > (3, 8, 0, 'alpha', 3):  # Python 3.8+
         f.__code__ = CodeType(co.co_argcount, co.co_posonlyargcount,
                               co.co_kwonlyargcount, co.co_nlocals,
                               co.co_stacksize, co.co_flags, co.co_code,
                               co.co_consts, co.co_names, co.co_varnames,
                               co.co_filename, name, co.co_firstlineno,
                               co.co_lnotab, co.co_freevars, co.co_cellvars)
     else:
         f.__code__ = CodeType(co.co_argcount, co.co_kwonlyargcount,
                               co.co_nlocals, co.co_stacksize, co.co_flags,
                               co.co_code, co.co_consts, co.co_names,
                               co.co_varnames, co.co_filename, name,
                               co.co_firstlineno, co.co_lnotab,
                               co.co_freevars, co.co_cellvars)
     return f
Esempio n. 4
0
    def as_traceback(self):
        """
        Convert to a builtin Traceback object that is usable for raising or rendering a stacktrace.
        """
        if tproxy:
            return tproxy(TracebackType, self.__tproxy__)
        if not tb_set_next:
            raise RuntimeError("Unsupported Python interpreter!")

        current = self
        top_tb = None
        tb = None
        while current:
            f_code = current.tb_frame.f_code
            code = compile(
                '\n' * (current.tb_lineno - 1) + 'raise __traceback_maker',
                current.tb_frame.f_code.co_filename, 'exec')
            if hasattr(code, "replace"):
                # Python 3.8 and newer
                code = code.replace(co_argcount=0,
                                    co_filename=f_code.co_filename,
                                    co_name=f_code.co_name,
                                    co_freevars=(),
                                    co_cellvars=())
            elif PY3:
                code = CodeType(0, code.co_kwonlyargcount, code.co_nlocals,
                                code.co_stacksize, code.co_flags, code.co_code,
                                code.co_consts, code.co_names,
                                code.co_varnames, f_code.co_filename,
                                f_code.co_name, code.co_firstlineno,
                                code.co_lnotab, (), ())
            else:
                code = CodeType(0, code.co_nlocals, code.co_stacksize,
                                code.co_flags, code.co_code, code.co_consts,
                                code.co_names, code.co_varnames,
                                f_code.co_filename.encode(),
                                f_code.co_name.encode(), code.co_firstlineno,
                                code.co_lnotab, (), ())

            # noinspection PyBroadException
            try:
                exec(code, dict(current.tb_frame.f_globals), {})
            except Exception:
                next_tb = sys.exc_info()[2].tb_next
                if top_tb is None:
                    top_tb = next_tb
                if tb is not None:
                    tb_set_next(tb, next_tb)
                tb = next_tb
                del next_tb

            current = current.tb_next
        try:
            return top_tb
        finally:
            del top_tb
            del tb
Esempio n. 5
0
 def new_code(
     self,
     code,
     argcount=0,
     posonlyargcount=0,
     kwonlyargcount=0,
     nlocals=0,
     stacksize=0,
     flags=0,
     constants=(),
     names=(),
     varnames=(),
     filename="foo.py",
     name="foo",
     firstlineno=1,
     lnotab=b"",
     freevars=(),
     cellvars=(),
 ):
     if sys.version_info >= (3, 8):
         return CodeType(
             argcount,
             posonlyargcount,
             kwonlyargcount,
             nlocals,
             stacksize,
             flags,
             code,
             constants,
             names,
             varnames,
             filename,
             name,
             firstlineno,
             lnotab,
             freevars,
             cellvars,
         )
     assert not posonlyargcount
     return CodeType(
         argcount,
         kwonlyargcount,
         nlocals,
         stacksize,
         flags,
         code,
         constants,
         names,
         varnames,
         filename,
         name,
         firstlineno,
         lnotab,
         freevars,
         cellvars,
     )
Esempio n. 6
0
    def as_traceback(self):
        if tproxy:
            return tproxy(TracebackType, self.__tproxy_handler)
        if not tb_set_next:
            raise RuntimeError("Cannot re-create traceback !")

        current = self
        top_tb = None
        tb = None
        while current:
            f_code = current.tb_frame.f_code
            code = compile(
                '\n' * (current.tb_lineno - 1) + 'raise __traceback_maker',
                current.tb_frame.f_code.co_filename, 'exec')
            if hasattr(code, "replace"):
                # Python 3.8 and newer
                code = code.replace(co_argcount=0,
                                    co_filename=f_code.co_filename,
                                    co_name=f_code.co_name,
                                    co_freevars=(),
                                    co_cellvars=())
            elif PY3:
                code = CodeType(0, code.co_kwonlyargcount, code.co_nlocals,
                                code.co_stacksize, code.co_flags, code.co_code,
                                code.co_consts, code.co_names,
                                code.co_varnames, f_code.co_filename,
                                f_code.co_name, code.co_firstlineno,
                                code.co_lnotab, (), ())
            else:
                code = CodeType(0, code.co_nlocals, code.co_stacksize,
                                code.co_flags, code.co_code, code.co_consts,
                                code.co_names, code.co_varnames,
                                f_code.co_filename.encode(),
                                f_code.co_name.encode(), code.co_firstlineno,
                                code.co_lnotab, (), ())

            # noinspection PyBroadException
            try:
                exec(code, current.tb_frame.f_globals, {})
            except:
                next_tb = sys.exc_info()[2].tb_next
                if top_tb is None:
                    top_tb = next_tb
                if tb is not None:
                    tb_set_next(tb, next_tb)
                tb = next_tb
                del next_tb

            current = current.tb_next
        try:
            return top_tb
        finally:
            del top_tb
            del tb
Esempio n. 7
0
    def code(self, parent=None):
        if self.blocks:
            raise AssertionError("%d unclosed block(s)" % len(self.blocks))

        flags = self.co_flags & ~CO_NOFREE
        if parent is not None:
            locals_written = self.locals_written()
            self.makefree([
                n for n in self.co_varnames[self.co_argcount + (
                    (self.co_flags & CO_VARARGS) == CO_VARARGS) + (
                        (self.co_flags & CO_VARKEYWORDS) == CO_VARKEYWORDS):]
                if n not in locals_written
            ])

        if not self.co_freevars and not self.co_cellvars:
            flags |= CO_NOFREE
        elif parent is not None and self.co_freevars:
            parent.makecells(self.co_freevars)

        return CodeType(self.co_argcount, len(self.co_varnames),
                        self.co_stacksize, flags, self.co_code.tostring(),
                        tuple(self.co_consts), tuple(self.co_names),
                        tuple(self.co_varnames), self.co_filename,
                        self.co_name, self.co_firstlineno,
                        self.co_lnotab.tostring(), self.co_freevars,
                        self.co_cellvars)
Esempio n. 8
0
def update(f, **kwargs):
    "A function that performs a functional update on a function."
    code = f.__code__
    attrs = [
        'co_argcount',
        'co_kwonlyargcount',
        'co_nlocals',
        'co_stacksize',
        'co_flags',
        'co_code',
        'co_consts',
        'co_names',
        'co_varnames',
        'co_filename',
        'co_name',
        'co_firstlineno',
        'co_lnotab',
        'co_freevars',
        'co_cellvars',
    ]
    newcode = CodeType(*(kwargs.get(a, getattr(code, a)) for a in attrs))
    return FunctionType(
        newcode,
        f.__globals__,
        f.__name__,
        f.__defaults__,
        f.__closure__,
    )
Esempio n. 9
0
def deserialize_function(f: dict):
    code_fields = f[CODE_FIELD_NAME][VALUE_FIELD_NAME]
    code_args = []
    for field in CODE_OBJECT_ARGS:
        arg = code_fields[field]
        if type(arg) == dict:
            code_args.append(deserialize_obj(arg))
            # if arg[TYPE_FIELD_NAME] == "bytes":
            #     code_args.append(bytes(arg[VALUE_FIELD_NAME]))
            # else:
            #     code_args.append(tuple(arg[VALUE_FIELD_NAME]))
        else:
            code_args.append(arg)
    details = [CodeType(*code_args)]
    glob = {"__builtins__": __builtins__}
    for name, o in f[GLOBAL_FIELD_NAME].items():
        glob[name] = deserialize_obj(o)
    details.append(glob)
    for attr in FUNCTION_ATTRS_NAMES:
        if attr == CODE_FIELD_NAME:
            continue
        details.append(deserialize_obj(f[attr]))

    result_func = FunctionType(*details)
    if result_func.__name__ in result_func.__getattribute__(GLOBAL_FIELD_NAME):
        result_func.__getattribute__(GLOBAL_FIELD_NAME)[
            result_func.__name__] = result_func
    return result_func
Esempio n. 10
0
def _import_codetup(codetup):
    if is_py38x:
        (argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize, flags,
         code, consts, names, varnames, filename, name, firstlineno, lnotab,
         freevars, cellvars) = codetup
    elif is_py3k:
        (argcount, kwonlyargcount, nlocals, stacksize, flags, code, consts,
         names, varnames, filename, name, firstlineno, lnotab, freevars,
         cellvars) = codetup
    else:
        (argcount, nlocals, stacksize, flags, code, consts, names, varnames,
         filename, name, firstlineno, lnotab, freevars, cellvars) = codetup

    consts2 = []
    for const in consts:
        if isinstance(const,
                      tuple) and len(const) == 2 and const[0] == CODEOBJ_MAGIC:
            consts2.append(_import_codetup(const[1]))
        else:
            consts2.append(const)
    consts = tuple(consts2)
    if is_py38x:
        codetup = (argcount, posonlyargcount, kwonlyargcount, nlocals,
                   stacksize, flags, code, consts, names, varnames, filename,
                   name, firstlineno, lnotab, freevars, cellvars)
    elif is_py3k:
        codetup = (argcount, kwonlyargcount, nlocals, stacksize, flags, code,
                   consts, names, varnames, filename, name, firstlineno,
                   lnotab, freevars, cellvars)
    else:
        codetup = (argcount, nlocals, stacksize, flags, code, consts, names,
                   varnames, filename, name, firstlineno, lnotab, freevars,
                   cellvars)
    return CodeType(*codetup)
Esempio n. 11
0
def implicit_self(function):
    code = function.func_code
    bytecode, varnames, names = inject_self(code)
    function.func_code = CodeType(code.co_argcount + 1, code.co_nlocals + 1,
        code.co_stacksize, code.co_flags, bytecode, code.co_consts, names,
        varnames, code.co_filename, code.co_name, code.co_firstlineno,
        code.co_lnotab, code.co_freevars, code.co_cellvars)
Esempio n. 12
0
def copy_code_with_changes(codeobject,
                           argcount=None,
                           nlocals=None,
                           stacksize=None,
                           flags=None,
                           code=None,
                           consts=None,
                           names=None,
                           varnames=None,
                           filename=None,
                           name=None,
                           firstlineno=None,
                           lnotab=None):
    if argcount is None: argcount = codeobject.co_argcount
    if nlocals is None: nlocals = codeobject.co_nlocals
    if stacksize is None: stacksize = codeobject.co_stacksize
    if flags is None: flags = codeobject.co_flags
    if code is None: code = codeobject.co_code
    if consts is None: consts = codeobject.co_consts
    if names is None: names = codeobject.co_names
    if varnames is None: varnames = codeobject.co_varnames
    if filename is None: filename = codeobject.co_filename
    if name is None: name = codeobject.co_name
    if firstlineno is None: firstlineno = codeobject.co_firstlineno
    if lnotab is None: lnotab = codeobject.co_lnotab
    return CodeType(argcount, nlocals, stacksize, flags, code, consts, names,
                    varnames, filename, name, firstlineno, lnotab)
Esempio n. 13
0
def create_new_co(code_object):
    new_code = swap_add_mul(code_object.co_code)
    new_const = []
    for c in code_object.co_consts:
        if isinstance(c, CodeType):
            new_const.append(create_new_co(c))
        else:
            new_const.append(c)
    new_code_object = CodeType(
        code_object.co_argcount,
        code_object.co_kwonlyargcount,
        code_object.co_nlocals,
        code_object.co_stacksize,
        code_object.co_flags,
        new_code,
        tuple(new_const),
        code_object.co_names,
        code_object.co_varnames,
        code_object.co_filename,
        code_object.co_name,
        code_object.co_firstlineno,
        code_object.co_lnotab,
        code_object.co_freevars,
        code_object.co_cellvars,
    )
    return new_code_object
Esempio n. 14
0
 def new_code(c):
     '''A new code object with a __class__ cell added to freevars'''
     return CodeType(c.co_argcount, c.co_kwonlyargcount, c.co_nlocals,
                     c.co_stacksize, c.co_flags, c.co_code, c.co_consts,
                     c.co_names, c.co_varnames, c.co_filename,
                     c.co_name, c.co_firstlineno, c.co_lnotab,
                     c.co_freevars + ('__class__', ), c.co_cellvars)
Esempio n. 15
0
def _deserialize_func(funcs, globalDict):
    items = pickle.loads(funcs)
    res = None
    for objType, name, data in items:
        if objType == 'func':
            codeArgs, funcArgs, updatedGlobals = pickle.loads(data)
            code = CodeType(*codeArgs)    
    
            globalDict.update(**updatedGlobals)

            value = FunctionType(code, globalDict, *funcArgs)
        elif objType == 'mod':
            value = __import__(data)
        elif objType == 'oldclass':
            class_name, module, bases, class_dict = data
            value = typesmod.ClassType(class_name, bases, {k:_deserialize_func(v, globalDict) for k, v in class_dict.items()})
            value.__module__ = module
        elif objType == 'type':
            raise Exception('deserialize type')
        else:
            raise Exception('Unknown serialization type')
        globalDict[name] = value

        if res is None:
            res = value

    return res
Esempio n. 16
0
    def replace_paths_in_code(self, co: types.CodeType) -> types.CodeType:
        new_filename = original_filename = os.path.normpath(co.co_filename)
        for f, r in self.replace_paths:
            if original_filename.startswith(f):
                new_filename = r + original_filename[len(f):]
                break

        if self.debug and original_filename not in self.processed_paths:
            if new_filename != original_filename:
                self.msgout(
                    2,
                    "co_filename %r changed to %r" % (
                        original_filename,
                        new_filename,
                    ),
                )
            else:
                self.msgout(
                    2,
                    "co_filename %r remains unchanged" % (original_filename, ))
            self.processed_paths.append(original_filename)

        consts = list(co.co_consts)
        for i in range(len(consts)):  # pylint: disable=consider-using-enumerate
            if isinstance(consts[i], type(co)):
                consts[i] = self.replace_paths_in_code(consts[i])

        return co.replace(co_consts=tuple(consts), co_filename=new_filename)
Esempio n. 17
0
 def code_with_custom_location(code, filename, location):
     return CodeType(code.co_argcount, code.co_kwonlyargcount,
                     code.co_nlocals, code.co_stacksize, code.co_flags,
                     code.co_code, code.co_consts, code.co_names,
                     code.co_varnames, filename, location,
                     code.co_firstlineno, code.co_lnotab, code.co_freevars,
                     code.co_cellvars)
Esempio n. 18
0
def _make_cell_set_template_code():
    """See _cell_set"""
    def _cell_set_factory(value):
        lambda: cell
        cell = value

    co = _cell_set_factory.__code__

    _cell_set_template_code = CodeType(
        co.co_argcount,
        co.co_kwonlyargcount,
        co.co_nlocals,
        co.co_stacksize,
        co.co_flags,
        co.co_code,
        co.co_consts,
        co.co_names,
        co.co_varnames,
        co.co_filename,
        co.co_name,
        co.co_firstlineno,
        co.co_lnotab,
        co.co_cellvars,  # co_freevars is initialized with co_cellvars
        (),  # co_cellvars is made empty
    )
    return _cell_set_template_code
Esempio n. 19
0
def execute_bytecode(code):
    """
    Executes the provided bytecode. Handy for getting the
    top item off the stack.
    """
    from types import CodeType
    import builtins

    # This should be large enough for most things
    stacksize = 1024

    # Load in enough for put_on_stack to work.
    # NOTE: This function is unable to call "import" or similar
    #       dangerous things due to co_names acting as a whitelist.
    #     (Python loads names from a constants array, so it can"t
    #      load something that"s not there!)
    consts = (*range(256), )
    names = ("chr", "ord", "globals", "locals", "getattr", "setattr")

    # Tag on a trailing RETURN call just incase.
    code += b"S\x00"
    # Construt the code object
    inject = CodeType(0, 0, 0, stacksize, 2, code, consts, names, (), "", "",
                      0, b"", (), ())

    # Create a copy of globals() and load in builtins. builtins aren"t
    # normally included in global scope.
    globs = dict(globals())
    globs.update({i: getattr(builtins, i) for i in dir(builtins)})

    # Go go go!
    return eval(inject, globs)
Esempio n. 20
0
 def build(self):
     # let x = let a = 1 in a + a in x * x
     # (lambda x : x * x )( (lambda a: a + a) (1) )
     #self.consts.add( 1 )
     #self.varnames.add( 'x' )
     #self.freevars.add( 'a' )
     self.converts()
     self.flags = 1  # NOFREE + OPTIMZED
     self.code += [opmap["RETURN_VALUE"], 0]
     code = CodeType(
         self.argcount,  # argcount
         self.kwonlyargcount,  # kwonlyargcount
         self.nlocals,  # nlocals
         self.stacksize,  # stacksize
         self.flags,  # flags
         bytes(self.code),  # codestring
         self.consts,  # consts
         self.names,  # names
         self.varnames,  # varnames
         self.filename,  # filename
         self.name,  # name
         self.firstlineno,  # firstlineno
         self.lnotab,  # lnotab
         self.freevars,  # freevars
         self.cellvars,  # cellvars
     )
     return code
Esempio n. 21
0
 def __call__(self, func):
     self.func = func
     _globals_ = func.__globals__
     _code_ = func.__code__
     varnames = list(_code_.co_varnames) + [v for v in self.env.keys()]
     nlocals = len(varnames)
     binlst = list(_code_.co_code)
     lstbin = self.processGlobals(binlst, _code_.co_names, varnames)
     genCo = self.genCode(_code_.co_consts, _code_.co_varnames)
     lstbin = genCo + lstbin
     consts = list(_code_.co_consts) + [v for v in self.env.values()]
     code = CodeType(
         _code_.co_argcount,  # argcount
         _code_.co_kwonlyargcount,  # kwonlyargcount
         nlocals,  # nlocals
         _code_.co_stacksize,  # stacksize
         _code_.co_flags,  # flags
         bytes(lstbin),  # codestring
         tuple(consts),  # consts
         _code_.co_names,  # names
         tuple(varnames),  # varnames
         _code_.co_filename,  # filename
         _code_.co_name,  # name
         _code_.co_firstlineno,  # firstlineno
         _code_.co_lnotab,  # lnotab
         _code_.co_freevars,  # freevars
         _code_.co_cellvars,  # cellvars
     )
     #_globals_.update(self.env)
     function = FunctionType(code, _globals_)
     return function
Esempio n. 22
0
 def makeCode(self):
     self.converts()
     self.getIndexs()
     self.LabelConvert()
     self.nlocals = len(self.varnames)
     # varnames is local variable names and function arguments
     self.code += [opmap["RETURN_VALUE"],0]
     #print( self.code )
     code = CodeType(self.argcount,       # argcount
                     self.kwonlyargcount, # kwonlyargcount
                     self.nlocals,        # nlocals
                     self.stacksize,      # stacksize
                     self.flags,          # flags
                     bytes(self.code),    # codestring
                     self.consts,         # consts
                     self.names,          # names
                     self.varnames,       # varnames
                     self.filename,       # filename
                     self.name,           # name
                     self.firstlineno,    # firstlineno
                     self.lnotab,         # lnotab
                     self.freevars,       # freevars
                     self.cellvars,       # cellvars
                 )
     return code
Esempio n. 23
0
def code_object_replace(code: types.CodeType, **kwargs) -> types.CodeType:
    """
    Return a copy of the code object with new values for the specified fields.
    """
    try:
        kwargs["co_consts"] = tuple(kwargs["co_consts"])
    except ValueError:
        pass
    # Python 3.8+
    if hasattr(code, "replace"):
        return code.replace(**kwargs)
    params = [
        kwargs.get("co_argcount", code.co_argcount),
        kwargs.get("co_kwonlyargcount", code.co_kwonlyargcount),
        kwargs.get("co_nlocals", code.co_nlocals),
        kwargs.get("co_stacksize", code.co_stacksize),
        kwargs.get("co_flags", code.co_flags),
        kwargs.get("co_code", code.co_code),
        kwargs.get("co_consts", code.co_consts),
        kwargs.get("co_names", code.co_names),
        kwargs.get("co_varnames", code.co_varnames),
        kwargs.get("co_filename", code.co_filename),
        kwargs.get("co_name", code.co_name),
        kwargs.get("co_firstlineno", code.co_firstlineno),
        kwargs.get("co_lnotab", code.co_lnotab),
        kwargs.get("co_freevars", code.co_freevars),
        kwargs.get("co_cellvars", code.co_cellvars),
    ]
    return types.CodeType(*params)
Esempio n. 24
0
 def stash(self, lineno=1, col_offset=0):
     stashed = super().stash(lineno, col_offset)
     for obj in self.objects:
         # Update the firstlineno in the functions so that it matches
         # the position in the written file (updates to the functions
         # above them might have pushed them down)
         co = obj.__code__
         if co.co_firstlineno != lineno:
             try:
                 obj.__code__ = CodeType(
                     co.co_argcount,
                     co.co_posonlyargcount,
                     co.co_kwonlyargcount,
                     co.co_nlocals,
                     co.co_stacksize,
                     co.co_flags,
                     co.co_code,
                     co.co_consts,
                     co.co_names,
                     co.co_varnames,
                     co.co_filename,
                     co.co_name,
                     lineno,
                     co.co_lnotab,
                     co.co_freevars,
                     co.co_cellvars,
                 )
             except Exception:  # pragma: no cover
                 # It's not a major issue if it fails
                 pass
     return stashed
Esempio n. 25
0
def _replace_codestring(old_code, new_code):
    # new_code should have same clean signature as old_code

    ## |  code(argcount, kwonlyargcount, nlocals, stacksize, flags, codestring,
    ## |        constants, names, varnames, filename, name, firstlineno,
    ## |        lnotab[, freevars[, cellvars]])
    # codestring is co_code!!
    #from types import CodeType
    old_doc_new_const = old_code.co_consts[:1] + new_code.co_consts[1:]
    code = \
        CodeType(new_code.co_argcount,
                 new_code.co_kwonlyargcount,
                 new_code.co_nlocals,
                 new_code.co_stacksize,
                 new_code.co_flags,
                 new_code.co_code, # codestring,
                 old_doc_new_const, # new_code.co_constants,
                 new_code.co_names,
                 new_code.co_varnames,
                 old_code.co_filename,
                 old_code.co_name,
                 old_code.co_firstlineno,
                 old_code.co_lnotab,
                 new_code.co_freevars,
                 new_code.co_cellvars)
    return code
Esempio n. 26
0
    def test_qualnames(self):
        self.assertEqual(cinder._get_qualname(f.__code__), "f")

        self.assertEqual(cinder._get_qualname(C.x.__code__), "C.x")
        self.assertEqual(cinder._get_qualname(C.sm.__code__), "C.sm")
        self.assertEqual(cinder._get_qualname(C.cm.__code__), "C.cm")

        self.assertEqual(cinder._get_qualname(C().f().__code__), "C.f.<locals>.G.y")

        c = f.__code__
        co = CodeType(
            c.co_argcount,
            c.co_posonlyargcount,
            c.co_kwonlyargcount,
            c.co_nlocals,
            c.co_stacksize,
            c.co_flags,
            c.co_code,
            c.co_consts,
            c.co_names,
            c.co_varnames,
            c.co_filename,
            c.co_name,
            c.co_firstlineno,
            c.co_lnotab,
            c.co_freevars,
            c.co_cellvars,
        )
        self.assertIsNone(cinder._get_qualname(co))

        co = c.replace(co_flags=c.co_flags)
        self.assertEqual(cinder._get_qualname(co), "f")
Esempio n. 27
0
def mock_code(name):
    """Makes a fake code object by name for built-in functions."""
    left_args = (0, 0, 0, 0, b'', (), (), (), '')
    if PY3:
        left_args = (0, ) + left_args
    args = left_args + (name, 0, b'')
    return CodeType(*args)
Esempio n. 28
0
 def build (self):
     code = CodeType(0,
                     # argcount
                     0,
                     # kwonlyargcount
                     len(self.varnames),
                     # nlocals
                     2,
                     # stacksize
                     67,
                     # flags
                     bytes(self.opec),
                     # codestring
                     tuple(self.consts),
                     # consts
                     tuple(self.names),
                     # names
                     tuple(self.varnames),
                     # varnames
                     '<unknow>',
                     # filename
                     "<unknow>",
                     # name
                     1,
                     # firstlineno
                     b'',
                     # lnotab
                     tuple (),
                     # freevars
                     tuple (),
                     # cellvars
                 )
     return code
Esempio n. 29
0
    def visit(self, co, *, name=None):
        code = co.co_code
        consts = list(co.co_consts)
        names = co.co_names
        lnotab = co.co_lnotab
        for n in range(self._passes):
            code = _optimize(code, consts, names, lnotab)

        return super().visit(
            CodeType(
                co.co_argcount,
                co.co_kwonlyargcount,
                co.co_nlocals,
                _calculate_stack_effect(code),
                co.co_flags,
                code,
                tuple(consts),
                names,
                tuple(self.visit_varnames(co.co_varnames)),
                co.co_filename,
                self.visit_name(name if name is not None else co.co_name),
                co.co_firstlineno,
                co.co_lnotab,
                tuple(self.visit_freevars(co.co_freevars)),
                tuple(self.visit_cellvars(co.co_cellvars)),
            ),
            name=name,
        )
Esempio n. 30
0
 def rename(f):
     if not isinstance(f, (LambdaType, FunctionType)):
         # TODO: Can't raise TypeError; @fploop et al. do-it-now-and-replace-def-with-result
         # TODO: decorators need to do this.
         return f
     f = copy(f)
     # __name__ for tools like pydoc; __qualname__ for repr(); __code__.co_name for stack traces
     #     https://stackoverflow.com/questions/40661758/name-of-a-python-function-in-a-stack-trace
     #     https://stackoverflow.com/questions/16064409/how-to-create-a-code-object-in-python
     f.__name__ = name
     idx = f.__qualname__.rfind('.')
     f.__qualname__ = f"{f.__qualname__[:idx]}.{name}" if idx != -1 else name
     # __code__.co_name is read-only, but there's a types.CodeType constructor
     # that we can use to re-create the code object with the new name.
     # (This is no worse than what the stdlib's Lib/modulefinder.py already does.)
     co = f.__code__
     # https://github.com/ipython/ipython/blob/master/IPython/core/interactiveshell.py
     # https://www.python.org/dev/peps/pep-0570/
     # https://docs.python.org/3/library/types.html#types.CodeType
     # https://docs.python.org/3/library/inspect.html#types-and-members
     if version_info >= (3, 8,
                         0):  # Python 3.8+: positional-only parameters
         # In Python 3.8+, `CodeType` has the convenient `replace()` method to functionally update it.
         # In Python 3.10, we must actually use it to avoid losing the line number info,
         # or `inspect.stack()` will crash in the unit tests for `callsite_filename()`.
         f.__code__ = f.__code__.replace(co_name=name)
     else:
         f.__code__ = CodeType(co.co_argcount, co.co_kwonlyargcount,
                               co.co_nlocals, co.co_stacksize, co.co_flags,
                               co.co_code, co.co_consts, co.co_names,
                               co.co_varnames, co.co_filename, name,
                               co.co_firstlineno, co.co_lnotab,
                               co.co_freevars, co.co_cellvars)
     return f