Repository: pandas-dev/pandas
File: pandas/tests/io/parser/test_encoding.py (Python)

Code before:
    if (
        parser.engine == "pyarrow"
        and data == "\n1"
        and kwargs.get("skip_blank_lines", True)
    ):
        # CSV parse error: Empty CSV file or block: cannot infer number of columns
        pytest.skip(reason="https://github.com/apache/arrow/issues/38676")

    # GH#63787: Both C and Python engines now warn about BOM stripping.
    # PyArrow currently does not support this warning path yet.
    if parser.engine == "pyarrow":
        # PyArrow doesn't warn yet
        with tm.assert_produces_warning(None):
            result = parser.read_csv(
                _encode_data_with_bom(data), encoding=utf8, **kwargs
            )
    else:
        # Both C-engine and Python engine now warn
        # GH#63787: Cython-compiled code has non-standard stack frames,
        # so we disable stacklevel checking.
        with tm.assert_produces_warning(
            Pandas4Warning, match="BOM", check_stacklevel=False
        ):
            result = parser.read_csv(
                _encode_data_with_bom(data), encoding=utf8, **kwargs
            )

    expected = DataFrame({"a": expected})
    tm.assert_frame_equal(result, expected)


def test_read_csv_utf_aliases(all_parsers, utf_value, encoding_fmt):
    # see gh-13549
    expected = DataFrame({"mb_num": [4.8], "multibyte": ["test"]})
    parser = all_parsers

    encoding = encoding_fmt.format(utf_value)
    data = "mb_num,multibyte\n4.8,test".encode(encoding)

    result = parser.read_csv(BytesIO(data), encoding=encoding)
    tm.assert_frame_equal(result, expected)


@pytest.mark.parametrize(
    "file_path,encoding",
    [
        (("io", "data", "csv", "test1.csv"), "utf-8"),
        (("io", "parser", "data", "unicode_series.csv"), "latin-1"),
        (("io", "parser", "data", "sauron.SHIFT_JIS.csv"), "shiftjis"),
    ],
)

Review comment (suggestion):
Can you remove all the duplication of code. Use

    warn = Pandas4Warning if ... else None

and then just pass `warn` to `tm.assert_produces_warning`.

Code after:
    ):
        # CSV parse error: Empty CSV file or block: cannot infer number of columns
        pytest.skip(reason="https://github.com/apache/arrow/issues/38676")

    result = parser.read_csv(
        _encode_data_with_bom(data),
        encoding=encoding,
        **kwargs,
    )
    expected = DataFrame({"a": expected})
    tm.assert_frame_equal(result, expected)


def test_latin1_bom_preserved(all_parsers):
    parser = all_parsers
    if parser.engine == "pyarrow":
        pytest.skip(reason="pyarrow does not support latin-1 encoding")

    bom_bytes = b"\xef\xbb\xbf"
    bom_text = bom_bytes.decode("latin1")
    data = b"a\n1"
    bio = BytesIO(bom_bytes + data)

    result = parser.read_csv(bio, encoding="latin1")
    expected = DataFrame({f"{bom_text}a": [1]})
    tm.assert_frame_equal(result, expected)


def test_read_csv_utf_aliases(all_parsers, utf_value, encoding_fmt):
    # see gh-13549
    expected = DataFrame({"mb_num": [4.8], "multibyte": ["test"]})
    parser = all_parsers

    encoding = encoding_fmt.format(utf_value)
    data = "mb_num,multibyte\n4.8,test".encode(encoding)

    result = parser.read_csv(BytesIO(data), encoding=encoding)
    tm.assert_frame_equal(result, expected)


@pytest.mark.parametrize(
    "file_path,encoding",
    [
        (("io", "data", "csv", "test1.csv"), "utf-8"),
        (("io", "parser", "data", "unicode_series.csv"), "latin-1"),
        (("io", "parser", "data", "sauron.SHIFT_JIS.csv"), "shiftjis"),
    ],
)
def test_binary_mode_file_buffers(all_parsers, file_path, encoding, datapath):
    # gh-23779: Python csv engine shouldn't error on files opened in binary.
    # gh-31575: Python csv engine shouldn't error on files opened in raw binary.