docs: def _unapply_interception(target, ctx=None):
      """Unapply interception on input target in cleaning it.
  
      :param routine target: target from where removing an interception
          function. is_joinpoint(target) must be True.
      :param ctx: target ctx.
      """
  
      # try to get the right ctx
      if ctx is None:
          ctx = find_ctx(elt=target)
  
      # get previous target
      intercepted, old_ctx = get_intercepted(target)
  
      # if ctx is None and old_ctx is not None, update ctx with old_ctx
      if ctx is None and old_ctx is not None:
          ctx = old_ctx
  
      if intercepted is None:
          raise JoinpointError('{0} must be intercepted'.format(target))
  
      # flag to deleting of joinpoint_function
      del_joinpoint_function = False
  
      # if old target is a not modifiable resource
      if isbuiltin(intercepted):
          module = getmodule(intercepted)
          found = False
  
          # update references to target to not modifiable element in module
          for name, member in getmembers(module):
              if member is target:
                  setattr(module, name, intercepted)
                  found = True
  
          # if no reference found, raise an Exception
          if not found:
              raise JoinpointError(
                  "Impossible to unapply interception on not modifiable element \
                  {0}. Must be contained in module {1}".format(target, module)
              )
  
      elif ctx is None:
          # get joinpoint function
          joinpoint_function = _get_function(target)
          # update old code on target
          joinpoint_function.__code__ = intercepted.__code__
          # ensure to delete joinpoint_function
          del_joinpoint_function = True
  
      else:
          # flag for joinpoint recovering
          recover = False
          # get interception name in order to update/delete interception from ctx
          intercepted_name = intercepted.__name__
          # should we change of target or is it inherited ?
          if isclass(ctx):
              base_interception, _ = super_method(name=intercepted_name, ctx=ctx)
          else:
              base_interception = getattr(ctx.__class__, intercepted_name, None)
          # if base interception does not exist
          if base_interception is None:  # recover intercepted
              recover = True
  
          else:
              # get joinpoint_function
              joinpoint_function = _get_function(target)
              # get base function
              if is_intercepted(base_interception):
                  base_intercepted, _ = get_intercepted(base_interception)
              else:
                  base_intercepted = _get_function(base_interception)
              # is interception inherited ?
              if base_intercepted is joinpoint_function:
                  pass  # do nothing
              # is intercepted inherited
              elif base_intercepted is intercepted:
                  # del interception
                  delattr(ctx, intercepted_name)
                  del_joinpoint_function = True
              else:  # base function is something else
                  recover = True
  
          if recover:  # if recover is required
              # new content to put in ctx
              new_content = intercepted
              if ismethod(target):  # in creating eventually a new method
                  args = [new_content, ctx]
                  if PY2:  # if py2, specify the ctx class
                      # and unbound method type
                      if target.__self__ is None:
                          args = [new_content, None, ctx]
                      else:  # or instance method
                          args.append(ctx.__class__)
                  # instantiate a new method
                  new_content = MethodType(*args)
              # update ctx with intercepted
              setattr(ctx, intercepted_name, new_content)
              joinpoint_function = _get_function(target)
              del_joinpoint_function = True
  
      if del_joinpoint_function:
          # delete _INTERCEPTED and _INTERCEPTED_CTX from joinpoint_function
          if hasattr(joinpoint_function, _INTERCEPTED):
              delattr(joinpoint_function, _INTERCEPTED)
              if hasattr(joinpoint_function, _INTERCEPTED_CTX):
                  delattr(joinpoint_function, _INTERCEPTED_CTX)
          del joinpoint_function