def decode(rlp, sedes=None, strict=True, recursive_cache=False, **kwargs):
if not is_bytes(rlp):<EOL><INDENT>raise DecodingError('<STR_LIT>' % type(rlp).__name__, rlp)<EOL><DEDENT>try:<EOL><INDENT>item, per_item_rlp, end = consume_item(rlp, <NUM_LIT:0>)<EOL><DEDENT>except IndexError:<EOL><INDENT>raise DecodingError('<STR_LIT>', rlp)<EOL><DEDENT>if end != len(rlp) and strict:<EOL><INDENT>msg = '<STR_LIT>'.format(len(rlp) - end)<EOL>raise DecodingError(msg, rlp)<EOL><DEDENT>if sedes:<EOL><INDENT>obj = sedes.deserialize(item, **kwargs)<EOL>if is_sequence(obj) or hasattr(obj, '<STR_LIT>'):<EOL><INDENT>_apply_rlp_cache(obj, per_item_rlp, recursive_cache)<EOL><DEDENT>return obj<EOL><DEDENT>else:<EOL><INDENT>return item<EOL><DEDENT>
Decode an RLP encoded object.

    If the deserialized result `obj` has an attribute :attr:`_cached_rlp` (e.g. if `sedes` is a
    subclass of :class:`rlp.Serializable`) it will be set to `rlp`, which will improve performance
    on subsequent :func:`rlp.encode` calls. Bear in mind however that `obj` needs to make sure that
    this value is updated whenever one of its fields changes or prevent such changes entirely
    (:class:`rlp.sedes.Serializable` does the latter).

    :param sedes: an object implementing a function ``deserialize(code)`` which will be applied
                  after decoding, or ``None`` if no deserialization should be performed
    :param \*\*kwargs: additional keyword arguments that will be passed to the deserializer
    :param strict: if false inputs that are longer than necessary don't cause an exception
    :returns: the decoded and maybe deserialized Python object
    :raises: :exc:`rlp.DecodingError` if the input string does not end after the root item and
             `strict` is true
    :raises: :exc:`rlp.DeserializationError` if the deserialization fails