Repository: pandas-dev/pandas
File: pandas/io/parsers/python_parser.py (Python)

Code before:
        if max_len > col_len and self.index_col is not False and self.usecols is None:
            footers = self.skipfooter if self.skipfooter else 0
            bad_lines = []

            iter_content = enumerate(content)
            content_len = len(content)
            content = []

            for i, _content in iter_content:
                actual_len = len(_content)
                if actual_len > col_len:
                    if callable(self.on_bad_lines):
                        new_l = self.on_bad_lines(_content)
                        if new_l is not None:
                            # Truncate extra elements and warn.
                            new_l = cast(list[Scalar], new_l)
                            if len(new_l) > col_len:
                                msg = (
                                    "Length returned by on_bad_lines callable "
                                    "does not match expected "
                                    f"number of columns ({col_len}). "
                                    "Extra fields will be dropped."
                                )
                                self._alert_malformed(
                                    msg, row_num=self.pos - (content_len - i + footers)
                                )
                                new_l = new_l[:col_len]
                            content.append(new_l)

                    elif self.on_bad_lines in (
                        self.BadLineHandleMethod.ERROR,
                        self.BadLineHandleMethod.WARN,
                        self.BadLineHandleMethod.SKIP,
                    ):
                        row_num = self.pos - (content_len - i + footers)
                        bad_lines.append((row_num, actual_len))
                        if self.on_bad_lines == self.BadLineHandleMethod.ERROR:
                            break
                    else:
                        content.append(_content)
                else:
                    content.append(_content)

            for row_num, actual_len in bad_lines:
                msg = (
                    f"Expected {col_len} fields in line {row_num + 1}, saw {actual_len}"
                )
                if (
                    self.delimiter
                    and len(self.delimiter) > 1
                    and self.quoting != csv.QUOTE_NONE

Review comment (suggestion):
This is determining the message and calling `_alert_malformed` from a new place. This should all be consolidated to the same section of code below. Instead, I think you can just do on ~L1229:

```python
if callable(self.on_bad_lines):
    msg += " from bad_lines callable"
elif (
    self.delimiter
    ...
):
    ...
```

Code after:
        # elements in their row (rows with too few
        # elements are padded with NaN).
        if max_len > col_len and self.index_col is not False and self.usecols is None:
            footers = self.skipfooter if self.skipfooter else 0
            bad_lines = []

            iter_content = enumerate(content)
            content_len = len(content)
            content = []

            for i, _content in iter_content:
                actual_len = len(_content)
                if actual_len > col_len:
                    if callable(self.on_bad_lines):
                        new_l = self.on_bad_lines(_content)
                        if new_l is not None:
                            new_l = cast(list[Scalar], new_l)
                            if len(new_l) > col_len:
                                row_num = self.pos - (content_len - i + footers)
                                bad_lines.append((row_num, len(new_l), "callable"))
                                new_l = new_l[:col_len]
                            content.append(new_l)

                    elif self.on_bad_lines in (
                        self.BadLineHandleMethod.ERROR,
                        self.BadLineHandleMethod.WARN,
                    ):
                        row_num = self.pos - (content_len - i + footers)
                        bad_lines.append((row_num, actual_len, "normal"))
                        if self.on_bad_lines == self.BadLineHandleMethod.ERROR:
                            break
                else:
                    content.append(_content)

            for row_num, actual_len, source in bad_lines:
                msg = (
                    f"Expected {col_len} fields in line {row_num + 1}, saw {actual_len}"
                )
                if source == "callable":
                    msg += " from bad_lines callable"
                elif (
                    self.delimiter
                    and len(self.delimiter) > 1
                    and self.quoting != csv.QUOTE_NONE
                ):
                    # see gh-13374
                    reason = (
                        "Error could possibly be due to quotes being "
                        "ignored when a multi-char delimiter is used."
                    )
                    msg += ". " + reason