Example #1
0
def _export_codeobj(cobj):
    consts2 = []
    for const in cobj.co_consts:
        if brine.dumpable(const):
            consts2.append(const)
        elif isinstance(const, CodeType):
            consts2.append(_export_codeobj(const))
        else:
            raise TypeError(
                "Cannot export a function with non-brinable constants: %r" %
                (const, ))

    if is_py3k:
        exported = (cobj.co_argcount, cobj.co_kwonlyargcount, cobj.co_nlocals,
                    cobj.co_stacksize, cobj.co_flags, cobj.co_code,
                    tuple(consts2), cobj.co_names, cobj.co_varnames,
                    cobj.co_filename, cobj.co_name, cobj.co_firstlineno,
                    cobj.co_lnotab, cobj.co_freevars, cobj.co_cellvars)
    else:
        exported = (cobj.co_argcount, cobj.co_nlocals,
                    cobj.co_stacksize, cobj.co_flags, cobj.co_code,
                    tuple(consts2), cobj.co_names, cobj.co_varnames,
                    cobj.co_filename, cobj.co_name, cobj.co_firstlineno,
                    cobj.co_lnotab, cobj.co_freevars, cobj.co_cellvars)

    assert brine.dumpable(exported)
    return (CODEOBJ_MAGIC, exported)
Example #2
0
def dump(typ, val, tb, include_local_traceback):
    if type(typ) is str:
        return typ
    if typ is StopIteration:
        return consts.EXC_STOP_ITERATION # optimization
    
    if include_local_traceback:
        tbtext = "".join(traceback.format_exception(typ, val, tb))
    else:
        tbtext = "<traceback denied>"
    attrs = []
    args = []
    for name in dir(val):
        if name == "args":
            for a in val.args:
                if brine.dumpable(a):
                    args.append(a)
                else:
                    args.append(repr(a))
        elif not name.startswith("_") or name == "_remote_tb":
            attrval = getattr(val, name)
            if not brine.dumpable(attrval):
                attrval = repr(attrval)
            attrs.append((name, attrval))
    return (typ.__module__, typ.__name__), tuple(args), tuple(attrs), tbtext
Example #3
0
def _export_codeobj(cobj):
    consts2 = []
    for const in cobj.co_consts:
        if brine.dumpable(const):
            consts2.append(const)
        elif isinstance(const, CodeType):
            consts2.append(_export_codeobj(const))
        else:
            raise TypeError(
                "Cannot export a function with non-brinable constants: %r" %
                (const, ))

    for op, arg in decode_codeobj(cobj):
        if op in ("LOAD_GLOBAL", "STORE_GLOBAL", "DELETE_GLOBAL"):
            if arg not in __builtin__.__dict__:
                raise TypeError(
                    "Cannot export a function with non-builtin globals: %r" %
                    (arg, ))

    if is_py3k:
        exported = (cobj.co_argcount, cobj.co_kwonlyargcount, cobj.co_nlocals,
                    cobj.co_stacksize, cobj.co_flags, cobj.co_code,
                    tuple(consts2), cobj.co_names, cobj.co_varnames,
                    cobj.co_filename, cobj.co_name, cobj.co_firstlineno,
                    cobj.co_lnotab, cobj.co_freevars, cobj.co_cellvars)
    else:
        exported = (cobj.co_argcount, cobj.co_nlocals,
                    cobj.co_stacksize, cobj.co_flags, cobj.co_code,
                    tuple(consts2), cobj.co_names, cobj.co_varnames,
                    cobj.co_filename, cobj.co_name, cobj.co_firstlineno,
                    cobj.co_lnotab, cobj.co_freevars, cobj.co_cellvars)

    assert brine.dumpable(exported)
    return (CODEOBJ_MAGIC, exported)
Example #4
0
def dump(typ, val, tb, include_local_traceback):
    if type(typ) is str:
        return typ
    if typ is StopIteration:
        return consts.EXC_STOP_ITERATION  # optimization

    if include_local_traceback:
        tbtext = "".join(traceback.format_exception(typ, val, tb))
    else:
        tbtext = "<traceback denied>"
    attrs = []
    args = []
    for name in dir(val):
        if name == "args":
            for a in val.args:
                if brine.dumpable(a):
                    args.append(a)
                else:
                    args.append(repr(a))
        elif not name.startswith("_") or name == "_remote_tb":
            attrval = getattr(val, name)
            if not brine.dumpable(attrval):
                attrval = repr(attrval)
            attrs.append((name, attrval))
    return (typ.__module__, typ.__name__), tuple(args), tuple(attrs), tbtext
Example #5
0
def _export_codeobj(cobj):
    consts2 = []
    for const in cobj.co_consts:
        if brine.dumpable(const):
            consts2.append(const)
        elif isinstance(const, CodeType):
            consts2.append(_export_codeobj(const))
        else:
            raise TypeError("Cannot export a function with non-brinable constants: %r" % (const,))

    for op, arg in decode_codeobj(cobj):
        if op in ("LOAD_GLOBAL", "STORE_GLOBAL", "DELETE_GLOBAL"):
            if arg not in __builtin__.__dict__:
                raise TypeError("Cannot export a function with non-builtin globals: %r" % (arg,))

    if is_py3k:
        exported = (cobj.co_argcount, cobj.co_kwonlyargcount, cobj.co_nlocals, cobj.co_stacksize, cobj.co_flags,
            cobj.co_code, tuple(consts2), cobj.co_names, cobj.co_varnames, cobj.co_filename,
            cobj.co_name, cobj.co_firstlineno, cobj.co_lnotab, cobj.co_freevars, cobj.co_cellvars)
    else:
        exported = (cobj.co_argcount, cobj.co_nlocals, cobj.co_stacksize, cobj.co_flags,
            cobj.co_code, tuple(consts2), cobj.co_names, cobj.co_varnames, cobj.co_filename,
            cobj.co_name, cobj.co_firstlineno, cobj.co_lnotab, cobj.co_freevars, cobj.co_cellvars)

    assert brine.dumpable(exported)
    return (CODEOBJ_MAGIC, exported)
Example #6
0
def _export_codeobj(cobj):
    consts2 = []
    for const in cobj.co_consts:
        if brine.dumpable(const):
            consts2.append(const)
        elif isinstance(const, CodeType):
            consts2.append(_export_codeobj(const))
        else:
            raise TypeError(
                f"Cannot export a function with non-brinable constants: {const!r}"
            )

    if is_py_gte38:
        # Constructor was changed in 3.8 to support "advanced" programming styles
        exported = (cobj.co_argcount, cobj.co_posonlyargcount,
                    cobj.co_kwonlyargcount, cobj.co_nlocals,
                    cobj.co_stacksize, cobj.co_flags, cobj.co_code,
                    tuple(consts2), cobj.co_names, cobj.co_varnames,
                    cobj.co_filename, cobj.co_name, cobj.co_firstlineno,
                    cobj.co_lnotab, cobj.co_freevars, cobj.co_cellvars)
    else:
        exported = (cobj.co_argcount, cobj.co_kwonlyargcount, cobj.co_nlocals,
                    cobj.co_stacksize, cobj.co_flags, cobj.co_code,
                    tuple(consts2), cobj.co_names, cobj.co_varnames,
                    cobj.co_filename, cobj.co_name, cobj.co_firstlineno,
                    cobj.co_lnotab, cobj.co_freevars, cobj.co_cellvars)
    assert brine.dumpable(exported)
    return (CODEOBJ_MAGIC, exported)
Example #7
0
def dump(typ, val, tb, include_local_traceback, include_local_version):
    """Dumps the given exceptions info, as returned by ``sys.exc_info()``

    :param typ: the exception's type (class)
    :param val: the exceptions' value (instance)
    :param tb: the exception's traceback (a ``traceback`` object)
    :param include_local_traceback: whether or not to include the local traceback
                                    in the dumped info. This may expose the other
                                    side to implementation details (code) and
                                    package structure, and may theoretically impose
                                    a security risk.

    :returns: A tuple of ``((module name, exception name), arguments, attributes,
              traceback text)``. This tuple can be safely passed to
              :func:`brine.dump <rpyc.core.brine.dump>`
    """
    if typ is StopIteration:
        return consts.EXC_STOP_ITERATION  # optimization
    if type(typ) is str:
        return typ

    if include_local_traceback:
        tbtext = "".join(traceback.format_exception(typ, val, tb))
    else:
        tbtext = "<traceback denied>"
    attrs = []
    args = []
    ignored_attrs = frozenset(["_remote_tb", "with_traceback"])
    for name in dir(val):
        if name == "args":
            for a in val.args:
                if brine.dumpable(a):
                    args.append(a)
                else:
                    args.append(repr(a))
        elif name.startswith("_") or name in ignored_attrs:
            continue
        else:
            try:
                attrval = getattr(val, name)
            except AttributeError:
                # skip this attr. see issue #108
                continue
            if not brine.dumpable(attrval):
                attrval = repr(attrval)
            attrs.append((name, attrval))
    if include_local_version:
        attrs.append(("_remote_version", version.version_string))
    else:
        attrs.append(("_remote_version", "<version denied>"))
    return (typ.__module__, typ.__name__), tuple(args), tuple(attrs), tbtext
Example #8
0
def test_brine():
    x = ("he", 7, u"llo", 8, (), 900, None, True, Ellipsis, 18.2, 18.2j + 13,
         slice(1, 2, 3), frozenset([5, 6, 7]), NotImplemented, (1, 2))
    assert dumpable(x)
    y = dump(x)
    z = load(y)
    assert x == z
Example #9
0
def export_function(func):
    closure = func.__closure__
    code = func.__code__
    defaults = func.__defaults__
    kwdefaults = func.__kwdefaults__
    if kwdefaults is not None:
        kwdefaults = tuple(kwdefaults.items())

    if closure:
        raise TypeError("Cannot export a function closure")
    if not brine.dumpable(defaults):
        raise TypeError("Cannot export a function with non-brinable defaults (__defaults__)")
    if not brine.dumpable(kwdefaults):
        raise TypeError("Cannot export a function with non-brinable defaults (__kwdefaults__)")

    return func.__name__, func.__module__, defaults, kwdefaults, _export_codeobj(code)[1]
Example #10
0
def test_brine():
    x = ("he", 7, u"llo", 8, (), 900, None, True, Ellipsis, 18.2, 18.2j + 13,
         slice(1, 2, 3), frozenset([5, 6, 7]), NotImplemented, (1,2))
    assert dumpable(x)
    y = dump(x)
    z = load(y)
    assert x == z
Example #11
0
def dump(typ, val, tb, include_local_traceback):
    """Dumps the given exceptions info, as returned by ``sys.exc_info()``
    
    :param typ: the exception's type (class)
    :param val: the exceptions' value (instance)
    :param tb: the exception's traceback (a ``traceback`` object)
    :param include_local_traceback: whether or not to include the local traceback
                                    in the dumped info. This may expose the other
                                    side to implementation details (code) and 
                                    package structure, and may theoretically impose
                                    a security risk.
    
    :returns: A tuple of ``((module name, exception name), arguments, attributes, 
              traceback text)``. This tuple can be safely passed to 
              :func:`brine.dump <rpyc.core.brine.dump>`
    """
    if typ is StopIteration:
        return consts.EXC_STOP_ITERATION # optimization
    if type(typ) is str:
        return typ

    if include_local_traceback:
        tbtext = "".join(traceback.format_exception(typ, val, tb))
    else:
        tbtext = "<traceback denied>"
    attrs = []
    args = []
    ignored_attrs = frozenset(["_remote_tb", "with_traceback"])
    for name in dir(val):
        if name == "args":
            for a in val.args:
                if brine.dumpable(a):
                    args.append(a)
                else:
                    args.append(repr(a))
        elif name.startswith("_") or name in ignored_attrs:
            continue
        else:
            try:
                attrval = getattr(val, name)
            except AttributeError:
                # skip this attr. see issue #108
                continue
            if not brine.dumpable(attrval):
                attrval = repr(attrval)
            attrs.append((name, attrval))
    return (typ.__module__, typ.__name__), tuple(args), tuple(attrs), tbtext
Example #12
0
def export_function(func):
    func_closure = func.__closure__
    func_code = func.__code__
    func_defaults = func.__defaults__

    if func_closure:
        raise TypeError("Cannot export a function closure")
    if not brine.dumpable(func_defaults):
        raise TypeError("Cannot export a function with non-brinable defaults (func_defaults)")

    return func.__name__, func.__module__, func_defaults, _export_codeobj(func_code)[1]
Example #13
0
 def test_brine_2(self):
     if is_py3k:
         exec('''x = (b"he", 7, "llo", 8, (), 900, None, True, Ellipsis, 18.2, 18.2j + 13,
              slice(1, 2, 3), frozenset([5, 6, 7]), NotImplemented, (1,2))''', globals())
     else:
         exec('''x = ("he", 7, u"llo", 8, (), 900, None, True, Ellipsis, 18.2, 18.2j + 13,
              slice(1, 2, 3), frozenset([5, 6, 7]), NotImplemented, (1,2))''')
     self.assertTrue(brine.dumpable(x))
     y = brine.dump(x)
     z = brine.load(y)
     self.assertEqual(x, z)
Example #14
0
def _export_codeobj(cobj):
    consts2 = []
    for const in cobj.co_consts:
        if brine.dumpable(const):
            consts2.append(const)
        elif isinstance(const, CodeType):
            consts2.append(_export_codeobj(const))
        else:
            raise TypeError("Cannot export a function with non-brinable constants: %r" % (const,))

    if is_py3k:
        exported = (cobj.co_argcount, cobj.co_kwonlyargcount, cobj.co_nlocals, cobj.co_stacksize, cobj.co_flags,
            cobj.co_code, tuple(consts2), cobj.co_names, cobj.co_varnames, cobj.co_filename,
            cobj.co_name, cobj.co_firstlineno, cobj.co_lnotab, cobj.co_freevars, cobj.co_cellvars)
    else:
        exported = (cobj.co_argcount, cobj.co_nlocals, cobj.co_stacksize, cobj.co_flags,
            cobj.co_code, tuple(consts2), cobj.co_names, cobj.co_varnames, cobj.co_filename,
            cobj.co_name, cobj.co_firstlineno, cobj.co_lnotab, cobj.co_freevars, cobj.co_cellvars)

    assert brine.dumpable(exported)
    return (CODEOBJ_MAGIC, exported)
Example #15
0
 def _box(self, obj):  # boxing
     """store a local object in such a way that it could be recreated on
     the remote party either by-value or by-reference"""
     if brine.dumpable(obj):
         return consts.LABEL_VALUE, obj
     if type(obj) is tuple:
         return consts.LABEL_TUPLE, tuple(self._box(item) for item in obj)
     elif isinstance(obj, netref.BaseNetref) and obj.____conn__ is self:
         return consts.LABEL_LOCAL_REF, obj.____id_pack__
     else:
         id_pack = get_id_pack(obj)
         self._local_objects.add(id_pack, obj)
         return consts.LABEL_REMOTE_REF, id_pack
Example #16
0
 def _box(self, obj):
     """store a local object in such a way that it could be recreated on
     the remote party either by-value or by-reference"""
     if brine.dumpable(obj):
         return consts.LABEL_VALUE, obj
     if type(obj) is tuple:
         return consts.LABEL_TUPLE, tuple(self._box(item) for item in obj)
     elif isinstance(obj, netref.BaseNetref) and obj.____conn__() is self:
         return consts.LABEL_LOCAL_REF, obj.____oid__
     else:
         self._local_objects.add(obj)
         cls = getattr(obj, "__class__", type(obj))
         return consts.LABEL_REMOTE_REF, (id(obj), cls.__name__, cls.__module__)
Example #17
0
 def _box(self, obj):
     """store a local object in such a way that it could be recreated on
     the remote party either by-value or by-reference"""
     if brine.dumpable(obj):
         return consts.LABEL_VALUE, obj
     if type(obj) is tuple:
         return consts.LABEL_TUPLE, tuple(self._box(item) for item in obj)
     elif isinstance(obj, netref.BaseNetref) and obj.____conn__() is self:
         return consts.LABEL_LOCAL_REF, obj.____oid__
     else:
         self._local_objects.add(obj)
         cls = getattr(obj, "__class__", type(obj))
         return consts.LABEL_REMOTE_REF, (id(obj), cls.__name__,
                                          cls.__module__)
Example #18
0
def export_function(func):
    if is_py3k:
        func_closure = func.__closure__
        func_code = func.__code__
        func_defaults = func.__defaults__
    else:
        func_closure = func.func_closure
        func_code = func.func_code
        func_defaults = func.func_defaults
    
    if func_closure:
        raise TypeError("Cannot export a function closure")
    if not brine.dumpable(func_defaults):
        raise TypeError("Cannot export a function with non-brinable defaults (func_defaults)")
    
    return func.__name__, func.__module__, func_defaults, _export_codeobj(func_code)[1]
Example #19
0
 def _box(self, obj):  # boxing
     """store a local object in such a way that it could be recreated on
     the remote party either by-value or by-reference"""
     if brine.dumpable(obj):
         return consts.LABEL_VALUE, obj
     if type(obj) is tuple:
         return consts.LABEL_TUPLE, tuple(self._box(item) for item in obj)
     elif isinstance(obj, netref.BaseNetref) and obj.____conn__ is self:
         return consts.LABEL_LOCAL_REF, obj.____oid__
     else:
         self._local_objects.add(obj)
         try:
             cls = obj.__class__
         except Exception:
             # see issue #16
             cls = type(obj)
         if not isinstance(cls, type):
             cls = type(obj)
         return consts.LABEL_REMOTE_REF, (id(obj), cls.__name__,
                                          cls.__module__)
Example #20
0
 def _box(self, obj):
     """store a local object in such a way that it could be recreated on
     the remote party either by-value or by-reference"""
     if brine.dumpable(obj):
         return consts.LABEL_VALUE, obj
     if type(obj) is tuple:
         return consts.LABEL_TUPLE, tuple(self._box(item) for item in obj)
     elif isinstance(obj, netref.BaseNetref) and obj.____conn__() is self:
         return consts.LABEL_LOCAL_REF, obj.____oid__
     elif isinstance(obj, AsyncResult):            
         obj.async_set_expiry(3)             # HACK: wait at most 3 seconds until the async result arrives     
         return self._box(obj.async_value)
     else:
         self._local_objects.add(obj)
         try:
             cls = obj.__class__
         except Exception:
             # see issue #16
             cls = type(obj)
         return consts.LABEL_REMOTE_REF, (id(obj), cls.__name__, cls.__module__)
Example #21
0
 def _box(self, obj):
     """store a local object in such a way that it could be recreated on
     the remote party either by-value or by-reference"""
     if brine.dumpable(obj):
         return consts.LABEL_VALUE, obj
     if type(obj) is tuple:
         return consts.LABEL_TUPLE, tuple(self._box(item) for item in obj)
     elif isinstance(obj, netref.BaseNetref) and obj.____conn__() is self:
         return consts.LABEL_LOCAL_REF, obj.____oid__
     elif isinstance(obj, AsyncResult):
         obj.async_set_expiry(
             3
         )  # HACK: wait at most 3 seconds until the async result arrives
         return self._box(obj.async_value)
     else:
         self._local_objects.add(obj)
         try:
             cls = obj.__class__
         except Exception:
             # see issue #16
             cls = type(obj)
         return consts.LABEL_REMOTE_REF, (id(obj), cls.__name__,
                                          cls.__module__)