docs: def add_file(self, src_path, dst_path=None, ctx_path=None, replace_space=True, expandvars=False, expanduser=False,
                   remove_final=False):
          """
          Adds a file to the Docker build. An ``ADD`` command is inserted, and the path is stored for later packaging of
          the context tarball.
  
          :param src_path: Path to the file or directory.
          :type src_path: unicode | str
          :param dst_path: Destination path during the Docker build. By default uses the last element of `src_path`.
          :type dst_path: unicode | str
          :param ctx_path: Path inside the context tarball. Can be set in order to avoid name clashes. By default
           identical to the destination path.
          :type ctx_path: unicode | str
          :param replace_space: Mask spaces in path names with a backslash. Default is ``True``.
          :type replace_space: bool
          :param expandvars: Expand local environment variables. Default is ``False``.
          :type expandvars: bool
          :param expanduser: Expand local user variables. Default is ``False``.
          :type expanduser: bool
          :param remove_final: Remove the file after the build operation has completed. Can be useful e.g. for source code
           archives, which are no longer needed after building the binaries. Note that this will not reduce the size of
           the resulting image (actually may increase instead) unless the image is squashed.
          :type remove_final: bool
          :return: The path of the file in the Dockerfile context.
          :rtype: unicode | str
          """
          if dst_path is None:
              head, tail = os.path.split(src_path)
              if not tail:
                  # On trailing backslashes.
                  tail = os.path.split(head)[1]
                  if not tail:
                      ValueError("Could not generate target path from input '{0}'; needs to be specified explicitly.")
              target_path = tail
          else:
              target_path = dst_path
  
          source_path = prepare_path(src_path, False, False, expandvars, expanduser)
          target_path = prepare_path(target_path, replace_space, True, expandvars, expanduser)
          if ctx_path:
              context_path = prepare_path(ctx_path, replace_space, True, expandvars, expanduser)
          else:
              context_path = target_path
          self.prefix('ADD', context_path, target_path)
          self._files.append((source_path, context_path))
          if remove_final:
              self._remove_files.add(target_path)
          return context_path