"""Числовой формат числовых ячеек в `Cell.number_format` (#42): xlsx синтетикой, xls — реальным файлом из fixtures.""" import datetime import io from pathlib import Path import openpyxl import pytest from src.parser.readers import read_book from src.parser.readers import xlsb as xlsb_reader from src.parser.readers._common import make_cell from tests.unit.parser.test_readers import _FakeXlsbBook, _zip_with FILLED_CELLS = 6 UNAGRANDE_XLS = "statements-xlsx/unagrande-group/2025-Q3/ББ. Лист 2 3кв.25.xls" def _xlsx() -> bytes: book = openpyxl.Workbook() ws = book.active assert ws is not None ws["A1"] = 10741981390 ws["A1"].number_format = "#,##0," ws["A2"] = 586260.26 ws["A2"].number_format = "0," ws["A3"] = 5 ws["A4"] = 7 ws["A4"].number_format = "General" ws["A5"] = "текст" ws["A5"].number_format = "0," ws["A6"] = datetime.datetime(2025, 9, 30) ws["A6"].number_format = "dd.mm.yyyy" out = io.BytesIO() book.save(out) return out.getvalue() def test_xlsx_number_format_is_kept_for_numbers_only() -> None: sheets, _ = read_book(_xlsx(), "XLSX") sheet = sheets[0] assert sheet.cell(1, 1).number_format == "#,##0," assert sheet.cell(2, 1).number_format == "0," assert sheet.cell(3, 1).number_format is None # General по умолчанию assert sheet.cell(4, 1).number_format is None # явный General assert sheet.cell(5, 1).number_format is None # текст assert sheet.cell(6, 1).kind == "date" assert sheet.cell(6, 1).number_format is None # дата assert len(sheet.cells) == FILLED_CELLS # разреженность: Cell только у непустых def test_make_cell_number_format_rules() -> None: assert make_cell(1.5, number_format="GENERAL").number_format is None # type: ignore[union-attr] assert make_cell(1.5, number_format="").number_format is None # type: ignore[union-attr] assert make_cell(1.5, number_format="0,").number_format == "0," # type: ignore[union-attr] assert make_cell("x", number_format="0,").number_format is None # type: ignore[union-attr] assert make_cell(datetime.datetime(2025, 1, 1), number_format="0,").number_format is None # type: ignore[union-attr] @pytest.mark.fixtures def test_xls_number_format_is_read(fixtures_dir: Path) -> None: sheets, _ = read_book((fixtures_dir / UNAGRANDE_XLS).read_bytes(), "XLS") formats = {cell.number_format for sheet in sheets for cell in sheet.cells.values() if cell.kind == "number"} assert {"#,##0,", "0,", '[=0]"-"'} <= formats assert all(cell.number_format is None for sheet in sheets for cell in sheet.cells.values() if cell.kind != "number") def test_xlsb_cells_have_no_number_format(monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr(xlsb_reader.pyxlsb, "open_workbook", lambda _stream: _FakeXlsbBook()) sheets, _ = read_book(_zip_with("xl/workbook.bin"), "XLSB") assert all(cell.number_format is None for cell in sheets[0].cells.values())