<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def upload(self, filename, filedata=None, filepath=None, **kwargs):
 """Upload the specified file into the project. .. note:: Either ``filedata`` or ``filepath`` *MUST* be specified. Args: filename (str):
 The name of the file being uploaded filedata (bytes):
 The raw data of the file being uploaded filepath (str):
 The path to a local file to upload (optional) Raises: GitlabConnectionError: If the server cannot be reached GitlabUploadError: If the file upload fails GitlabUploadError: If ``filedata`` and ``filepath`` are not specified GitlabUploadError: If both ``filedata`` and ``filepath`` are specified Returns: dict: A ``dict`` with the keys: * ``alt`` - The alternate text for the upload * ``url`` - The direct url to the uploaded file * ``markdown`` - Markdown for the uploaded file """

        if filepath is None and filedata is None:
            raise GitlabUploadError("No file contents or path specified")

        if filedata is not None and filepath is not None:
            raise GitlabUploadError("File contents and file path specified")

        if filepath is not None:
            with open(filepath, "rb") as f:
                filedata = f.read()

        url = ('/projects/%(id)s/uploads' % {
            'id': self.id,
        })
        file_info = {
            'file': (filename, filedata),
        }
        data = self.manager.gitlab.http_post(url, files=file_info)

        return {
            "alt": data['alt'],
            "url": data['url'],
            "markdown": data['markdown']
        }