def next_source_row(self, handle):
        """
        Given a file handle, return the next row of data as a key value dict.

        Return None to denote the EOF
        Return False to skip this row of data entirely
        """

        if not getattr(self, "detected_dialect", None):
            # Sniff for the dialect of the CSV file

            pos = handle.tell()
            handle.seek(0)
            readahead = handle.read(1024)
            handle.seek(pos)

            try:
                dialect = csv.Sniffer().sniff(readahead, ",")
            except csv.Error:
                # Fallback to excel format
                dialect = csv.excel

            dialect_attrs = [
                "delimiter",
                "doublequote",
                "escapechar",
                "lineterminator",
                "quotechar",
                "quoting",
                "skipinitialspace"
            ]

            self.detected_dialect = {x: getattr(dialect, x) for x in dialect_attrs}

        if not getattr(self, "reader", None):
            self.reader = csv.reader(handle, **self.detected_dialect)

        if not getattr(self, "detected_columns", None):
            # On first iteration, the line will be the column headings,
            # store those and return False to skip processing
            columns = self.reader.next()
            self.detected_columns = columns
            return False

        cols = self.detected_columns

        try:
            values = self.reader.next()
        except __HOLE__:
            return None

        if not values:
            return None

        return dict(zip(cols, values))
dataset/ETHPy150Open potatolondon/osmosis/osmosis/models.py/AbstractImportTask.next_source_row