# Buggy code
def _make_reader(self, f):
    sep = self.delimiter

    if sep is None or len(sep) == 1:
        if self.lineterminator:
            raise ValueError(
                "Custom line terminators not supported in python parser (yet)"
            )

        class MyDialect(csv.Dialect):
            delimiter = self.delimiter
            quotechar = self.quotechar
            escapechar = self.escapechar
            doublequote = self.doublequote
            skipinitialspace = self.skipinitialspace
            quoting = self.quoting
            lineterminator = "\n"

        dia = MyDialect

        sniff_sep = True

        if sep is not None:
            sniff_sep = False
            dia.delimiter = sep
        # attempt to sniff the delimiter
        if sniff_sep:
            line = f.readline()
            while self.skipfunc(self.pos):
                self.pos += 1
                line = f.readline()

            line = self._check_comments([line])[0]

            self.pos += 1
            self.line_pos += 1
            sniffed = csv.Sniffer().sniff(line)
            dia.delimiter = sniffed.delimiter

            # Note: self.encoding is irrelevant here
            line_rdr = csv.reader(StringIO(line), dialect=dia)
            self.buf.extend(list(line_rdr))

        # Note: self.encoding is irrelevant here
        reader = csv.reader(f, dialect=dia, strict=True)

    else:

        def _read():
            line = f.readline()
            pat = re.compile(sep)

            yield pat.split(line.strip())

            for line in f:
                yield pat.split(line.strip())

        reader = _read()

    self.data = reader


# Traceback (TypeError)
TypeError                                 Traceback (most recent call last)
<ipython-input-17-c89b3c3e691f> in <module>
----> 1 pd.read_csv('data.csv', sep=None, comment='#')

~/.local/share/virtualenvs/openqlab/lib/python3.8/site-packages/pandas/io/parsers.py in parser_f(filepath_or_buffer, sep, delimiter, header, names,
index_col, usecols, squeeze, prefix, mangle_dupe_cols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfoote
r, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, dayfirs
t, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encodin
g, dialect, error_bad_lines, warn_bad_lines, delim_whitespace, low_memory, memory_map, float_precision)
683         )
684
--> 685         return _read(filepath_or_buffer, kwds)
686
687     parser_f.__name__ = name

~/.local/share/virtualenvs/openqlab/lib/python3.8/site-packages/pandas/io/parsers.py in _read(filepath_or_buffer, kwds)
455
456     # Create the parser.
--> 457     parser = TextFileReader(fp_or_buf, **kwds)
458
459     if chunksize or iterator:

~/.local/share/virtualenvs/openqlab/lib/python3.8/site-packages/pandas/io/parsers.py in __init__(self, f, engine, **kwds)
893             self.options["has_index_names"] = kwds["has_index_names"]
894
--> 895         self._make_engine(self.engine)
896
897     def close(self):

~/.local/share/virtualenvs/openqlab/lib/python3.8/site-packages/pandas/io/parsers.py in _make_engine(self, engine)
1145                     ' "python-fwf")'.format(engine=engine)
1146                 )
-> 1147             self._engine = klass(self.f, **self.options)
1148
1149     def _failover_to_python(self):

~/.local/share/virtualenvs/openqlab/lib/python3.8/site-packages/pandas/io/parsers.py in __init__(self, f, **kwds)
2297         # Set self.data to something that can read lines.
2298         if hasattr(f, "readline"):
-> 2299             self._make_reader(f)
2300         else:
2301             self.data = f

~/.local/share/virtualenvs/openqlab/lib/python3.8/site-packages/pandas/io/parsers.py in _make_reader(self, f)
2427                 self.pos += 1
2428                 self.line_pos += 1
-> 2429                 sniffed = csv.Sniffer().sniff(line)
2430                 dia.delimiter = sniffed.delimiter
2431                 if self.encoding is not None:

/usr/lib64/python3.8/csv.py in sniff(self, sample, delimiters)
179
180         quotechar, doublequote, delimiter, skipinitialspace = \
--> 181                    self._guess_quote_and_delimiter(sample, delimiters)
182         if not delimiter:
183             delimiter, skipinitialspace = self._guess_delimiter(sample,

/usr/lib64/python3.8/csv.py in _guess_quote_and_delimiter(self, data, delimiters)
220                       r'(?:^|\n)(?P<quote>["\']).*?(?P=quote)(?:$|\n)'):                            #  ".*?" (no delim, no space)
221             regexp = re.compile(restr, re.DOTALL | re.MULTILINE)
--> 222             matches = regexp.findall(data)
223             if matches:
224                 break

TypeError: expected string or bytes-like object

# Fixed code
def _make_reader(self, f):
    sep = self.delimiter

    if sep is None or len(sep) == 1:
        if self.lineterminator:
            raise ValueError(
                "Custom line terminators not supported in python parser (yet)"
            )

        class MyDialect(csv.Dialect):
            delimiter = self.delimiter
            quotechar = self.quotechar
            escapechar = self.escapechar
            doublequote = self.doublequote
            skipinitialspace = self.skipinitialspace
            quoting = self.quoting
            lineterminator = "\n"

        dia = MyDialect

        if sep is not None:
            dia.delimiter = sep
        else:
            # attempt to sniff the delimiter from the first valid line,
            # i.e. no comment line and not in skiprows
            line = f.readline()
            lines = self._check_comments([[line]])[0]
            while self.skipfunc(self.pos) or not lines:
                self.pos += 1
                line = f.readline()
                lines = self._check_comments([[line]])[0]

            # since `line` was a string, lines will be a list containing
            # only a single string
            line = lines[0]

            self.pos += 1
            self.line_pos += 1
            sniffed = csv.Sniffer().sniff(line)
            dia.delimiter = sniffed.delimiter

            # Note: self.encoding is irrelevant here
            line_rdr = csv.reader(StringIO(line), dialect=dia)
            self.buf.extend(list(line_rdr))

        # Note: self.encoding is irrelevant here
        reader = csv.reader(f, dialect=dia, strict=True)

    else:

        def _read():
            line = f.readline()
            pat = re.compile(sep)

            yield pat.split(line.strip())

            for line in f:
                yield pat.split(line.strip())

        reader = _read()

    self.data = reader