# Buggy code
def _infer_columns(self):
    names = self.names
    num_original_columns = 0
    clear_buffer = True
    if self.header is not None:
        header = self.header

        # we have a mi columns, so read an extra line
        if isinstance(header, (list, tuple, np.ndarray)):
            have_mi_columns = True
            header = list(header) + [header[-1] + 1]
        else:
            have_mi_columns = False
            header = [header]

        columns = []
        for level, hr in enumerate(header):
            try:
                line = self._buffered_line()

                while self.line_pos <= hr:
                    line = self._next_line()

            except StopIteration:
                if self.line_pos < hr:
                    raise ValueError(
                        "Passed header=%s but only %d lines in file"
                        % (hr, self.line_pos + 1)
                    )

                # We have an empty file, so check
                # if columns are provided. That will
                # serve as the 'line' for parsing
                if have_mi_columns and hr > 0:
                    if clear_buffer:
                        self._clear_buffer()
                    columns.append([None] * len(columns[-1]))
                    return columns, num_original_columns

                if not self.names:
                    raise EmptyDataError("No columns to parse from file")

                line = self.names[:]

            unnamed_count = 0
            this_columns = []
            for i, c in enumerate(line):
                if c == "":
                    if have_mi_columns:
                        this_columns.append("Unnamed: %d_level_%d" % (i, level))
                    else:
                        this_columns.append("Unnamed: %d" % i)
                    unnamed_count += 1
                else:
                    this_columns.append(c)

            if not have_mi_columns and self.mangle_dupe_cols:
                counts = {}
                for i, col in enumerate(this_columns):
                    cur_count = counts.get(col, 0)
                    if cur_count > 0:
                        this_columns[i] = "%s.%d" % (col, cur_count)
                    counts[col] = cur_count + 1
            elif have_mi_columns:
                # if we have grabbed an extra line, but its not in our
                # format so save in the buffer, and create an blank extra
                # line for the rest of the parsing code
                if hr == header[-1]:
                    lc = len(this_columns)
                    ic = len(self.index_col) if self.index_col is not None else 0
                    if lc != unnamed_count and lc - ic > unnamed_count:
                        clear_buffer = False
                        this_columns = [None] * lc
                        self.buf = [self.buf[-1]]

            columns.append(this_columns)
            if len(columns) == 1:
                num_original_columns = len(this_columns)

        if clear_buffer:
            self._clear_buffer()

        if names is not None:
            if (self.usecols is not None and len(names) != len(self.usecols)) or (
                self.usecols is None and len(names) != len(columns[0])
            ):
                raise ValueError(
                    "Number of passed names did not match "
                    "number of header fields in the file"
                )
            if len(columns) > 1:
                raise TypeError("Cannot pass names with multi-index columns")

            if self.usecols is not None:
                # Set _use_cols. We don't store columns because they are
                # overwritten.
                self._handle_usecols(columns, names)
            else:
                self._col_indices = None
                num_original_columns = len(names)
            columns = [names]
        else:
            columns = self._handle_usecols(columns, columns[0])
    else:
        try:
            line = self._buffered_line()

        except StopIteration:
            if not names:
                raise EmptyDataError("No columns to parse from file")

            line = names[:]

        ncols = len(line)
        num_original_columns = ncols

        if not names:
            if self.prefix:
                columns = [["%s%d" % (self.prefix, i) for i in range(ncols)]]
            else:
                columns = [lrange(ncols)]
            columns = self._handle_usecols(columns, columns[0])
        else:
            if self.usecols is None or len(names) == num_original_columns:
                columns = self._handle_usecols([names], names)
                num_original_columns = len(names)
            else:
                if self.usecols and len(names) != len(self.usecols):
                    raise ValueError(
                        "Number of passed names did not match number of "
                        "header fields in the file"
                    )
                # Ignore output but set used columns.
                self._handle_usecols([names], names)
                columns = [names]
                num_original_columns = ncols

    return columns, num_original_columns


# Traceback (CParserError)
In [98]: mydata='1,2,3\n1,2\n1,2\n'
In [99]: pd.read_csv(StringIO(mydata), names=['a', 'b', 'c'], usecols=['a', 'c'])
Out[99]:
a   c
0  1   3
1  1 NaN
2  1 NaN

[3 rows x 2 columns]
In [100]: mydata='1,2\n1,2,3\n4,5,6\n'
In [101]: pd.read_csv(StringIO(mydata), names=['a', 'b', 'c'], usecols=['a', 'c'])
---------------------------------------------------------------------------
CParserError                              Traceback (most recent call last)
<ipython-input-101-f60127771eeb> in <module>()
----> 1 pd.read_csv(StringIO(mydata), names=['a', 'b', 'c'], usecols=['a', 'c'])

/home/altaurog/venv/p27/local/lib/python2.7/site-packages/pandas/io/parsers.pyc in parser_f(filepath_or_buffer, sep, dialect, compression, doublequote, escapechar, quotechar, quoting, skipinitialspace, lineterminator, header, index_col, names, prefix, skiprows, skipfooter, skip_footer, na_values, na_fvalues, true_values, false_values, delimiter, converters, dtype, usecols, engine, delim_whitespace, as_recarray, na_filter, compact_ints, use_unsigned, low_memory, buffer_lines, warn_bad_lines, error_bad_lines, keep_default_na, thousands, comment, decimal, parse_dates, keep_date_col, dayfirst, date_parser, memory_map, nrows, iterator, chunksize, verbose, encoding, squeeze, mangle_dupe_cols, tupleize_cols, infer_datetime_format)
418                     infer_datetime_format=infer_datetime_format)
419
--> 420         return _read(filepath_or_buffer, kwds)
421
422     parser_f.__name__ = name

/home/altaurog/venv/p27/local/lib/python2.7/site-packages/pandas/io/parsers.pyc in _read(filepath_or_buffer, kwds)
223         return parser
224
--> 225     return parser.read()
226
227 _parser_defaults = {

/home/altaurog/venv/p27/local/lib/python2.7/site-packages/pandas/io/parsers.pyc in read(self, nrows)
624                 raise ValueError('skip_footer not supported for iteration')
625
--> 626         ret = self._engine.read(nrows)
627
628         if self.options.get('as_recarray'):

/home/altaurog/venv/p27/local/lib/python2.7/site-packages/pandas/io/parsers.pyc in read(self, nrows)
1068
1069         try:
-> 1070             data = self._reader.read(nrows)
1071         except StopIteration:
1072             if nrows is None:

/home/altaurog/venv/p27/local/lib/python2.7/site-packages/pandas/parser.so in pandas.parser.TextReader.read (pandas/parser.c:6866)()

/home/altaurog/venv/p27/local/lib/python2.7/site-packages/pandas/parser.so in pandas.parser.TextReader._read_low_memory (pandas/parser.c:7086)()

/home/altaurog/venv/p27/local/lib/python2.7/site-packages/pandas/parser.so in pandas.parser.TextReader._read_rows (pandas/parser.c:7691)()

/home/altaurog/venv/p27/local/lib/python2.7/site-packages/pandas/parser.so in pandas.parser.TextReader._tokenize_rows (pandas/parser.c:7575)()

/home/altaurog/venv/p27/local/lib/python2.7/site-packages/pandas/parser.so in pandas.parser.raise_parser_error (pandas/parser.c:19038)()

CParserError: Error tokenizing data. C error: Expected 2 fields in line 2, saw 3

In [102]: pd.show_versions()

INSTALLED VERSIONS
------------------
commit: None
python: 2.7.3.final.0
python-bits: 64
OS: Linux
OS-release: 3.2.0-4-amd64
machine: x86_64
processor:
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8

pandas: 0.13.1
Cython: 0.20
numpy: 1.8.0
scipy: None
statsmodels: None
IPython: 1.2.1
sphinx: 1.1.3
patsy: None
scikits.timeseries: None
dateutil: 1.5
pytz: 2012c
bottleneck: 0.8.0
tables: 3.1.0
numexpr: 2.3.1
matplotlib: 1.3.1
openpyxl: None
xlrd: None
xlwt: 0.7.4
xlsxwriter: None
sqlalchemy: None
lxml: None
bs4: None
html5lib: 0.999
bq: None
apiclient: None

# Fixed code
def _infer_columns(self):
    names = self.names
    num_original_columns = 0
    clear_buffer = True
    if self.header is not None:
        header = self.header

        # we have a mi columns, so read an extra line
        if isinstance(header, (list, tuple, np.ndarray)):
            have_mi_columns = True
            header = list(header) + [header[-1] + 1]
        else:
            have_mi_columns = False
            header = [header]

        columns = []
        for level, hr in enumerate(header):
            try:
                line = self._buffered_line()

                while self.line_pos <= hr:
                    line = self._next_line()

            except StopIteration:
                if self.line_pos < hr:
                    raise ValueError(
                        "Passed header=%s but only %d lines in file"
                        % (hr, self.line_pos + 1)
                    )

                # We have an empty file, so check
                # if columns are provided. That will
                # serve as the 'line' for parsing
                if have_mi_columns and hr > 0:
                    if clear_buffer:
                        self._clear_buffer()
                    columns.append([None] * len(columns[-1]))
                    return columns, num_original_columns

                if not self.names:
                    raise EmptyDataError("No columns to parse from file")

                line = self.names[:]

            unnamed_count = 0
            this_columns = []
            for i, c in enumerate(line):
                if c == "":
                    if have_mi_columns:
                        this_columns.append("Unnamed: %d_level_%d" % (i, level))
                    else:
                        this_columns.append("Unnamed: %d" % i)
                    unnamed_count += 1
                else:
                    this_columns.append(c)

            if not have_mi_columns and self.mangle_dupe_cols:
                counts = {}
                for i, col in enumerate(this_columns):
                    cur_count = counts.get(col, 0)
                    if cur_count > 0:
                        this_columns[i] = "%s.%d" % (col, cur_count)
                    counts[col] = cur_count + 1
            elif have_mi_columns:
                # if we have grabbed an extra line, but its not in our
                # format so save in the buffer, and create an blank extra
                # line for the rest of the parsing code
                if hr == header[-1]:
                    lc = len(this_columns)
                    ic = len(self.index_col) if self.index_col is not None else 0
                    if lc != unnamed_count and lc - ic > unnamed_count:
                        clear_buffer = False
                        this_columns = [None] * lc
                        self.buf = [self.buf[-1]]

            columns.append(this_columns)
            if len(columns) == 1:
                num_original_columns = len(this_columns)

        if clear_buffer:
            self._clear_buffer()

        if names is not None:
            if (self.usecols is not None and len(names) != len(self.usecols)) or (
                self.usecols is None and len(names) != len(columns[0])
            ):
                raise ValueError(
                    "Number of passed names did not match "
                    "number of header fields in the file"
                )
            if len(columns) > 1:
                raise TypeError("Cannot pass names with multi-index columns")

            if self.usecols is not None:
                # Set _use_cols. We don't store columns because they are
                # overwritten.
                self._handle_usecols(columns, names)
            else:
                self._col_indices = None
                num_original_columns = len(names)
            columns = [names]
        else:
            columns = self._handle_usecols(columns, columns[0])
    else:
        try:
            line = self._buffered_line()

        except StopIteration:
            if not names:
                raise EmptyDataError("No columns to parse from file")

            line = names[:]

        ncols = len(line)
        num_original_columns = ncols

        if not names:
            if self.prefix:
                columns = [["%s%d" % (self.prefix, i) for i in range(ncols)]]
            else:
                columns = [lrange(ncols)]
            columns = self._handle_usecols(columns, columns[0])
        else:
            if self.usecols is None or len(names) >= num_original_columns:
                columns = self._handle_usecols([names], names)
                num_original_columns = len(names)
            else:
                if not callable(self.usecols) and len(names) != len(self.usecols):
                    raise ValueError(
                        "Number of passed names did not match number of "
                        "header fields in the file"
                    )
                # Ignore output but set used columns.
                self._handle_usecols([names], names)
                columns = [names]
                num_original_columns = ncols

    return columns, num_original_columns