From 6c15dd1f5315820c7b3add0f3acb7fb31ea4abd1 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 06:49:39 +0900 Subject: [PATCH 01/40] Add stubs --- typings/xlwings/__init__.pyi | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 typings/xlwings/__init__.pyi diff --git a/typings/xlwings/__init__.pyi b/typings/xlwings/__init__.pyi new file mode 100644 index 0000000..0d29943 --- /dev/null +++ b/typings/xlwings/__init__.pyi @@ -0,0 +1,12 @@ +from typing import Any + +class Range: + def __getitem__(self, key: Any) -> Range: ... + def get_address( + self, + row_absolute: bool = True, + column_absolute: bool = True, + include_sheetname: bool = False, + external: bool = False, + ) -> str: ... + def offset(self, row_offset: int = 0, column_offset: int = 0) -> Range: ... From f7a23e7a36f13e0d4174cf2db7a8a359a6bfb485 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 07:19:57 +0900 Subject: [PATCH 02/40] Add pre-commit --- .pre-commit-config.yaml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..c5d5760 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,26 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: check-json + - id: check-toml + - id: check-yaml + exclude: ^mkdocs\.yml$ + - id: end-of-file-fixer + - id: trailing-whitespace + - repo: https://github.com/abravalheri/validate-pyproject + rev: v0.25 + hooks: + - id: validate-pyproject + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.15.0 + hooks: + - id: ruff-check + files: ^(src|tests)/ + - id: ruff-format + files: ^(src|tests)/ + - repo: https://github.com/DetachHead/basedpyright-prek-mirror + rev: 1.37.4 + hooks: + - id: basedpyright + files: ^(src|tests)/ From 1063054ec9b933841e443684b3c1d5b14f11d16d Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 07:20:41 +0900 Subject: [PATCH 03/40] Update stubs --- typings/xlwings/__init__.pyi | 61 +++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/typings/xlwings/__init__.pyi b/typings/xlwings/__init__.pyi index 0d29943..2b22976 100644 --- a/typings/xlwings/__init__.pyi +++ b/typings/xlwings/__init__.pyi @@ -1,7 +1,23 @@ +from collections.abc import Iterator from typing import Any class Range: - def __getitem__(self, key: Any) -> Range: ... + @property + def api(self) -> Any: ... + @property + def impl(self) -> Any: ... + def __iter__(self) -> Iterator[Range]: ... + def options(self, convert: type | None = None, **options: Any) -> Range: ... + @property + def sheet(self) -> Sheet: ... + def __len__(self) -> int: ... + @property + def count(self) -> int: ... + @property + def row(self) -> int: ... + @property + def column(self) -> int: ... + def end(self, direction: str) -> Range: ... def get_address( self, row_absolute: bool = True, @@ -9,4 +25,47 @@ class Range: include_sheetname: bool = False, external: bool = False, ) -> str: ... + @property + def value(self) -> Any: ... + @value.setter + def value(self, value: Any) -> None: ... + def expand(self, mode: str = "table") -> Range: ... + def __getitem__(self, key: Any) -> Range: ... def offset(self, row_offset: int = 0, column_offset: int = 0) -> Range: ... + @property + def last_cell(self) -> Range: ... + +class Sheet: + @property + def api(self) -> Any: ... + @property + def impl(self) -> Any: ... + @property + def name(self) -> str: ... + @name.setter + def name(self, value: str) -> None: ... + def range( + self, + cell1: Range | tuple[int, int], + cell2: Range | tuple[int, int], + ) -> Range: ... + @property + def book(self) -> Book: ... + +class Book: + @property + def name(self) -> str: ... + @property + def app(self) -> App: ... + +class App: + @property + def api(self) -> Any: ... + +class Sheets: + @property + def active(self) -> Sheet: ... + +class ActiveBookSheets(Sheets): ... + +sheets: ActiveBookSheets From 1436ed63f1e53cdf80191456e08f6bd9e3bfcf62 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 07:24:45 +0900 Subject: [PATCH 04/40] Update core --- pyproject.toml | 54 ++++++++++++++-------------- src/xlviews/core/formula.py | 7 ++-- src/xlviews/core/index.py | 9 ++--- src/xlviews/core/range.py | 5 +-- src/xlviews/core/range_collection.py | 5 ++- 5 files changed, 41 insertions(+), 39 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e9600f4..60c53ef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,14 +27,18 @@ Issues = "https://github.com/daizutabi/xlviews/issues" [dependency-groups] dev = [ + "basedpyright>=1.37.3", "pandas-stubs>=3.0.0.260204", - "pytest>=9.0.1", + "prek>=0.3.1", "pytest-benchmark>=5.2.3", "pytest-clarity>=1.0.1", "pytest-cov>=7.0.0", "pytest-randomly>=4.0.1", "pytest-skip-slow>=0.0.5", - "scipy>=1.16.3", + "pytest>=9.0.1", + "ruff>=0.15.0", + "scipy-stubs>=1.17.0", + "scipy>=1.17.0", ] [tool.pytest.ini_options] @@ -59,43 +63,39 @@ line-length = 88 target-version = "py311" [tool.ruff.lint] +preview = true select = ["ALL"] unfixable = ["F401"] ignore = [ - "ANN002", - "ANN003", "ANN401", - "ARG001", - "ARG002", - "C901", + "CPY001", "D", - "D105", - "D107", - "D203", - "D213", - "EM101", + "DOC201", + "DOC402", + "DOC501", + "DOC502", "ERA001", "FBT001", "FBT002", - "PERF401", - "PGH003", - "PLC0415", - "PLR", - "RUF001", - "RUF003", - "SIM102", - "SIM108", - "TD", - "TRY003", + "PLR0913", + "PLR0917", ] [tool.ruff.lint.per-file-ignores] -"tests/*" = ["ANN", "ARG", "D", "FBT", "PLR", "RUF", "S", "SLF"] +"tests/*" = ["ANN", "ARG", "D", "PLC2701", "PLR2004", "PT011", "S", "SLF001"] "src/xlviews/testing/*" = ["T201"] -[tool.pyright] +[tool.ruff.lint.isort] +required-imports = ["from __future__ import annotations"] + +[tool.ruff.format] +preview = true + +[tool.basedpyright] include = ["src", "tests"] +reportAny = false +reportExplicitAny = false +reportImportCycles = false +reportImplicitOverride = false +reportUnusedCallResult = false reportIncompatibleMethodOverride = false -strictDictionaryInference = true -strictListInference = true -strictSetInference = true diff --git a/src/xlviews/core/formula.py b/src/xlviews/core/formula.py index c54df29..c93ffe3 100644 --- a/src/xlviews/core/formula.py +++ b/src/xlviews/core/formula.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, TypeAlias +from typing import TYPE_CHECKING, Any, TypeAlias from xlwings import Range as RangeImpl @@ -52,7 +52,7 @@ def _aggregate( func: Func, ranges: Range | RangeCollection | Iterable[Range | RangeCollection] | str, option: int, - **kwargs, + **kwargs: Any, ) -> str: if func == "soa": std = aggregate("std", ranges, option, **kwargs) @@ -87,6 +87,7 @@ def aggregate( func: Func, ranges: Range | RangeCollection | Iterable[Range | RangeCollection] | str, option: int = 7, # ignore hidden rows and error values + *, row_absolute: bool = True, column_absolute: bool = True, include_sheetname: bool = False, @@ -173,7 +174,7 @@ def aggregate( # cell = ref.range(column, 0) # cell = cell.get_address(include_sheetname=include_sheetname) # formula = ( -# f"INDIRECT(ADDRESS({formula},COLUMN({cell}),1,1," + f'"{ref.sheet.name}"))' +# f"INDIRECT(ADDRESS({formula},COLUMN({cell}),1,1,"+f'"{ref.sheet.name}"))' # ) # if error is not False: # formula = f"IFERROR({formula},{error})" diff --git a/src/xlviews/core/index.py b/src/xlviews/core/index.py index 422c290..03b667a 100644 --- a/src/xlviews/core/index.py +++ b/src/xlviews/core/index.py @@ -1,5 +1,6 @@ from __future__ import annotations +from collections import UserDict from typing import TYPE_CHECKING, Any import numpy as np @@ -13,7 +14,7 @@ from pandas._typing import Axes -class WideIndex(dict[str, list[Any]]): +class WideIndex(UserDict[str, list[Any]]): """Represent a wide index.""" def __len__(self) -> int: @@ -62,7 +63,7 @@ def __len__(self) -> int: @property def names(self) -> list[str]: - return self.index.names # type: ignore + return self.index.names # pyright: ignore[reportReturnType] @property def nlevels(self) -> int: @@ -170,7 +171,7 @@ def get_indexer( self, columns: dict[str, Any] | None = None, offset: int = 0, - **kwargs, + **kwargs: Any, ) -> NDArray[np.intp]: if self.index.nlevels == 1: raise NotImplementedError @@ -182,5 +183,5 @@ def get_indexer( return np.where(np.all(idx, axis=0))[0] + offset - def to_frame(self, index: bool = True) -> DataFrame: + def to_frame(self, *, index: bool = True) -> DataFrame: return self.index.to_frame(index=index) diff --git a/src/xlviews/core/range.py b/src/xlviews/core/range.py index d068431..73e88ca 100644 --- a/src/xlviews/core/range.py +++ b/src/xlviews/core/range.py @@ -67,7 +67,8 @@ def __getitem__(self, key: int) -> Self: key += len(self) if key < 0 or key >= len(self): - raise IndexError("Index out of range") + msg = "Index out of range" + raise IndexError(msg) row = self.row + key // (self.column_end - self.column + 1) column = self.column + key % (self.column_end - self.column + 1) @@ -139,7 +140,7 @@ def value(self, value: Any) -> None: self.impl.value = value @property - def api(self): # noqa: ANN201 + def api(self) -> Any: return self.impl.api @property diff --git a/src/xlviews/core/range_collection.py b/src/xlviews/core/range_collection.py index 421cc27..2179f95 100644 --- a/src/xlviews/core/range_collection.py +++ b/src/xlviews/core/range_collection.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any from .range import Range, iter_addresses @@ -34,7 +34,6 @@ def __iter__(self) -> Iterator[Range]: def get_address( self, - *, row_absolute: bool = True, column_absolute: bool = True, include_sheetname: bool = False, @@ -68,7 +67,7 @@ def iter_addresses( ) @property - def api(self): # noqa: ANN201 + def api(self) -> Any: api = self.ranges[0].api if len(self.ranges) == 1: From 3705bfb9fd66785f4473db537dacd7118352043b Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 07:38:55 +0900 Subject: [PATCH 05/40] Update pyproject.toml --- pyproject.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 60c53ef..0bcdfc8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -95,7 +95,8 @@ preview = true include = ["src", "tests"] reportAny = false reportExplicitAny = false -reportImportCycles = false reportImplicitOverride = false -reportUnusedCallResult = false +reportImportCycles = false reportIncompatibleMethodOverride = false +reportMissingTypeStubs = false +reportUnusedCallResult = false From ae9492f36825167882ec3d275543c12536647730 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 07:39:10 +0900 Subject: [PATCH 06/40] Update stubs --- typings/xlwings/__init__.pyi | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/typings/xlwings/__init__.pyi b/typings/xlwings/__init__.pyi index 2b22976..30ee571 100644 --- a/typings/xlwings/__init__.pyi +++ b/typings/xlwings/__init__.pyi @@ -61,11 +61,27 @@ class Book: class App: @property def api(self) -> Any: ... + @property + def screen_updating(self) -> bool: ... + @screen_updating.setter + def screen_updating(self, value: bool) -> None: ... + +class Apps: + @property + def active(self) -> App: ... + +class Books: + @property + def active(self) -> Book: ... class Sheets: @property def active(self) -> Sheet: ... +class ActiveEngineApps(Apps): ... +class ActiveAppBooks(Books): ... class ActiveBookSheets(Sheets): ... +apps: ActiveEngineApps +books: ActiveAppBooks sheets: ActiveBookSheets From 983d93d515f4eeb834587cd99b2414194cebe9bb Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 07:41:23 +0900 Subject: [PATCH 07/40] Update top-level modules --- src/xlviews/colors.py | 2 +- src/xlviews/style.py | 10 +++++----- src/xlviews/utils.py | 9 +++++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/xlviews/colors.py b/src/xlviews/colors.py index 119a2c3..06535d4 100644 --- a/src/xlviews/colors.py +++ b/src/xlviews/colors.py @@ -39,7 +39,7 @@ def rgb( if isinstance(color, str): color = cnames.get(color, color) - if not isinstance(color, str) or not color.startswith("#") or len(color) != 7: + if not color.startswith("#") or len(color) != 7: # noqa: PLR2004 msg = "Invalid color format. Expected int, tuple[int, int, int], or str." raise ValueError(msg) diff --git a/src/xlviews/style.py b/src/xlviews/style.py index 0fed298..58bcca7 100644 --- a/src/xlviews/style.py +++ b/src/xlviews/style.py @@ -109,15 +109,15 @@ def set_font_api( ) -> None: font = api.Font if name: - font.Name = name # type: ignore + font.Name = name # pyright: ignore[reportAttributeAccessIssue] if size: - font.Size = size # type: ignore + font.Size = size # pyright: ignore[reportAttributeAccessIssue] if bold is not None: - font.Bold = bold # type: ignore + font.Bold = bold # pyright: ignore[reportAttributeAccessIssue] if italic is not None: - font.Italic = italic # type: ignore + font.Italic = italic # pyright: ignore[reportAttributeAccessIssue] if color is not None: - font.Color = rgb(color) # type: ignore + font.Color = rgb(color) # pyright: ignore[reportAttributeAccessIssue] def set_font( diff --git a/src/xlviews/utils.py b/src/xlviews/utils.py index 55f19cd..be4ccf8 100644 --- a/src/xlviews/utils.py +++ b/src/xlviews/utils.py @@ -1,7 +1,7 @@ from __future__ import annotations from functools import wraps -from typing import TYPE_CHECKING, ParamSpec, TypeVar +from typing import TYPE_CHECKING, Any, ParamSpec, TypeVar import xlwings from pandas import DataFrame, Series @@ -10,6 +10,7 @@ if TYPE_CHECKING: from collections.abc import Callable, Iterable, Iterator + import numpy as np from numpy.typing import NDArray from pandas import Index from xlwings import Range as RangeImpl @@ -37,13 +38,13 @@ def constant(type_: str, name: str | None = None) -> int: if not name.startswith("xl"): name = "xl" + name[0].upper() + name[1:] - type_ = getattr(xlwings.constants, type_) + type_ = getattr(xlwings.constants, type_) # pyright: ignore[reportUnknownMemberType, reportUnknownArgumentType, reportAttributeAccessIssue] return getattr(type_, name) def iter_columns( - iterable: Iterable | DataFrame, + iterable: Iterable[Any] | DataFrame, columns: str | list[str], ) -> Iterator[str]: """Yield the columns in the order of appearance with colon notation. @@ -73,7 +74,7 @@ def iter_columns( def iter_group_locs( - index: list | NDArray | Index | Series, + index: list[int] | NDArray[np.integer] | Index | Series, offset: int = 0, padding: int = 0, ) -> Iterator[tuple[int, int]]: From efe41e24079c4d5c64cb86e7d410026d9b7f8da6 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 08:34:04 +0900 Subject: [PATCH 08/40] Update pyproject.toml --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 0bcdfc8..1528d42 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,6 +68,7 @@ select = ["ALL"] unfixable = ["F401"] ignore = [ "ANN401", + "C901", "CPY001", "D", "DOC201", @@ -77,6 +78,7 @@ ignore = [ "ERA001", "FBT001", "FBT002", + "PLR0904", "PLR0913", "PLR0917", ] @@ -99,4 +101,5 @@ reportImplicitOverride = false reportImportCycles = false reportIncompatibleMethodOverride = false reportMissingTypeStubs = false +reportPropertyTypeMismatch = false reportUnusedCallResult = false From c83b6d04f3861c94646ea8b014aba52aba2490f2 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 08:36:56 +0900 Subject: [PATCH 09/40] Update dataframes modules --- src/xlviews/dataframes/colorbar.py | 8 ++-- src/xlviews/dataframes/dist_frame.py | 7 +-- src/xlviews/dataframes/groupby.py | 24 +++++----- src/xlviews/dataframes/heat_frame.py | 9 ++-- src/xlviews/dataframes/sheet_frame.py | 65 ++++++++++++++------------- src/xlviews/dataframes/stats_frame.py | 25 +++++------ src/xlviews/dataframes/table.py | 22 +++++---- typings/xlwings/__init__.pyi | 20 ++++++++- 8 files changed, 100 insertions(+), 80 deletions(-) diff --git a/src/xlviews/dataframes/colorbar.py b/src/xlviews/dataframes/colorbar.py index ab319b3..347bd03 100644 --- a/src/xlviews/dataframes/colorbar.py +++ b/src/xlviews/dataframes/colorbar.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Literal, Self import xlwings @@ -17,8 +17,6 @@ ) if TYPE_CHECKING: - from typing import Literal, Self - from xlwings import Sheet @@ -152,6 +150,6 @@ def autofit(self) -> Self: def set_adjacent_column_width(self, width: float, offset: int = 1) -> None: """Set the width of the adjacent empty column.""" if self.orientation == "vertical": - self.range.offset(0, 1).impl.column_width = width + self.range.offset(0, offset).impl.column_width = width else: - self.range.last_cell.offset(0, 2).impl.column_width = width + self.range.last_cell.offset(0, offset + 1).impl.column_width = width diff --git a/src/xlviews/dataframes/dist_frame.py b/src/xlviews/dataframes/dist_frame.py index 27b9925..54eb81c 100644 --- a/src/xlviews/dataframes/dist_frame.py +++ b/src/xlviews/dataframes/dist_frame.py @@ -57,7 +57,8 @@ def set_values( for row in group.values(): if len(row) != 1: - raise ValueError("group must be continuous") + msg = "group must be continuous" + raise ValueError(msg) start = row[0][0] length = row[0][1] - start + 1 @@ -92,7 +93,7 @@ def set_values( # ): # if ylabel == "auto": # dist = self.dist_func[x] if isinstance(x, str) else self.dist_func[x[0]] - # ylabel = "σ" if dist == "norm" else "ln(-ln(1-F))" + # ylabel = "σ" if dist == "norm" else "ln(-ln(1-F))" # noqa: RUF003 # plot = None # if isinstance(x, str) and xlabel == "auto": # x_ = x.split("_")[0] @@ -170,7 +171,7 @@ def set_values( # cell = self.sheet.range(row, column) # range_ = self.sheet.range(cell, cell.offset(len(self) - 1)) # range_.api.NumberFormatLocal = "0.00_ " - # formula = f"=IF(AND({cell_ref}>=-{sigma},{cell_ref}<={sigma}),{cell_ref},NA())" + # formula = f"=IF(AND({cell_ref}>=-{sigma},{cell_ref}<={sigma}),{cell_ref},NA())" # noqa: E501 # range_.value = formula # return column_ diff --git a/src/xlviews/dataframes/groupby.py b/src/xlviews/dataframes/groupby.py index 00b60cd..82faef2 100644 --- a/src/xlviews/dataframes/groupby.py +++ b/src/xlviews/dataframes/groupby.py @@ -1,7 +1,7 @@ from __future__ import annotations from functools import partial -from typing import TYPE_CHECKING, TypeVar +from typing import TYPE_CHECKING, Any, TypeVar import numpy as np from pandas import DataFrame, Index, MultiIndex, Series @@ -22,7 +22,7 @@ def to_dict(keys: Iterable[H], values: Iterable[T]) -> dict[H, list[T]]: - result = {} + result: dict[H, list[T]] = {} for key, value in zip(keys, values, strict=True): result.setdefault(key, []).append(value) @@ -31,9 +31,9 @@ def to_dict(keys: Iterable[H], values: Iterable[T]) -> dict[H, list[T]]: def create_group_index( - a: Sequence | Series | DataFrame, + a: Sequence[Any] | Series | DataFrame, sort: bool = True, -) -> dict[tuple, list[tuple[int, int]]]: +) -> dict[tuple[Any, ...], list[tuple[int, int]]]: if isinstance(a, DataFrame): df = a.reset_index(drop=True) else: @@ -60,7 +60,7 @@ def groupby( by: str | list[str] | None, *, sort: bool = True, -) -> dict[tuple, list[tuple[int, int]]]: +) -> dict[tuple[Any, ...], list[tuple[int, int]]]: """Group by the specified column and return the group key and row number.""" if sf.columns.nlevels != 1: raise NotImplementedError @@ -83,7 +83,7 @@ def groupby( class GroupBy: sf: SheetFrame by: list[str] - group: dict[tuple, list[tuple[int, int]]] + group: dict[tuple[Any, ...], list[tuple[int, int]]] def __init__( self, @@ -99,19 +99,19 @@ def __init__( def __len__(self) -> int: return len(self.group) - def keys(self) -> Iterator[tuple]: + def keys(self) -> Iterator[tuple[Any, ...]]: yield from self.group.keys() def values(self) -> Iterator[list[tuple[int, int]]]: yield from self.group.values() - def items(self) -> Iterator[tuple[tuple, list[tuple[int, int]]]]: + def items(self) -> Iterator[tuple[tuple[Any, ...], list[tuple[int, int]]]]: yield from self.group.items() - def __iter__(self) -> Iterator[tuple]: + def __iter__(self) -> Iterator[tuple[Any, ...]]: return self.keys() - def __getitem__(self, key: tuple) -> list[tuple[int, int]]: + def __getitem__(self, key: tuple[Any, ...]) -> list[tuple[int, int]]: return self.group[key] def index( @@ -153,7 +153,7 @@ def index( def agg( self, - func: Func | dict | Sequence[Func] = None, + func: Func | dict[str, str] | Sequence[Func] = None, columns: str | list[str] | None = None, as_address: bool = False, row_absolute: bool = True, @@ -206,7 +206,7 @@ def agg( columns_ = MultiIndex.from_tuples([(c, f) for c in columns for f in func]) return DataFrame(values, index=index, columns=columns_) - def _agg(self, func: Func, column: int, **kwargs) -> Iterator[str]: + def _agg(self, func: Func, column: int, **kwargs: Any) -> Iterator[str]: if func == "first": func = None for row in self.values(): diff --git a/src/xlviews/dataframes/heat_frame.py b/src/xlviews/dataframes/heat_frame.py index 3e9a820..b581357 100644 --- a/src/xlviews/dataframes/heat_frame.py +++ b/src/xlviews/dataframes/heat_frame.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any, Literal, Self from pandas import DataFrame, Index, MultiIndex @@ -15,7 +15,6 @@ if TYPE_CHECKING: from collections.abc import Hashable, Iterator, Sequence - from typing import Any, Literal, Self from pandas import Index from xlwings import Sheet @@ -42,7 +41,7 @@ def __init__( super().__init__(row, column, data, sheet) - self.columns = data.columns # type: ignore + self.columns = data.columns # pyright: ignore[reportIncompatibleVariableOverride] start = self.row + 1, self.column + 1 end = start[0] + self.shape[0] - 1, start[1] + self.shape[1] - 1 @@ -198,9 +197,9 @@ def xs( columns: dict[Hashable, Any] | None, ) -> DataFrame: if index: - df = df.xs(tuple(index.values()), 0, tuple(index.keys())) # type: ignore + df = df.xs(tuple(index.values()), 0, tuple(index.keys())) # pyright: ignore[reportAssignmentType] if columns: - df = df.xs(tuple(columns.values()), 1, tuple(columns.keys())) # type: ignore + df = df.xs(tuple(columns.values()), 1, tuple(columns.keys())) # pyright: ignore[reportAssignmentType] return df diff --git a/src/xlviews/dataframes/sheet_frame.py b/src/xlviews/dataframes/sheet_frame.py index 59a5181..8bc5acf 100644 --- a/src/xlviews/dataframes/sheet_frame.py +++ b/src/xlviews/dataframes/sheet_frame.py @@ -4,7 +4,7 @@ import re from functools import partial -from typing import TYPE_CHECKING, overload +from typing import TYPE_CHECKING, Any, Literal, Self, overload import numpy as np import pandas as pd @@ -27,7 +27,6 @@ if TYPE_CHECKING: from collections.abc import Iterator, Sequence - from typing import Any, Literal, Self from numpy.typing import NDArray @@ -139,7 +138,7 @@ def get_indexer(self, columns: dict[str, Any]) -> NDArray[np.intp]: ... def get_indexer( self, columns: list[str] | dict[str, Any] | None = None, - **kwargs, + **kwargs: Any, ) -> list[int] | NDArray[np.intp]: if isinstance(columns, dict) or (columns is None and kwargs): return self.columns.get_indexer( @@ -188,8 +187,8 @@ def get_range( case None: start = self.row + 1 end = start + len(self) - 1 - case _: - msg = f"invalid offset: {offset}" + case _: # pyright: ignore[reportUnnecessaryComparison] + msg = f"invalid offset: {offset}" # pyright: ignore[reportUnreachable] raise ValueError(msg) if isinstance(columns, str): @@ -219,7 +218,8 @@ def iter_ranges(self, axis: Literal[0, 1] = 0) -> Iterator[Range]: yield Range((index + offset, start), (index + offset, end), self.sheet) else: - raise ValueError("axis must be 0 or 1") + msg = "axis must be 0 or 1" # pyright: ignore[reportUnreachable] + raise ValueError(msg) def add_column( self, @@ -302,15 +302,15 @@ def add_formula_column( """Add a formula column. Args: - rng (Range): The range of the column. - formula (str or tuple): The formula. + column (str): The column. + formula (str): The formula. number_format (str, optional): The number format. autofit (bool): Whether to autofit the width. """ if self.columns.nlevels != 1: raise NotImplementedError - refs = {} + refs: dict[str, str] = {} for m in re.finditer(r"{(.+?)}", formula): key = m.group(1) loc = self.get_loc(key) @@ -325,7 +325,7 @@ def add_formula_column( refs[key] = addr - if isinstance(column, str) and column not in self.columns: + if column not in self.columns: self.add_column(column) rng = self.get_range(column).impl @@ -400,7 +400,7 @@ def get_address( @overload def agg( self, - func: Func | dict = None, + func: Func | dict[str, str] = None, columns: str | list[str] | None = None, row_absolute: bool = True, column_absolute: bool = True, @@ -423,7 +423,7 @@ def agg( def agg( self, - func: Func | dict | Sequence[Func] = None, + func: Func | dict[str, str] | Sequence[Func] = None, columns: str | list[str] | None = None, row_absolute: bool = True, column_absolute: bool = True, @@ -451,9 +451,11 @@ def agg( if isinstance(func, Range | RangeImpl): if func.sheet.book.name != self.sheet.book.name: - raise ValueError("Range is from a different book") + msg = "Range is from a different book" + raise ValueError(msg) if func.sheet.name != self.sheet.name: - raise ValueError("Range is from a different sheet") + msg = "Range is from a different sheet" + raise ValueError(msg) rngs = self.get_range(columns) @@ -480,7 +482,8 @@ def agg( values = [[agg(f, r) for r in rngs] for f in func] return DataFrame(values, index=list(func), columns=columns) - def _agg(self, func: Func, rng: Range, **kwargs) -> str: + @staticmethod + def _agg(func: Func, rng: Range, **kwargs: Any) -> str: if func == "first": rng = rng[0] func = None @@ -561,14 +564,12 @@ def pivot_table( formula=formula, ) - if index is None: - by = [] - else: - by = [index] if isinstance(index, str) else index + by = [] if index is None else [index] if isinstance(index, str) else index if columns is None: if not by: - raise ValueError("No group keys passed!") + msg = "No group keys passed!" + raise ValueError(msg) else: by = [*by, columns] if isinstance(columns, str) else by + columns @@ -582,7 +583,7 @@ def pivot_table( formula=formula, ) - return data.pivot_table(values, index, columns, aggfunc=lambda x: x) + return data.pivot_table(values, index, columns, aggfunc=lambda x: x) # pyright: ignore[reportUnknownArgumentType, reportUnknownLambdaType] def groupby(self, by: str | list[str] | None, *, sort: bool = True) -> GroupBy: return GroupBy(self, by, sort=sort) @@ -595,10 +596,10 @@ def get_number_format(self, column: str) -> str: def number_format( self, - number_format: str | dict | None = None, + number_format: str | dict[str, str] | None = None, *, autofit: bool = False, - **columns_format, + **columns_format: str, ) -> Self: if isinstance(number_format, dict): columns_format.update(number_format) @@ -608,13 +609,13 @@ def number_format( if self.columns.nlevels == 1: for column in [*self.index.names, *self.columns]: - if not column: + if not column or not isinstance(column, str): continue - for pattern, number_format in columns_format.items(): - if re.match(pattern, column): # type: ignore - rng = self.get_range(column).impl # type: ignore - rng.number_format = number_format + for pattern, number_format_ in columns_format.items(): + if re.match(pattern, column): + rng = self.get_range(column).impl + rng.number_format = number_format_ if autofit: rng.autofit() break @@ -631,7 +632,7 @@ def number_format( return self - def style(self, **kwargs) -> Self: + def style(self, **kwargs: Any) -> Self: set_frame_style(self, **kwargs) set_wide_column_style(self) return self @@ -717,7 +718,11 @@ def move(sf: SheetFrame, count: int, direction: str = "down", width: int = 0) -> case "right": return _move_right(sf, count, width) - raise ValueError("direction must be 'down' or 'right'") + case _: + pass + + msg = "direction must be 'down' or 'right'" + raise ValueError(msg) def _move_down(sf: SheetFrame, count: int) -> None: diff --git a/src/xlviews/dataframes/stats_frame.py b/src/xlviews/dataframes/stats_frame.py index e72d34e..a766eeb 100644 --- a/src/xlviews/dataframes/stats_frame.py +++ b/src/xlviews/dataframes/stats_frame.py @@ -45,9 +45,7 @@ def __init__( # Store the position of the parent SheetFrame before moving down. row = parent.row - column = parent.column - if isinstance(funcs, list): - column -= 1 + column = parent.column - 1 move_down(parent, offset) @@ -59,12 +57,11 @@ def __init__( self.as_table(autofit=False, const_header=True) self.style() - if isinstance(funcs, list): - set_style(self, parent, func_column_name) + set_style(self, parent, func_column_name) self.alignment("left") - if self.table and auto_filter and isinstance(funcs, list) and len(funcs) > 1: + if self.table and auto_filter and len(funcs) > 1: func = default if default in funcs else funcs[0] self.table.auto_filter(func_column_name, func) @@ -81,18 +78,16 @@ def get_func(func: str | list[str] | None) -> list[str]: def get_by(sf: SheetFrame, by: str | list[str] | None) -> list[str]: if not by: - return sf.index.names # type: ignore + return sf.index.names # pyright: ignore[reportReturnType] return list(iter_columns(sf.index.names, by)) -def get_length(sf: SheetFrame, by: list[str], funcs: list | dict) -> int: - n = 1 if isinstance(funcs, dict) else len(funcs) - +def get_length(sf: SheetFrame, by: list[str], funcs: list[str]) -> int: if not by: - return n + return len(funcs) - return len(sf.index.to_frame()[by].drop_duplicates()) * n + return len(sf.index.to_frame()[by].drop_duplicates()) * len(funcs) def get_frame( @@ -122,7 +117,7 @@ def has_header(sf: SheetFrame) -> bool: if not isinstance(value, list): raise NotImplementedError - return any(value) + return any(value) # pyright: ignore[reportUnknownArgumentType] def move_down(sf: SheetFrame, length: int) -> int: @@ -142,13 +137,13 @@ def set_style(sf: SheetFrame, parent: SheetFrame, func_column_name: str) -> None idx = [sf.column + i for i in range(sf.index.nlevels + len(sf.columns))] columns = (*parent.index.names, *parent.columns) - formats = [None, *[parent.get_number_format(column) for column in columns]] # type: ignore + formats = [None, *[parent.get_number_format(column) for column in columns]] # pyright: ignore[reportArgumentType] for (func,), rows in sf.groupby(func_column_name).items(): for col, fmt in zip(idx, formats, strict=True): rc = RangeCollection(rows, col, sf.sheet) - if func in ["median", "min", "mean", "max", "std", "sum"] and fmt: + if func in {"median", "min", "mean", "max", "std", "sum"} and fmt: set_number_format(rc, fmt) color = rcParams.get(f"stats.{func}.color") diff --git a/src/xlviews/dataframes/table.py b/src/xlviews/dataframes/table.py index e61928a..42fad0a 100644 --- a/src/xlviews/dataframes/table.py +++ b/src/xlviews/dataframes/table.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any from xlwings import Range from xlwings.constants import AutoFilterOperator, ListObjectSourceType, YesNoGuess @@ -42,9 +42,10 @@ def __init__( ) elif sheet and api: self.api = api - self.cell = sheet.range(api.Range.Row, api.Range.Column) # type: ignore + self.cell = sheet.range(api.Range.Row, api.Range.Column) # pyright: ignore[reportUnknownMemberType, reportArgumentType, reportAttributeAccessIssue] else: - raise ValueError("Either range or sheet and api must be provided") + msg = "Either range or sheet and api must be provided" + raise ValueError(msg) self.sheet = self.cell.sheet @@ -79,7 +80,7 @@ def columns(self) -> list[str]: if not isinstance(names, list): raise NotImplementedError - return [c or "" for c in names] + return [name or "" for name in names] # pyright: ignore[reportUnknownVariableType] def add_const_header( self, @@ -103,7 +104,12 @@ def add_const_header( set_font(const_header, size=8, italic=True, color="blue") set_alignment(const_header, "center") - def auto_filter(self, *args, clear: bool = False, **field_criteria) -> None: + def auto_filter( + self, + *args: Any, + clear: bool = False, + **field_criteria: Any, + ) -> None: """Filter the table by the given criteria. Args: @@ -123,12 +129,12 @@ def auto_filter(self, *args, clear: bool = False, **field_criteria) -> None: field_criteria = clear_filter if args and isinstance(args[0], dict): - field_criteria.update(args[0]) + field_criteria.update(args[0]) # pyright: ignore[reportUnknownArgumentType] else: for name, criteria in zip(args[::2], args[1::2], strict=True): field_criteria[name] = criteria - auto_filter = self.api.Range.AutoFilter # type: ignore + auto_filter = self.api.Range.AutoFilter # pyright: ignore[reportUnknownMemberType, reportAttributeAccessIssue, reportUnknownVariableType] columns = self.columns @@ -138,7 +144,7 @@ def auto_filter(self, *args, clear: bool = False, **field_criteria) -> None: if isinstance(criteria, list): auto_filter( Field=field, - Criteria1=[str(x) for x in criteria], + Criteria1=[str(x) for x in criteria], # pyright: ignore[reportUnknownVariableType, reportUnknownArgumentType] Operator=AutoFilterOperator.xlFilterValues, ) diff --git a/typings/xlwings/__init__.pyi b/typings/xlwings/__init__.pyi index 30ee571..a62da1f 100644 --- a/typings/xlwings/__init__.pyi +++ b/typings/xlwings/__init__.pyi @@ -34,6 +34,20 @@ class Range: def offset(self, row_offset: int = 0, column_offset: int = 0) -> Range: ... @property def last_cell(self) -> Range: ... + def autofit(self) -> None: ... + @property + def column_width(self) -> float: ... + @column_width.setter + def column_width(self, value: float) -> None: ... + def merge(self, across: bool = False) -> None: ... + @property + def number_format(self) -> str: ... + @number_format.setter + def number_format(self, value: str) -> None: ... + @property + def formula(self) -> Any: ... + @formula.setter + def formula(self, value: Any) -> None: ... class Sheet: @property @@ -46,13 +60,15 @@ class Sheet: def name(self, value: str) -> None: ... def range( self, - cell1: Range | tuple[int, int], - cell2: Range | tuple[int, int], + cell1: Range | tuple[int, int] | int, + cell2: Range | tuple[int, int] | int | None = None, ) -> Range: ... @property def book(self) -> Book: ... class Book: + @property + def api(self) -> Any: ... @property def name(self) -> str: ... @property From afc685c24f461ba1c2fd3ea83b39b09b8fa66a84 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 08:37:38 +0900 Subject: [PATCH 10/40] Move import --- src/xlviews/core/range.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/xlviews/core/range.py b/src/xlviews/core/range.py index 73e88ca..132cf1a 100644 --- a/src/xlviews/core/range.py +++ b/src/xlviews/core/range.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any, Self import numpy as np import xlwings @@ -11,7 +11,6 @@ if TYPE_CHECKING: from collections.abc import Iterable, Iterator - from typing import Any, Self from pandas._typing import Axes from xlwings import Sheet From 29573c8fdbd81ab414b831618fbc7d747aa26155 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 08:37:57 +0900 Subject: [PATCH 11/40] Update CI --- .github/workflows/ci.yaml | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4e07367..f30e691 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -6,7 +6,7 @@ on: pull_request: concurrency: - group: test-${{ github.head_ref }} + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true env: @@ -24,17 +24,15 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v6 + - name: Install uv and set up Python ${{ matrix.python-version }} + uses: astral-sh/setup-uv@v7 with: python-version: ${{ matrix.python-version }} - allow-prereleases: true - - name: Install uv and ruff - run: pip install uv ruff - # - name: Ruff check - # run: ruff check + activate-environment: true - name: Install the project run: uv sync + - name: Run prek hooks + run: uv run prek run --all-files - name: Upload local coverage (lcov.info) if present if: hashFiles('lcov.info') != '' uses: codecov/codecov-action@v5 From 1607d03dbdc35fc0ce85fbb312a1dd6fe0b2bc53 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 09:02:55 +0900 Subject: [PATCH 12/40] Update chart modules --- pyproject.toml | 2 ++ src/xlviews/chart/axes.py | 44 ++++++++++++++++++++-------------- src/xlviews/chart/series.py | 14 +++++------ src/xlviews/chart/style.py | 34 +++++++++++++------------- typings/xlwings/__init__.pyi | 46 ++++++++++++++++++++++++++++++++++++ 5 files changed, 98 insertions(+), 42 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1528d42..6231578 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -79,7 +79,9 @@ ignore = [ "FBT001", "FBT002", "PLR0904", + "PLR0911", "PLR0913", + "PLR0914", "PLR0917", ] diff --git a/src/xlviews/chart/axes.py b/src/xlviews/chart/axes.py index 5472624..d009c81 100644 --- a/src/xlviews/chart/axes.py +++ b/src/xlviews/chart/axes.py @@ -1,7 +1,7 @@ from __future__ import annotations from contextlib import suppress -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any, Self import xlwings from xlwings.constants import AxisType, ChartType, Placement, TickMark @@ -24,8 +24,6 @@ ) if TYPE_CHECKING: - from typing import Any, Self - from xlwings import Chart, Sheet @@ -103,7 +101,7 @@ def __init__( width = width or rcParams["chart.width"] height = height or rcParams["chart.height"] - self.chart = self.sheet.charts.add(left, top, width, height) # type: ignore + self.chart = self.sheet.charts.add(left, top, width, height) self.chart_type = chart_type self.chart.api[1].ChartType = chart_type @@ -159,12 +157,12 @@ def copy( ) @property - def xaxis(self): # noqa: ANN201 + def xaxis(self) -> Any: chart = self.chart.api[1] return chart.Axes(AxisType.xlCategory) @property - def yaxis(self): # noqa: ANN201 + def yaxis(self) -> Any: chart = self.chart.api[1] return chart.Axes(AxisType.xlValue) @@ -203,7 +201,7 @@ def set_title( *, name: str | None = None, size: int | None = None, - **kwargs, + **kwargs: Any, ) -> None: api = self.chart.api[1] @@ -235,10 +233,10 @@ def ylabel(self) -> str | None: def ylabel(self, value: str | None) -> None: self.set_ylabel(value) - def set_xlabel(self, label: str | None = None, **kwargs) -> None: + def set_xlabel(self, label: str | None = None, **kwargs: Any) -> None: set_axis_label(self.xaxis, label, **kwargs) - def set_ylabel(self, label: str | None = None, **kwargs) -> None: + def set_ylabel(self, label: str | None = None, **kwargs: Any) -> None: set_axis_label(self.yaxis, label, **kwargs) @property @@ -257,16 +255,26 @@ def yticks(self) -> tuple[float, float, float, float]: def yticks(self, value: tuple[float, ...]) -> None: set_ticks(self.yaxis, *value) - def set_xticks(self, *args, **kwargs) -> None: - set_ticks(self.xaxis, *args, **kwargs) + def set_xticks( + self, + *args: float, + gridlines: bool = True, + **kwargs: float | None, + ) -> None: + set_ticks(self.xaxis, *args, gridlines=gridlines, **kwargs) - def set_yticks(self, *args, **kwargs) -> None: - set_ticks(self.yaxis, *args, **kwargs) + def set_yticks( + self, + *args: float, + gridlines: bool = True, + **kwargs: float | None, + ) -> None: + set_ticks(self.yaxis, *args, gridlines=gridlines, **kwargs) - def set_xtick_labels(self, *args, **kwargs) -> None: + def set_xtick_labels(self, *args: Any, **kwargs: Any) -> None: set_tick_labels(self.xaxis, *args, **kwargs) - def set_ytick_labels(self, *args, **kwargs) -> None: + def set_ytick_labels(self, *args: Any, **kwargs: Any) -> None: set_tick_labels(self.yaxis, *args, **kwargs) @property @@ -299,9 +307,9 @@ def set( tight_layout: bool = True, legend: bool | tuple[float, float] = False, ) -> Self: - if xlabel != "": + if xlabel != "": # noqa: PLC1901 self.xlabel = xlabel - if ylabel != "": + if ylabel != "": # noqa: PLC1901 self.ylabel = ylabel if xticks: self.xticks = xticks @@ -360,7 +368,7 @@ def legend( if not series.label: entry.Delete() - if api.HasLegend is False: + if api.HasLegend is False: # pyright: ignore[reportUnnecessaryComparison] return self name = name or rcParams["chart.font.name"] diff --git a/src/xlviews/chart/series.py b/src/xlviews/chart/series.py index 200472f..1049e80 100644 --- a/src/xlviews/chart/series.py +++ b/src/xlviews/chart/series.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any, Self from xlwings import Range as RangeImpl from xlwings.constants import ChartType @@ -12,8 +12,6 @@ from .style import get_line_style, get_marker_style if TYPE_CHECKING: - from typing import Any, Self - from .axes import Axes @@ -53,15 +51,15 @@ def label(self, label: str | None) -> None: @property def chart_type(self) -> int: - return self.api.ChartType # type: ignore + return self.api.ChartType @chart_type.setter def chart_type(self, chart_type: int) -> None: self.api.ChartType = chart_type @property - def x(self) -> tuple: - return self.api.XValues # type: ignore + def x(self) -> tuple[Any, ...]: + return self.api.XValues @x.setter def x(self, x: Any) -> None: @@ -71,8 +69,8 @@ def x(self, x: Any) -> None: self.api.XValues = x @property - def y(self) -> tuple: - return self.api.Values # type: ignore + def y(self) -> tuple[Any, ...]: + return self.api.Values @y.setter def y(self, y: Any) -> None: diff --git a/src/xlviews/chart/style.py b/src/xlviews/chart/style.py index 935ffe1..e85562b 100644 --- a/src/xlviews/chart/style.py +++ b/src/xlviews/chart/style.py @@ -2,6 +2,8 @@ from __future__ import annotations +from typing import Any + from xlwings.constants import LineStyle, MarkerStyle, ScaleType from xlviews.colors import rgb @@ -57,7 +59,7 @@ def get_line_style(line: int | str | None) -> int | None: return LINE_DICT[line] -def get_axis_label(axis) -> str | None: # noqa: ANN001 +def get_axis_label(axis: Any) -> str | None: if not axis.HasTitle: return None @@ -65,11 +67,11 @@ def get_axis_label(axis) -> str | None: # noqa: ANN001 def set_axis_label( - axis, # noqa: ANN001 + axis: Any, label: str | None = None, name: str | None = None, size: float | None = None, - **kwargs, + **kwargs: Any, ) -> None: if not label: axis.HasTitle = False @@ -85,7 +87,7 @@ def set_axis_label( set_font_api(axis_title, name, size=size, **kwargs) -def get_ticks(axis) -> tuple[float, float, float, float]: # noqa: ANN001 +def get_ticks(axis: Any) -> tuple[float, float, float, float]: return ( axis.MinimumScale, axis.MaximumScale, @@ -95,20 +97,20 @@ def get_ticks(axis) -> tuple[float, float, float, float]: # noqa: ANN001 def set_ticks( - axis, # noqa: ANN001 - *args, + axis: Any, + *args: float, min: float | None = None, # noqa: A002 max: float | None = None, # noqa: A002 major: float | None = None, minor: float | None = None, gridlines: bool = True, ) -> None: - args = [*args, None, None, None, None][:4] + args_ = [*args, None, None, None, None][:4] - min = min or args[0] # noqa: A001 - max = max or args[1] # noqa: A001 - major = major or args[2] - minor = minor or args[3] + min = min or args_[0] # noqa: A001 + max = max or args_[1] # noqa: A001 + major = major or args_[2] + minor = minor or args_[3] if min is not None: axis.MinimumScale = min @@ -137,7 +139,7 @@ def set_ticks( def set_tick_labels( - axis, # noqa: ANN001 + axis: Any, name: str | None = None, size: float | None = None, number_format: str | None = None, @@ -150,7 +152,7 @@ def set_tick_labels( axis.TickLabels.NumberFormatLocal = number_format -def get_axis_scale(axis) -> str: # noqa: ANN001 +def get_axis_scale(axis: Any) -> str: if axis.ScaleType == ScaleType.xlScaleLogarithmic: return "log" @@ -160,7 +162,7 @@ def get_axis_scale(axis) -> str: # noqa: ANN001 raise NotImplementedError -def set_axis_scale(axis, scale: str) -> None: # noqa: ANN001 +def set_axis_scale(axis: Any, scale: str) -> None: if scale == "log": axis.ScaleType = ScaleType.xlScaleLogarithmic return @@ -173,7 +175,7 @@ def set_axis_scale(axis, scale: str) -> None: # noqa: ANN001 def set_dimensions( - api, # noqa: ANN001 + api: Any, left: float | None = None, top: float | None = None, width: float | None = None, @@ -193,7 +195,7 @@ def set_dimensions( def set_area_format( - api, # noqa: ANN001 + api: Any, border: str | int | tuple[int, int, int] | None = None, fill: str | int | tuple[int, int, int] | None = None, alpha: float | None = None, diff --git a/typings/xlwings/__init__.pyi b/typings/xlwings/__init__.pyi index a62da1f..89e6537 100644 --- a/typings/xlwings/__init__.pyi +++ b/typings/xlwings/__init__.pyi @@ -48,6 +48,14 @@ class Range: def formula(self) -> Any: ... @formula.setter def formula(self, value: Any) -> None: ... + @property + def left(self) -> float: ... + @property + def top(self) -> float: ... + @property + def width(self) -> float: ... + @property + def height(self) -> float: ... class Sheet: @property @@ -65,6 +73,44 @@ class Sheet: ) -> Range: ... @property def book(self) -> Book: ... + @property + def charts(self) -> Charts: ... + +class Chart: + @property + def api(self) -> Any: ... + @property + def chart_type(self) -> str: ... + @chart_type.setter + def chart_type(self, value: str) -> None: ... + @property + def left(self) -> float: ... + @left.setter + def left(self, value: float) -> None: ... + @property + def top(self) -> float: ... + @top.setter + def top(self, value: float) -> None: ... + @property + def width(self) -> float: ... + @width.setter + def width(self, value: float) -> None: ... + @property + def height(self) -> float: ... + @height.setter + def height(self, value: float) -> None: ... + +class Charts: + def add( + self, + left: float = 0, + top: float = 0, + width: float = 355, + height: float = 211, + ) -> Chart: ... + def __iter__(self) -> Iterator[Chart]: ... + def __getitem__(self, key: Any) -> Chart: ... + def __contains__(self, key: Any) -> bool: ... class Book: @property From 4d5c92cde08bd85a1c1f78c8ca7906396f114de0 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 09:27:18 +0900 Subject: [PATCH 13/40] Update stubs --- typings/xlwings/__init__.pyi | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/typings/xlwings/__init__.pyi b/typings/xlwings/__init__.pyi index 89e6537..7959b15 100644 --- a/typings/xlwings/__init__.pyi +++ b/typings/xlwings/__init__.pyi @@ -1,5 +1,5 @@ from collections.abc import Iterator -from typing import Any +from typing import Any, Self class Range: @property @@ -124,13 +124,24 @@ class App: @property def api(self) -> Any: ... @property + def visible(self) -> bool: ... + @visible.setter + def visible(self, value: bool) -> None: ... + @property def screen_updating(self) -> bool: ... @screen_updating.setter def screen_updating(self, value: bool) -> None: ... + def quit(self) -> None: ... + def kill(self) -> None: ... + @property + def books(self) -> Books: ... + def __enter__(self) -> Self: ... + def __exit__(self, exc_type, exc_value, exc_tb) -> None: ... # noqa: ANN001 # pyright: ignore[reportUnknownParameterType, reportMissingParameterType] class Apps: @property def active(self) -> App: ... + def __iter__(self) -> Iterator[App]: ... class Books: @property From b61c50c4238b9cfbbb1da63f06dcf3755de27085 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 15:21:20 +0900 Subject: [PATCH 14/40] Drop python 3.11 --- .github/workflows/ci.yaml | 2 +- pyproject.toml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f30e691..bc35816 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -20,7 +20,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.11", "3.12", "3.13", "3.14"] + python-version: ["3.12", "3.13", "3.14"] steps: - uses: actions/checkout@v6 diff --git a/pyproject.toml b/pyproject.toml index 6231578..9a5798d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,12 +12,11 @@ authors = [{ name = "daizutabi", email = "daizutabi@gmail.com" }] classifiers = [ "Development Status :: 4 - Beta", "Programming Language :: Python", - "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", ] -requires-python = ">=3.11" +requires-python = ">=3.12" dependencies = ["numpy>=2", "pandas>=2", "xlwings>=0.33"] [project.urls] @@ -60,7 +59,7 @@ skip_covered = true [tool.ruff] line-length = 88 -target-version = "py311" +target-version = "py312" [tool.ruff.lint] preview = true @@ -83,10 +82,11 @@ ignore = [ "PLR0913", "PLR0914", "PLR0917", + "PLR2004", ] [tool.ruff.lint.per-file-ignores] -"tests/*" = ["ANN", "ARG", "D", "PLC2701", "PLR2004", "PT011", "S", "SLF001"] +"tests/*" = ["ANN", "ARG", "D", "PLC2701", "PT011", "S", "SLF001"] "src/xlviews/testing/*" = ["T201"] [tool.ruff.lint.isort] From 5b72c88ec6cb36e03bf5ef49883bda5c95eb620a Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 15:26:53 +0900 Subject: [PATCH 15/40] Use generic --- src/xlviews/colors.py | 6 +-- src/xlviews/dataframes/groupby.py | 7 +--- src/xlviews/figure/palette.py | 66 +++++++++++++++---------------- src/xlviews/figure/plot.py | 35 ++++++++-------- src/xlviews/utils.py | 8 +--- 5 files changed, 56 insertions(+), 66 deletions(-) diff --git a/src/xlviews/colors.py b/src/xlviews/colors.py index 06535d4..98e2847 100644 --- a/src/xlviews/colors.py +++ b/src/xlviews/colors.py @@ -1,8 +1,6 @@ from __future__ import annotations -from typing import TypeAlias - -Color: TypeAlias = int | tuple[int, int, int] | str +type Color = int | tuple[int, int, int] | str def rgb( @@ -39,7 +37,7 @@ def rgb( if isinstance(color, str): color = cnames.get(color, color) - if not color.startswith("#") or len(color) != 7: # noqa: PLR2004 + if not color.startswith("#") or len(color) != 7: msg = "Invalid color format. Expected int, tuple[int, int, int], or str." raise ValueError(msg) diff --git a/src/xlviews/dataframes/groupby.py b/src/xlviews/dataframes/groupby.py index 82faef2..894ac9a 100644 --- a/src/xlviews/dataframes/groupby.py +++ b/src/xlviews/dataframes/groupby.py @@ -1,7 +1,7 @@ from __future__ import annotations from functools import partial -from typing import TYPE_CHECKING, Any, TypeVar +from typing import TYPE_CHECKING, Any import numpy as np from pandas import DataFrame, Index, MultiIndex, Series @@ -17,11 +17,8 @@ from .sheet_frame import SheetFrame -H = TypeVar("H") -T = TypeVar("T") - -def to_dict(keys: Iterable[H], values: Iterable[T]) -> dict[H, list[T]]: +def to_dict[H, T](keys: Iterable[H], values: Iterable[T]) -> dict[H, list[T]]: result: dict[H, list[T]] = {} for key, value in zip(keys, values, strict=True): diff --git a/src/xlviews/figure/palette.py b/src/xlviews/figure/palette.py index aeae4ce..ebec7e9 100644 --- a/src/xlviews/figure/palette.py +++ b/src/xlviews/figure/palette.py @@ -3,7 +3,7 @@ from abc import ABC, abstractmethod from collections.abc import Callable, Hashable from itertools import cycle, islice -from typing import TYPE_CHECKING, Generic, TypeAlias, TypeVar +from typing import TYPE_CHECKING from pandas import MultiIndex @@ -15,10 +15,7 @@ from pandas import DataFrame -T = TypeVar("T") - - -def get_columns_default( +def get_columns_default[T]( data: DataFrame, columns: str | list[str], default: dict[Hashable, T] | list[T] | None = None, @@ -49,14 +46,14 @@ def get_index( if default is None: return dict(zip(values, range(len(data)), strict=True)) - index = {} + index: dict[tuple[Hashable, ...], int] = {} current_index = 0 for default_value in default: if isinstance(default_value, tuple): - value = default_value + value = default_value # pyright: ignore[reportUnknownVariableType] elif isinstance(default_value, list): - value = tuple(default_value) + value = tuple(default_value) # pyright: ignore[reportUnknownVariableType] else: value = (default_value,) @@ -72,7 +69,7 @@ def get_index( return index -class Palette(ABC, Generic[T]): +class Palette[T](ABC): """A palette of items.""" columns: list[str] @@ -102,7 +99,7 @@ def get(self, value: Hashable) -> int: return self.index[value] - def __getitem__(self, key: dict) -> T: + def __getitem__(self, key: dict[str | None, Hashable]) -> T: if key == {None: 0}: # from series return self.items[0] @@ -112,7 +109,7 @@ def __getitem__(self, key: dict) -> T: class MarkerPalette(Palette[str]): - def cycle(self, defaults: Iterable[str]) -> Iterator[str]: + def cycle(self, defaults: Iterable[str]) -> Iterator[str]: # noqa: PLR6301 """Generate an infinite iterator of markers.""" return cycle_markers(defaults) @@ -122,14 +119,14 @@ def cycle_markers(skips: Iterable[str] | None = None) -> Iterator[str]: if skips is None: skips = [] - markers = (m for m in MARKER_DICT if m != "") + markers = (m for m in MARKER_DICT if m) for marker in cycle(markers): if marker not in skips: yield marker class ColorPalette(Palette[str]): - def cycle(self, defaults: Iterable[str]) -> Iterator[str]: + def cycle(self, defaults: Iterable[str]) -> Iterator[str]: # noqa: PLR6301 """Generate an infinite iterator of colors.""" return cycle_colors(defaults) @@ -144,7 +141,7 @@ def cycle_colors(skips: Iterable[str] | None = None) -> Iterator[str]: yield color -class FunctionPalette(Generic[T]): +class FunctionPalette[T]: columns: str | list[str] func: Callable[[Hashable], T] @@ -152,7 +149,7 @@ def __init__(self, columns: str | list[str], func: Callable[[Hashable], T]) -> N self.columns = columns self.func = func - def __getitem__(self, key: dict) -> T: + def __getitem__(self, key: dict[str, Hashable]) -> T: if isinstance(self.columns, str): return self.func(key[self.columns]) @@ -160,23 +157,26 @@ def __getitem__(self, key: dict) -> T: return self.func(value) -PaletteStyle: TypeAlias = ( +type PaletteStyle[T] = ( str | list[str] | dict[Hashable, str] | Callable[[Hashable], str] | tuple[str | list[str], list[str] | dict[Hashable, str]] | tuple[str | list[str], Callable[[Hashable], str]] - | Palette - | FunctionPalette + | Palette[T] + | FunctionPalette[T] ) +# pyright: reportArgumentType=false +# pyright: reportReturnType=false + -def get_palette( - cls: type[Palette], +def get_palette[T]( + cls: type[Palette[T]], data: DataFrame, - style: PaletteStyle | None, -) -> Palette | FunctionPalette | None: + style: PaletteStyle[T] | None, +) -> Palette[T] | FunctionPalette[T] | None: """Get a palette from a style.""" if isinstance(style, Palette | FunctionPalette): return style @@ -186,8 +186,8 @@ def get_palette( if isinstance(style, Callable): if isinstance(data.index, MultiIndex): - return FunctionPalette(data.index.names, style) # type: ignore - return FunctionPalette(data.index.name, style) # type: ignore + return FunctionPalette(data.index.names, style) + return FunctionPalette(data.index.name, style) if data.index.name is not None or isinstance(data.index, MultiIndex): data = data.index.to_frame(index=False) @@ -211,20 +211,20 @@ def get_palette( data = data.drop_duplicates() values = [tuple(t) for t in data.itertuples(index=False)] default = dict(zip(values, cycle(columns), strict=False)) - return cls(data, data.columns.tolist(), default) # type: ignore + return cls(data, data.columns.tolist(), default) return cls(data, columns) -def get_marker_palette( +def get_marker_palette[T]( data: DataFrame, - marker: PaletteStyle | None, -) -> MarkerPalette | FunctionPalette | None: - return get_palette(MarkerPalette, data, marker) # type: ignore + marker: PaletteStyle[T] | None, +) -> MarkerPalette | FunctionPalette[T] | None: + return get_palette(MarkerPalette, data, marker) -def get_color_palette( +def get_color_palette[T]( data: DataFrame, - color: PaletteStyle | None, -) -> ColorPalette | FunctionPalette | None: - return get_palette(ColorPalette, data, color) # type: ignore + color: PaletteStyle[T] | None, +) -> ColorPalette | FunctionPalette[T] | None: + return get_palette(ColorPalette, data, color) diff --git a/src/xlviews/figure/plot.py b/src/xlviews/figure/plot.py index 5769cc4..4f792bd 100644 --- a/src/xlviews/figure/plot.py +++ b/src/xlviews/figure/plot.py @@ -2,7 +2,7 @@ from collections.abc import Callable, Hashable from itertools import product -from typing import TYPE_CHECKING, TypeAlias +from typing import TYPE_CHECKING, Any, Self import pandas as pd from pandas import DataFrame, Index @@ -11,12 +11,11 @@ if TYPE_CHECKING: from collections.abc import Iterator, Sequence - from typing import Any, Self from xlviews.chart.axes import Axes from xlviews.chart.series import Series -Label: TypeAlias = str | Callable[[dict[str, Hashable]], str] +type Label = str | Callable[[dict[str, Hashable]], str] class Plot: @@ -32,6 +31,8 @@ def __init__(self, axes: Axes, data: DataFrame | pd.Series) -> None: data = data.to_frame().T self.data = data + self.index = [] + self.series_collection = [] def add( self, @@ -39,17 +40,15 @@ def add( y: str | list[str], chart_type: int | None = None, ) -> Self: - self.index = [] - self.series_collection = [] xs = x if isinstance(x, list) else [x] ys = y if isinstance(y, list) else [y] - for x, y in product(xs, ys): + for x_, y_ in product(xs, ys): for idx, s in self.data.iterrows(): - series = self.axes.add_series(s[x], s[y], chart_type=chart_type) - index = idx if isinstance(idx, tuple) else (idx,) - self.index.append(index) + series = self.axes.add_series(s[x_], s[y_], chart_type=chart_type) + index = idx if isinstance(idx, tuple) else (idx,) # pyright: ignore[reportUnknownVariableType] + self.index.append(index) # pyright: ignore[reportUnknownArgumentType] self.series_collection.append(series) return self @@ -58,13 +57,13 @@ def keys(self) -> Iterator[dict[str, Hashable]]: names = self.data.index.names for index in self.index: - yield dict(zip(names, index, strict=True)) # type: ignore + yield dict(zip(names, index, strict=True)) # pyright: ignore[reportReturnType] - def set( + def set[T]( self, label: Label | None = None, - marker: PaletteStyle | None = None, - color: PaletteStyle | None = None, + marker: PaletteStyle[T] | None = None, + color: PaletteStyle[T] | None = None, alpha: float | None = None, weight: float | None = None, size: int | None = None, @@ -75,8 +74,8 @@ def set( for key, s in zip(self.keys(), self.series_collection, strict=True): s.set( label=label and get_label(label, key), - color=color_palette and color_palette[key], - marker=marker_palette and marker_palette[key], + color=color_palette and color_palette[key], # pyright: ignore[reportArgumentType] + marker=marker_palette and marker_palette[key], # pyright: ignore[reportArgumentType] alpha=alpha, weight=weight, size=size, @@ -120,7 +119,7 @@ def get_label(label: Label, key: dict[str, Hashable]) -> str: if callable(label): return label(key) - msg = f"Invalid label: {label}" + msg = f"Invalid label: {label}" # pyright: ignore[reportUnreachable] raise ValueError(msg) @@ -140,11 +139,11 @@ def iterrows( it = DataFrame(values).drop_duplicates().iterrows() for _, s in it: - yield s.to_dict() + yield s.to_dict() # pyright: ignore[reportReturnType] def xs(df: DataFrame, index: dict[str, Any] | None) -> DataFrame: if index: - df = df.xs(tuple(index.values()), 0, tuple(index.keys()), drop_level=False) # type: ignore + df = df.xs(tuple(index.values()), 0, tuple(index.keys()), drop_level=False) # pyright: ignore[reportAssignmentType] return df diff --git a/src/xlviews/utils.py b/src/xlviews/utils.py index be4ccf8..907f5a7 100644 --- a/src/xlviews/utils.py +++ b/src/xlviews/utils.py @@ -1,7 +1,7 @@ from __future__ import annotations from functools import wraps -from typing import TYPE_CHECKING, Any, ParamSpec, TypeVar +from typing import TYPE_CHECKING, Any import xlwings from pandas import DataFrame, Series @@ -120,11 +120,7 @@ def add_validate_list( rng.api.Validation.Add(Type=type_, Operator=operator, Formula1=formula) -P = ParamSpec("P") -R = TypeVar("R") - - -def suspend_screen_updates(func: Callable[P, R]) -> Callable[P, R]: +def suspend_screen_updates[**P, R](func: Callable[P, R]) -> Callable[P, R]: """Suspend screen updates to speed up operations.""" @wraps(func) From cea652e387d3dd1304f22e0540b4f8aa1e9505cb Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 15:43:49 +0900 Subject: [PATCH 16/40] Update stubs --- typings/xlwings/__init__.pyi | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/typings/xlwings/__init__.pyi b/typings/xlwings/__init__.pyi index 7959b15..a167c99 100644 --- a/typings/xlwings/__init__.pyi +++ b/typings/xlwings/__init__.pyi @@ -68,8 +68,8 @@ class Sheet: def name(self, value: str) -> None: ... def range( self, - cell1: Range | tuple[int, int] | int, - cell2: Range | tuple[int, int] | int | None = None, + cell1: Range | tuple[int, int] | int | str, + cell2: Range | tuple[int, int] | int | str | None = None, ) -> Range: ... @property def book(self) -> Book: ... @@ -119,8 +119,11 @@ class Book: def name(self) -> str: ... @property def app(self) -> App: ... + @property + def sheets(self) -> Sheets: ... class App: + def __init__(self, visible: bool | None = None) -> None: ... @property def api(self) -> Any: ... @property @@ -150,6 +153,12 @@ class Books: class Sheets: @property def active(self) -> Sheet: ... + def add( + self, + name: str | None = None, + before: Sheet | None = None, + after: Sheet | None = None, + ) -> Sheet: ... class ActiveEngineApps(Apps): ... class ActiveAppBooks(Books): ... From eae40dcd612c8683328665e907bf409832da9c5e Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 16:10:21 +0900 Subject: [PATCH 17/40] api as Any --- src/xlviews/dataframes/table.py | 9 ++++----- src/xlviews/style.py | 16 +++++++--------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/xlviews/dataframes/table.py b/src/xlviews/dataframes/table.py index 42fad0a..c2d5727 100644 --- a/src/xlviews/dataframes/table.py +++ b/src/xlviews/dataframes/table.py @@ -12,13 +12,12 @@ if TYPE_CHECKING: from xlwings import Sheet - from xlwings._xlwindows import COMRetryObjectWrapper class Table: sheet: Sheet cell: Range - api: COMRetryObjectWrapper + api: Any def __init__( self, @@ -28,7 +27,7 @@ def __init__( const_header: bool = False, style: bool = False, sheet: Sheet | None = None, - api: COMRetryObjectWrapper | None = None, + api: Any | None = None, index_nlevels: int | None = None, ) -> None: if isinstance(rng, Range): @@ -42,7 +41,7 @@ def __init__( ) elif sheet and api: self.api = api - self.cell = sheet.range(api.Range.Row, api.Range.Column) # pyright: ignore[reportUnknownMemberType, reportArgumentType, reportAttributeAccessIssue] + self.cell = sheet.range(api.Range.Row, api.Range.Column) else: msg = "Either range or sheet and api must be provided" raise ValueError(msg) @@ -134,7 +133,7 @@ def auto_filter( for name, criteria in zip(args[::2], args[1::2], strict=True): field_criteria[name] = criteria - auto_filter = self.api.Range.AutoFilter # pyright: ignore[reportUnknownMemberType, reportAttributeAccessIssue, reportUnknownVariableType] + auto_filter = self.api.Range.AutoFilter columns = self.columns diff --git a/src/xlviews/style.py b/src/xlviews/style.py index 58bcca7..89133f5 100644 --- a/src/xlviews/style.py +++ b/src/xlviews/style.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any import xlwings from xlwings import Range as RangeImpl @@ -20,8 +20,6 @@ from xlviews.utils import constant if TYPE_CHECKING: - from xlwings._xlwindows import COMRetryObjectWrapper - from .core.range_collection import RangeCollection @@ -99,7 +97,7 @@ def set_fill( def set_font_api( - api: COMRetryObjectWrapper, + api: Any, name: str | None = None, *, size: float | None = None, @@ -109,15 +107,15 @@ def set_font_api( ) -> None: font = api.Font if name: - font.Name = name # pyright: ignore[reportAttributeAccessIssue] + font.Name = name if size: - font.Size = size # pyright: ignore[reportAttributeAccessIssue] + font.Size = size if bold is not None: - font.Bold = bold # pyright: ignore[reportAttributeAccessIssue] + font.Bold = bold if italic is not None: - font.Italic = italic # pyright: ignore[reportAttributeAccessIssue] + font.Italic = italic if color is not None: - font.Color = rgb(color) # pyright: ignore[reportAttributeAccessIssue] + font.Color = rgb(color) def set_font( From d95f57a7b68d35d7b9d6652d8bb0acd30d110bbf Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 16:11:03 +0900 Subject: [PATCH 18/40] columns_format: Any --- src/xlviews/dataframes/sheet_frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xlviews/dataframes/sheet_frame.py b/src/xlviews/dataframes/sheet_frame.py index 8bc5acf..ec0368a 100644 --- a/src/xlviews/dataframes/sheet_frame.py +++ b/src/xlviews/dataframes/sheet_frame.py @@ -599,7 +599,7 @@ def number_format( number_format: str | dict[str, str] | None = None, *, autofit: bool = False, - **columns_format: str, + **columns_format: Any, ) -> Self: if isinstance(number_format, dict): columns_format.update(number_format) From 5445fb229040fe81942917a14a43426fc35a47c8 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 16:51:56 +0900 Subject: [PATCH 19/40] Update stubs --- typings/xlwings/__init__.pyi | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/typings/xlwings/__init__.pyi b/typings/xlwings/__init__.pyi index a167c99..b2458ab 100644 --- a/typings/xlwings/__init__.pyi +++ b/typings/xlwings/__init__.pyi @@ -1,3 +1,4 @@ +import types from collections.abc import Iterator from typing import Any, Self @@ -139,7 +140,12 @@ class App: @property def books(self) -> Books: ... def __enter__(self) -> Self: ... - def __exit__(self, exc_type, exc_value, exc_tb) -> None: ... # noqa: ANN001 # pyright: ignore[reportUnknownParameterType, reportMissingParameterType] + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + exc_tb: types.TracebackType | None, + ) -> None: ... class Apps: @property @@ -159,6 +165,7 @@ class Sheets: before: Sheet | None = None, after: Sheet | None = None, ) -> Sheet: ... + def __getitem__(self, key: Any) -> Sheet: ... class ActiveEngineApps(Apps): ... class ActiveAppBooks(Books): ... From 3cd4b51db7ba1bb1b078773f6925237b29cbc656 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 18:01:15 +0900 Subject: [PATCH 20/40] fix src --- src/xlviews/chart/axes.py | 1 + src/xlviews/core/index.py | 9 +++-- src/xlviews/dataframes/heat_frame.py | 14 ++++---- src/xlviews/dataframes/sheet_frame.py | 11 ++---- src/xlviews/dataframes/stats_frame.py | 22 +++++++----- src/xlviews/dataframes/table.py | 7 +--- src/xlviews/figure/grid.py | 31 ++++++----------- src/xlviews/figure/palette.py | 12 +++---- src/xlviews/figure/plot.py | 37 +++++++++------------ src/xlviews/testing/__init__.py | 2 ++ src/xlviews/testing/chart.py | 2 +- src/xlviews/testing/common.py | 4 +-- src/xlviews/testing/figure/facet.py | 3 +- src/xlviews/testing/heat_frame/common.py | 2 +- src/xlviews/testing/heat_frame/facet.py | 6 ++-- src/xlviews/testing/heat_frame/facet_agg.py | 6 ++-- src/xlviews/testing/heat_frame/pair.py | 6 ++-- src/xlviews/testing/sheet_frame/pivot.py | 4 +-- src/xlviews/utils.py | 8 ++--- 19 files changed, 83 insertions(+), 104 deletions(-) diff --git a/src/xlviews/chart/axes.py b/src/xlviews/chart/axes.py index d009c81..21f9d09 100644 --- a/src/xlviews/chart/axes.py +++ b/src/xlviews/chart/axes.py @@ -368,6 +368,7 @@ def legend( if not series.label: entry.Delete() + # `api.HasLegend` may be `False` after deleting entries. if api.HasLegend is False: # pyright: ignore[reportUnnecessaryComparison] return self diff --git a/src/xlviews/core/index.py b/src/xlviews/core/index.py index 03b667a..c933e04 100644 --- a/src/xlviews/core/index.py +++ b/src/xlviews/core/index.py @@ -7,11 +7,10 @@ import pandas as pd if TYPE_CHECKING: - from collections.abc import Iterable, Iterator + from collections.abc import Hashable, Iterable, Iterator from numpy.typing import NDArray from pandas import DataFrame - from pandas._typing import Axes class WideIndex(UserDict[str, list[Any]]): @@ -46,7 +45,7 @@ class Index: def __init__( self, - index: Axes, + index: pd.Index | Iterable[Any], wide_index: WideIndex | dict[str, Any] | None = None, ) -> None: self.index = index if isinstance(index, pd.Index) else pd.Index(index) @@ -62,8 +61,8 @@ def __len__(self) -> int: return len(self.index) + len(self.wide_index) @property - def names(self) -> list[str]: - return self.index.names # pyright: ignore[reportReturnType] + def names(self) -> list[Hashable | None]: + return self.index.names @property def nlevels(self) -> int: diff --git a/src/xlviews/dataframes/heat_frame.py b/src/xlviews/dataframes/heat_frame.py index b581357..2023ac6 100644 --- a/src/xlviews/dataframes/heat_frame.py +++ b/src/xlviews/dataframes/heat_frame.py @@ -2,7 +2,8 @@ from typing import TYPE_CHECKING, Any, Literal, Self -from pandas import DataFrame, Index, MultiIndex +import pandas as pd +from pandas import DataFrame from xlviews.core.formula import aggregate from xlviews.core.range import Range @@ -16,15 +17,14 @@ if TYPE_CHECKING: from collections.abc import Hashable, Iterator, Sequence - from pandas import Index from xlwings import Sheet from xlviews.colors import Color class HeatFrame(SheetFrame): - index: Index - columns: Index + index: pd.Index[Any] + columns: pd.Index[str] range: Range @suspend_screen_updates @@ -156,10 +156,10 @@ def pair( def clean_data(data: DataFrame) -> DataFrame: data = data.copy() - if isinstance(data.columns, MultiIndex): + if isinstance(data.columns, pd.MultiIndex): data.columns = data.columns.droplevel(list(range(1, data.columns.nlevels))) - if isinstance(data.index, MultiIndex): + if isinstance(data.index, pd.MultiIndex): data.index = data.index.droplevel(list(range(1, data.index.nlevels))) data.index.name = None @@ -168,7 +168,7 @@ def clean_data(data: DataFrame) -> DataFrame: def iterrows( - index: Index, + index: pd.Index, levels: int | str | Sequence[int | str] | None, offset: int = 0, padding: int = 0, diff --git a/src/xlviews/dataframes/sheet_frame.py b/src/xlviews/dataframes/sheet_frame.py index ec0368a..f6326ca 100644 --- a/src/xlviews/dataframes/sheet_frame.py +++ b/src/xlviews/dataframes/sheet_frame.py @@ -36,7 +36,7 @@ class SheetFrame: cell: RangeImpl sheet: Sheet - index: pd.Index + index: pd.Index[Any] columns: Index table: Table | None = None @@ -187,9 +187,6 @@ def get_range( case None: start = self.row + 1 end = start + len(self) - 1 - case _: # pyright: ignore[reportUnnecessaryComparison] - msg = f"invalid offset: {offset}" # pyright: ignore[reportUnreachable] - raise ValueError(msg) if isinstance(columns, str): loc = self.get_loc(columns) @@ -209,7 +206,7 @@ def iter_ranges(self, axis: Literal[0, 1] = 0) -> Iterator[Range]: for index in range(len(self.columns)): yield Range((start, index + offset), (end, index + offset), self.sheet) - elif axis == 1: + else: start = self.column + self.index.nlevels end = start + len(self.columns) - 1 offset = self.row + self.columns.nlevels @@ -217,10 +214,6 @@ def iter_ranges(self, axis: Literal[0, 1] = 0) -> Iterator[Range]: for index in range(len(self)): yield Range((index + offset, start), (index + offset, end), self.sheet) - else: - msg = "axis must be 0 or 1" # pyright: ignore[reportUnreachable] - raise ValueError(msg) - def add_column( self, column: str, diff --git a/src/xlviews/dataframes/stats_frame.py b/src/xlviews/dataframes/stats_frame.py index a766eeb..dd23f4d 100644 --- a/src/xlviews/dataframes/stats_frame.py +++ b/src/xlviews/dataframes/stats_frame.py @@ -1,5 +1,7 @@ from __future__ import annotations +from typing import TYPE_CHECKING + import pandas as pd from pandas import DataFrame from xlwings.constants import Direction @@ -13,6 +15,9 @@ from .groupby import GroupBy from .sheet_frame import SheetFrame +if TYPE_CHECKING: + from collections.abc import Hashable + class StatsFrame(SheetFrame): @suspend_screen_updates @@ -78,7 +83,7 @@ def get_func(func: str | list[str] | None) -> list[str]: def get_by(sf: SheetFrame, by: str | list[str] | None) -> list[str]: if not by: - return sf.index.names # pyright: ignore[reportReturnType] + return [name for name in sf.index.names if isinstance(name, str)] return list(iter_columns(sf.index.names, by)) @@ -113,11 +118,7 @@ def has_header(sf: SheetFrame) -> bool: start = sf.cell.offset(-1) end = start.offset(0, sf.index.nlevels) value = sf.sheet.range(start, end).options(ndim=1).value - - if not isinstance(value, list): - raise NotImplementedError - - return any(value) # pyright: ignore[reportUnknownArgumentType] + return any(value) def move_down(sf: SheetFrame, length: int) -> int: @@ -134,10 +135,15 @@ def move_down(sf: SheetFrame, length: int) -> int: def set_style(sf: SheetFrame, parent: SheetFrame, func_column_name: str) -> None: - idx = [sf.column + i for i in range(sf.index.nlevels + len(sf.columns))] + def get_number_format(column: Hashable | None) -> str | None: + if isinstance(column, str): + return parent.get_number_format(column) + return None + + idx = [sf.column + i for i in range(sf.index.nlevels + len(sf.columns))] columns = (*parent.index.names, *parent.columns) - formats = [None, *[parent.get_number_format(column) for column in columns]] # pyright: ignore[reportArgumentType] + formats = [None, *[get_number_format(column) for column in columns]] for (func,), rows in sf.groupby(func_column_name).items(): for col, fmt in zip(idx, formats, strict=True): diff --git a/src/xlviews/dataframes/table.py b/src/xlviews/dataframes/table.py index c2d5727..e4ae8ae 100644 --- a/src/xlviews/dataframes/table.py +++ b/src/xlviews/dataframes/table.py @@ -74,12 +74,7 @@ def const_header(self) -> Range: @property def columns(self) -> list[str]: - names = self.header.value - - if not isinstance(names, list): - raise NotImplementedError - - return [name or "" for name in names] # pyright: ignore[reportUnknownVariableType] + return [str(name) if name is not None else "" for name in self.header.value] def add_const_header( self, diff --git a/src/xlviews/figure/grid.py b/src/xlviews/figure/grid.py index 7bb8f80..247e4ee 100644 --- a/src/xlviews/figure/grid.py +++ b/src/xlviews/figure/grid.py @@ -1,10 +1,9 @@ from __future__ import annotations -from typing import TYPE_CHECKING, overload +from typing import TYPE_CHECKING, Literal, overload if TYPE_CHECKING: from collections.abc import Iterator - from typing import Literal from xlviews.chart.axes import Axes @@ -23,14 +22,7 @@ def __init__( self.axes = ax return - if axis == 0: - series = Grid(ax, 1, n)[0, :] - elif axis == 1: - series = Grid(ax, n, 1)[:, 0] - else: - msg = f"Invalid axis: {axis}" - raise ValueError(msg) - + series = Grid(ax, 1, n)[0, :] if axis == 0 else Grid(ax, n, 1)[:, 0] self.axes = list(series) @overload @@ -43,17 +35,13 @@ def __getitem__(self, key: int | slice) -> Axes | Series: if isinstance(key, int): return self.axes[key] - if isinstance(key, slice): - return Series(self.axes[key]) - - msg = f"Invalid key: {key}" - raise ValueError(msg) + return Series(self.axes[key]) def __len__(self) -> int: return len(self.axes) def __iter__(self) -> Iterator[Axes]: - return iter(self.axes) + yield from self.axes class Grid: @@ -74,9 +62,9 @@ def __init__( width = ax.chart.width height = ax.chart.height - axes = [] + axes: list[list[Axes]] = [] for r in range(nrows): - row = [] + row: list[Axes] = [] for c in range(ncols): if r == 0 and c == 0: row.append(ax) @@ -107,11 +95,14 @@ def __getitem__(self, key: tuple[int, slice]) -> Series: ... @overload def __getitem__(self, key: tuple[slice, slice]) -> Grid: ... - def __getitem__(self, key: int | tuple) -> Axes | Series | Grid: + def __getitem__( + self, + key: int | tuple[int | slice, int | slice], + ) -> Axes | Series | Grid: if isinstance(key, int): return Series(self.axes[key]) - if isinstance(key, tuple) and len(key) == 2: + if len(key) == 2: r, c = key if isinstance(r, int) and isinstance(c, int): return self.axes[r][c] diff --git a/src/xlviews/figure/palette.py b/src/xlviews/figure/palette.py index ebec7e9..9d47f33 100644 --- a/src/xlviews/figure/palette.py +++ b/src/xlviews/figure/palette.py @@ -216,15 +216,15 @@ def get_palette[T]( return cls(data, columns) -def get_marker_palette[T]( +def get_marker_palette( data: DataFrame, - marker: PaletteStyle[T] | None, -) -> MarkerPalette | FunctionPalette[T] | None: + marker: PaletteStyle[str] | None, +) -> MarkerPalette | FunctionPalette[str] | None: return get_palette(MarkerPalette, data, marker) -def get_color_palette[T]( +def get_color_palette( data: DataFrame, - color: PaletteStyle[T] | None, -) -> ColorPalette | FunctionPalette[T] | None: + color: PaletteStyle[str] | None, +) -> ColorPalette | FunctionPalette[str] | None: return get_palette(ColorPalette, data, color) diff --git a/src/xlviews/figure/plot.py b/src/xlviews/figure/plot.py index 4f792bd..136af70 100644 --- a/src/xlviews/figure/plot.py +++ b/src/xlviews/figure/plot.py @@ -5,12 +5,12 @@ from typing import TYPE_CHECKING, Any, Self import pandas as pd -from pandas import DataFrame, Index +from pandas import DataFrame from .palette import PaletteStyle, get_color_palette, get_marker_palette if TYPE_CHECKING: - from collections.abc import Iterator, Sequence + from collections.abc import Iterator from xlviews.chart.axes import Axes from xlviews.chart.series import Series @@ -40,30 +40,29 @@ def add( y: str | list[str], chart_type: int | None = None, ) -> Self: - xs = x if isinstance(x, list) else [x] ys = y if isinstance(y, list) else [y] for x_, y_ in product(xs, ys): for idx, s in self.data.iterrows(): series = self.axes.add_series(s[x_], s[y_], chart_type=chart_type) - index = idx if isinstance(idx, tuple) else (idx,) # pyright: ignore[reportUnknownVariableType] - self.index.append(index) # pyright: ignore[reportUnknownArgumentType] + index: tuple[Hashable, ...] = idx if isinstance(idx, tuple) else (idx,) # pyright: ignore[reportUnknownVariableType] + self.index.append(index) self.series_collection.append(series) return self - def keys(self) -> Iterator[dict[str, Hashable]]: + def keys(self) -> Iterator[dict[Hashable | None, Hashable]]: names = self.data.index.names for index in self.index: - yield dict(zip(names, index, strict=True)) # pyright: ignore[reportReturnType] + yield dict(zip(names, index, strict=True)) - def set[T]( + def set( self, label: Label | None = None, - marker: PaletteStyle[T] | None = None, - color: PaletteStyle[T] | None = None, + marker: PaletteStyle[str] | None = None, + color: PaletteStyle[str] | None = None, alpha: float | None = None, weight: float | None = None, size: int | None = None, @@ -112,26 +111,20 @@ def facet( yield key, cls(axes_, sub) -def get_label(label: Label, key: dict[str, Hashable]) -> str: - if isinstance(label, str): - return label.format(**key) - - if callable(label): - return label(key) - - msg = f"Invalid label: {label}" # pyright: ignore[reportUnreachable] - raise ValueError(msg) +def get_label(label: Label, key: dict[Hashable | None, Hashable]) -> str: + key_ = {k: v for k, v in key.items() if isinstance(k, str)} + return label(key_) if callable(label) else label.format(**key_) def iterrows( - index: Index, - levels: int | str | Sequence[int | str] | None, + index: pd.Index[Any], + levels: str | list[str] | None, ) -> Iterator[dict[str, Any]]: if levels is None: yield {} return - if isinstance(levels, int | str): + if isinstance(levels, str): levels = [levels] if levels: diff --git a/src/xlviews/testing/__init__.py b/src/xlviews/testing/__init__.py index d0ca63c..e12e636 100644 --- a/src/xlviews/testing/__init__.py +++ b/src/xlviews/testing/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from .common import ( FrameContainer, create_sheet, diff --git a/src/xlviews/testing/chart.py b/src/xlviews/testing/chart.py index 9dc35cf..4f534b0 100644 --- a/src/xlviews/testing/chart.py +++ b/src/xlviews/testing/chart.py @@ -55,7 +55,7 @@ def dataframe(cls) -> DataFrame: ax = Axes(chart_type=ChartType.xlXYScatterLinesNoMarkers) df = sf.groupby(["b", "c"]).agg(include_sheetname=True) for key, s in df.iterrows(): - x = ax.add_series(s["x"], s["y"], label=f"{key[0]}_{key[1]}") # type: ignore + x = ax.add_series(s["x"], s["y"], label=f"{key}") x.set(marker="o") ax.set( diff --git a/src/xlviews/testing/common.py b/src/xlviews/testing/common.py index 9487a18..00c6ae7 100644 --- a/src/xlviews/testing/common.py +++ b/src/xlviews/testing/common.py @@ -69,7 +69,7 @@ def __init__( row: int = 0, column: int = 0, style: bool = False, - **kwargs, + **kwargs: Any, ) -> None: self.df = self.dataframe() self.row = row or self.row @@ -84,7 +84,7 @@ def __init__( ) self.init() - def kwargs(self, **kwargs) -> dict[str, Any]: + def kwargs(self, **kwargs: Any) -> dict[str, Any]: # noqa: PLR6301 return kwargs def init(self) -> None: diff --git a/src/xlviews/testing/figure/facet.py b/src/xlviews/testing/figure/facet.py index 35a927e..86e1959 100644 --- a/src/xlviews/testing/figure/facet.py +++ b/src/xlviews/testing/figure/facet.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any from xlviews.chart.axes import Axes from xlviews.figure.palette import get_color_palette, get_marker_palette @@ -10,7 +10,6 @@ if TYPE_CHECKING: from collections.abc import Iterator - from typing import Any from xlviews.dataframes.sheet_frame import SheetFrame diff --git a/src/xlviews/testing/heat_frame/common.py b/src/xlviews/testing/heat_frame/common.py index 1f2bae4..e1d6894 100644 --- a/src/xlviews/testing/heat_frame/common.py +++ b/src/xlviews/testing/heat_frame/common.py @@ -27,5 +27,5 @@ def init(self) -> None: self.sf.autofit() @classmethod - def dataframe(cls, sf: SheetFrame) -> DataFrame: + def dataframe(cls, sf: SheetFrame) -> DataFrame: # pyright: ignore[reportUnusedParameter] raise NotImplementedError diff --git a/src/xlviews/testing/heat_frame/facet.py b/src/xlviews/testing/heat_frame/facet.py index 9cc78fc..86b1c9f 100644 --- a/src/xlviews/testing/heat_frame/facet.py +++ b/src/xlviews/testing/heat_frame/facet.py @@ -1,15 +1,15 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any from xlviews.core.range import Range -from xlviews.dataframes.heat_frame import Colorbar, HeatFrame +from xlviews.dataframes.colorbar import Colorbar +from xlviews.dataframes.heat_frame import HeatFrame from xlviews.testing.common import create_sheet from xlviews.testing.sheet_frame.pivot import Pivot if TYPE_CHECKING: from collections.abc import Hashable, Iterator - from typing import Any from xlviews.dataframes.sheet_frame import SheetFrame diff --git a/src/xlviews/testing/heat_frame/facet_agg.py b/src/xlviews/testing/heat_frame/facet_agg.py index b81eea7..7c10fc0 100644 --- a/src/xlviews/testing/heat_frame/facet_agg.py +++ b/src/xlviews/testing/heat_frame/facet_agg.py @@ -1,15 +1,15 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any from xlviews.core.range import Range -from xlviews.dataframes.heat_frame import Colorbar, HeatFrame +from xlviews.dataframes.colorbar import Colorbar +from xlviews.dataframes.heat_frame import HeatFrame from xlviews.testing.common import create_sheet from xlviews.testing.sheet_frame.pivot import Pivot if TYPE_CHECKING: from collections.abc import Hashable, Iterator - from typing import Any from xlviews.dataframes.sheet_frame import SheetFrame diff --git a/src/xlviews/testing/heat_frame/pair.py b/src/xlviews/testing/heat_frame/pair.py index e0627f3..88ad034 100644 --- a/src/xlviews/testing/heat_frame/pair.py +++ b/src/xlviews/testing/heat_frame/pair.py @@ -1,15 +1,15 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any, Literal from xlviews.core.range import Range -from xlviews.dataframes.heat_frame import Colorbar, HeatFrame +from xlviews.dataframes.colorbar import Colorbar +from xlviews.dataframes.heat_frame import HeatFrame from xlviews.testing.common import create_sheet from xlviews.testing.sheet_frame.pivot import Pivot if TYPE_CHECKING: from collections.abc import Hashable, Iterator - from typing import Any, Literal from xlviews.dataframes.sheet_frame import SheetFrame diff --git a/src/xlviews/testing/sheet_frame/pivot.py b/src/xlviews/testing/sheet_frame/pivot.py index 832770f..7386616 100644 --- a/src/xlviews/testing/sheet_frame/pivot.py +++ b/src/xlviews/testing/sheet_frame/pivot.py @@ -27,7 +27,7 @@ class MultiIndex(FrameContainer): def dataframe(cls) -> DataFrame: df = Base.dataframe().reset_index() - dfs = [] + dfs: list[DataFrame] = [] for x in range(1, 4): for y in range(1, 5): a = df.copy() @@ -52,7 +52,7 @@ def dataframe(cls) -> DataFrame: for a, b in [(2, 1), (3, 3), (4, 1), (4, 3)]: df = df[~((df["Y"] == a) & (df["y"] == b))] - dfs = [] + dfs: list[DataFrame] = [] for x in range(1, 3): for y in range(1, 4): if x == 1 and y == 3: diff --git a/src/xlviews/utils.py b/src/xlviews/utils.py index 907f5a7..9e8b17e 100644 --- a/src/xlviews/utils.py +++ b/src/xlviews/utils.py @@ -4,8 +4,8 @@ from typing import TYPE_CHECKING, Any import xlwings +import xlwings.constants from pandas import DataFrame, Series -from xlwings.constants import DVType, FormatConditionOperator if TYPE_CHECKING: from collections.abc import Callable, Iterable, Iterator @@ -38,7 +38,7 @@ def constant(type_: str, name: str | None = None) -> int: if not name.startswith("xl"): name = "xl" + name[0].upper() + name[1:] - type_ = getattr(xlwings.constants, type_) # pyright: ignore[reportUnknownMemberType, reportUnknownArgumentType, reportAttributeAccessIssue] + type_ = getattr(xlwings.constants, type_) return getattr(type_, name) @@ -113,8 +113,8 @@ def add_validate_list( if default: rng.value = default - type_ = DVType.xlValidateList - operator = FormatConditionOperator.xlEqual + type_ = xlwings.constants.DVType.xlValidateList + operator = xlwings.constants.FormatConditionOperator.xlEqual formula = ",".join(map(str, value)) rng.api.Validation.Add(Type=type_, Operator=operator, Formula1=formula) From 4d9cf189553fd778499acd1b4621adc09c58f7b1 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sat, 7 Feb 2026 18:17:18 +0900 Subject: [PATCH 21/40] Update stubs --- typings/xlwings/__init__.pyi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/typings/xlwings/__init__.pyi b/typings/xlwings/__init__.pyi index b2458ab..e43d23e 100644 --- a/typings/xlwings/__init__.pyi +++ b/typings/xlwings/__init__.pyi @@ -63,6 +63,7 @@ class Sheet: def api(self) -> Any: ... @property def impl(self) -> Any: ... + def __getitem__(self, item: Any) -> Range: ... @property def name(self) -> str: ... @name.setter @@ -76,6 +77,7 @@ class Sheet: def book(self) -> Book: ... @property def charts(self) -> Charts: ... + def delete(self) -> None: ... class Chart: @property @@ -122,6 +124,7 @@ class Book: def app(self) -> App: ... @property def sheets(self) -> Sheets: ... + def close(self) -> None: ... class App: def __init__(self, visible: bool | None = None) -> None: ... @@ -155,6 +158,7 @@ class Apps: class Books: @property def active(self) -> Book: ... + def add(self) -> Book: ... class Sheets: @property From 0da23e193bd006851a4cd5db06d36d26dedb41dd Mon Sep 17 00:00:00 2001 From: Daizu Date: Sun, 8 Feb 2026 06:07:31 +0900 Subject: [PATCH 22/40] Update stub --- typings/pytest_benchmark/fixture.pyi | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 typings/pytest_benchmark/fixture.pyi diff --git a/typings/pytest_benchmark/fixture.pyi b/typings/pytest_benchmark/fixture.pyi new file mode 100644 index 0000000..dac0736 --- /dev/null +++ b/typings/pytest_benchmark/fixture.pyi @@ -0,0 +1,9 @@ +from collections.abc import Callable + +class BenchmarkFixture: + def __call__[**P, R]( + self, + function_to_benchmark: Callable[P, R], + *args: P.args, + **kwargs: P.kwargs, + ) -> R: ... From 4d9474c3d9267cacf0cb2f34e25b9acefece98cf Mon Sep 17 00:00:00 2001 From: Daizu Date: Sun, 8 Feb 2026 06:12:51 +0900 Subject: [PATCH 23/40] fix benchmark --- tests/benchmark/test_address.py | 35 +++++++++++++++++++++-------- tests/benchmark/test_sheet_frame.py | 34 +++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 15 deletions(-) diff --git a/tests/benchmark/test_address.py b/tests/benchmark/test_address.py index aebdec9..3c33127 100644 --- a/tests/benchmark/test_address.py +++ b/tests/benchmark/test_address.py @@ -1,21 +1,28 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import numpy as np import pytest from pandas import DataFrame -from xlwings import Range as RangeImpl -from xlwings import Sheet from xlviews.core.range import Range from xlviews.testing import is_app_available +if TYPE_CHECKING: + from pytest_benchmark.fixture import BenchmarkFixture + from xlwings import Range as RangeImpl + from xlwings import Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @pytest.fixture( scope="module", params=[(10, 10), (20, 10), (50, 10), (500, 500)], - ids=lambda x: str(x), + ids=str, ) -def shape(request: pytest.FixtureRequest): +def shape(request: pytest.FixtureRequest) -> tuple[int, int]: return request.param @@ -32,23 +39,33 @@ def rng(shape: tuple[int, int], sheet_module: Sheet): @pytest.mark.slow -def test_address_impl(benchmark, rng_impl: RangeImpl, rng: Range, shape): +def test_address_impl( + benchmark: BenchmarkFixture, + rng_impl: RangeImpl, + rng: Range, + shape: tuple[int, int], +): x = benchmark(lambda: [r.get_address() for r in rng_impl]) + assert isinstance(x, list) assert len(x) == shape[0] * shape[1] assert x == list(rng.iter_addresses()) -def test_address(benchmark, rng: Range, shape): +def test_address(benchmark: BenchmarkFixture, rng: Range, shape: tuple[int, int]): x = benchmark(lambda: list(rng.iter_addresses())) assert len(x) == shape[0] * shape[1] -def test_address_frame(benchmark, rng: Range, shape): - x = benchmark(lambda: rng.frame.get_address()) +def test_address_frame(benchmark: BenchmarkFixture, rng: Range, shape: tuple[int, int]): + x = benchmark(rng.frame.get_address) assert x.shape == (shape[0], shape[1]) -def test_address_iter_frame(benchmark, rng: Range, shape): +def test_address_iter_frame( + benchmark: BenchmarkFixture, + rng: Range, + shape: tuple[int, int], +): def f(): x = np.array(list(rng.iter_addresses())).reshape(shape[0], shape[1]) return DataFrame(x) diff --git a/tests/benchmark/test_sheet_frame.py b/tests/benchmark/test_sheet_frame.py index 4a349d7..d5cc5d7 100644 --- a/tests/benchmark/test_sheet_frame.py +++ b/tests/benchmark/test_sheet_frame.py @@ -1,13 +1,20 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Literal + import numpy as np import pytest from pandas import DataFrame -from xlwings import Sheet from xlviews.core.address import index_to_column_name from xlviews.dataframes.groupby import GroupBy from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.testing import is_app_available +if TYPE_CHECKING: + from pytest_benchmark.fixture import BenchmarkFixture + from xlwings import Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -23,7 +30,12 @@ def create_sheet_frame(df: DataFrame, sheet: Sheet) -> SheetFrame: @pytest.mark.parametrize(("rows", "columns"), [(10, 20), (100, 100), (1000, 100)]) -def test_create_sheet_frame(benchmark, sheet: Sheet, rows: int, columns: int): +def test_create_sheet_frame( + benchmark: BenchmarkFixture, + sheet: Sheet, + rows: int, + columns: int, +): df = create_data_frame(rows, columns) sf = benchmark(create_sheet_frame, df, sheet) assert isinstance(sf, SheetFrame) @@ -57,24 +69,34 @@ def columns(request: pytest.FixtureRequest): @pytest.mark.parametrize("axis", [0, 1]) -def test_ranges(benchmark, sf: SheetFrame, shape, axis): +def test_ranges( + benchmark: BenchmarkFixture, + sf: SheetFrame, + shape: tuple[int, int], + axis: Literal[0, 1], +): x = benchmark(lambda: list(sf.iter_ranges(axis))) assert len(x) == shape[1 - axis] - 10 * (1 - axis) -def test_agg(benchmark, sf: SheetFrame, columns): +def test_agg(benchmark: BenchmarkFixture, sf: SheetFrame, columns: list[str]): x = benchmark(lambda: sf.agg(["sum", "count"], columns)) assert isinstance(x, DataFrame) assert x.shape == (2, len(columns)) -def test_groupby(benchmark, sf: SheetFrame, columns): +def test_groupby(benchmark: BenchmarkFixture, sf: SheetFrame, columns: list[str]): x = benchmark(lambda: sf.groupby(columns)) assert isinstance(x, GroupBy) assert len(x) == len(sf) -def test_groupby_agg(benchmark, sf: SheetFrame, columns, shape): +def test_groupby_agg( + benchmark: BenchmarkFixture, + sf: SheetFrame, + columns: list[str], + shape: tuple[int, int], +): x = benchmark(lambda: sf.groupby(columns).agg(["sum", "count"])) assert isinstance(x, DataFrame) assert x.shape == (len(sf), 2 * (shape[1] - 10)) From ad2d63e09acb70ca382863caed54abc2489ee131 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sun, 8 Feb 2026 06:13:42 +0900 Subject: [PATCH 24/40] fix top level tests --- tests/conftest.py | 6 ++- tests/test_colors.py | 12 ++--- tests/test_config.py | 6 +-- tests/test_style.py | 104 ++++++++++++++++++++++--------------------- tests/test_utils.py | 18 ++++---- 5 files changed, 75 insertions(+), 71 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index cfd1573..d417346 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,11 @@ +from __future__ import annotations + import pytest import xlwings from xlwings import App, Book +from xlviews.style import hide_gridlines + @pytest.fixture(scope="session") def app(): @@ -20,8 +24,6 @@ def book(app: App): @pytest.fixture(scope="module") def sheet_module(book: Book): - from xlviews.style import hide_gridlines - sheet = book.sheets.add() hide_gridlines(sheet) diff --git a/tests/test_colors.py b/tests/test_colors.py index 25ef365..00b21af 100644 --- a/tests/test_colors.py +++ b/tests/test_colors.py @@ -1,5 +1,9 @@ +from __future__ import annotations + import pytest +from xlviews.colors import rgb + @pytest.mark.parametrize( ("name", "color"), @@ -18,17 +22,13 @@ (100, 100), ], ) -def test_rgb(name, color): - from xlviews.colors import rgb - +def test_rgb(name: str | int | tuple[int, int, int], color: int): assert rgb(name) == color if isinstance(name, tuple): assert rgb(*name) == color @pytest.mark.parametrize("name", ["invalid", (1, "x", "y")]) -def test_rgb_error(name): - from xlviews.colors import rgb - +def test_rgb_error(name: str): with pytest.raises(ValueError, match="Invalid color format"): rgb(name) diff --git a/tests/test_config.py b/tests/test_config.py index e864201..a148ec0 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,11 +1,11 @@ +from __future__ import annotations + import pytest -from xlviews.config import rcParams +from xlviews.config import CONFIG_FILE, rcParams def test_config_file(): - from xlviews.config import CONFIG_FILE - assert CONFIG_FILE.exists() diff --git a/tests/test_style.py b/tests/test_style.py index f1d25a4..4f611d2 100644 --- a/tests/test_style.py +++ b/tests/test_style.py @@ -1,21 +1,52 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from xlwings import Sheet from xlwings.constants import BordersIndex from xlviews.config import rcParams from xlviews.core.range import Range +from xlviews.core.range_collection import RangeCollection +from xlviews.style import ( + hide_gridlines, + hide_succession, + hide_unique, + set_alignment, + set_banding, + set_border, + set_border_edge, + set_border_inside, + set_border_line, + set_fill, + set_font, + set_number_format, +) from xlviews.testing import is_app_available +if TYPE_CHECKING: + from collections.abc import Callable + + from xlwings import Range as RangeImpl + from xlwings import Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @pytest.mark.parametrize(("index", "value"), [("Vertical", 11), ("Horizontal", 12)]) -def test_border_index(index, value): +def test_border_index(index: str, value: int): assert getattr(BordersIndex, f"xlInside{index}") == value -@pytest.fixture(params=[lambda x: x, Range.from_range], ids=["RangeImpl", "Range"]) -def cls(request: pytest.FixtureRequest): +type Cls = Callable[[RangeImpl], RangeImpl | Range] + + +def identity(x: RangeImpl) -> RangeImpl: + return x + + +@pytest.fixture(params=[identity, Range.from_range], ids=["RangeImpl", "Range"]) +def cls(request: pytest.FixtureRequest) -> Cls: return request.param @@ -23,9 +54,12 @@ def cls(request: pytest.FixtureRequest): ("weight", "value"), [((1, 2, 3, 4), (1, 2, -4138, 4)), (2, (2, 2, 2, 2))], ) -def test_border_edge(weight, value, cls, sheet: Sheet): - from xlviews.style import set_border_edge - +def test_border_edge( + weight: tuple[int, int, int, int] | int, + value: tuple[int, int, int, int], + cls: Cls, + sheet: Sheet, +): set_border_edge(cls(sheet["C3:E5"]), weight, color="red") assert sheet["B3:C5"].api.Borders(11).Weight == value[0] assert sheet["B3:C5"].api.Borders(11).Color == 255 @@ -37,9 +71,7 @@ def test_border_edge(weight, value, cls, sheet: Sheet): assert sheet["C5:E6"].api.Borders(12).Color == 255 -def test_border_inside(cls, sheet: Sheet): - from xlviews.style import set_border_inside - +def test_border_inside(cls: Cls, sheet: Sheet): set_border_inside(cls(sheet["C3:E5"]), weight=2, color="red") assert sheet["C3:E5"].api.Borders(11).Weight == 2 assert sheet["C3:E5"].api.Borders(11).Color == 255 @@ -47,32 +79,24 @@ def test_border_inside(cls, sheet: Sheet): assert sheet["C3:E5"].api.Borders(12).Color == 255 -def test_border(cls, sheet: Sheet): - from xlviews.style import set_border - +def test_border(cls: Cls, sheet: Sheet): set_border(cls(sheet["C3:E5"]), edge_weight=2, inside_weight=1) assert sheet["B3:C5"].api.Borders(11).Weight == 2 assert sheet["C3:E5"].api.Borders(11).Weight == 1 -def test_border_zero(cls, sheet: Sheet): - from xlviews.style import set_border_line - +def test_border_zero(cls: Cls, sheet: Sheet): set_border_line(cls(sheet["C3:D5"]), "xlInsideVertical", weight=0, color="red") assert sheet["C3:D5"].api.Borders(11).Weight == 2 assert sheet["C3:D5"].api.Borders(12).Weight == 2 -def test_fill(cls, sheet: Sheet): - from xlviews.style import set_fill - +def test_fill(cls: Cls, sheet: Sheet): set_fill(cls(sheet["C3:E5"]), color="pink") assert sheet["C3:E5"].api.Interior.Color == 13353215 -def test_font(cls, sheet: Sheet): - from xlviews.style import set_font - +def test_font(cls: Cls, sheet: Sheet): rng = cls(sheet["C3"]) rng.value = "abc" set_font(rng, "Times", size=24, bold=True, italic=True, color="green") @@ -84,9 +108,6 @@ def test_font(cls, sheet: Sheet): def test_font_collection(sheet: Sheet): - from xlviews.core.range_collection import RangeCollection - from xlviews.style import set_font - rc = RangeCollection([(2, 3), (6, 7)], 2, sheet) set_font(rc, "Times", size=24, bold=True, italic=True, color="green") @@ -103,9 +124,7 @@ def test_font_collection(sheet: Sheet): assert rng.api.Font.Size != 24 -def test_font_without_name(cls, sheet: Sheet): - from xlviews.style import set_font - +def test_font_without_name(cls: Cls, sheet: Sheet): rng = cls(sheet["C3"]) rng.value = "abc" set_font(rng) @@ -116,9 +135,7 @@ def test_font_without_name(cls, sheet: Sheet): ("align", "value"), [("right", -4152), ("left", -4131), ("center", -4108)], ) -def test_alignment_horizontal(align, value, cls, sheet: Sheet): - from xlviews.style import set_alignment - +def test_alignment_horizontal(align: str, value: int, cls: Cls, sheet: Sheet): rng = cls(sheet["C3"]) rng.value = "a" set_alignment(rng, horizontal_alignment=align) @@ -129,27 +146,20 @@ def test_alignment_horizontal(align, value, cls, sheet: Sheet): ("align", "value"), [("top", -4160), ("bottom", -4107), ("center", -4108)], ) -def test_alignment_vertical(align, value, cls, sheet: Sheet): - from xlviews.style import set_alignment - +def test_alignment_vertical(align: str, value: int, cls: Cls, sheet: Sheet): rng = cls(sheet["C3"]) rng.value = "a" set_alignment(rng, vertical_alignment=align) assert rng.api.VerticalAlignment == value -def test_number_format(cls, sheet: Sheet): - from xlviews.style import set_number_format - +def test_number_format(cls: Cls, sheet: Sheet): rng = cls(sheet["C3"]) set_number_format(rng, "0.0%") assert rng.api.NumberFormat == "0.0%" def test_number_format_collection(sheet: Sheet): - from xlviews.core.range_collection import RangeCollection - from xlviews.style import set_number_format - rc = RangeCollection([(2, 3), (6, 7)], 3, sheet) set_number_format(rc, "0.0%") @@ -166,18 +176,14 @@ def test_number_format_collection(sheet: Sheet): ("axis", "even_color", "odd_color"), [(0, 100, 200), (1, 300, 400)], ) -def test_banding(axis, even_color, odd_color, cls, sheet: Sheet): - from xlviews.style import set_banding - +def test_banding(axis: int, even_color: int, odd_color: int, cls: Cls, sheet: Sheet): rng = cls(sheet["C3:F6"]) set_banding(rng, axis, even_color, odd_color) assert rng.api.FormatConditions(1).Interior.Color == even_color assert rng.api.FormatConditions(2).Interior.Color == odd_color -def test_hide_succession(cls, sheet: Sheet): - from xlviews.style import hide_succession - +def test_hide_succession(cls: Cls, sheet: Sheet): rng = sheet["C3:C8"] rng.options(transpose=True).value = [1, 1, 2, 2, 3, 3] rng = sheet["D3:D8"] @@ -187,9 +193,7 @@ def test_hide_succession(cls, sheet: Sheet): assert rng.api.FormatConditions(1).Font.Color == 255 -def test_hide_unique(cls, sheet: Sheet): - from xlviews.style import hide_unique - +def test_hide_unique(cls: Cls, sheet: Sheet): rng = sheet["C3:C8"] rng.options(transpose=True).value = [1, 1, 2, 2, 3, 3] rng = sheet["D3:D8"] @@ -201,7 +205,5 @@ def test_hide_unique(cls, sheet: Sheet): def test_hide_gridlines(sheet: Sheet): - from xlviews.style import hide_gridlines - hide_gridlines(sheet) assert sheet.book.app.api.ActiveWindow.DisplayGridlines is False diff --git a/tests/test_utils.py b/tests/test_utils.py index 4a8a919..7044810 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,8 +1,15 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest from pandas import DataFrame -from xlwings import Sheet from xlviews.testing import is_app_available +from xlviews.utils import add_validate_list, constant, iter_columns + +if TYPE_CHECKING: + from xlwings import Sheet @pytest.mark.parametrize( @@ -19,8 +26,6 @@ ], ) def test_constant(name: str, value: int): - from xlviews.utils import constant - assert constant(name) == value assert constant(*name.split(".")) == value @@ -34,21 +39,16 @@ def test_constant(name: str, value: int): (["::B", "C"], ["A", "C"]), ], ) -def test_iter_columns(columns, lst): - from xlviews.utils import iter_columns - +def test_iter_columns(columns: str | list[str], lst: list[str]): df = DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]], columns=["A", "B", "C"]) assert list(iter_columns(df, columns)) == lst @pytest.mark.skipif(not is_app_available(), reason="Excel not installed") def test_validate_list(sheet: Sheet): - from xlviews.utils import add_validate_list - rng = sheet.range("a1") add_validate_list(rng, [1, 2, 3], 2) assert rng.value == 2 - assert rng.api.Validation.Type == 3 assert rng.api.Validation.Operator == 3 assert rng.api.Validation.Formula1 == "1,2,3" From 00b498deb15d6b072ddb44693addffe8af20937a Mon Sep 17 00:00:00 2001 From: Daizu Date: Sun, 8 Feb 2026 06:26:27 +0900 Subject: [PATCH 25/40] tests/core --- tests/core/test_address.py | 5 +-- tests/core/test_formula.py | 48 ++++++++++++++--------------- tests/core/test_index.py | 4 ++- tests/core/test_range.py | 46 +++++++++++++++++++-------- tests/core/test_range_collection.py | 22 +++++++++++-- 5 files changed, 83 insertions(+), 42 deletions(-) diff --git a/tests/core/test_address.py b/tests/core/test_address.py index 58a7e4f..072adac 100644 --- a/tests/core/test_address.py +++ b/tests/core/test_address.py @@ -1,5 +1,8 @@ +from __future__ import annotations + import pytest +from xlviews.core.address import column_name_to_index, index_to_column_name from xlviews.testing import is_app_available pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -7,6 +10,4 @@ @pytest.mark.parametrize("index", range(1, 1000, 50)) def test_column_name(index: int): - from xlviews.core.address import column_name_to_index, index_to_column_name - assert column_name_to_index(index_to_column_name(index)) == index diff --git a/tests/core/test_formula.py b/tests/core/test_formula.py index 9cc9933..a0194ad 100644 --- a/tests/core/test_formula.py +++ b/tests/core/test_formula.py @@ -1,10 +1,14 @@ +from __future__ import annotations + +from collections.abc import Callable + import numpy as np import pytest from pandas import DataFrame from xlwings import Range as RangeImpl from xlwings import Sheet -from xlviews.core.formula import NONCONST_VALUE +from xlviews.core.formula import NONCONST_VALUE, aggregate, const from xlviews.core.range import Range from xlviews.testing import is_app_available @@ -35,7 +39,7 @@ def test_range_address(rng: Range | RangeImpl): def column(rng: Range | RangeImpl): start = rng[0].offset(1) end = start.offset(3) - return rng.__class__((start.row, start.column), (end.row, end.column)) + return rng.__class__((start.row, start.column), (end.row, end.column)) # pyright: ignore[reportCallIssue] def test_column(column: Range | RangeImpl): @@ -47,7 +51,7 @@ def const_header(rng: Range | RangeImpl): start = (rng[0].row, rng[0].column) rng_impl = rng if isinstance(rng, RangeImpl) else rng.impl end = rng_impl[0].expand("right") - return rng.__class__(start, (end[-1].row, end[-1].column)).offset(-1) + return rng.__class__(start, (end[-1].row, end[-1].column)).offset(-1) # pyright: ignore[reportCallIssue] def test_header(const_header: Range | RangeImpl): @@ -55,9 +59,12 @@ def test_header(const_header: Range | RangeImpl): @pytest.mark.parametrize(("k", "value"), [(0, 1), (1, NONCONST_VALUE), (2, 4)]) -def test_const(column: Range | RangeImpl, const_header: Range | RangeImpl, k, value): - from xlviews.core.formula import const - +def test_const( + column: Range | RangeImpl, + const_header: Range | RangeImpl, + k: int, + value: int, +): const_header.value = "=" + const(column) assert const_header.value[k] == value @@ -83,29 +90,21 @@ def test_ranges(ranges: list[Range]): def test_aggregate_value(ranges: list[Range]): - from xlviews.core.formula import aggregate - x = aggregate("count", ranges) assert x == "AGGREGATE(2,7,$B$100:$B$110,$C$100:$C$110)" def test_aggregate_none(ranges: list[Range]): - from xlviews.core.formula import aggregate - x = aggregate(None, ranges) assert x == "$B$100:$B$110,$C$100:$C$110" def test_aggregate_formula(ranges: list[Range]): - from xlviews.core.formula import aggregate - x = aggregate("max", ranges, formula=True) assert x == "=AGGREGATE(4,7,$B$100:$B$110,$C$100:$C$110)" def test_aggreate_range_range(ranges: list[Range]): - from xlviews.core.formula import aggregate - assert aggregate("max", ranges[0]) == "AGGREGATE(4,7,$B$100:$B$110)" @@ -122,20 +121,23 @@ def test_aggreate_range_range(ranges: list[Range]): @pytest.mark.parametrize(("func", "value"), FUNC_VALUES) -def test_aggregate_str(ranges: list[Range], func, value): - from xlviews.core.formula import aggregate - +def test_aggregate_str(ranges: list[Range], func: str, value: float): cell = ranges[0].sheet.range("D100") cell.value = aggregate(func, ranges, formula=True) assert cell.value == value -@pytest.mark.parametrize(("func", "value"), FUNC_VALUES) -@pytest.mark.parametrize("apply", [lambda x: x, Range.from_range]) -def test_aggregate_range(ranges: list[Range], func, value, apply): - from xlviews.core.formula import aggregate +type Cls = Callable[[RangeImpl], RangeImpl | Range] + + +def identity(x: RangeImpl) -> RangeImpl: + return x - ref = apply(ranges[0].sheet.range("E100")) + +@pytest.mark.parametrize(("func", "value"), FUNC_VALUES) +@pytest.mark.parametrize("cls", [identity, Range.from_range]) +def test_aggregate_range(ranges: list[Range], func: str, value: float, cls: Cls): + ref = cls(ranges[0].sheet.range("E100")) ref.value = func formula = aggregate(ref, ranges) cell = ranges[0].sheet.range("D100") @@ -144,7 +146,5 @@ def test_aggregate_range(ranges: list[Range], func, value, apply): def test_aggreate_func_invalid(): - from xlviews.core.formula import aggregate - with pytest.raises(ValueError, match="Invalid aggregate function: sin"): aggregate("sin", "A1:A10") diff --git a/tests/core/test_index.py b/tests/core/test_index.py index 4d8f35c..8fd49f3 100644 --- a/tests/core/test_index.py +++ b/tests/core/test_index.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import pytest from xlviews.core.index import Index, WideIndex @@ -27,7 +29,7 @@ def test_wide_to_list(wide_index: WideIndex): @pytest.mark.parametrize(("key", "loc"), [("A", (0, 3)), ("B", (3, 7))]) -def test_wide_loc(wide_index: WideIndex, key, loc): +def test_wide_loc(wide_index: WideIndex, key: str, loc: tuple[int, int]): assert wide_index.get_loc(key) == loc diff --git a/tests/core/test_range.py b/tests/core/test_range.py index b436ff5..29157a7 100644 --- a/tests/core/test_range.py +++ b/tests/core/test_range.py @@ -1,11 +1,17 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import numpy as np import pytest -from xlwings import Range as RangeImpl -from xlwings import Sheet from xlviews.core.range import Range from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlwings import Range as RangeImpl + from xlwings import Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -15,7 +21,7 @@ def addr(request: pytest.FixtureRequest): @pytest.fixture(scope="module") -def rng_impl(addr, sheet_module: Sheet): +def rng_impl(addr: str, sheet_module: Sheet): return sheet_module.range(addr) @@ -30,32 +36,41 @@ def external(request: pytest.FixtureRequest): @pytest.fixture(scope="module") -def addr_impl(rng_impl: RangeImpl, include_sheetname, external): +def addr_impl(rng_impl: RangeImpl, include_sheetname: bool, external: bool): return rng_impl.get_address(include_sheetname=include_sheetname, external=external) -def test_range_int_int(rng_impl: RangeImpl, include_sheetname, external): +def test_range_int_int(rng_impl: RangeImpl, include_sheetname: bool, external: bool): rng = Range(rng_impl.row, rng_impl.column) x = rng.get_address(include_sheetname=include_sheetname, external=external) y = rng_impl[0].get_address(include_sheetname=include_sheetname, external=external) assert x == y -def test_range_tuple_first(rng_impl: RangeImpl, include_sheetname, external): +def test_range_tuple_first( + rng_impl: RangeImpl, + include_sheetname: bool, + external: bool, +): rng = Range((rng_impl.row, rng_impl.column)) x = rng.get_address(include_sheetname=include_sheetname, external=external) y = rng_impl[0].get_address(include_sheetname=include_sheetname, external=external) assert x == y -def test_range_tuple_last(rng_impl: RangeImpl, include_sheetname, external): +def test_range_tuple_last(rng_impl: RangeImpl, include_sheetname: bool, external: bool): rng = Range((rng_impl.last_cell.row, rng_impl.last_cell.column)) x = rng.get_address(include_sheetname=include_sheetname, external=external) y = rng_impl[-1].get_address(include_sheetname=include_sheetname, external=external) assert x == y -def test_range_tuple_tuple(rng_impl: RangeImpl, addr_impl, include_sheetname, external): +def test_range_tuple_tuple( + rng_impl: RangeImpl, + addr_impl: str, + include_sheetname: bool, + external: bool, +): cell1 = (rng_impl.row, rng_impl.column) cell2 = (rng_impl.last_cell.row, rng_impl.last_cell.column) rng = Range(cell1, cell2) @@ -63,7 +78,12 @@ def test_range_tuple_tuple(rng_impl: RangeImpl, addr_impl, include_sheetname, ex assert x == addr_impl -def test_range_from_range(rng_impl: RangeImpl, addr_impl, include_sheetname, external): +def test_range_from_range( + rng_impl: RangeImpl, + addr_impl: str, + include_sheetname: bool, + external: bool, +): rng = Range.from_range(rng_impl) x = rng.get_address(include_sheetname=include_sheetname, external=external) assert x == addr_impl @@ -80,11 +100,13 @@ def test_range_from_range_last(rng_impl: RangeImpl): def test_range_error_tuple(sheet_module: Sheet): + assert sheet_module with pytest.raises(TypeError, match="cell2 must be a tuple or None"): Range((1, 1), 1) def test_range_error_int(sheet_module: Sheet): + assert sheet_module with pytest.raises(TypeError, match="cell2 must be an integer"): Range(1, (1, 1)) @@ -129,7 +151,7 @@ def test_last_cell(rng: Range, rng_impl: RangeImpl): @pytest.mark.parametrize("row_offset", [2, 0, -2]) @pytest.mark.parametrize("column_offset", [2, 0, -2]) -def test_offset(rng: Range, rng_impl: RangeImpl, row_offset, column_offset): +def test_offset(rng: Range, rng_impl: RangeImpl, row_offset: int, column_offset: int): x = rng.offset(row_offset, column_offset) y = rng_impl.offset(row_offset, column_offset) assert x.get_address() == y.get_address() @@ -145,13 +167,13 @@ def test_impl_to(rng: Range, rng_impl: RangeImpl): assert rng_impl.value == rng.impl.value -def test_iter_addresses(rng: Range, rng_impl: RangeImpl, external): +def test_iter_addresses(rng: Range, rng_impl: RangeImpl, external: bool): x = list(rng.iter_addresses(external=external)) y = [r.get_address(external=external) for r in rng_impl] assert x == y -def test_iter_addresses_formula(rng: Range, rng_impl: RangeImpl, external): +def test_iter_addresses_formula(rng: Range, rng_impl: RangeImpl, external: bool): x = list(rng.iter_addresses(external=external, formula=True)) y = ["=" + r.get_address(external=external) for r in rng_impl] assert x == y diff --git a/tests/core/test_range_collection.py b/tests/core/test_range_collection.py index 0b72fab..a5ea78e 100644 --- a/tests/core/test_range_collection.py +++ b/tests/core/test_range_collection.py @@ -1,9 +1,15 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from xlwings import Sheet from xlviews.core.range_collection import RangeCollection from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlwings import Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -16,7 +22,12 @@ (4, 1, "E4"), ], ) -def test_range_collection_row(row, n, address, sheet_module: Sheet): +def test_range_collection_row( + row: int | list[int] | list[tuple[int, int]], + n: int, + address: str, + sheet_module: Sheet, +): rc = RangeCollection(row, 5, sheet_module) assert len(rc) == n a = rc.get_address(row_absolute=False, column_absolute=False) @@ -33,7 +44,12 @@ def test_range_collection_row(row, n, address, sheet_module: Sheet): (4, 1, "$D$5"), ], ) -def test_range_collection_column(column, n, address, sheet_module: Sheet): +def test_range_collection_column( + column: int | list[int] | list[tuple[int, int]], + n: int, + address: str, + sheet_module: Sheet, +): rc = RangeCollection(5, column, sheet_module) assert len(rc) == n assert rc.get_address() == address From 0f50439393167f5c4d1ed25c75c05d0b58503829 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sun, 8 Feb 2026 06:41:42 +0900 Subject: [PATCH 26/40] Use type instead of TypeAlias --- src/xlviews/core/formula.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xlviews/core/formula.py b/src/xlviews/core/formula.py index c93ffe3..dbd1269 100644 --- a/src/xlviews/core/formula.py +++ b/src/xlviews/core/formula.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, TypeAlias +from typing import TYPE_CHECKING, Any from xlwings import Range as RangeImpl @@ -10,7 +10,7 @@ if TYPE_CHECKING: from collections.abc import Iterable -Func: TypeAlias = str | Range | RangeImpl | None +type Func = str | Range | RangeImpl | None NONCONST_VALUE = "*" From f0bf4bd3b1bdcc2ee522455a5194e81a2905abf5 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sun, 8 Feb 2026 06:42:26 +0900 Subject: [PATCH 27/40] fix tests/dataframes --- tests/dataframes/test_colorbar.py | 13 +++++---- tests/dataframes/test_groupby.py | 48 +++++++++++++++++++------------ tests/dataframes/test_style.py | 32 ++++++++++----------- tests/dataframes/test_table.py | 18 ++++++++++-- 4 files changed, 69 insertions(+), 42 deletions(-) diff --git a/tests/dataframes/test_colorbar.py b/tests/dataframes/test_colorbar.py index cc65685..76403de 100644 --- a/tests/dataframes/test_colorbar.py +++ b/tests/dataframes/test_colorbar.py @@ -1,9 +1,16 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from xlwings import Sheet from xlviews.core.range import Range +from xlviews.dataframes.colorbar import Colorbar from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlwings import Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -15,8 +22,6 @@ def rng(sheet_module: Sheet): def test_colorbar_vertical(rng: Range, sheet_module: Sheet): - from xlviews.dataframes.colorbar import Colorbar - cb = Colorbar(2, 5, 6, sheet=sheet_module) cb.set(vmin=rng, vmax=rng, label="T", autofit=True) cb.set_adjacent_column_width(1) @@ -29,8 +34,6 @@ def test_colorbar_vertical(rng: Range, sheet_module: Sheet): def test_colorbar_horizontal(rng: Range, sheet_module: Sheet): - from xlviews.dataframes.colorbar import Colorbar - cb = Colorbar(2, 7, 10, orientation="horizontal", sheet=sheet_module) cb.set(vmin=rng, vmax=rng, label="T", autofit=True) cb.set_adjacent_column_width(1) diff --git a/tests/dataframes/test_groupby.py b/tests/dataframes/test_groupby.py index 0b995c1..85599f0 100644 --- a/tests/dataframes/test_groupby.py +++ b/tests/dataframes/test_groupby.py @@ -1,12 +1,20 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Any + import numpy as np import pytest from pandas import DataFrame, Series -from xlwings import Sheet -from xlviews.dataframes.groupby import GroupBy, to_dict +from xlviews.dataframes.groupby import GroupBy, create_group_index, to_dict from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.testing import is_app_available +if TYPE_CHECKING: + from collections.abc import Callable + + from xlwings import Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -20,29 +28,33 @@ ([None, None], ["a", "b"], {None: ["a", "b"]}), ], ) -def test_to_dict(keys, values, expected): +def test_to_dict( + keys: list[int | str | bool | None], + values: list[str | float], + expected: dict[int | str | bool | None, list[str | float]], +): assert to_dict(keys, values) == expected -@pytest.mark.parametrize("func", [lambda x: x, np.array, Series]) -def test_create_group_index_series(func): - from xlviews.dataframes.groupby import create_group_index +def identity[T](x: T) -> T: + return x + +@pytest.mark.parametrize("func", [identity, np.array, Series]) +def test_create_group_index_series(func: Callable[..., Any]): values = [1, 1, 2, 2, 2, 3, 3, 1, 1, 2, 2, 3, 3] index = create_group_index(func(values)) - assert index[(1,)] == [(0, 1), (7, 8)] - assert index[(2,)] == [(2, 4), (9, 10)] - assert index[(3,)] == [(5, 6), (11, 12)] - + assert index[1,] == [(0, 1), (7, 8)] + assert index[2,] == [(2, 4), (9, 10)] + assert index[3,] == [(5, 6), (11, 12)] -@pytest.mark.parametrize("func", [lambda x: x, DataFrame]) -def test_create_group_index_dataframe(func): - from xlviews.dataframes.groupby import create_group_index +@pytest.mark.parametrize("func", [identity, DataFrame]) +def test_create_group_index_dataframe(func: Callable[..., Any]): values = [[1, 2], [1, 2], [3, 4], [3, 4], [1, 2], [3, 4], [3, 4]] index = create_group_index(func(values)) - assert index[(1, 2)] == [(0, 1), (4, 4)] - assert index[(3, 4)] == [(2, 3), (5, 6)] + assert index[1, 2] == [(0, 1), (4, 4)] + assert index[3, 4] == [(2, 3), (5, 6)] @pytest.fixture(scope="module") @@ -69,7 +81,7 @@ def sf(sheet_module: Sheet): (["a", "b", "c"], 4), ], ) -def test_len(sf: SheetFrame, by, n: int): +def test_len(sf: SheetFrame, by: str | list[str], n: int): gr = GroupBy(sf, by) assert len(gr) == n @@ -104,7 +116,7 @@ def test_iter(gp: GroupBy): (("c", 200), [(5, 7), (10, 12)]), ], ) -def test_getitem(gp: GroupBy, key, value): +def test_getitem(gp: GroupBy, key: tuple[str, int], value: list[tuple[int, int]]): assert gp[key] == value @@ -126,7 +138,7 @@ def sf2(sheet: Sheet): ("by", "n"), [(None, 1), ("x", 2), (["x", "y"], 4), (["x", "y", "z"], 20)], ) -def test_by(sf2: SheetFrame, by, n): +def test_by(sf2: SheetFrame, by: str | list[str] | None, n: int): gp = GroupBy(sf2, by) assert len(gp.group) == n diff --git a/tests/dataframes/test_style.py b/tests/dataframes/test_style.py index 13fb460..360eaec 100644 --- a/tests/dataframes/test_style.py +++ b/tests/dataframes/test_style.py @@ -1,12 +1,26 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest from pandas import DataFrame, MultiIndex -from xlwings import Sheet from xlviews.colors import rgb from xlviews.config import rcParams from xlviews.dataframes.sheet_frame import SheetFrame +from xlviews.dataframes.style import ( + _set_style, + set_frame_style, + set_table_style, + set_wide_column_style, +) from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlwings import Sheet + +# pyright: reportPrivateUsage=false + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -14,9 +28,7 @@ "name", ["index.name", "index", "columns.name", "columns", "values"], ) -def test_set_style(sheet: Sheet, name): - from xlviews.dataframes.style import _set_style - +def test_set_style(sheet: Sheet, name: str): rng = sheet["C3:E5"] _set_style(rng[0], rng[-1], name) param = f"frame.{name}.fill.color" @@ -26,8 +38,6 @@ def test_set_style(sheet: Sheet, name): @pytest.fixture(scope="module") def sf_basic(sheet_module: Sheet): - from xlviews.dataframes.style import set_frame_style - df = DataFrame({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]}) sf = SheetFrame(2, 2, data=df, sheet=sheet_module) set_frame_style(sf) @@ -44,8 +54,6 @@ def test_frame_style_basic(sf_basic: SheetFrame, cell: str, name: str): def test_frame_style_banding_succession(sheet_module: Sheet): - from xlviews.dataframes.style import set_frame_style - df = DataFrame({"x": [1, 1, 2, 2], "a": [1, 2, 3, 4], "b": [5, 6, 7, 8]}) df = df.set_index("x") sf = SheetFrame(2, 6, data=df, sheet=sheet_module) @@ -65,8 +73,6 @@ def df_mc(): @pytest.fixture(scope="module") def sf_mc(sheet_module: Sheet, df_mc: DataFrame): - from xlviews.dataframes.style import set_frame_style - sf = SheetFrame(9, 2, data=df_mc, sheet=sheet_module) set_frame_style(sf) return sf @@ -104,8 +110,6 @@ def df_mic(df_mc: DataFrame): @pytest.fixture(scope="module") def sf_mic(sheet_module: Sheet, df_mic: DataFrame): - from xlviews.dataframes.style import set_frame_style - sf = SheetFrame(9, 7, data=df_mic, sheet=sheet_module) set_frame_style(sf) return sf @@ -133,8 +137,6 @@ def test_frame_style_multi_index_names(sf_mic: SheetFrame, cell: str, name: str) @pytest.fixture(scope="module") def sf_wide(sheet_module: Sheet): - from xlviews.dataframes.style import set_wide_column_style - df = DataFrame({"x": ["i", "j"], "y": ["k", "l"], "a": [1, 2], "b": [3, 4]}) sf = SheetFrame(24, 2, data=df, sheet=sheet_module) sf.add_wide_column("u", range(3), autofit=True) @@ -153,8 +155,6 @@ def test_frame_style_wide(sf_wide: SheetFrame, cell: str, name: str): def test_table_style(sheet_module: Sheet): - from xlviews.dataframes.style import set_table_style - df = DataFrame({"x": [1, 1, 2, 2], "a": [1, 2, 3, 4], "b": [5, 6, 7, 8]}) df = df.set_index("x") sf = SheetFrame(17, 2, data=df, sheet=sheet_module) diff --git a/tests/dataframes/test_table.py b/tests/dataframes/test_table.py index 6a18db5..db2a664 100644 --- a/tests/dataframes/test_table.py +++ b/tests/dataframes/test_table.py @@ -1,11 +1,17 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest from pandas import DataFrame -from xlwings import Range, Sheet from xlviews.core.formula import NONCONST_VALUE from xlviews.dataframes.table import Table from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlwings import Range, Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -61,7 +67,7 @@ def test_add_const_header_clear(table: Table): def test_from_api(table: Table): - api = list(table.cell.sheet.api.ListObjects)[0] + api = next(iter(table.cell.sheet.api.ListObjects)) table2 = Table(api=api, sheet=table.sheet) assert table2.cell.row == table.cell.row assert table2.cell.column == table.cell.column @@ -92,7 +98,13 @@ def test_unlist(df: DataFrame, sheet: Sheet): ], ) @pytest.mark.parametrize("to_dict", [True, False]) -def test_auto_filter(table: Table, name, value, const, to_dict): +def test_auto_filter( + table: Table, + name: str, + value: int | list[int] | tuple[int, int], + const: list[int | str], + to_dict: bool, +): table.add_const_header() if to_dict: From 171e51cfeaf3a63277b1f164e723ba6409a51199 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sun, 8 Feb 2026 06:45:08 +0900 Subject: [PATCH 28/40] Update stub --- typings/xlwings/__init__.pyi | 1 + 1 file changed, 1 insertion(+) diff --git a/typings/xlwings/__init__.pyi b/typings/xlwings/__init__.pyi index e43d23e..d27881f 100644 --- a/typings/xlwings/__init__.pyi +++ b/typings/xlwings/__init__.pyi @@ -78,6 +78,7 @@ class Sheet: @property def charts(self) -> Charts: ... def delete(self) -> None: ... + def activate(self) -> None: ... class Chart: @property From 3cc2e221b9091877d7a41730d9114f2b8a90b4e2 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sun, 8 Feb 2026 07:27:12 +0900 Subject: [PATCH 29/40] fix tests/sheet_frame --- src/xlviews/__init__.py | 2 + src/xlviews/core/formula.py | 5 ++- src/xlviews/core/range_collection.py | 10 +++-- src/xlviews/dataframes/sheet_frame.py | 12 ++---- tests/dataframes/sheet_frame/test_add.py | 12 ++++-- tests/dataframes/sheet_frame/test_common.py | 34 ++++----------- tests/dataframes/sheet_frame/test_index.py | 28 +++++++++---- tests/dataframes/sheet_frame/test_move.py | 8 +++- .../sheet_frame/test_multi_column.py | 18 +++++--- .../sheet_frame/test_multi_index.py | 41 +++++++++++++------ .../sheet_frame/test_multi_index_column.py | 13 ++++-- tests/dataframes/sheet_frame/test_noindex.py | 40 +++++++++--------- tests/dataframes/sheet_frame/test_table.py | 15 +++++-- .../sheet_frame/test_wide_column.py | 11 ++++- 14 files changed, 149 insertions(+), 100 deletions(-) diff --git a/src/xlviews/__init__.py b/src/xlviews/__init__.py index 3f46fac..0e60f5c 100644 --- a/src/xlviews/__init__.py +++ b/src/xlviews/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from xlviews.chart.axes import Axes from xlviews.chart.series import Series from xlviews.core.formula import aggregate diff --git a/src/xlviews/core/formula.py b/src/xlviews/core/formula.py index dbd1269..6a99bce 100644 --- a/src/xlviews/core/formula.py +++ b/src/xlviews/core/formula.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, TypeAlias from xlwings import Range as RangeImpl @@ -10,7 +10,8 @@ if TYPE_CHECKING: from collections.abc import Iterable -type Func = str | Range | RangeImpl | None +# Used for `isinstance` in `sheet_frame.py` +Func: TypeAlias = str | Range | RangeImpl | None # noqa: UP040 NONCONST_VALUE = "*" diff --git a/src/xlviews/core/range_collection.py b/src/xlviews/core/range_collection.py index 2179f95..862183e 100644 --- a/src/xlviews/core/range_collection.py +++ b/src/xlviews/core/range_collection.py @@ -1,11 +1,12 @@ from __future__ import annotations +from collections.abc import Sequence from typing import TYPE_CHECKING, Any from .range import Range, iter_addresses if TYPE_CHECKING: - from collections.abc import Iterator, Sequence + from collections.abc import Iterator from xlwings import Sheet @@ -87,15 +88,16 @@ def _iter_ranges_from_index( column: int | Sequence[int | tuple[int, int]], sheet: Sheet | None = None, ) -> Iterator[Range]: - if isinstance(row, int) and isinstance(column, int): + # row/column may be np.int + if not isinstance(row, Sequence) and not isinstance(column, Sequence): yield Range((row, column), sheet=sheet) - elif isinstance(row, int) and not isinstance(column, int): + elif not isinstance(row, Sequence) and isinstance(column, Sequence): for c in column: start, end = (c, c) if isinstance(c, int) else c yield Range((row, start), (row, end), sheet) - elif isinstance(column, int) and not isinstance(row, int): + elif not isinstance(column, Sequence) and isinstance(row, Sequence): for r in row: start, end = (r, r) if isinstance(r, int) else r yield Range((start, column), (end, column), sheet) diff --git a/src/xlviews/dataframes/sheet_frame.py b/src/xlviews/dataframes/sheet_frame.py index f6326ca..c457956 100644 --- a/src/xlviews/dataframes/sheet_frame.py +++ b/src/xlviews/dataframes/sheet_frame.py @@ -129,17 +129,11 @@ def get_loc(self, column: str) -> int | tuple[int, int]: return self.columns.get_loc(column, self.column + self.index.nlevels) - @overload - def get_indexer(self, columns: list[str] | None) -> list[int]: ... - - @overload - def get_indexer(self, columns: dict[str, Any]) -> NDArray[np.intp]: ... - def get_indexer( self, columns: list[str] | dict[str, Any] | None = None, **kwargs: Any, - ) -> list[int] | NDArray[np.intp]: + ) -> NDArray[np.intp]: if isinstance(columns, dict) or (columns is None and kwargs): return self.columns.get_indexer( columns, @@ -152,10 +146,10 @@ def get_indexer( columns = self.columns.to_list() start = column + self.index.nlevels end = start + len(columns) - return list(range(start, end)) + return np.arange(start, end) cs = [*self.index.names, *self.columns] - return [cs.index(c) + column for c in columns] + return np.array([cs.index(c) + column for c in columns]) @overload def get_range( diff --git a/tests/dataframes/sheet_frame/test_add.py b/tests/dataframes/sheet_frame/test_add.py index 22fb6c8..3528ef2 100644 --- a/tests/dataframes/sheet_frame/test_add.py +++ b/tests/dataframes/sheet_frame/test_add.py @@ -1,10 +1,16 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest from pandas import DataFrame -from xlwings import Sheet from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlwings import Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -26,7 +32,7 @@ def test_add_column_value(sheet: Sheet): ("formula", "value"), [("={a}+{b}", [6, 8, 10, 12]), ("={a}*{b}", [5, 12, 21, 32])], ) -def test_add_formula_column(formula, value, sheet: Sheet): +def test_add_formula_column(formula: str, value: list[int], sheet: Sheet): df = DataFrame({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]}) sf = SheetFrame(2, 3, data=df, sheet=sheet) sf.add_formula_column("c", formula) @@ -43,7 +49,7 @@ def test_add_formula_column(formula, value, sheet: Sheet): ("={a}*{b}*{c}", ([5, 12, 21, 32], [20, 48, 84, 128])), ], ) -def test_formula_wide(formula, value, sheet: Sheet): +def test_formula_wide(formula: str, value: tuple[list[int], list[int]], sheet: Sheet): df = DataFrame({"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]}) sf = SheetFrame(10, 3, data=df, sheet=sheet) sf.add_wide_column("c", [1, 2, 3, 4], number_format="0", style=True) diff --git a/tests/dataframes/sheet_frame/test_common.py b/tests/dataframes/sheet_frame/test_common.py index 7994012..c649a14 100644 --- a/tests/dataframes/sheet_frame/test_common.py +++ b/tests/dataframes/sheet_frame/test_common.py @@ -1,10 +1,16 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest from pandas import DataFrame -from xlwings import Sheet from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlwings import Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -40,32 +46,6 @@ def test_adjacent_column_width(sf: SheetFrame): assert sf.sheet["F1"].column_width == 10 -# def test_child_frame(sf: SheetFrame): -# cell = sf.get_child_cell() -# assert cell.get_address() == "$G$3" - -# cell = sf.get_adjacent_cell(offset=3) -# assert cell.get_address() == "$J$3" - -# df = DataFrame({"x": [1, 2], "y": [5, 6], "z": [7, 8]}) -# sf_child = SheetFrame(parent=sf, data=df) -# assert sf_child.cell.get_address() == "$G$3" - -# assert sf_child.parent is sf -# assert sf.children[0] is sf_child - -# cell = sf.get_adjacent_cell() -# assert cell.get_address() == "$L$3" - - -# def test_head_frame(sf: SheetFrame): -# df = DataFrame({"x": [1, 2], "y": [5, 6], "z": [7, 8]}) -# sf_tail = SheetFrame(head=sf, data=df) -# assert sf_tail.cell.get_address() == "$C$9" -# assert sf.tail is sf_tail -# assert sf_tail.head is sf - - def test_active_sheet(sheet: Sheet): sheet.name = "active" sheet.activate() diff --git a/tests/dataframes/sheet_frame/test_index.py b/tests/dataframes/sheet_frame/test_index.py index 4661930..01c9e5f 100644 --- a/tests/dataframes/sheet_frame/test_index.py +++ b/tests/dataframes/sheet_frame/test_index.py @@ -1,11 +1,18 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Literal + import pytest -from pandas import DataFrame -from xlwings import Sheet -from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.testing import FrameContainer, is_app_available from xlviews.testing.sheet_frame.base import Index +if TYPE_CHECKING: + from pandas import DataFrame + from xlwings import Sheet + + from xlviews.dataframes.sheet_frame import SheetFrame + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -44,7 +51,7 @@ def test_index_names(sf: SheetFrame): @pytest.mark.parametrize(("x", "b"), [("name", False), ("a", True)]) -def test_contains(sf: SheetFrame, x, b): +def test_contains(sf: SheetFrame, x: str, b: bool): assert (x in sf) is b @@ -60,13 +67,13 @@ def test_value(sf: SheetFrame, df: DataFrame): @pytest.mark.parametrize(("column", "index"), [("name", 2), ("a", 3), ("b", 4)]) -def test_loc(sf: SheetFrame, column, index): +def test_loc(sf: SheetFrame, column: str, index: int): assert sf.get_loc(column) == index @pytest.mark.parametrize(("column", "index"), [(["name", "b"], [2, 4])]) -def test_indexer(sf: SheetFrame, column, index): - assert sf.get_indexer(column) == index +def test_indexer(sf: SheetFrame, column: list[str], index: list[int]): + assert sf.get_indexer(column).tolist() == index @pytest.mark.parametrize( @@ -79,7 +86,12 @@ def test_indexer(sf: SheetFrame, column, index): ("a", None, "$C$9:$C$12"), ], ) -def test_get_range(sf: SheetFrame, column: str, offset, address): +def test_get_range( + sf: SheetFrame, + column: str, + offset: Literal[0, -1] | None, + address: str, +): assert sf.get_range(column, offset).get_address() == address diff --git a/tests/dataframes/sheet_frame/test_move.py b/tests/dataframes/sheet_frame/test_move.py index 8cdbc1c..eec2343 100644 --- a/tests/dataframes/sheet_frame/test_move.py +++ b/tests/dataframes/sheet_frame/test_move.py @@ -1,10 +1,16 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest from pandas import DataFrame -from xlwings import Sheet from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlwings import Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") diff --git a/tests/dataframes/sheet_frame/test_multi_column.py b/tests/dataframes/sheet_frame/test_multi_column.py index 34076f5..643cfcb 100644 --- a/tests/dataframes/sheet_frame/test_multi_column.py +++ b/tests/dataframes/sheet_frame/test_multi_column.py @@ -1,13 +1,19 @@ +from __future__ import annotations + import string +from typing import TYPE_CHECKING, Any import pytest from pandas import DataFrame -from xlwings import Sheet -from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.testing import FrameContainer, is_app_available from xlviews.testing.sheet_frame.base import MultiColumn +if TYPE_CHECKING: + from xlwings import Sheet + + from xlviews.dataframes.sheet_frame import SheetFrame + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -66,9 +72,9 @@ def test_value(sf: SheetFrame, df: DataFrame): ({"t": "c", "i": "x"}, [12, 14, 20, 22]), ], ) -def test_get_indexer(sf: SheetFrame, columns, indexer): - assert all(sf.get_indexer(columns) == indexer) - assert all(sf.get_indexer(**columns) == indexer) +def test_get_indexer(sf: SheetFrame, columns: dict[str, Any], indexer: list[int]): + assert sf.get_indexer(columns).tolist() == indexer + assert sf.get_indexer(**columns).tolist() == indexer def test_iter_ranges(sf: SheetFrame): @@ -101,7 +107,7 @@ def test_melt_columns(df_melt: DataFrame): (15, ["b", "d", 8, "y", "=$AA$6:$AA$11"]), ], ) -def test_melt_value(df_melt: DataFrame, i, v): +def test_melt_value(df_melt: DataFrame, i: int, v: list[str | int]): assert df_melt.iloc[i].to_list() == v diff --git a/tests/dataframes/sheet_frame/test_multi_index.py b/tests/dataframes/sheet_frame/test_multi_index.py index d4b1177..fbea9df 100644 --- a/tests/dataframes/sheet_frame/test_multi_index.py +++ b/tests/dataframes/sheet_frame/test_multi_index.py @@ -1,12 +1,19 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Literal + import pytest -from pandas import DataFrame -from xlwings import Sheet from xlviews.dataframes.groupby import groupby -from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.testing import FrameContainer, is_app_available from xlviews.testing.sheet_frame.base import MultiIndex +if TYPE_CHECKING: + from pandas import DataFrame + from xlwings import Sheet + + from xlviews.dataframes.sheet_frame import SheetFrame + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -42,7 +49,7 @@ def test_index_names(sf: SheetFrame): @pytest.mark.parametrize(("x", "b"), [("x", False), ("b", True)]) -def test_contains(sf: SheetFrame, x, b): +def test_contains(sf: SheetFrame, x: str, b: bool): assert (x in sf) is b @@ -67,7 +74,12 @@ def test_value(sf: SheetFrame, df: DataFrame): ("y", None, "$G$3:$G$10"), ], ) -def test_get_range(sf: SheetFrame, column, offset, address): +def test_get_range( + sf: SheetFrame, + column: str, + offset: Literal[0, -1] | None, + address: str, +): assert sf.get_range(column, offset).get_address() == address @@ -78,20 +90,25 @@ def test_get_range(sf: SheetFrame, column, offset, address): ("y", [(3, 4), (7, 8)], [(5, 6), (9, 10)]), ], ) -def test_groupby(sf: SheetFrame, by, v1, v2): +def test_groupby( + sf: SheetFrame, + by: str, + v1: list[tuple[int, int]], + v2: list[tuple[int, int]], +): g = groupby(sf, by) assert len(g) == 2 - assert g[(1,)] == v1 - assert g[(2,)] == v2 + assert g[1,] == v1 + assert g[2,] == v2 def test_groupby_list(sf: SheetFrame): g = groupby(sf, ["x", "y"]) assert len(g) == 4 - assert g[(1, 1)] == [(3, 4)] - assert g[(1, 2)] == [(5, 6)] - assert g[(2, 1)] == [(7, 8)] - assert g[(2, 2)] == [(9, 10)] + assert g[1, 1] == [(3, 4)] + assert g[1, 2] == [(5, 6)] + assert g[2, 1] == [(7, 8)] + assert g[2, 2] == [(9, 10)] def test_get_address(sf: SheetFrame): diff --git a/tests/dataframes/sheet_frame/test_multi_index_column.py b/tests/dataframes/sheet_frame/test_multi_index_column.py index 55b4338..97b2f70 100644 --- a/tests/dataframes/sheet_frame/test_multi_index_column.py +++ b/tests/dataframes/sheet_frame/test_multi_index_column.py @@ -1,11 +1,18 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from pandas import DataFrame -from xlwings import Sheet -from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.testing import FrameContainer, is_app_available from xlviews.testing.sheet_frame.base import MultiIndexColumn +if TYPE_CHECKING: + from pandas import DataFrame + from xlwings import Sheet + + from xlviews.dataframes.sheet_frame import SheetFrame + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") diff --git a/tests/dataframes/sheet_frame/test_noindex.py b/tests/dataframes/sheet_frame/test_noindex.py index 858a416..5e251c1 100644 --- a/tests/dataframes/sheet_frame/test_noindex.py +++ b/tests/dataframes/sheet_frame/test_noindex.py @@ -1,12 +1,19 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Literal + import pytest from pandas import DataFrame, Series -from xlwings import App, Sheet from xlviews.core.range import Range -from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.testing import FrameContainer, is_app_available from xlviews.testing.sheet_frame.base import NoIndex +if TYPE_CHECKING: + from xlwings import App, Sheet + + from xlviews.dataframes.sheet_frame import SheetFrame + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -45,7 +52,7 @@ def test_len(sf: SheetFrame): @pytest.mark.parametrize(("x", "b"), [("a", True), ("x", False), (0, False)]) -def test_contains(sf: SheetFrame, x, b): +def test_contains(sf: SheetFrame, x: str, b: bool): assert (x in sf) is b @@ -61,7 +68,7 @@ def test_value(sf: SheetFrame, df: DataFrame): @pytest.mark.parametrize(("column", "loc"), [("a", 3), ("b", 4)]) -def test_loc(sf: SheetFrame, column, loc): +def test_loc(sf: SheetFrame, column: str, loc: int): assert sf.get_loc(column) == loc @@ -69,8 +76,8 @@ def test_loc(sf: SheetFrame, column, loc): ("columns", "indexer"), [(["a"], [3]), (["b"], [4]), (None, [3, 4])], ) -def test_get_indexer(sf: SheetFrame, columns, indexer): - assert sf.get_indexer(columns) == indexer +def test_get_indexer(sf: SheetFrame, columns: list[str] | None, indexer: list[int]): + assert sf.get_indexer(columns).tolist() == indexer @pytest.mark.parametrize( @@ -82,32 +89,27 @@ def test_get_indexer(sf: SheetFrame, columns, indexer): ("a", None, "$C$3:$C$6"), ], ) -def test_get_range(sf: SheetFrame, column: str, offset, address): +def test_get_range( + sf: SheetFrame, + column: str, + offset: Literal[0, -1] | None, + address: str, +): assert sf.get_range(column, offset).get_address() == address -def test_get_range_error(sf: SheetFrame): - with pytest.raises(ValueError, match="invalid offset"): - sf.get_range(None, offset=1) # type: ignore - - @pytest.mark.parametrize( ("axis", "v0", "v1"), [(0, [1, 2, 3, 4], [5, 6, 7, 8]), (1, [1, 5], [2, 6])], ) -def test_iter_ranges(sf: SheetFrame, axis, v0, v1): +def test_iter_ranges(sf: SheetFrame, axis: Literal[0, 1], v0: list[int], v1: list[int]): values = list(sf.iter_ranges(axis)) assert values[0].value == v0 assert values[1].value == v1 -def test_iter_ranges_error(sf: SheetFrame): - with pytest.raises(ValueError, match="axis must be 0 or 1"): - list(sf.iter_ranges(axis=2)) # type: ignore - - @pytest.mark.parametrize("columns", [["a", "b"], None]) -def test_get_address_none(sf: SheetFrame, columns): +def test_get_address_none(sf: SheetFrame, columns: list[str] | None): df = sf.get_address(columns) assert df.columns.to_list() == ["a", "b"] assert df.index.to_list() == [0, 1, 2, 3] diff --git a/tests/dataframes/sheet_frame/test_table.py b/tests/dataframes/sheet_frame/test_table.py index 68be888..bbd3edd 100644 --- a/tests/dataframes/sheet_frame/test_table.py +++ b/tests/dataframes/sheet_frame/test_table.py @@ -1,11 +1,18 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from xlwings import Sheet -from xlviews.dataframes.sheet_frame import SheetFrame -from xlviews.dataframes.table import Table from xlviews.testing import FrameContainer, is_app_available from xlviews.testing.sheet_frame.base import Index +if TYPE_CHECKING: + from xlwings import Sheet + + from xlviews.dataframes.sheet_frame import SheetFrame + from xlviews.dataframes.table import Table + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -31,7 +38,7 @@ def table(sf: SheetFrame): @pytest.mark.parametrize("value", ["x", "y"]) -def test_table(table: Table, value): +def test_table(table: Table, value: str): table.auto_filter("name", value) header = table.const_header.value assert isinstance(header, list) diff --git a/tests/dataframes/sheet_frame/test_wide_column.py b/tests/dataframes/sheet_frame/test_wide_column.py index 971b49e..1409e01 100644 --- a/tests/dataframes/sheet_frame/test_wide_column.py +++ b/tests/dataframes/sheet_frame/test_wide_column.py @@ -1,10 +1,17 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from xlwings import Sheet -from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.testing import FrameContainer, is_app_available from xlviews.testing.sheet_frame.base import WideColumn +if TYPE_CHECKING: + from xlwings import Sheet + + from xlviews.dataframes.sheet_frame import SheetFrame + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") From 2bf79232f35dedfc270aab345e24138cc3d1dd90 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sun, 8 Feb 2026 07:38:49 +0900 Subject: [PATCH 30/40] fix tests/stats_frame --- tests/dataframes/stats_frame/conftest.py | 11 +++++-- .../dataframes/stats_frame/test_funcs_list.py | 12 +++++-- .../dataframes/stats_frame/test_funcs_str.py | 10 ++++-- tests/dataframes/stats_frame/test_group.py | 18 +++++------ tests/dataframes/stats_frame/test_style.py | 20 +++++++++--- tests/dataframes/stats_frame/test_utils.py | 31 +++++++------------ 6 files changed, 61 insertions(+), 41 deletions(-) diff --git a/tests/dataframes/stats_frame/conftest.py b/tests/dataframes/stats_frame/conftest.py index dffb76d..5f2b751 100644 --- a/tests/dataframes/stats_frame/conftest.py +++ b/tests/dataframes/stats_frame/conftest.py @@ -1,9 +1,16 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from xlwings import Sheet -from xlviews.testing import FrameContainer from xlviews.testing.stats_frame import Parent +if TYPE_CHECKING: + from xlwings import Sheet + + from xlviews.testing import FrameContainer + @pytest.fixture(scope="module") def fc(sheet_module: Sheet): diff --git a/tests/dataframes/stats_frame/test_funcs_list.py b/tests/dataframes/stats_frame/test_funcs_list.py index 38b85bd..8ac2d48 100644 --- a/tests/dataframes/stats_frame/test_funcs_list.py +++ b/tests/dataframes/stats_frame/test_funcs_list.py @@ -1,11 +1,17 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import numpy as np import pytest from pandas import DataFrame -from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.dataframes.stats_frame import StatsFrame from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlviews.dataframes.sheet_frame import SheetFrame + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -45,7 +51,7 @@ def test_index_names(sf: StatsFrame): ("median", "c", [18, 30, 2, 7]), ], ) -def test_value_float(df: DataFrame, func, column, value): +def test_value_float(df: DataFrame, func: str, column: str, value: list[float]): np.testing.assert_allclose(df.loc[func][column], value) @@ -57,6 +63,6 @@ def test_value_float(df: DataFrame, func, column, value): ("c", [[20, 22, 24, 12, 14, 16, 18], [28, 30, 34]]), ], ) -def test_value_soa(df: DataFrame, column, value): +def test_value_soa(df: DataFrame, column: str, value: list[list[int]]): soa = [np.std(x) / np.median(x) for x in value] np.testing.assert_allclose(df.loc["soa"][column][:2], soa) diff --git a/tests/dataframes/stats_frame/test_funcs_str.py b/tests/dataframes/stats_frame/test_funcs_str.py index e803dad..c559313 100644 --- a/tests/dataframes/stats_frame/test_funcs_str.py +++ b/tests/dataframes/stats_frame/test_funcs_str.py @@ -1,9 +1,15 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.dataframes.stats_frame import StatsFrame from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlviews.dataframes.sheet_frame import SheetFrame + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -31,5 +37,5 @@ def test_index_names(sf: SheetFrame): ("H3:H5", ["c", 10, 7]), ], ) -def test_value(sf: SheetFrame, cell, value): +def test_value(sf: SheetFrame, cell: str, value: list[str | int | None]): assert sf.sheet[cell].value == value diff --git a/tests/dataframes/stats_frame/test_group.py b/tests/dataframes/stats_frame/test_group.py index 1b46e2a..fb1562d 100644 --- a/tests/dataframes/stats_frame/test_group.py +++ b/tests/dataframes/stats_frame/test_group.py @@ -1,9 +1,16 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest from xlviews.dataframes.groupby import GroupBy -from xlviews.dataframes.sheet_frame import SheetFrame +from xlviews.dataframes.stats_frame import get_by, get_frame from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlviews.dataframes.sheet_frame import SheetFrame + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -16,22 +23,17 @@ def gr(sf_parent: SheetFrame): ("funcs", "shape"), [(["mean"], (4, 3)), (["min", "max"], (8, 3))], ) -def test_get_frame_shape(gr: GroupBy, funcs, shape): - from xlviews.dataframes.stats_frame import get_frame +def test_get_frame_shape(gr: GroupBy, funcs: list[str], shape: tuple[int, int]): assert get_frame(gr, funcs).shape == shape def test_get_frame_index_list(gr: GroupBy): - from xlviews.dataframes.stats_frame import get_frame - df = get_frame(gr, ["mean"]) assert df.index.names == ["func", "x", "y", "z"] def test_get_frame_offset(gr: GroupBy): - from xlviews.dataframes.stats_frame import get_frame - df = get_frame(gr, ["mean"]).reset_index() assert df["x"].iloc[0] == "=$C$4" assert df["y"].iloc[-1] == "=$D$16" @@ -40,6 +42,4 @@ def test_get_frame_offset(gr: GroupBy): def test_get_by_none(sf_parent: SheetFrame): - from xlviews.dataframes.stats_frame import get_by - assert get_by(sf_parent, None) == ["x", "y", "z"] diff --git a/tests/dataframes/stats_frame/test_style.py b/tests/dataframes/stats_frame/test_style.py index 2534765..4c4f3f7 100644 --- a/tests/dataframes/stats_frame/test_style.py +++ b/tests/dataframes/stats_frame/test_style.py @@ -1,11 +1,21 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import numpy as np import pytest from xlviews.colors import rgb -from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.dataframes.stats_frame import StatsFrame from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlviews.dataframes.sheet_frame import SheetFrame + +# pyright: reportAttributeAccessIssue=false +# pyright: reportUnknownArgumentType=false +# pyright: reportUnknownMemberType=false + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -39,7 +49,7 @@ def test_func(sf: StatsFrame, funcs: list[str]): ) @pytest.mark.parametrize("c", ["func", "c"]) @pytest.mark.parametrize("o", [0, 8]) -def test_color(sf: StatsFrame, funcs: list[str], func: str, color, c, o): +def test_color(sf: StatsFrame, funcs: list[str], func: str, color: str, c: str, o: int): row = funcs.index(func) + sf.row + o + 1 column = sf.get_loc(c) rng = sf.sheet.range(row, column) @@ -49,7 +59,7 @@ def test_color(sf: StatsFrame, funcs: list[str], func: str, color, c, o): @pytest.mark.parametrize("func", ["soa", "sum"]) @pytest.mark.parametrize("c", ["func", "a"]) @pytest.mark.parametrize("o", [16, 24]) -def test_italic(sf: StatsFrame, funcs: list[str], func: str, c, o): +def test_italic(sf: StatsFrame, funcs: list[str], func: str, c: str, o: int): row = funcs.index(func) + sf.row + o + 1 column = sf.get_loc(c) rng = sf.sheet.range(row, column) @@ -57,7 +67,7 @@ def test_italic(sf: StatsFrame, funcs: list[str], func: str, c, o): @pytest.mark.parametrize("c", ["a", "b"]) -def test_soa(sf: StatsFrame, funcs: list[str], c): +def test_soa(sf: StatsFrame, funcs: list[str], c: str): row = funcs.index("soa") + sf.row + 1 column = sf.get_loc(c) rng = sf.sheet.range(row, column) @@ -66,7 +76,7 @@ def test_soa(sf: StatsFrame, funcs: list[str], c): @pytest.mark.parametrize("func", ["median", "min", "mean", "max", "std", "sum"]) @pytest.mark.parametrize("o", [0, 16]) -def test_number_format(sf: StatsFrame, funcs: list[str], func, o): +def test_number_format(sf: StatsFrame, funcs: list[str], func: str, o: int): row = funcs.index(func) + sf.row + o + 1 column = sf.get_loc("c") rng = sf.sheet.range(row, column) diff --git a/tests/dataframes/stats_frame/test_utils.py b/tests/dataframes/stats_frame/test_utils.py index 9293f2b..6964472 100644 --- a/tests/dataframes/stats_frame/test_utils.py +++ b/tests/dataframes/stats_frame/test_utils.py @@ -1,28 +1,29 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest from pandas import DataFrame -from xlwings import Sheet from xlviews.dataframes.sheet_frame import SheetFrame +from xlviews.dataframes.stats_frame import get_func, get_length, has_header, move_down from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlwings import Sheet -def test_func_none(): - from xlviews.dataframes.stats_frame import get_func +def test_func_none(): func = ["count", "max", "mean", "median", "min", "soa"] assert sorted(get_func(None)) == func def test_func_str(): - from xlviews.dataframes.stats_frame import get_func - assert get_func("count") == ["count"] -@pytest.mark.parametrize("func", [["count"], {"a": "count"}]) -def test_func_else(func): - from xlviews.dataframes.stats_frame import get_func - +@pytest.mark.parametrize("func", [["count"]]) +def test_func_else(func: list[str]): assert get_func(func) == func @@ -31,30 +32,22 @@ def test_func_else(func): ("funcs", "n"), [(["mean"], 4), (["min", "max", "median"], 12)], ) -def test_length(sf_parent: SheetFrame, funcs, n): - from xlviews.dataframes.stats_frame import get_length - +def test_length(sf_parent: SheetFrame, funcs: list[str], n: int): assert get_length(sf_parent, ["x", "y"], funcs) == n @pytest.mark.skipif(not is_app_available(), reason="Excel not installed") def test_length_none_list(sf_parent: SheetFrame): - from xlviews.dataframes.stats_frame import get_length - assert get_length(sf_parent, [], ["min", "max"]) == 2 @pytest.mark.skipif(not is_app_available(), reason="Excel not installed") def test_has_header(sf_parent: SheetFrame): - from xlviews.dataframes.stats_frame import has_header - assert has_header(sf_parent) @pytest.mark.skipif(not is_app_available(), reason="Excel not installed") def test_move_down(sheet: Sheet): - from xlviews.dataframes.stats_frame import move_down - df = DataFrame([[1, 2, 3], [4, 5, 6]], columns=["a", "b", "c"]) sf = SheetFrame(3, 3, data=df, sheet=sheet) assert sheet["D3:F3"].value == ["a", "b", "c"] @@ -67,8 +60,6 @@ def test_move_down(sheet: Sheet): @pytest.mark.skipif(not is_app_available(), reason="Excel not installed") def test_move_down_header(sheet: Sheet): - from xlviews.dataframes.stats_frame import move_down - df = DataFrame([[1, 2, 3], [4, 5, 6]], columns=["a", "b", "c"]) sf = SheetFrame(3, 3, data=df, sheet=sheet) sheet["D2"].value = "x" From 93e2c986b5c88f469570ff871d5eb8189cdff17b Mon Sep 17 00:00:00 2001 From: Daizu Date: Sun, 8 Feb 2026 07:43:50 +0900 Subject: [PATCH 31/40] fix tests/dist_frame --- tests/dataframes/dist_frame/conftest.py | 13 ++++++++--- tests/dataframes/dist_frame/test_columns.py | 10 ++++++-- tests/dataframes/dist_frame/test_dist_func.py | 9 ++++---- tests/dataframes/dist_frame/test_frame.py | 23 ++++++++----------- tests/dataframes/dist_frame/test_sigma.py | 16 ++++++++----- 5 files changed, 42 insertions(+), 29 deletions(-) diff --git a/tests/dataframes/dist_frame/conftest.py b/tests/dataframes/dist_frame/conftest.py index 1022a47..bad75fd 100644 --- a/tests/dataframes/dist_frame/conftest.py +++ b/tests/dataframes/dist_frame/conftest.py @@ -1,12 +1,19 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest from pandas import DataFrame -from xlwings import Sheet from xlviews.dataframes.dist_frame import DistFrame -from xlviews.dataframes.sheet_frame import SheetFrame -from xlviews.testing import FrameContainer from xlviews.testing.dist_frame import Parent +if TYPE_CHECKING: + from xlwings import Sheet + + from xlviews.dataframes.sheet_frame import SheetFrame + from xlviews.testing import FrameContainer + @pytest.fixture(scope="module") def fc(sheet_module: Sheet): diff --git a/tests/dataframes/dist_frame/test_columns.py b/tests/dataframes/dist_frame/test_columns.py index 269846d..3b895bd 100644 --- a/tests/dataframes/dist_frame/test_columns.py +++ b/tests/dataframes/dist_frame/test_columns.py @@ -1,12 +1,18 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest from pandas import DataFrame -from xlwings import Sheet from xlviews.dataframes.dist_frame import DistFrame from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.testing import is_app_available from xlviews.testing.dist_frame import Parent +if TYPE_CHECKING: + from xlwings import Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -18,7 +24,7 @@ ("b", ["b_n", "b_v", "b_s"]), ], ) -def test_columns(columns, values, sheet: Sheet): +def test_columns(columns: str | None, values: list[str], sheet: Sheet): fc = Parent(sheet, 3, 2) sf = DistFrame(fc.sf, columns, by=["x", "y"]) assert sf.columns.to_list() == values diff --git a/tests/dataframes/dist_frame/test_dist_func.py b/tests/dataframes/dist_frame/test_dist_func.py index 05b96cf..26a064f 100644 --- a/tests/dataframes/dist_frame/test_dist_func.py +++ b/tests/dataframes/dist_frame/test_dist_func.py @@ -1,12 +1,13 @@ -def test_dist_func_str(): - from xlviews.dataframes.dist_frame import get_dist_func +from __future__ import annotations + +from xlviews.dataframes.dist_frame import get_dist_func + +def test_dist_func_str(): df = get_dist_func("norm", ["a", "b"]) assert df == {"a": "norm", "b": "norm"} def test_dist_func_dict(): - from xlviews.dataframes.dist_frame import get_dist_func - df = get_dist_func({"a": "none"}, ["a", "b"]) assert df == {"a": "none", "b": "norm"} diff --git a/tests/dataframes/dist_frame/test_frame.py b/tests/dataframes/dist_frame/test_frame.py index 1700ae6..8a367df 100644 --- a/tests/dataframes/dist_frame/test_frame.py +++ b/tests/dataframes/dist_frame/test_frame.py @@ -1,34 +1,35 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import numpy as np import pytest from pandas import Index, MultiIndex from scipy.stats import norm -from xlviews.dataframes.dist_frame import DistFrame -from xlviews.dataframes.sheet_frame import SheetFrame +from xlviews.dataframes.dist_frame import get_init_data, select_index from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlviews.dataframes.dist_frame import DistFrame + from xlviews.dataframes.sheet_frame import SheetFrame + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") def test_select_index(): - from xlviews.dataframes.dist_frame import select_index - index = Index(["a", "b"], name="x") x = select_index(index, ["x"]) assert x.equals(index) def test_select_index_none(): - from xlviews.dataframes.dist_frame import select_index - index = Index(["a", "b"], name="x") x = select_index(index, ["y"]) assert x.equals(Index([0, 1])) def test_select_index_multi_one(): - from xlviews.dataframes.dist_frame import select_index - index = MultiIndex.from_tuples([(1, 2), (3, 4)], names=["x", "y"]) x = select_index(index, ["x"]) assert isinstance(x, Index) @@ -38,8 +39,6 @@ def test_select_index_multi_one(): def test_select_index_multi_two(): - from xlviews.dataframes.dist_frame import select_index - index = MultiIndex.from_tuples([(1, 2), (3, 4)], names=["x", "y"]) x = select_index(index, ["x", "y"]) assert isinstance(x, MultiIndex) @@ -47,16 +46,12 @@ def test_select_index_multi_two(): def test_select_index_multi_none(): - from xlviews.dataframes.dist_frame import select_index - index = MultiIndex.from_tuples([(1, 2), (3, 4)], names=["x", "y"]) x = select_index(index, []) assert x.equals(Index([0, 1])) def test_init_data(sf_parent: SheetFrame): - from xlviews.dataframes.dist_frame import get_init_data - df = get_init_data(sf_parent.index, ["a", "b"]) c = ["a_n", "a_v", "a_s", "b_n", "b_v", "b_s"] assert df.columns.to_list() == c diff --git a/tests/dataframes/dist_frame/test_sigma.py b/tests/dataframes/dist_frame/test_sigma.py index 5b3a959..bb60847 100644 --- a/tests/dataframes/dist_frame/test_sigma.py +++ b/tests/dataframes/dist_frame/test_sigma.py @@ -1,11 +1,19 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import numpy as np import pytest from scipy.stats import norm -from xlwings import Sheet from xlviews.core.range import Range +from xlviews.dataframes.dist_frame import set_formula, sigma_value from xlviews.testing import is_app_available +if TYPE_CHECKING: + from numpy.typing import NDArray + from xlwings import Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -16,8 +24,6 @@ def dist(request: pytest.FixtureRequest): @pytest.fixture def value(sheet_module: Sheet, dist: str): - from xlviews.dataframes.dist_frame import set_formula, sigma_value - rng = Range((1, 1), (10, 1), sheet_module) rng.value = [[x] for x in range(1, 11)] cell = rng[0] @@ -34,12 +40,10 @@ def expected(dist: str): return np.log(-np.log(1 - np.arange(1, 11) / 11)) -def test_sigma_value(value, expected): +def test_sigma_value(value: list[float], expected: NDArray[np.float64]): np.testing.assert_allclose(value, expected) def test_sigma_value_error(sheet_module: Sheet): - from xlviews.dataframes.dist_frame import sigma_value - with pytest.raises(ValueError, match="unknown distribution"): sigma_value(Range((1, 1), (1, 1), sheet_module), 10, "unknown") From 8bc8277584ea2bf8ce17fd96f4a349488915168b Mon Sep 17 00:00:00 2001 From: Daizu Date: Sun, 8 Feb 2026 07:54:26 +0900 Subject: [PATCH 32/40] fix tests/agg --- src/xlviews/dataframes/sheet_frame.py | 9 +++--- tests/dataframes/agg/test_multi_index.py | 36 +++++++++++++++++------- tests/dataframes/agg/test_wide_column.py | 13 ++++++--- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/xlviews/dataframes/sheet_frame.py b/src/xlviews/dataframes/sheet_frame.py index c457956..d2f8044 100644 --- a/src/xlviews/dataframes/sheet_frame.py +++ b/src/xlviews/dataframes/sheet_frame.py @@ -3,6 +3,7 @@ from __future__ import annotations import re +from collections.abc import Mapping from functools import partial from typing import TYPE_CHECKING, Any, Literal, Self, overload @@ -387,7 +388,7 @@ def get_address( @overload def agg( self, - func: Func | dict[str, str] = None, + func: Func | Mapping[str, str | None] = None, columns: str | list[str] | None = None, row_absolute: bool = True, column_absolute: bool = True, @@ -410,7 +411,7 @@ def agg( def agg( self, - func: Func | dict[str, str] | Sequence[Func] = None, + func: Func | Mapping[str, str | None] | Sequence[Func] = None, columns: str | list[str] | None = None, row_absolute: bool = True, column_absolute: bool = True, @@ -431,7 +432,7 @@ def agg( raise NotImplementedError - if isinstance(func, dict): + if isinstance(func, Mapping): columns = list(func.keys()) elif isinstance(columns, str): columns = [columns] @@ -458,7 +459,7 @@ def agg( formula=formula, ) - if isinstance(func, dict): + if isinstance(func, Mapping): it = zip(rngs, func.values(), strict=True) return Series([agg(f, r) for r, f in it], index=columns) diff --git a/tests/dataframes/agg/test_multi_index.py b/tests/dataframes/agg/test_multi_index.py index 4747b24..da6bb02 100644 --- a/tests/dataframes/agg/test_multi_index.py +++ b/tests/dataframes/agg/test_multi_index.py @@ -1,14 +1,19 @@ +from __future__ import annotations + from importlib.metadata import version +from typing import TYPE_CHECKING import numpy as np import pytest from pandas import DataFrame, Index, MultiIndex, Series -from xlwings import Sheet from xlviews.core.range import Range from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlwings import Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -114,9 +119,8 @@ def test_sf_dict(sf: SheetFrame, df: DataFrame): def test_sf_list(sf: SheetFrame, df: DataFrame): - func = ["min", "max"] - a = sf.agg(func, formula=True) - b = df.agg(func) # type: ignore + a = sf.agg(["min", "max"], formula=True) + b = df.agg(["min", "max"]) assert isinstance(a, DataFrame) assert a.index.to_list() == b.index.to_list() assert a.columns.to_list() == b.columns.to_list() @@ -125,6 +129,7 @@ def test_sf_list(sf: SheetFrame, df: DataFrame): def test_sf_list_columns(sf: SheetFrame, df: DataFrame): + assert isinstance(df, DataFrame) a = sf.agg(["sum", "count"], columns="b", formula=True) assert isinstance(a, DataFrame) sf = SheetFrame(20, 2, data=a, sheet=sf.sheet) @@ -230,7 +235,7 @@ def test_index_list_as_address(sf: SheetFrame): @pytest.mark.parametrize("func", ["sum", "median", "mean"]) @pytest.mark.parametrize("by", ["x", "y"]) -def test_sf_group_str_str(sf: SheetFrame, df: DataFrame, func, by): +def test_sf_group_str_str(sf: SheetFrame, df: DataFrame, func: str, by: str): a = sf.groupby(by).agg(func, as_address=True, formula=True) b = df.groupby(by).agg(func).astype(float) sf = SheetFrame(50, 2, data=a, sheet=sf.sheet) @@ -242,7 +247,7 @@ def test_sf_group_str_str(sf: SheetFrame, df: DataFrame, func, by): @pytest.mark.parametrize("func", ["sum", "median", "mean"]) @pytest.mark.parametrize("by", ["x", "y"]) -def test_sf_group_str_range(sf: SheetFrame, df: DataFrame, func, by): +def test_sf_group_str_range(sf: SheetFrame, df: DataFrame, func: str, by: str): rng = Range((50, 1), sheet=sf.sheet) rng.value = func a = sf.groupby(by).agg(rng, as_address=True, formula=True) @@ -256,7 +261,7 @@ def test_sf_group_str_range(sf: SheetFrame, df: DataFrame, func, by): @pytest.mark.parametrize("func", ["sum", "min", "max"]) @pytest.mark.parametrize("by", [["x", "y"], ["y", "x"]]) -def test_sf_group_list_str(sf: SheetFrame, df: DataFrame, func, by): +def test_sf_group_list_str(sf: SheetFrame, df: DataFrame, func: str, by: list[str]): a = sf.groupby(by).agg(func, as_address=True, formula=True) b = df.groupby(by).agg(func).astype(float) sf = SheetFrame(50, 10, data=a, sheet=sf.sheet) @@ -268,7 +273,12 @@ def test_sf_group_list_str(sf: SheetFrame, df: DataFrame, func, by): @pytest.mark.parametrize("by", [["x", "y"], ["y", "x"]]) @pytest.mark.parametrize("sort", [True, False]) -def test_sf_group_list_str_sort(sf: SheetFrame, df: DataFrame, by, sort): +def test_sf_group_list_str_sort( + sf: SheetFrame, + df: DataFrame, + by: list[str], + sort: bool, +): a = sf.groupby(by, sort=sort).agg("sum", as_address=True, formula=True) b = df.groupby(by, sort=sort).agg("sum").astype(float) sf = SheetFrame(50, 20, data=a, sheet=sf.sheet) @@ -284,7 +294,13 @@ def test_sf_group_list_str_sort(sf: SheetFrame, df: DataFrame, by, sort): ) @pytest.mark.parametrize("by", [["x", "y"], ["y", "x"]]) @pytest.mark.parametrize("sort", [True, False]) -def test_sf_group_list_dict(sf: SheetFrame, df: DataFrame, func, by, sort): +def test_sf_group_list_dict( + sf: SheetFrame, + df: DataFrame, + func: dict[str, str], + by: list[str], + sort: bool, +): a = sf.groupby(by, sort=sort).agg(func, as_address=True, formula=True) b = df.groupby(by, sort=sort).agg(func).astype(float) sf = SheetFrame(50, 30, data=a, sheet=sf.sheet) @@ -296,7 +312,7 @@ def test_sf_group_list_dict(sf: SheetFrame, df: DataFrame, func, by, sort): @pytest.mark.parametrize("func", [["sum", "mean"], ["min", "max"]]) @pytest.mark.parametrize("sort", [True, False]) -def test_sf_group_list_list(sf: SheetFrame, df: DataFrame, func, sort): +def test_sf_group_list_list(sf: SheetFrame, df: DataFrame, func: list[str], sort: bool): by = ["y", "x"] a = sf.groupby(by, sort=sort).agg(func, as_address=True, formula=True) b = df.groupby(by, sort=sort).agg(func).astype(float) diff --git a/tests/dataframes/agg/test_wide_column.py b/tests/dataframes/agg/test_wide_column.py index fad1311..30ba7df 100644 --- a/tests/dataframes/agg/test_wide_column.py +++ b/tests/dataframes/agg/test_wide_column.py @@ -1,12 +1,18 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import numpy as np import pytest from pandas import DataFrame, Series -from xlwings import Sheet from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.testing import FrameContainer, is_app_available from xlviews.testing.sheet_frame.base import WideColumn +if TYPE_CHECKING: + from xlwings import Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -38,9 +44,8 @@ def test_str(sf: SheetFrame, df: DataFrame, func: str): def test_list(sf: SheetFrame, df: DataFrame): - func = ["min", "max", "median", "sum"] - a = sf.agg(func, formula=True) - b = df.agg(func) # type: ignore + a = sf.agg(["min", "max", "median", "sum"], formula=True) + b = df.agg(["min", "max", "median", "sum"]) assert isinstance(a, DataFrame) assert isinstance(b, DataFrame) assert a.index.to_list() == b.index.to_list() From c5398eb66c9bc5e100a27b7e1509d3cb4f23c0a9 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sun, 8 Feb 2026 07:59:45 +0900 Subject: [PATCH 33/40] fix tests/head_frame --- tests/dataframes/heat_frame/test_agg.py | 13 ++++++++++--- tests/dataframes/heat_frame/test_base.py | 14 +++++++++++--- tests/dataframes/heat_frame/test_facet.py | 15 +++++++++++---- tests/dataframes/heat_frame/test_facet_agg.py | 15 +++++++++++---- tests/dataframes/heat_frame/test_multi_index.py | 11 +++++++++-- tests/dataframes/heat_frame/test_pair_1.py | 15 +++++++++++---- tests/dataframes/heat_frame/test_pair_2.py | 15 +++++++++++---- tests/dataframes/heat_frame/test_pair_3.py | 15 +++++++++++---- 8 files changed, 85 insertions(+), 28 deletions(-) diff --git a/tests/dataframes/heat_frame/test_agg.py b/tests/dataframes/heat_frame/test_agg.py index dc031d4..4813e34 100644 --- a/tests/dataframes/heat_frame/test_agg.py +++ b/tests/dataframes/heat_frame/test_agg.py @@ -1,10 +1,17 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from xlwings import Sheet -from xlviews.dataframes.heat_frame import HeatFrame from xlviews.testing import is_app_available from xlviews.testing.heat_frame.agg import AggParent, AggRange, AggStr +if TYPE_CHECKING: + from xlwings import Sheet + + from xlviews.dataframes.heat_frame import HeatFrame + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -43,6 +50,6 @@ def sf_range(fc_parent: AggParent): ("func", "value"), [("min", 0), ("max", 17), ("mean", 8.5), ("count", 18)], ) -def test_values_func(sf_range: HeatFrame, func, value): +def test_values_func(sf_range: HeatFrame, func: str, value: float): sf_range.sheet.range("$N$13").value = func assert sf_range.sheet.range("J9").value == value diff --git a/tests/dataframes/heat_frame/test_base.py b/tests/dataframes/heat_frame/test_base.py index f28c6ba..3eac57a 100644 --- a/tests/dataframes/heat_frame/test_base.py +++ b/tests/dataframes/heat_frame/test_base.py @@ -1,10 +1,18 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import numpy as np import pytest -from xlwings import Sheet -from xlviews.dataframes.heat_frame import HeatFrame from xlviews.testing import is_app_available -from xlviews.testing.heat_frame.base import Base, BaseParent +from xlviews.testing.heat_frame.base import Base +from xlviews.testing.sheet_frame.pivot import Base as BaseParent + +if TYPE_CHECKING: + from xlwings import Sheet + + from xlviews.dataframes.heat_frame import HeatFrame pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") diff --git a/tests/dataframes/heat_frame/test_facet.py b/tests/dataframes/heat_frame/test_facet.py index 41394c6..a5e0082 100644 --- a/tests/dataframes/heat_frame/test_facet.py +++ b/tests/dataframes/heat_frame/test_facet.py @@ -1,12 +1,19 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from xlwings import Sheet -from xlviews.dataframes.heat_frame import HeatFrame -from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.testing import is_app_available from xlviews.testing.heat_frame.facet import facet from xlviews.testing.sheet_frame.pivot import Pivot +if TYPE_CHECKING: + from xlwings import Sheet + + from xlviews.dataframes.heat_frame import HeatFrame + from xlviews.dataframes.sheet_frame import SheetFrame + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -34,5 +41,5 @@ def hfs(sf: SheetFrame): ("i", "v"), [(0, 1411), (1, 2511), (2, 1711), (3, 2811), (4, None), (5, 3111)], ) -def test_value(hfs: list[HeatFrame], i: int, v): +def test_value(hfs: list[HeatFrame], i: int, v: int | None): assert hfs[i].cell.offset(1, 1).value == v diff --git a/tests/dataframes/heat_frame/test_facet_agg.py b/tests/dataframes/heat_frame/test_facet_agg.py index 9911e52..faba67e 100644 --- a/tests/dataframes/heat_frame/test_facet_agg.py +++ b/tests/dataframes/heat_frame/test_facet_agg.py @@ -1,13 +1,20 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from pandas import DataFrame -from xlwings import Sheet -from xlviews.dataframes.heat_frame import HeatFrame -from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.testing import is_app_available from xlviews.testing.heat_frame.facet_agg import facet from xlviews.testing.sheet_frame.pivot import Pivot +if TYPE_CHECKING: + from pandas import DataFrame + from xlwings import Sheet + + from xlviews.dataframes.heat_frame import HeatFrame + from xlviews.dataframes.sheet_frame import SheetFrame + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") diff --git a/tests/dataframes/heat_frame/test_multi_index.py b/tests/dataframes/heat_frame/test_multi_index.py index 87c330f..1cab52c 100644 --- a/tests/dataframes/heat_frame/test_multi_index.py +++ b/tests/dataframes/heat_frame/test_multi_index.py @@ -1,11 +1,18 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import numpy as np import pytest -from xlwings import Sheet -from xlviews.dataframes.heat_frame import HeatFrame from xlviews.testing import is_app_available from xlviews.testing.heat_frame.base import MultiIndex, MultiIndexParent +if TYPE_CHECKING: + from xlwings import Sheet + + from xlviews.dataframes.heat_frame import HeatFrame + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") diff --git a/tests/dataframes/heat_frame/test_pair_1.py b/tests/dataframes/heat_frame/test_pair_1.py index 2cb6f35..31c872d 100644 --- a/tests/dataframes/heat_frame/test_pair_1.py +++ b/tests/dataframes/heat_frame/test_pair_1.py @@ -1,12 +1,19 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from xlwings import Sheet -from xlviews.dataframes.heat_frame import HeatFrame -from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.testing import is_app_available from xlviews.testing.heat_frame.pair import pair from xlviews.testing.sheet_frame.pivot import Pivot +if TYPE_CHECKING: + from xlwings import Sheet + + from xlviews.dataframes.heat_frame import HeatFrame + from xlviews.dataframes.sheet_frame import SheetFrame + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -51,5 +58,5 @@ def test_len(hfs: list[HeatFrame]): (11, 402), ], ) -def test_value(hfs: list[HeatFrame], i: int, v): +def test_value(hfs: list[HeatFrame], i: int, v: int | None): assert hfs[i].cell.offset(1, 1).value == v diff --git a/tests/dataframes/heat_frame/test_pair_2.py b/tests/dataframes/heat_frame/test_pair_2.py index 2d1cb7e..de3ed4a 100644 --- a/tests/dataframes/heat_frame/test_pair_2.py +++ b/tests/dataframes/heat_frame/test_pair_2.py @@ -1,12 +1,19 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from xlwings import Sheet -from xlviews.dataframes.heat_frame import HeatFrame -from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.testing import is_app_available from xlviews.testing.heat_frame.pair import pair from xlviews.testing.sheet_frame.pivot import Pivot +if TYPE_CHECKING: + from xlwings import Sheet + + from xlviews.dataframes.heat_frame import HeatFrame + from xlviews.dataframes.sheet_frame import SheetFrame + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -38,5 +45,5 @@ def test_len(hfs: list[HeatFrame]): ("i", "v"), [(0, 2614), (1, 2914), (2, 3214)], ) -def test_value(hfs: list[HeatFrame], i: int, v): +def test_value(hfs: list[HeatFrame], i: int, v: int): assert hfs[i].cell.offset(1, 15).value == v diff --git a/tests/dataframes/heat_frame/test_pair_3.py b/tests/dataframes/heat_frame/test_pair_3.py index b96eb1b..d32e2aa 100644 --- a/tests/dataframes/heat_frame/test_pair_3.py +++ b/tests/dataframes/heat_frame/test_pair_3.py @@ -1,12 +1,19 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from xlwings import Sheet -from xlviews.dataframes.heat_frame import HeatFrame -from xlviews.dataframes.sheet_frame import SheetFrame from xlviews.testing import is_app_available from xlviews.testing.heat_frame.pair import pair from xlviews.testing.sheet_frame.pivot import Pivot +if TYPE_CHECKING: + from xlwings import Sheet + + from xlviews.dataframes.heat_frame import HeatFrame + from xlviews.dataframes.sheet_frame import SheetFrame + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -38,5 +45,5 @@ def test_len(hfs: list[HeatFrame]): ("i", "v"), [(0, 0), (1, 241), (2, 138), (3, 333), (4, None), (5, 402)], ) -def test_value(hfs: list[HeatFrame], i: int, v): +def test_value(hfs: list[HeatFrame], i: int, v: int | None): assert hfs[i].cell.offset(1, 1).value == v From f545b68aefa24462cb82e5308b64ab4b4c2b4fb3 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sun, 8 Feb 2026 08:07:59 +0900 Subject: [PATCH 34/40] fix tests/pivot --- tests/dataframes/pivot/test_base.py | 44 ++++++++++++++++++---- tests/dataframes/pivot/test_multi_index.py | 13 +++++-- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/tests/dataframes/pivot/test_base.py b/tests/dataframes/pivot/test_base.py index 44bc278..784b0c3 100644 --- a/tests/dataframes/pivot/test_base.py +++ b/tests/dataframes/pivot/test_base.py @@ -1,11 +1,17 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Any + import pytest -from pandas import DataFrame -from xlwings import Sheet from xlviews import SheetFrame from xlviews.testing import is_app_available from xlviews.testing.sheet_frame.pivot import Base +if TYPE_CHECKING: + from pandas import DataFrame + from xlwings import Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -40,7 +46,13 @@ def columns(request: pytest.FixtureRequest): @pytest.fixture -def sf(sf_parent: SheetFrame, values, index, columns, sheet): +def sf( + sf_parent: SheetFrame, + values: str | list[str] | None, + index: str | list[str], + columns: str | list[str], + sheet: Sheet, +): df = sf_parent.pivot_table( values, index, @@ -52,8 +64,13 @@ def sf(sf_parent: SheetFrame, values, index, columns, sheet): @pytest.fixture -def df(df_parent: DataFrame, values, index, columns): - return df_parent.pivot_table(values, index, columns, aggfunc=lambda x: x) +def df( + df_parent: DataFrame, + values: str | list[str] | None, + index: str | list[str], + columns: str | list[str], +): + return df_parent.pivot_table(values, index, columns, aggfunc=lambda x: x) # pyright: ignore[reportUnknownArgumentType, reportUnknownLambdaType] def test_index(sf: SheetFrame, df: DataFrame): @@ -79,7 +96,13 @@ def aggfunc(request: pytest.FixtureRequest): @pytest.fixture -def sf_agg(sf_parent: SheetFrame, values, index_columns, aggfunc, sheet): +def sf_agg( + sf_parent: SheetFrame, + values: str | list[str] | None, + index_columns: tuple[str | None, str | None], + aggfunc: Any, + sheet: Sheet, +): index, columns = index_columns df = sf_parent.pivot_table( values, @@ -93,7 +116,12 @@ def sf_agg(sf_parent: SheetFrame, values, index_columns, aggfunc, sheet): @pytest.fixture -def df_agg(df_parent: DataFrame, values, index_columns, aggfunc): +def df_agg( + df_parent: DataFrame, + values: str | list[str] | None, + index_columns: tuple[str | None, str | None], + aggfunc: Any, +): index, columns = index_columns return df_parent.pivot_table(values, index, columns, aggfunc) @@ -115,6 +143,6 @@ def test_agg_values(sf_agg: SheetFrame, df_agg: DataFrame): @pytest.mark.parametrize("aggfunc", [None, "mean"]) -def test_error(sf_parent: SheetFrame, aggfunc): +def test_error(sf_parent: SheetFrame, aggfunc: str | None): with pytest.raises(ValueError, match="No group keys passed!"): sf_parent.pivot_table(None, None, None, aggfunc, formula=True) diff --git a/tests/dataframes/pivot/test_multi_index.py b/tests/dataframes/pivot/test_multi_index.py index 8e80d46..b331f0d 100644 --- a/tests/dataframes/pivot/test_multi_index.py +++ b/tests/dataframes/pivot/test_multi_index.py @@ -1,12 +1,19 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from pandas import DataFrame -from xlwings import Sheet -from xlviews import SheetFrame from xlviews.testing import is_app_available from xlviews.testing.sheet_frame.pivot import Pivot from xlviews.utils import iter_group_locs +if TYPE_CHECKING: + from pandas import DataFrame + from xlwings import Sheet + + from xlviews import SheetFrame + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") From 9581f6ea5c12b11b5673a1151f1c22dbc59cf6fa Mon Sep 17 00:00:00 2001 From: Daizu Date: Sun, 8 Feb 2026 08:16:09 +0900 Subject: [PATCH 35/40] fix tests/chart --- tests/chart/axes/test_axes.py | 8 +++++- tests/chart/axes/test_position.py | 8 +++++- tests/chart/axes/test_series.py | 22 ++++++---------- tests/chart/axes/test_style.py | 10 ++++++-- tests/chart/series/test_property.py | 11 ++++++-- tests/chart/series/test_style.py | 39 +++++++++++++++++++++++++---- tests/chart/test_style.py | 9 ++++--- typings/xlwings/__init__.pyi | 3 +++ 8 files changed, 81 insertions(+), 29 deletions(-) diff --git a/tests/chart/axes/test_axes.py b/tests/chart/axes/test_axes.py index f14061e..440cbec 100644 --- a/tests/chart/axes/test_axes.py +++ b/tests/chart/axes/test_axes.py @@ -1,10 +1,16 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from xlwings import Sheet from xlwings.constants import ChartType, TickMark from xlviews.chart.axes import Axes from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlwings import Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") diff --git a/tests/chart/axes/test_position.py b/tests/chart/axes/test_position.py index 5702456..f875ab1 100644 --- a/tests/chart/axes/test_position.py +++ b/tests/chart/axes/test_position.py @@ -1,10 +1,16 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from xlwings import Sheet from xlviews.chart.axes import Axes from xlviews.config import rcParams from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlwings import Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") LEFT = rcParams["chart.left"] diff --git a/tests/chart/axes/test_series.py b/tests/chart/axes/test_series.py index bd56328..7322628 100644 --- a/tests/chart/axes/test_series.py +++ b/tests/chart/axes/test_series.py @@ -1,11 +1,17 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from xlwings import Sheet from xlwings.constants import ChartType from xlviews.chart.axes import Axes -from xlviews.core.range import Range +from xlviews.core.range_collection import RangeCollection from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlwings import Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -56,19 +62,7 @@ def test_add_series_chart_type(ax: Axes): assert s.chart_type == ChartType.xlXYScatter -# def test_add_series_name_range(ax: Axes): -# x = ax.sheet.range("A2:A5") -# rng = Range(1, 1, ax.sheet) -# label = rng.get_address(include_sheetname=True, formula=True) -# s = ax.add_series(x, label=label) - -# rng.value = "Series Name" -# assert s.api.Name == "Series Name" -# assert s.label == "Series Name" - - def test_add_series_xy_range_collection(ax: Axes): - from xlviews.core.range_collection import RangeCollection ax.sheet.range("A1:A10").options(transpose=True).value = list(range(10)) ax.sheet.range("B1:B10").options(transpose=True).value = list(range(10, 20)) diff --git a/tests/chart/axes/test_style.py b/tests/chart/axes/test_style.py index 2a65272..01ac132 100644 --- a/tests/chart/axes/test_style.py +++ b/tests/chart/axes/test_style.py @@ -1,10 +1,16 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from xlwings import Sheet from xlwings.constants import ChartType from xlviews.chart.axes import Axes from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlwings import Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -156,7 +162,7 @@ def ax2(sheet: Sheet): ((1, -1), 145, 148), ], ) -def test_legend_position(ax2: Axes, loc, left, top): +def test_legend_position(ax2: Axes, loc: tuple[int, int], left: int, top: int): ax2.set(legend=loc) assert ax2.chart.api[1].HasLegend legend = ax2.chart.api[1].Legend diff --git a/tests/chart/series/test_property.py b/tests/chart/series/test_property.py index 788d21b..dce8c7a 100644 --- a/tests/chart/series/test_property.py +++ b/tests/chart/series/test_property.py @@ -1,11 +1,18 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from xlwings import Sheet from xlwings.constants import ChartType from xlviews.chart.axes import Axes -from xlviews.chart.series import Series from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlwings import Sheet + + from xlviews.chart.series import Series + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") diff --git a/tests/chart/series/test_style.py b/tests/chart/series/test_style.py index a688e0f..80f5bff 100644 --- a/tests/chart/series/test_style.py +++ b/tests/chart/series/test_style.py @@ -1,10 +1,18 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from xlwings import Sheet from xlwings.constants import ChartType, LineStyle, MarkerStyle from xlviews.chart.axes import Axes from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlwings import Sheet + + from xlviews.core.range import Range + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -43,7 +51,14 @@ def ax(sheet_module: Sheet): ("*", MarkerStyle.xlMarkerStyleStar, 2), ], ) -def test_series_style_marker(ax: Axes, x, y, style, value, size): +def test_series_style_marker( + ax: Axes, + x: Range, + y: Range, + style: str, + value: int, + size: int, +): series = ax.add_series(x, y, label="a") series.marker(style, size=size) assert series.api.MarkerStyle == value @@ -61,14 +76,21 @@ def test_series_style_marker(ax: Axes, x, y, style, value, size): (".", LineStyle.xlDot, 2), ], ) -def test_series_style_line(ax: Axes, x, y, style, value, weight): +def test_series_style_line( + ax: Axes, + x: Range, + y: Range, + style: str, + value: int, + weight: int, +): series = ax.add_series(x, y, label="a") series.line(style, weight=weight) assert series.api.Border.LineStyle == value series.delete() -def test_series_style_line_none(x, y, sheet: Sheet): +def test_series_style_line_none(x: Range, y: Range, sheet: Sheet): ct = ChartType.xlXYScatterLines ax = Axes(300, 10, chart_type=ct, sheet=sheet) series = ax.add_series(x, y, label="a") @@ -86,7 +108,14 @@ def test_series_style_line_none(x, y, sheet: Sheet): ("lime", 65280, 0.7), ], ) -def test_series_style_color(ax: Axes, x, y, color, value, alpha): +def test_series_style_color( + ax: Axes, + x: Range, + y: Range, + color: str, + value: int, + alpha: float, +): series = ax.add_series(x, y, label="a") series.line("-", color=color, alpha=alpha) assert value == series.api.Format.Line.ForeColor.RGB diff --git a/tests/chart/test_style.py b/tests/chart/test_style.py index e7808cb..779bb7b 100644 --- a/tests/chart/test_style.py +++ b/tests/chart/test_style.py @@ -1,10 +1,11 @@ -def test_marker_style_int(): - from xlviews.chart.style import get_marker_style +from __future__ import annotations + +from xlviews.chart.style import get_line_style, get_marker_style + +def test_marker_style_int(): assert get_marker_style(1) == 1 def test_line_style_int(): - from xlviews.chart.style import get_line_style - assert get_line_style(1) == 1 diff --git a/typings/xlwings/__init__.pyi b/typings/xlwings/__init__.pyi index d27881f..b76af27 100644 --- a/typings/xlwings/__init__.pyi +++ b/typings/xlwings/__init__.pyi @@ -31,6 +31,7 @@ class Range: @value.setter def value(self, value: Any) -> None: ... def expand(self, mode: str = "table") -> Range: ... + def __call__(self, *args: Any) -> Range: ... def __getitem__(self, key: Any) -> Range: ... def offset(self, row_offset: int = 0, column_offset: int = 0) -> Range: ... @property @@ -79,6 +80,8 @@ class Sheet: def charts(self) -> Charts: ... def delete(self) -> None: ... def activate(self) -> None: ... + @property + def cells(self) -> Range: ... class Chart: @property From 0216a488100c581edae4bb2614c67c083cb99f38 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sun, 8 Feb 2026 08:31:15 +0900 Subject: [PATCH 36/40] fix tests/figure --- src/xlviews/figure/plot.py | 4 ++-- tests/figure/test_facet.py | 35 ++++++++++++++++++++++++++------- tests/figure/test_grid.py | 27 +++++++++++-------------- tests/figure/test_plot.py | 40 ++++++++++++++++++++------------------ 4 files changed, 62 insertions(+), 44 deletions(-) diff --git a/src/xlviews/figure/plot.py b/src/xlviews/figure/plot.py index 136af70..58aa786 100644 --- a/src/xlviews/figure/plot.py +++ b/src/xlviews/figure/plot.py @@ -10,7 +10,7 @@ from .palette import PaletteStyle, get_color_palette, get_marker_palette if TYPE_CHECKING: - from collections.abc import Iterator + from collections.abc import Iterator, Mapping from xlviews.chart.axes import Axes from xlviews.chart.series import Series @@ -111,7 +111,7 @@ def facet( yield key, cls(axes_, sub) -def get_label(label: Label, key: dict[Hashable | None, Hashable]) -> str: +def get_label(label: Label, key: Mapping[Hashable | None, Hashable]) -> str: key_ = {k: v for k, v in key.items() if isinstance(k, str)} return label(key_) if callable(label) else label.format(**key_) diff --git a/tests/figure/test_facet.py b/tests/figure/test_facet.py index a7f41c9..7fe1b71 100644 --- a/tests/figure/test_facet.py +++ b/tests/figure/test_facet.py @@ -1,12 +1,21 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +import pandas as pd import pytest -from xlwings import Sheet -from xlviews.dataframes.sheet_frame import SheetFrame -from xlviews.figure.plot import Plot +from xlviews.figure.plot import iterrows from xlviews.testing import is_app_available from xlviews.testing.figure.facet import facet from xlviews.testing.sheet_frame.pivot import Pivot +if TYPE_CHECKING: + from xlwings import Sheet + + from xlviews.dataframes.sheet_frame import SheetFrame + from xlviews.figure.plot import Plot + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -42,9 +51,21 @@ def test_title(plots: list[Plot], i: int, title: str): assert plots[i].axes.title == title -def test_iterrows_none(): - from pandas import Index +def test_iterrows() -> None: + df = pd.DataFrame({"a": [1, 1, 2, 2], "b": [1, 2, 3, 4]}) + df = df.set_index("a") + result = list(iterrows(df.index, "a")) + assert result == [{"a": 1}, {"a": 2}] + - from xlviews.figure.plot import iterrows +def test_iterrows_multi() -> None: + df = pd.DataFrame({"a": [1, 1, 2, 2], "b": [1, 1, 3, 4], "c": range(4)}) + df = df.set_index(["a", "b"]) + result = list(iterrows(df.index, ["a"])) + assert result == [{"a": 1}, {"a": 2}] + result = list(iterrows(df.index, ["a", "b"])) + assert result == [{"a": 1, "b": 1}, {"a": 2, "b": 3}, {"a": 2, "b": 4}] - assert list(iterrows(Index([]), None)) == [{}] + +def test_iterrows_none(): + assert list(iterrows(pd.Index([]), None)) == [{}] diff --git a/tests/figure/test_grid.py b/tests/figure/test_grid.py index 378041e..2a06d89 100644 --- a/tests/figure/test_grid.py +++ b/tests/figure/test_grid.py @@ -1,10 +1,16 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + import pytest -from xlwings import Sheet from xlviews.chart.axes import Axes from xlviews.figure.grid import Grid, Series from xlviews.testing import is_app_available +if TYPE_CHECKING: + from xlwings import Sheet + pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") @@ -22,7 +28,7 @@ def test_series_len(seriesx: Series): ("k", "left", "top"), [(0, 30, 40), (1, 150, 40), (2, 270, 40)], ) -def test_seriesx_init(seriesx: Series, k: int, left, top): +def test_seriesx_init(seriesx: Series, k: int, left: int, top: int): assert seriesx[k].chart.left == left assert seriesx[k].chart.top == top assert seriesx[:][k].chart.left == left @@ -39,30 +45,19 @@ def seriesy(sheet_module: Sheet): ("k", "left", "top"), [(0, 30, 40), (1, 30, 190), (2, 30, 340)], ) -def test_seriesy_init(seriesy: Series, k: int, left, top): +def test_seriesy_init(seriesy: Series, k: int, left: int, top: int): assert seriesy[k].chart.left == left assert seriesy[k].chart.top == top assert seriesy[:][k].chart.left == left assert seriesy[:][k].chart.top == top -def test_series_getitem_error(seriesx: Series): - with pytest.raises(ValueError, match="Invalid key: abc"): - seriesx["abc"] # type: ignore - - def test_series_iter(seriesx: Series): ax = list(seriesx)[-1] assert ax.chart.left == 270 assert ax.chart.top == 40 -def test_series_axis_error(seriesx): - ax = seriesx[0] - with pytest.raises(ValueError, match="Invalid axis: 2"): - Series(ax, 1, axis=2) # type: ignore - - @pytest.fixture(scope="module") def grid(sheet_module: Sheet): ax = Axes(left=30, top=40, width=120, height=150, sheet=sheet_module) @@ -86,7 +81,7 @@ def grid(sheet_module: Sheet): (2, 3, 390, 340), ], ) -def test_grid_init(grid: Grid, r: int, c: int, left, top): +def test_grid_init(grid: Grid, r: int, c: int, left: int, top: int): assert grid[r, c].chart.left == left assert grid[r, c].chart.top == top assert grid[r][c].chart.left == left @@ -113,7 +108,7 @@ def test_grid_shape_empty(): def test_grid_getitem_error(grid: Grid): with pytest.raises(ValueError, match="Invalid key: abc"): - grid["abc"] # type: ignore + grid["abc"] # pyright: ignore[reportCallIssue, reportArgumentType] def test_grid_iter(grid: Grid): diff --git a/tests/figure/test_plot.py b/tests/figure/test_plot.py index ddb11a9..a5fc79f 100644 --- a/tests/figure/test_plot.py +++ b/tests/figure/test_plot.py @@ -1,37 +1,45 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Any + import pytest -from xlwings import Sheet from xlwings.constants import ChartType, MarkerStyle from xlviews.chart.axes import Axes -from xlviews.dataframes.sheet_frame import SheetFrame +from xlviews.figure.plot import Plot, get_label from xlviews.testing import is_app_available from xlviews.testing.chart import Base +if TYPE_CHECKING: + from collections.abc import Callable, Hashable, Mapping + + from xlwings import Sheet + + from xlviews.dataframes.sheet_frame import SheetFrame pytestmark = pytest.mark.skipif(not is_app_available(), reason="Excel not installed") +def func(x: Any) -> str: + return f"_{x['a']}_" + + @pytest.mark.parametrize( ("label", "key", "expected"), [ ("a", {}, "a"), ("a{b}", {"b": "B"}, "aB"), ("{a}{b}", {"a": "A", "b": "B"}, "AB"), - (lambda x: f"_{x['a']}_", {"a": "A"}, "_A_"), + (func, {"a": "A"}, "_A_"), ], ) -def test_get_label(label, key, expected): - from xlviews.figure.plot import get_label - +def test_get_label( + label: str | Callable[..., str], + key: Mapping[Hashable, str], + expected: str, +): assert get_label(label, key) == expected -def test_get_label_error(): - from xlviews.figure.plot import get_label - - with pytest.raises(ValueError, match="Invalid label"): - get_label(1, 1) # type: ignore - - @pytest.fixture def sf(sheet: Sheet): fc = Base(sheet, style=True) @@ -44,8 +52,6 @@ def ax(sf: SheetFrame): def test_plot_series(ax: Axes, sf: SheetFrame): - from xlviews.figure.plot import Plot - data = sf.agg(include_sheetname=True) p = ( Plot(ax, data) @@ -58,8 +64,6 @@ def test_plot_series(ax: Axes, sf: SheetFrame): def test_plot_index(ax: Axes, sf: SheetFrame): - from xlviews.figure.plot import Plot - data = sf.groupby("b").agg(include_sheetname=True) p = ( Plot(ax, data) @@ -76,8 +80,6 @@ def test_plot_index(ax: Axes, sf: SheetFrame): def test_plot_multi_index(ax: Axes, sf: SheetFrame): - from xlviews.figure.plot import Plot - data = sf.groupby(["b", "c"]).agg(include_sheetname=True) p = ( Plot(ax, data) From c4ec3b8f28d9c08f4022043d88407d84edc479bd Mon Sep 17 00:00:00 2001 From: Daizu Date: Sun, 8 Feb 2026 09:21:34 +0900 Subject: [PATCH 37/40] Series -> AxesSeries --- src/xlviews/figure/grid.py | 26 +++++++++++++------------- tests/figure/test_grid.py | 14 +++++++------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/xlviews/figure/grid.py b/src/xlviews/figure/grid.py index 247e4ee..d9eb401 100644 --- a/src/xlviews/figure/grid.py +++ b/src/xlviews/figure/grid.py @@ -8,7 +8,7 @@ from xlviews.chart.axes import Axes -class Series: +class AxesSeries: axes: list[Axes] def __init__( @@ -29,13 +29,13 @@ def __init__( def __getitem__(self, key: int) -> Axes: ... @overload - def __getitem__(self, key: slice) -> Series: ... + def __getitem__(self, key: slice) -> AxesSeries: ... - def __getitem__(self, key: int | slice) -> Axes | Series: + def __getitem__(self, key: int | slice) -> Axes | AxesSeries: if isinstance(key, int): return self.axes[key] - return Series(self.axes[key]) + return AxesSeries(self.axes[key]) def __len__(self) -> int: return len(self.axes) @@ -81,16 +81,16 @@ def shape(self) -> tuple[int, int]: return 0, 0 @overload - def __getitem__(self, key: int) -> Series: ... + def __getitem__(self, key: int) -> AxesSeries: ... @overload def __getitem__(self, key: tuple[int, int]) -> Axes: ... @overload - def __getitem__(self, key: tuple[slice, int]) -> Series: ... + def __getitem__(self, key: tuple[slice, int]) -> AxesSeries: ... @overload - def __getitem__(self, key: tuple[int, slice]) -> Series: ... + def __getitem__(self, key: tuple[int, slice]) -> AxesSeries: ... @overload def __getitem__(self, key: tuple[slice, slice]) -> Grid: ... @@ -98,9 +98,9 @@ def __getitem__(self, key: tuple[slice, slice]) -> Grid: ... def __getitem__( self, key: int | tuple[int | slice, int | slice], - ) -> Axes | Series | Grid: + ) -> Axes | AxesSeries | Grid: if isinstance(key, int): - return Series(self.axes[key]) + return AxesSeries(self.axes[key]) if len(key) == 2: r, c = key @@ -108,10 +108,10 @@ def __getitem__( return self.axes[r][c] if isinstance(r, slice) and isinstance(c, int): - return Series([row[c] for row in self.axes[r]]) + return AxesSeries([row[c] for row in self.axes[r]]) if isinstance(r, int) and isinstance(c, slice): - return Series(self.axes[r][c]) + return AxesSeries(self.axes[r][c]) if isinstance(r, slice) and isinstance(c, slice): return Grid([row[c] for row in self.axes[r]]) @@ -122,6 +122,6 @@ def __getitem__( def __len__(self) -> int: return len(self.axes) - def __iter__(self) -> Iterator[Series]: + def __iter__(self) -> Iterator[AxesSeries]: for row in self.axes: - yield Series(row) + yield AxesSeries(row) diff --git a/tests/figure/test_grid.py b/tests/figure/test_grid.py index 2a06d89..6dab1e0 100644 --- a/tests/figure/test_grid.py +++ b/tests/figure/test_grid.py @@ -5,7 +5,7 @@ import pytest from xlviews.chart.axes import Axes -from xlviews.figure.grid import Grid, Series +from xlviews.figure.grid import AxesSeries, Grid from xlviews.testing import is_app_available if TYPE_CHECKING: @@ -17,10 +17,10 @@ @pytest.fixture(scope="module") def seriesx(sheet_module: Sheet): ax = Axes(left=30, top=40, width=120, height=150, sheet=sheet_module) - return Series(ax, 3, axis=0) + return AxesSeries(ax, 3, axis=0) -def test_series_len(seriesx: Series): +def test_series_len(seriesx: AxesSeries): assert len(seriesx) == 3 @@ -28,7 +28,7 @@ def test_series_len(seriesx: Series): ("k", "left", "top"), [(0, 30, 40), (1, 150, 40), (2, 270, 40)], ) -def test_seriesx_init(seriesx: Series, k: int, left: int, top: int): +def test_seriesx_init(seriesx: AxesSeries, k: int, left: int, top: int): assert seriesx[k].chart.left == left assert seriesx[k].chart.top == top assert seriesx[:][k].chart.left == left @@ -38,21 +38,21 @@ def test_seriesx_init(seriesx: Series, k: int, left: int, top: int): @pytest.fixture(scope="module") def seriesy(sheet_module: Sheet): ax = Axes(left=30, top=40, width=120, height=150, sheet=sheet_module) - return Series(ax, 3, axis=1) + return AxesSeries(ax, 3, axis=1) @pytest.mark.parametrize( ("k", "left", "top"), [(0, 30, 40), (1, 30, 190), (2, 30, 340)], ) -def test_seriesy_init(seriesy: Series, k: int, left: int, top: int): +def test_seriesy_init(seriesy: AxesSeries, k: int, left: int, top: int): assert seriesy[k].chart.left == left assert seriesy[k].chart.top == top assert seriesy[:][k].chart.left == left assert seriesy[:][k].chart.top == top -def test_series_iter(seriesx: Series): +def test_series_iter(seriesx: AxesSeries): ax = list(seriesx)[-1] assert ax.chart.left == 270 assert ax.chart.top == 40 From 677c158933be190c758a461a60e9a90a266b8974 Mon Sep 17 00:00:00 2001 From: Daizu Date: Sun, 8 Feb 2026 10:28:15 +0900 Subject: [PATCH 38/40] fix tests --- lcov.info | 4887 ++++++++++++++++----------------- src/xlviews/figure/palette.py | 87 +- src/xlviews/figure/plot.py | 4 +- tests/figure/test_palette.py | 143 +- 4 files changed, 2557 insertions(+), 2564 deletions(-) diff --git a/lcov.info b/lcov.info index f66aaf6..7d54dd6 100644 --- a/lcov.info +++ b/lcov.info @@ -1,6 +1,5 @@ SF:src\xlviews\__init__.py DA:1,1 -DA:2,1 DA:3,1 DA:4,1 DA:5,1 @@ -10,9 +9,11 @@ DA:8,1 DA:9,1 DA:10,1 DA:11,1 +DA:12,1 DA:13,1 -LF:12 -LH:12 +DA:15,1 +LF:13 +LH:13 end_of_record SF:src\xlviews\chart\__init__.py end_of_record @@ -27,343 +28,343 @@ DA:10,1 DA:11,1 DA:13,1 DA:14,1 -DA:32,1 -DA:38,1 -DA:39,1 -DA:41,1 -DA:42,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:64,1 -DA:65,1 -DA:66,1 -DA:68,1 +DA:30,1 +DA:36,0 +DA:37,0 +DA:39,0 +DA:40,0 +DA:42,0 +DA:43,0 +DA:44,0 +DA:45,0 +DA:46,0 +DA:47,0 +DA:48,0 +DA:49,0 +DA:50,0 +DA:52,0 +DA:53,0 +DA:54,0 +DA:55,0 +DA:56,0 +DA:57,0 +DA:58,0 +DA:59,0 +DA:60,0 +DA:62,0 +DA:63,0 +DA:64,0 +DA:66,0 +DA:69,1 +DA:70,1 DA:71,1 DA:72,1 DA:73,1 -DA:74,1 DA:75,1 -DA:77,1 -DA:78,1 -DA:94,1 -DA:96,1 -DA:97,1 -DA:98,1 -DA:99,1 -DA:101,1 -DA:103,1 -DA:104,1 -DA:106,1 -DA:108,1 -DA:109,1 -DA:112,1 -DA:113,1 -DA:114,1 -DA:116,1 -DA:117,1 -DA:119,1 -DA:120,1 +DA:76,1 +DA:92,0 +DA:94,0 +DA:95,0 +DA:96,0 +DA:97,0 +DA:99,0 +DA:101,0 +DA:102,0 +DA:104,0 +DA:106,0 +DA:107,0 +DA:110,0 +DA:111,0 +DA:112,0 +DA:114,0 +DA:115,0 +DA:117,0 +DA:118,0 +DA:120,0 DA:122,1 -DA:124,1 -DA:125,1 -DA:133,1 -DA:134,1 -DA:135,1 -DA:136,1 -DA:138,1 -DA:139,1 -DA:140,1 -DA:142,1 -DA:143,1 -DA:144,1 -DA:146,1 -DA:161,1 -DA:162,1 -DA:163,1 +DA:123,1 +DA:131,0 +DA:132,0 +DA:133,0 +DA:134,0 +DA:136,0 +DA:137,0 +DA:138,0 +DA:140,0 +DA:141,0 +DA:142,0 +DA:144,0 +DA:159,1 +DA:160,1 +DA:161,0 +DA:162,0 DA:164,1 -DA:166,1 -DA:167,1 -DA:168,1 +DA:165,1 +DA:166,0 +DA:167,0 DA:169,1 -DA:171,1 -DA:172,1 -DA:179,1 -DA:180,1 -DA:182,1 -DA:183,1 +DA:170,1 +DA:177,0 +DA:178,0 +DA:180,0 +DA:181,0 +DA:183,0 DA:185,1 -DA:187,1 -DA:188,1 -DA:189,1 -DA:191,1 -DA:192,1 +DA:186,1 +DA:187,0 +DA:189,0 +DA:190,0 +DA:192,0 DA:194,1 -DA:196,1 -DA:197,1 +DA:195,1 +DA:196,0 DA:198,1 -DA:200,1 -DA:208,1 -DA:210,1 -DA:211,1 -DA:212,1 -DA:214,1 -DA:215,1 -DA:216,1 -DA:218,1 -DA:219,1 +DA:206,0 +DA:208,0 +DA:209,0 +DA:210,0 +DA:212,0 +DA:213,0 +DA:214,0 +DA:216,0 +DA:217,0 +DA:218,0 DA:220,1 -DA:222,1 -DA:223,1 +DA:221,1 +DA:222,0 DA:224,1 -DA:226,1 -DA:227,1 +DA:225,1 +DA:226,0 DA:228,1 -DA:230,1 -DA:231,1 +DA:229,1 +DA:230,0 DA:232,1 -DA:234,1 -DA:235,1 +DA:233,1 +DA:234,0 DA:236,1 -DA:238,1 +DA:237,0 DA:239,1 -DA:241,1 +DA:240,0 DA:242,1 -DA:244,1 -DA:245,1 +DA:243,1 +DA:244,0 DA:246,1 -DA:248,1 -DA:249,1 +DA:247,1 +DA:248,0 DA:250,1 -DA:252,1 -DA:253,1 +DA:251,1 +DA:252,0 DA:254,1 -DA:256,1 -DA:257,1 +DA:255,1 +DA:256,0 DA:258,1 -DA:260,1 -DA:261,1 -DA:263,1 -DA:264,1 +DA:264,0 DA:266,1 -DA:267,1 -DA:269,1 -DA:270,1 -DA:272,1 -DA:273,1 +DA:272,0 DA:274,1 -DA:276,1 +DA:275,0 DA:277,1 -DA:278,1 +DA:278,0 DA:280,1 DA:281,1 -DA:282,1 +DA:282,0 DA:284,1 DA:285,1 -DA:286,1 +DA:286,0 DA:288,1 DA:289,1 -DA:302,1 -DA:303,1 -DA:304,1 -DA:305,1 -DA:306,1 -DA:307,1 -DA:308,1 -DA:309,1 -DA:310,1 -DA:311,1 -DA:312,1 -DA:313,1 -DA:314,1 -DA:315,1 -DA:316,1 -DA:317,1 -DA:318,1 -DA:319,1 -DA:321,1 -DA:322,1 -DA:323,1 -DA:324,1 -DA:326,1 -DA:328,1 -DA:329,1 -DA:330,1 -DA:331,1 -DA:333,1 -DA:334,1 -DA:350,1 -DA:351,1 -DA:352,1 -DA:354,1 -DA:355,1 -DA:357,1 -DA:358,1 -DA:359,1 -DA:360,1 -DA:361,1 -DA:363,1 -DA:364,1 -DA:366,1 -DA:367,1 -DA:368,1 -DA:370,1 -DA:371,1 -DA:372,1 -DA:373,1 -DA:374,1 -DA:375,1 -DA:377,1 -DA:378,1 -DA:379,1 -DA:380,1 -DA:381,1 -DA:382,1 -DA:384,1 -DA:386,1 -DA:387,1 -DA:388,1 -DA:389,1 -DA:390,1 -DA:391,1 -DA:392,1 -DA:394,1 -DA:395,1 -DA:396,1 -DA:397,1 -DA:399,1 -DA:400,1 -DA:401,1 -DA:402,1 -DA:403,1 -DA:405,1 -DA:406,1 -DA:408,1 -DA:410,1 -DA:412,1 -DA:413,1 -DA:414,1 -DA:415,1 -DA:417,1 -DA:418,1 -DA:420,1 +DA:290,0 +DA:292,1 +DA:293,1 +DA:294,0 +DA:296,1 +DA:297,1 +DA:310,0 +DA:311,0 +DA:312,0 +DA:313,0 +DA:314,0 +DA:315,0 +DA:316,0 +DA:317,0 +DA:318,0 +DA:319,0 +DA:320,0 +DA:321,0 +DA:322,0 +DA:323,0 +DA:324,0 +DA:325,0 +DA:326,0 +DA:327,0 +DA:329,0 +DA:330,0 +DA:331,0 +DA:332,0 +DA:334,0 +DA:336,1 +DA:337,0 +DA:338,0 +DA:339,0 +DA:341,1 +DA:342,1 +DA:358,0 +DA:359,0 +DA:360,0 +DA:362,0 +DA:363,0 +DA:365,0 +DA:366,0 +DA:367,0 +DA:368,0 +DA:369,0 +DA:372,0 +DA:373,0 +DA:375,0 +DA:376,0 +DA:377,0 +DA:379,0 +DA:380,0 +DA:381,0 +DA:382,0 +DA:383,0 +DA:384,0 +DA:386,0 +DA:387,0 +DA:388,0 +DA:389,0 +DA:390,0 +DA:391,0 +DA:393,0 +DA:395,0 +DA:396,0 +DA:397,0 +DA:398,0 +DA:399,0 +DA:400,0 +DA:401,0 +DA:403,0 +DA:404,0 +DA:405,0 +DA:406,0 +DA:408,0 +DA:409,0 +DA:410,0 +DA:411,0 +DA:412,0 +DA:414,0 +DA:415,0 +DA:417,0 +DA:419,0 DA:421,1 -DA:422,1 -DA:424,1 -DA:425,1 -DA:426,1 -DA:428,1 -DA:429,1 -DA:430,1 -DA:431,1 -DA:433,1 -DA:435,1 -DA:438,1 -DA:442,1 -DA:444,1 -DA:446,1 -DA:447,1 -DA:449,1 -DA:451,1 -DA:452,1 +DA:422,0 +DA:423,0 +DA:424,0 +DA:426,0 +DA:427,0 +DA:429,0 +DA:430,0 +DA:431,0 +DA:433,0 +DA:434,0 +DA:435,0 +DA:437,0 +DA:438,0 +DA:439,0 +DA:440,0 +DA:442,0 +DA:444,0 +DA:447,0 +DA:451,0 DA:453,1 -DA:454,1 -DA:455,1 -DA:456,1 -DA:458,1 -DA:459,1 -DA:460,1 -DA:461,1 -DA:462,1 -DA:464,1 -DA:465,1 -DA:466,1 -DA:467,1 -DA:468,1 -DA:470,1 +DA:455,0 +DA:456,0 +DA:458,0 +DA:460,0 +DA:461,0 +DA:462,0 +DA:463,0 +DA:464,0 +DA:465,0 +DA:467,0 +DA:468,0 +DA:469,0 +DA:470,0 +DA:471,0 +DA:473,0 +DA:474,0 +DA:475,0 +DA:476,0 +DA:477,0 +DA:479,0 LF:279 -LH:279 -FN:32,68,chart_position -FNDA:1,chart_position -FN:78,122,Axes.__init__ -FNDA:1,Axes.__init__ -FN:125,159,Axes.copy -FNDA:1,Axes.copy -FN:162,164,Axes.xaxis -FNDA:1,Axes.xaxis -FN:167,169,Axes.yaxis -FNDA:1,Axes.yaxis -FN:172,185,Axes.add_series -FNDA:1,Axes.add_series -FN:188,194,Axes.title -FNDA:1,Axes.title -FN:197,198,Axes.title -FNDA:1,Axes.title -FN:200,220,Axes.set_title -FNDA:1,Axes.set_title -FN:223,224,Axes.xlabel -FNDA:1,Axes.xlabel -FN:227,228,Axes.xlabel -FNDA:1,Axes.xlabel -FN:231,232,Axes.ylabel -FNDA:1,Axes.ylabel -FN:235,236,Axes.ylabel -FNDA:1,Axes.ylabel -FN:238,239,Axes.set_xlabel -FNDA:1,Axes.set_xlabel -FN:241,242,Axes.set_ylabel -FNDA:1,Axes.set_ylabel -FN:245,246,Axes.xticks -FNDA:1,Axes.xticks -FN:249,250,Axes.xticks -FNDA:1,Axes.xticks -FN:253,254,Axes.yticks -FNDA:1,Axes.yticks -FN:257,258,Axes.yticks -FNDA:1,Axes.yticks -FN:260,261,Axes.set_xticks -FNDA:1,Axes.set_xticks -FN:263,264,Axes.set_yticks -FNDA:1,Axes.set_yticks -FN:266,267,Axes.set_xtick_labels -FNDA:1,Axes.set_xtick_labels -FN:269,270,Axes.set_ytick_labels -FNDA:1,Axes.set_ytick_labels -FN:273,274,Axes.xscale -FNDA:1,Axes.xscale -FN:277,278,Axes.xscale -FNDA:1,Axes.xscale -FN:281,282,Axes.yscale -FNDA:1,Axes.yscale -FN:285,286,Axes.yscale -FNDA:1,Axes.yscale -FN:289,326,Axes.set -FNDA:1,Axes.set -FN:328,331,Axes.delete_legend -FNDA:1,Axes.delete_legend -FN:334,410,Axes.legend -FNDA:1,Axes.legend -FN:412,442,Axes.tight_layout -FNDA:1,Axes.tight_layout -FN:444,470,Axes.style -FNDA:1,Axes.style +LH:68 +FN:30,66,chart_position +FNDA:0,chart_position +FN:76,120,Axes.__init__ +FNDA:0,Axes.__init__ +FN:123,157,Axes.copy +FNDA:0,Axes.copy +FN:160,162,Axes.xaxis +FNDA:0,Axes.xaxis +FN:165,167,Axes.yaxis +FNDA:0,Axes.yaxis +FN:170,183,Axes.add_series +FNDA:0,Axes.add_series +FN:186,192,Axes.title +FNDA:0,Axes.title +FN:195,196,Axes.title +FNDA:0,Axes.title +FN:198,218,Axes.set_title +FNDA:0,Axes.set_title +FN:221,222,Axes.xlabel +FNDA:0,Axes.xlabel +FN:225,226,Axes.xlabel +FNDA:0,Axes.xlabel +FN:229,230,Axes.ylabel +FNDA:0,Axes.ylabel +FN:233,234,Axes.ylabel +FNDA:0,Axes.ylabel +FN:236,237,Axes.set_xlabel +FNDA:0,Axes.set_xlabel +FN:239,240,Axes.set_ylabel +FNDA:0,Axes.set_ylabel +FN:243,244,Axes.xticks +FNDA:0,Axes.xticks +FN:247,248,Axes.xticks +FNDA:0,Axes.xticks +FN:251,252,Axes.yticks +FNDA:0,Axes.yticks +FN:255,256,Axes.yticks +FNDA:0,Axes.yticks +FN:258,264,Axes.set_xticks +FNDA:0,Axes.set_xticks +FN:266,272,Axes.set_yticks +FNDA:0,Axes.set_yticks +FN:274,275,Axes.set_xtick_labels +FNDA:0,Axes.set_xtick_labels +FN:277,278,Axes.set_ytick_labels +FNDA:0,Axes.set_ytick_labels +FN:281,282,Axes.xscale +FNDA:0,Axes.xscale +FN:285,286,Axes.xscale +FNDA:0,Axes.xscale +FN:289,290,Axes.yscale +FNDA:0,Axes.yscale +FN:293,294,Axes.yscale +FNDA:0,Axes.yscale +FN:297,334,Axes.set +FNDA:0,Axes.set +FN:336,339,Axes.delete_legend +FNDA:0,Axes.delete_legend +FN:342,419,Axes.legend +FNDA:0,Axes.legend +FN:421,451,Axes.tight_layout +FNDA:0,Axes.tight_layout +FN:453,479,Axes.style +FNDA:0,Axes.style FNF:32 -FNH:32 +FNH:0 end_of_record SF:src\xlviews\chart\series.py DA:1,1 @@ -374,273 +375,273 @@ DA:8,1 DA:9,1 DA:10,1 DA:12,1 +DA:18,1 +DA:19,1 DA:20,1 -DA:21,1 DA:22,1 -DA:24,1 -DA:32,1 -DA:33,1 -DA:34,1 -DA:36,1 -DA:37,1 -DA:39,1 -DA:40,1 -DA:41,1 +DA:30,0 +DA:31,0 +DA:32,0 +DA:34,0 +DA:35,0 +DA:37,0 +DA:38,0 +DA:39,0 +DA:42,0 DA:44,1 -DA:46,1 -DA:47,1 +DA:45,1 +DA:46,0 DA:48,1 -DA:50,1 -DA:51,1 +DA:49,1 +DA:50,0 DA:52,1 -DA:54,1 -DA:55,1 +DA:53,1 +DA:54,0 DA:56,1 -DA:58,1 -DA:59,1 +DA:57,1 +DA:58,0 DA:60,1 -DA:62,1 -DA:63,1 +DA:61,1 +DA:62,0 DA:64,1 -DA:66,1 -DA:67,1 -DA:68,1 -DA:69,1 +DA:65,1 +DA:66,0 +DA:67,0 +DA:69,0 DA:71,1 -DA:73,1 -DA:74,1 +DA:72,1 +DA:73,0 DA:75,1 -DA:77,1 -DA:78,1 -DA:79,1 -DA:80,1 +DA:76,1 +DA:77,0 +DA:78,0 +DA:80,0 DA:82,1 -DA:84,1 +DA:83,0 DA:85,1 -DA:87,1 -DA:98,1 -DA:99,1 -DA:101,1 -DA:102,1 -DA:103,1 -DA:105,1 +DA:96,0 +DA:97,0 +DA:99,0 +DA:100,0 +DA:101,0 +DA:103,0 +DA:104,0 DA:106,1 -DA:108,1 -DA:116,1 -DA:118,1 -DA:119,1 -DA:120,1 -DA:121,1 +DA:114,0 +DA:116,0 +DA:117,0 +DA:118,0 +DA:119,0 +DA:121,0 DA:123,1 -DA:125,1 -DA:134,1 -DA:135,1 -DA:137,1 -DA:139,1 -DA:140,1 -DA:141,1 -DA:142,1 -DA:144,1 -DA:147,1 -DA:148,1 -DA:149,1 -DA:150,1 -DA:151,1 -DA:154,1 -DA:155,1 -DA:156,1 -DA:157,1 -DA:158,1 -DA:159,1 -DA:162,1 -DA:169,1 -DA:170,1 -DA:172,1 -DA:173,1 -DA:174,1 -DA:175,1 -DA:176,1 -DA:177,1 -DA:179,1 +DA:132,0 +DA:133,0 +DA:135,0 +DA:137,0 +DA:138,0 +DA:139,0 +DA:140,0 +DA:142,0 +DA:145,1 +DA:146,0 +DA:147,0 +DA:148,0 +DA:149,0 +DA:152,1 +DA:153,0 +DA:154,0 +DA:155,0 +DA:156,0 +DA:157,0 +DA:160,1 +DA:167,0 +DA:168,0 +DA:170,0 +DA:171,0 +DA:172,0 +DA:173,0 +DA:174,0 +DA:175,0 +DA:177,0 LF:96 -LH:96 -FN:24,44,Series.__init__ -FNDA:1,Series.__init__ -FN:47,48,Series.label -FNDA:1,Series.label -FN:51,52,Series.label -FNDA:1,Series.label -FN:55,56,Series.chart_type -FNDA:1,Series.chart_type -FN:59,60,Series.chart_type -FNDA:1,Series.chart_type -FN:63,64,Series.x -FNDA:1,Series.x -FN:67,71,Series.x -FNDA:1,Series.x -FN:74,75,Series.y -FNDA:1,Series.y -FN:78,82,Series.y -FNDA:1,Series.y -FN:84,85,Series.delete -FNDA:1,Series.delete -FN:87,106,Series.set -FNDA:1,Series.set -FN:108,123,Series.marker -FNDA:1,Series.marker -FN:125,144,Series.line -FNDA:1,Series.line -FN:147,151,set_marker -FNDA:1,set_marker -FN:154,159,set_fill -FNDA:1,set_fill -FN:162,179,set_line -FNDA:1,set_line +LH:35 +FN:22,42,Series.__init__ +FNDA:0,Series.__init__ +FN:45,46,Series.label +FNDA:0,Series.label +FN:49,50,Series.label +FNDA:0,Series.label +FN:53,54,Series.chart_type +FNDA:0,Series.chart_type +FN:57,58,Series.chart_type +FNDA:0,Series.chart_type +FN:61,62,Series.x +FNDA:0,Series.x +FN:65,69,Series.x +FNDA:0,Series.x +FN:72,73,Series.y +FNDA:0,Series.y +FN:76,80,Series.y +FNDA:0,Series.y +FN:82,83,Series.delete +FNDA:0,Series.delete +FN:85,104,Series.set +FNDA:0,Series.set +FN:106,121,Series.marker +FNDA:0,Series.marker +FN:123,142,Series.line +FNDA:0,Series.line +FN:145,149,set_marker +FNDA:0,set_marker +FN:152,157,set_fill +FNDA:0,set_fill +FN:160,177,set_line +FNDA:0,set_line FNF:16 -FNH:16 +FNH:0 end_of_record SF:src\xlviews\chart\style.py DA:3,1 DA:5,1 DA:7,1 -DA:8,1 DA:9,1 +DA:10,1 DA:11,1 -DA:24,1 -DA:37,1 -DA:46,1 -DA:47,1 +DA:13,1 +DA:26,1 +DA:39,1 DA:48,1 -DA:50,1 -DA:53,1 -DA:54,1 +DA:49,0 +DA:50,0 +DA:52,0 DA:55,1 -DA:57,1 -DA:60,1 -DA:61,1 +DA:56,0 +DA:57,0 +DA:59,0 DA:62,1 -DA:64,1 -DA:67,1 -DA:74,1 -DA:75,1 -DA:76,1 -DA:78,1 -DA:79,1 -DA:80,1 -DA:82,1 -DA:83,1 -DA:85,1 -DA:88,1 -DA:89,1 -DA:97,1 -DA:106,1 -DA:108,1 -DA:109,1 -DA:110,1 -DA:111,1 -DA:113,1 -DA:114,1 -DA:116,1 -DA:117,1 -DA:119,1 -DA:120,1 -DA:122,1 -DA:123,1 -DA:125,1 -DA:127,1 -DA:128,1 -DA:130,1 -DA:131,1 -DA:133,1 -DA:135,1 -DA:136,1 -DA:139,1 -DA:145,1 -DA:146,1 -DA:147,1 -DA:149,1 -DA:150,1 -DA:153,1 -DA:154,1 +DA:63,0 +DA:64,0 +DA:66,0 +DA:69,1 +DA:76,0 +DA:77,0 +DA:78,0 +DA:80,0 +DA:81,0 +DA:82,0 +DA:84,0 +DA:85,0 +DA:87,0 +DA:90,1 +DA:91,0 +DA:99,1 +DA:108,0 +DA:110,0 +DA:111,0 +DA:112,0 +DA:113,0 +DA:115,0 +DA:116,0 +DA:118,0 +DA:119,0 +DA:121,0 +DA:122,0 +DA:124,0 +DA:125,0 +DA:127,0 +DA:129,0 +DA:130,0 +DA:132,0 +DA:133,0 +DA:135,0 +DA:137,0 +DA:138,0 +DA:141,1 +DA:147,0 +DA:148,0 +DA:149,0 +DA:151,0 +DA:152,0 DA:155,1 -DA:157,1 -DA:158,1 -DA:163,1 -DA:164,1 +DA:156,0 +DA:157,0 +DA:159,0 +DA:160,0 DA:165,1 -DA:166,1 -DA:168,1 -DA:169,1 -DA:170,1 -DA:175,1 -DA:182,1 -DA:183,1 -DA:185,1 -DA:186,1 -DA:188,1 -DA:189,1 -DA:191,1 -DA:192,1 -DA:195,1 -DA:201,1 -DA:202,1 -DA:203,1 -DA:205,1 -DA:206,1 -DA:207,1 -DA:209,1 -DA:210,1 -DA:211,1 -LF:91 -LH:91 -FN:46,50,get_marker_style -FNDA:1,get_marker_style -FN:53,57,get_line_style -FNDA:1,get_line_style -FN:60,64,get_axis_label -FNDA:1,get_axis_label -FN:67,85,set_axis_label -FNDA:1,set_axis_label -FN:88,94,get_ticks -FNDA:1,get_ticks -FN:97,136,set_ticks -FNDA:1,set_ticks -FN:139,150,set_tick_labels -FNDA:1,set_tick_labels -FN:153,160,get_axis_scale -FNDA:1,get_axis_scale -FN:163,172,set_axis_scale -FNDA:1,set_axis_scale -FN:175,192,set_dimensions -FNDA:1,set_dimensions -FN:195,211,set_area_format -FNDA:1,set_area_format +DA:166,0 +DA:167,0 +DA:168,0 +DA:170,0 +DA:171,0 +DA:172,0 +DA:177,1 +DA:184,0 +DA:185,0 +DA:187,0 +DA:188,0 +DA:190,0 +DA:191,0 +DA:193,0 +DA:194,0 +DA:197,1 +DA:203,0 +DA:204,0 +DA:205,0 +DA:207,0 +DA:208,0 +DA:209,0 +DA:211,0 +DA:212,0 +DA:213,0 +LF:92 +LH:20 +FN:48,52,get_marker_style +FNDA:0,get_marker_style +FN:55,59,get_line_style +FNDA:0,get_line_style +FN:62,66,get_axis_label +FNDA:0,get_axis_label +FN:69,87,set_axis_label +FNDA:0,set_axis_label +FN:90,96,get_ticks +FNDA:0,get_ticks +FN:99,138,set_ticks +FNDA:0,set_ticks +FN:141,152,set_tick_labels +FNDA:0,set_tick_labels +FN:155,162,get_axis_scale +FNDA:0,get_axis_scale +FN:165,174,set_axis_scale +FNDA:0,set_axis_scale +FN:177,194,set_dimensions +FNDA:0,set_dimensions +FN:197,213,set_area_format +FNDA:0,set_area_format FNF:11 -FNH:11 +FNH:0 end_of_record SF:src\xlviews\colors.py DA:1,1 DA:3,1 -DA:5,1 -DA:8,1 -DA:33,1 +DA:6,1 +DA:31,1 +DA:32,0 DA:34,1 -DA:36,1 -DA:37,1 -DA:39,1 -DA:40,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:46,1 -DA:48,1 -DA:49,1 -DA:51,1 -DA:52,1 -DA:55,1 -LF:19 -LH:19 -FN:8,52,rgb +DA:35,1 +DA:37,0 +DA:38,0 +DA:40,0 +DA:41,0 +DA:42,0 +DA:44,0 +DA:46,0 +DA:47,0 +DA:49,0 +DA:50,0 +DA:53,1 +LF:18 +LH:7 +FN:6,50,rgb FNDA:1,rgb FNF:1 FNH:1 @@ -665,19 +666,19 @@ DA:33,1 DA:34,1 DA:36,1 DA:38,1 -DA:39,1 -DA:40,1 -DA:42,1 -DA:43,1 -DA:45,1 +DA:39,0 +DA:40,0 +DA:42,0 +DA:43,0 +DA:45,0 DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 +DA:48,0 +DA:49,0 +DA:50,0 +DA:51,0 DA:54,1 LF:30 -LH:30 +LH:21 FN:18,20,load_config FNDA:1,load_config FN:26,27,Config.__init__ @@ -685,11 +686,11 @@ FNDA:1,Config.__init__ FN:29,36,Config.__getitem__ FNDA:1,Config.__getitem__ FN:38,45,Config.__setitem__ -FNDA:1,Config.__setitem__ +FNDA:0,Config.__setitem__ FN:47,51,Config.get -FNDA:1,Config.get +FNDA:0,Config.get FNF:5 -FNH:5 +FNH:3 end_of_record SF:src\xlviews\core\__init__.py end_of_record @@ -698,26 +699,26 @@ DA:1,1 DA:3,1 DA:6,1 DA:7,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:26,1 +DA:20,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:24,0 +DA:26,0 DA:29,1 DA:30,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:47,1 +DA:43,0 +DA:44,0 +DA:45,0 +DA:47,0 LF:16 -LH:16 +LH:6 FN:7,26,index_to_column_name -FNDA:1,index_to_column_name +FNDA:0,index_to_column_name FN:30,47,column_name_to_index -FNDA:1,column_name_to_index +FNDA:0,column_name_to_index FNF:2 -FNH:2 +FNH:0 end_of_record SF:src\xlviews\core\formula.py DA:1,1 @@ -725,165 +726,166 @@ DA:3,1 DA:5,1 DA:7,1 DA:8,1 -DA:13,1 -DA:15,1 -DA:18,1 -DA:20,1 -DA:21,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:32,1 -DA:35,1 -DA:46,1 +DA:14,1 +DA:16,1 +DA:19,1 +DA:21,0 +DA:22,0 +DA:24,0 +DA:25,0 +DA:26,0 +DA:27,0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:33,0 +DA:36,1 DA:47,1 DA:48,1 -DA:51,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:62,1 -DA:63,1 -DA:65,1 -DA:66,1 -DA:68,1 -DA:70,1 -DA:71,1 -DA:73,1 -DA:74,1 -DA:75,1 -DA:77,1 -DA:78,1 -DA:80,1 -DA:81,1 -DA:82,1 -DA:83,1 -DA:86,1 -DA:96,1 -DA:106,1 -DA:107,1 -DA:109,1 +DA:49,1 +DA:52,1 +DA:58,0 +DA:59,0 +DA:60,0 +DA:61,0 +DA:63,0 +DA:64,0 +DA:66,0 +DA:67,0 +DA:69,0 +DA:71,0 +DA:72,0 +DA:74,0 +DA:75,0 +DA:76,0 +DA:78,0 +DA:79,0 +DA:81,0 +DA:82,0 +DA:83,0 +DA:84,0 +DA:87,1 +DA:98,0 +DA:108,0 +DA:109,0 +DA:111,0 LF:48 -LH:48 -FN:18,32,const -FNDA:1,const -FN:51,83,_aggregate -FNDA:1,_aggregate -FN:86,109,aggregate -FNDA:1,aggregate +LH:14 +FN:19,33,const +FNDA:0,const +FN:52,84,_aggregate +FNDA:0,_aggregate +FN:87,111,aggregate +FNDA:0,aggregate FNF:3 -FNH:3 +FNH:0 end_of_record SF:src\xlviews\core\index.py DA:1,1 DA:3,1 -DA:5,1 +DA:4,1 DA:6,1 +DA:7,1 DA:16,1 DA:19,1 -DA:20,1 +DA:20,0 DA:22,1 DA:23,1 -DA:24,1 +DA:24,0 DA:26,1 -DA:27,1 +DA:27,0 DA:29,1 -DA:30,1 -DA:31,1 -DA:32,1 +DA:30,0 +DA:31,0 +DA:32,0 DA:34,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:39,1 +DA:35,0 +DA:36,0 +DA:37,0 +DA:39,0 DA:42,1 DA:43,1 DA:44,1 DA:46,1 -DA:51,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:58,1 +DA:51,0 +DA:53,0 +DA:54,0 +DA:55,0 +DA:56,0 +DA:58,0 DA:60,1 -DA:61,1 +DA:61,0 DA:63,1 DA:64,1 -DA:65,1 +DA:65,0 DA:67,1 DA:68,1 -DA:80,1 +DA:80,0 DA:82,1 -DA:90,1 +DA:90,0 DA:92,1 -DA:100,1 -DA:101,1 +DA:100,0 +DA:101,0 DA:103,1 -DA:117,1 -DA:118,1 -DA:120,1 +DA:117,0 +DA:118,0 +DA:120,0 DA:122,1 -DA:139,1 -DA:140,1 -DA:142,1 +DA:139,0 +DA:140,0 +DA:142,0 DA:144,1 -DA:158,1 -DA:159,1 -DA:160,1 -DA:161,1 -DA:163,1 -DA:164,1 -DA:165,1 +DA:158,0 +DA:159,0 +DA:160,0 +DA:161,0 +DA:163,0 +DA:164,0 +DA:165,0 DA:169,1 -DA:175,1 -DA:178,1 -DA:179,1 -DA:181,1 -DA:183,1 +DA:175,0 +DA:178,0 +DA:179,0 +DA:181,0 +DA:183,0 DA:185,1 -DA:186,1 -LF:68 -LH:68 +DA:186,0 +LF:69 +LH:28 FN:19,20,WideIndex.__len__ -FNDA:1,WideIndex.__len__ +FNDA:0,WideIndex.__len__ FN:23,24,WideIndex.names -FNDA:1,WideIndex.names +FNDA:0,WideIndex.names FN:26,27,WideIndex.to_list -FNDA:1,WideIndex.to_list +FNDA:0,WideIndex.to_list FN:29,32,WideIndex.get_loc -FNDA:1,WideIndex.get_loc +FNDA:0,WideIndex.get_loc FN:34,39,WideIndex.append -FNDA:1,WideIndex.append +FNDA:0,WideIndex.append FN:46,58,Index.__init__ -FNDA:1,Index.__init__ +FNDA:0,Index.__init__ FN:60,61,Index.__len__ -FNDA:1,Index.__len__ +FNDA:0,Index.__len__ FN:64,65,Index.names -FNDA:1,Index.names +FNDA:0,Index.names FN:68,80,Index.nlevels -FNDA:1,Index.nlevels +FNDA:0,Index.nlevels FN:82,90,Index.to_list -FNDA:1,Index.to_list +FNDA:0,Index.to_list FN:92,101,Index.__iter__ -FNDA:1,Index.__iter__ +FNDA:0,Index.__iter__ FN:103,120,Index.__contains__ -FNDA:1,Index.__contains__ +FNDA:0,Index.__contains__ FN:122,142,Index.append -FNDA:1,Index.append +FNDA:0,Index.append FN:144,167,Index.get_loc -FNDA:1,Index.get_loc +FNDA:0,Index.get_loc FN:169,183,Index.get_indexer -FNDA:1,Index.get_indexer +FNDA:0,Index.get_indexer FN:185,186,Index.to_frame -FNDA:1,Index.to_frame +FNDA:0,Index.to_frame FNF:16 -FNH:16 +FNH:0 end_of_record SF:src\xlviews\core\range.py DA:1,1 @@ -893,224 +895,226 @@ DA:6,1 DA:7,1 DA:8,1 DA:10,1 +DA:19,1 DA:20,1 DA:21,1 DA:22,1 DA:23,1 DA:24,1 -DA:25,1 -DA:27,1 -DA:33,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:40,1 -DA:41,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:48,1 -DA:49,1 +DA:26,1 +DA:32,0 +DA:34,0 +DA:35,0 +DA:36,0 +DA:37,0 +DA:39,0 +DA:40,0 +DA:42,0 +DA:43,0 +DA:44,0 +DA:47,0 +DA:48,0 +DA:50,1 DA:51,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:57,1 -DA:58,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:65,1 -DA:66,1 -DA:67,1 -DA:69,1 -DA:70,1 -DA:72,1 -DA:73,1 -DA:74,1 +DA:52,0 +DA:53,0 +DA:54,0 +DA:56,1 +DA:57,0 +DA:59,1 +DA:60,0 +DA:61,0 +DA:62,0 +DA:64,1 +DA:65,0 +DA:66,0 +DA:68,0 +DA:69,0 +DA:70,0 +DA:72,0 +DA:73,0 +DA:74,0 DA:76,1 DA:77,1 -DA:78,1 +DA:78,0 DA:80,1 -DA:81,1 -DA:82,1 +DA:81,0 +DA:82,0 DA:84,1 -DA:85,1 +DA:85,0 DA:91,1 -DA:99,1 -DA:107,1 +DA:99,0 +DA:107,0 DA:109,1 -DA:117,1 +DA:117,0 DA:127,1 DA:128,1 -DA:129,1 -DA:130,1 -DA:131,1 +DA:129,0 +DA:130,0 +DA:131,0 DA:133,1 DA:134,1 -DA:135,1 +DA:135,0 DA:137,1 DA:138,1 -DA:139,1 +DA:139,0 DA:141,1 DA:142,1 -DA:143,1 +DA:143,0 DA:145,1 DA:146,1 -DA:147,1 +DA:147,0 DA:154,1 -DA:164,1 -DA:165,1 -DA:167,1 -DA:168,1 -DA:176,1 -DA:177,1 -DA:179,1 +DA:164,0 +DA:165,0 +DA:167,0 +DA:168,0 +DA:176,0 +DA:177,0 +DA:179,0 DA:182,1 -DA:191,1 -DA:192,1 -DA:194,1 -DA:195,1 -DA:196,1 -DA:197,1 -DA:199,1 -DA:201,1 -DA:202,1 -DA:203,1 -DA:204,1 -DA:206,1 -DA:207,1 -DA:208,1 -DA:209,1 -DA:211,1 -DA:212,1 -DA:215,1 -DA:216,1 -DA:217,1 +DA:191,0 +DA:192,0 +DA:194,0 +DA:195,0 +DA:196,0 +DA:197,0 +DA:199,0 +DA:201,0 +DA:202,0 +DA:203,0 +DA:204,0 +DA:206,0 +DA:207,0 +DA:208,0 +DA:209,0 +DA:211,0 +DA:212,0 +DA:215,0 +DA:216,0 +DA:217,0 DA:220,1 DA:221,1 -DA:231,1 -DA:232,1 -DA:233,1 -DA:235,1 -DA:236,1 -DA:237,1 -DA:238,1 -DA:240,1 -DA:242,1 -DA:243,1 -DA:245,1 -DA:246,1 -DA:247,1 -DA:249,1 -LF:120 -LH:120 -FN:27,49,Range.__init__ -FNDA:1,Range.__init__ -FN:52,55,Range.from_range -FNDA:1,Range.from_range -FN:57,58,Range.__len__ -FNDA:1,Range.__len__ -FN:60,63,Range.__iter__ -FNDA:1,Range.__iter__ -FN:65,74,Range.__getitem__ -FNDA:1,Range.__getitem__ +DA:231,0 +DA:232,0 +DA:233,0 +DA:235,0 +DA:236,0 +DA:237,0 +DA:238,0 +DA:240,0 +DA:242,0 +DA:243,0 +DA:245,0 +DA:246,0 +DA:247,0 +DA:249,0 +LF:121 +LH:39 +FN:26,48,Range.__init__ +FNDA:0,Range.__init__ +FN:51,54,Range.from_range +FNDA:0,Range.from_range +FN:56,57,Range.__len__ +FNDA:0,Range.__len__ +FN:59,62,Range.__iter__ +FNDA:0,Range.__iter__ +FN:64,74,Range.__getitem__ +FNDA:0,Range.__getitem__ FN:77,78,Range.last_cell -FNDA:1,Range.last_cell +FNDA:0,Range.last_cell FN:80,82,Range.__repr__ -FNDA:1,Range.__repr__ +FNDA:0,Range.__repr__ FN:84,89,Range.offset -FNDA:1,Range.offset +FNDA:0,Range.offset FN:91,107,Range.get_address -FNDA:1,Range.get_address +FNDA:0,Range.get_address FN:109,125,Range.iter_addresses -FNDA:1,Range.iter_addresses +FNDA:0,Range.iter_addresses FN:128,131,Range.impl -FNDA:1,Range.impl +FNDA:0,Range.impl FN:134,135,Range.value -FNDA:1,Range.value +FNDA:0,Range.value FN:138,139,Range.value -FNDA:1,Range.value +FNDA:0,Range.value FN:142,143,Range.api -FNDA:1,Range.api +FNDA:0,Range.api FN:146,151,Range.frame -FNDA:1,Range.frame +FNDA:0,Range.frame FN:154,179,iter_addresses -FNDA:1,iter_addresses +FNDA:0,iter_addresses FN:182,217,_iter_addresses -FNDA:1,_iter_addresses +FNDA:0,_iter_addresses FN:221,249,FrameRange.get_address -FNDA:1,FrameRange.get_address +FNDA:0,FrameRange.get_address FNF:18 -FNH:18 +FNH:0 end_of_record SF:src\xlviews\core\range_collection.py DA:1,1 DA:3,1 -DA:5,1 -DA:13,1 +DA:4,1 +DA:6,1 DA:14,1 -DA:16,1 -DA:22,1 -DA:24,1 +DA:15,1 +DA:17,1 +DA:23,0 DA:25,1 -DA:26,1 -DA:27,1 -DA:29,1 +DA:26,0 +DA:27,0 +DA:28,0 DA:30,1 -DA:32,1 +DA:31,0 DA:33,1 -DA:35,1 -DA:43,1 -DA:49,1 +DA:34,0 +DA:36,1 +DA:43,0 +DA:49,0 DA:51,1 -DA:60,1 +DA:60,0 DA:70,1 DA:71,1 -DA:72,1 -DA:74,1 -DA:75,1 -DA:77,1 -DA:78,1 -DA:80,1 -DA:81,1 -DA:83,1 +DA:72,0 +DA:74,0 +DA:75,0 +DA:77,0 +DA:78,0 +DA:80,0 +DA:81,0 +DA:83,0 DA:86,1 -DA:91,1 -DA:92,1 -DA:94,1 -DA:95,1 -DA:96,1 -DA:97,1 -DA:99,1 -DA:100,1 -DA:101,1 -DA:102,1 -DA:105,1 -DA:106,1 -LF:43 -LH:43 -FN:16,22,RangeCollection.__init__ -FNDA:1,RangeCollection.__init__ -FN:24,27,RangeCollection.__repr__ -FNDA:1,RangeCollection.__repr__ -FN:29,30,RangeCollection.__len__ -FNDA:1,RangeCollection.__len__ -FN:32,33,RangeCollection.__iter__ -FNDA:1,RangeCollection.__iter__ -FN:35,49,RangeCollection.get_address -FNDA:1,RangeCollection.get_address +DA:92,0 +DA:93,0 +DA:95,0 +DA:96,0 +DA:97,0 +DA:98,0 +DA:100,0 +DA:101,0 +DA:102,0 +DA:103,0 +DA:106,0 +DA:107,0 +LF:44 +LH:15 +FN:17,23,RangeCollection.__init__ +FNDA:0,RangeCollection.__init__ +FN:25,28,RangeCollection.__repr__ +FNDA:0,RangeCollection.__repr__ +FN:30,31,RangeCollection.__len__ +FNDA:0,RangeCollection.__len__ +FN:33,34,RangeCollection.__iter__ +FNDA:0,RangeCollection.__iter__ +FN:36,49,RangeCollection.get_address +FNDA:0,RangeCollection.get_address FN:51,68,RangeCollection.iter_addresses -FNDA:1,RangeCollection.iter_addresses +FNDA:0,RangeCollection.iter_addresses FN:71,83,RangeCollection.api -FNDA:1,RangeCollection.api -FN:86,106,_iter_ranges_from_index -FNDA:1,_iter_ranges_from_index +FNDA:0,RangeCollection.api +FN:86,107,_iter_ranges_from_index +FNDA:0,_iter_ranges_from_index FNF:8 -FNH:8 +FNH:0 end_of_record SF:src\xlviews\dataframes\__init__.py end_of_record @@ -1123,126 +1127,126 @@ DA:8,1 DA:9,1 DA:10,1 DA:11,1 +DA:23,1 +DA:24,1 DA:25,1 DA:26,1 DA:27,1 DA:28,1 DA:29,1 -DA:30,1 DA:31,1 -DA:33,1 -DA:41,1 -DA:42,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:51,1 -DA:52,1 -DA:53,1 +DA:39,0 +DA:40,0 +DA:42,0 +DA:43,0 +DA:44,0 +DA:45,0 +DA:46,0 +DA:49,0 +DA:50,0 +DA:51,0 +DA:52,0 DA:54,1 -DA:56,1 -DA:63,1 -DA:64,1 -DA:65,1 -DA:66,1 -DA:67,1 -DA:68,1 -DA:70,1 -DA:72,1 -DA:73,1 +DA:61,0 +DA:62,0 +DA:63,0 +DA:64,0 +DA:65,0 +DA:66,0 +DA:68,0 +DA:70,0 +DA:71,0 +DA:73,0 DA:75,1 -DA:77,1 -DA:78,1 -DA:79,1 +DA:76,1 +DA:77,0 +DA:78,0 DA:80,1 -DA:82,1 -DA:83,1 -DA:84,1 +DA:81,1 +DA:82,0 +DA:83,0 DA:85,1 -DA:87,1 -DA:88,1 -DA:89,1 -DA:90,1 -DA:91,1 +DA:86,1 +DA:87,0 +DA:88,0 +DA:89,0 +DA:91,0 DA:93,1 -DA:95,1 -DA:96,1 -DA:97,1 -DA:98,1 -DA:99,1 +DA:94,1 +DA:95,0 +DA:96,0 +DA:97,0 +DA:99,0 DA:101,1 -DA:103,1 -DA:104,1 -DA:105,1 +DA:102,1 +DA:103,0 +DA:104,0 DA:106,1 -DA:108,1 -DA:109,1 -DA:110,1 -DA:111,1 -DA:112,1 +DA:107,1 +DA:108,0 +DA:109,0 +DA:110,0 +DA:111,0 DA:113,1 -DA:115,1 -DA:116,1 -DA:117,1 -DA:118,1 -DA:119,1 -DA:120,1 -DA:121,1 -DA:123,1 -DA:124,1 -DA:126,1 -DA:127,1 -DA:128,1 -DA:129,1 -DA:130,1 -DA:132,1 -DA:134,1 -DA:135,1 +DA:114,0 +DA:115,0 +DA:116,0 +DA:117,0 +DA:118,0 +DA:119,0 +DA:121,0 +DA:122,0 +DA:124,0 +DA:125,0 +DA:126,0 +DA:127,0 +DA:128,0 +DA:130,0 +DA:132,0 +DA:133,0 +DA:134,0 DA:136,1 -DA:138,1 +DA:137,0 DA:139,1 -DA:141,1 -DA:142,1 -DA:143,1 -DA:144,1 -DA:146,1 -DA:147,1 -DA:149,1 +DA:140,0 +DA:141,0 +DA:142,0 +DA:144,0 +DA:145,0 +DA:147,0 +DA:148,0 DA:150,1 -DA:152,1 -DA:154,1 -DA:155,1 -DA:157,1 +DA:152,0 +DA:153,0 +DA:155,0 LF:100 -LH:100 -FN:33,54,Colorbar.__init__ -FNDA:1,Colorbar.__init__ -FN:56,75,Colorbar.set -FNDA:1,Colorbar.set -FN:78,80,Colorbar.vmin -FNDA:1,Colorbar.vmin -FN:83,85,Colorbar.vmax -FNDA:1,Colorbar.vmax -FN:88,93,Colorbar.vmin -FNDA:1,Colorbar.vmin -FN:96,101,Colorbar.vmax -FNDA:1,Colorbar.vmax -FN:104,106,Colorbar.label -FNDA:1,Colorbar.label -FN:109,113,Colorbar.label -FNDA:1,Colorbar.label -FN:115,136,Colorbar.draw -FNDA:1,Colorbar.draw -FN:138,139,Colorbar.apply -FNDA:1,Colorbar.apply -FN:141,150,Colorbar.autofit -FNDA:1,Colorbar.autofit -FN:152,157,Colorbar.set_adjacent_column_width -FNDA:1,Colorbar.set_adjacent_column_width +LH:33 +FN:31,52,Colorbar.__init__ +FNDA:0,Colorbar.__init__ +FN:54,73,Colorbar.set +FNDA:0,Colorbar.set +FN:76,78,Colorbar.vmin +FNDA:0,Colorbar.vmin +FN:81,83,Colorbar.vmax +FNDA:0,Colorbar.vmax +FN:86,91,Colorbar.vmin +FNDA:0,Colorbar.vmin +FN:94,99,Colorbar.vmax +FNDA:0,Colorbar.vmax +FN:102,104,Colorbar.label +FNDA:0,Colorbar.label +FN:107,111,Colorbar.label +FNDA:0,Colorbar.label +FN:113,134,Colorbar.draw +FNDA:0,Colorbar.draw +FN:136,137,Colorbar.apply +FNDA:0,Colorbar.apply +FN:139,148,Colorbar.autofit +FNDA:0,Colorbar.autofit +FN:150,155,Colorbar.set_adjacent_column_width +FNDA:0,Colorbar.set_adjacent_column_width FNF:12 -FNH:12 +FNH:0 end_of_record SF:src\xlviews\dataframes\dist_frame.py DA:1,1 @@ -1256,109 +1260,110 @@ DA:14,1 DA:15,1 DA:17,1 DA:18,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:30,1 -DA:32,1 -DA:33,1 -DA:34,1 -DA:35,1 -DA:36,1 -DA:38,1 -DA:40,1 -DA:41,1 -DA:42,1 +DA:25,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:30,0 +DA:32,0 +DA:33,0 +DA:34,0 +DA:35,0 +DA:36,0 +DA:38,0 +DA:40,0 +DA:41,0 +DA:42,0 DA:44,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:62,1 -DA:63,1 -DA:65,1 -DA:66,1 -DA:68,1 -DA:69,1 -DA:71,1 -DA:72,1 -DA:74,1 -DA:75,1 -DA:77,1 -DA:78,1 -DA:79,1 -DA:80,1 -DA:178,1 +DA:50,0 +DA:51,0 +DA:52,0 +DA:54,0 +DA:55,0 +DA:56,0 +DA:58,0 +DA:59,0 +DA:60,0 +DA:61,0 +DA:63,0 +DA:64,0 +DA:66,0 +DA:67,0 +DA:69,0 +DA:70,0 +DA:72,0 +DA:73,0 +DA:75,0 +DA:76,0 +DA:78,0 +DA:79,0 +DA:80,0 +DA:81,0 DA:179,1 -DA:180,1 -DA:182,1 -DA:183,1 -DA:184,1 -DA:185,1 -DA:187,1 -DA:188,1 -DA:189,1 -DA:191,1 -DA:194,1 +DA:180,0 +DA:181,0 +DA:183,0 +DA:184,0 +DA:185,0 +DA:186,0 +DA:188,0 +DA:189,0 +DA:190,0 +DA:192,0 DA:195,1 -DA:196,1 -DA:197,1 -DA:200,1 +DA:196,0 +DA:197,0 +DA:198,0 DA:201,1 -DA:202,1 -DA:204,1 -DA:205,1 -DA:206,1 -DA:208,1 -DA:211,1 +DA:202,0 +DA:203,0 +DA:205,0 +DA:206,0 +DA:207,0 +DA:209,0 DA:212,1 -DA:213,1 -DA:214,1 -DA:217,1 +DA:213,0 +DA:214,0 +DA:215,0 DA:218,1 -DA:219,1 -DA:220,1 -DA:221,1 -DA:224,1 +DA:219,0 +DA:220,0 +DA:221,0 +DA:222,0 DA:225,1 -DA:226,1 -DA:228,1 -DA:229,1 -DA:231,1 -DA:232,1 -DA:234,1 -DA:235,1 -DA:238,1 +DA:226,0 +DA:227,0 +DA:229,0 +DA:230,0 +DA:232,0 +DA:233,0 +DA:235,0 +DA:236,0 DA:239,1 -DA:240,1 -LF:92 -LH:92 +DA:240,0 +DA:241,0 +LF:93 +LH:19 FN:18,42,DistFrame.__init__ -FNDA:1,DistFrame.__init__ -FN:44,80,DistFrame.set_values -FNDA:1,DistFrame.set_values -FN:178,191,select_index -FNDA:1,select_index -FN:194,197,get_init_data -FNDA:1,get_init_data -FN:200,208,get_dist_func -FNDA:1,get_dist_func -FN:211,214,counter -FNDA:1,counter -FN:217,221,sorted_value -FNDA:1,sorted_value -FN:224,235,sigma_value -FNDA:1,sigma_value -FN:238,240,set_formula -FNDA:1,set_formula +FNDA:0,DistFrame.__init__ +FN:44,81,DistFrame.set_values +FNDA:0,DistFrame.set_values +FN:179,192,select_index +FNDA:0,select_index +FN:195,198,get_init_data +FNDA:0,get_init_data +FN:201,209,get_dist_func +FNDA:0,get_dist_func +FN:212,215,counter +FNDA:0,counter +FN:218,222,sorted_value +FNDA:0,sorted_value +FN:225,236,sigma_value +FNDA:0,sigma_value +FN:239,241,set_formula +FNDA:0,set_formula FNF:9 -FNH:9 +FNH:0 end_of_record SF:src\xlviews\dataframes\groupby.py DA:1,1 @@ -1371,822 +1376,816 @@ DA:10,1 DA:11,1 DA:12,1 DA:13,1 -DA:20,1 DA:21,1 -DA:24,1 -DA:25,1 -DA:27,1 -DA:28,1 +DA:22,0 +DA:24,0 +DA:25,0 +DA:27,0 DA:30,1 -DA:33,1 -DA:37,1 -DA:38,1 -DA:40,1 -DA:42,1 -DA:44,1 -DA:45,1 -DA:47,1 -DA:48,1 -DA:50,1 -DA:52,1 -DA:53,1 +DA:34,0 +DA:35,0 +DA:37,0 +DA:39,0 +DA:41,0 +DA:42,0 +DA:44,0 +DA:45,0 +DA:47,0 +DA:49,0 +DA:50,0 +DA:52,0 DA:55,1 -DA:58,1 -DA:65,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:71,1 -DA:73,1 -DA:74,1 -DA:76,1 -DA:77,1 -DA:79,1 +DA:62,0 +DA:65,0 +DA:66,0 +DA:67,0 +DA:68,0 +DA:70,0 +DA:71,0 +DA:73,0 +DA:74,0 +DA:76,0 +DA:77,0 DA:80,1 +DA:81,1 +DA:82,1 DA:83,1 -DA:84,1 DA:85,1 -DA:86,1 -DA:88,1 -DA:95,1 +DA:92,0 +DA:93,0 +DA:94,0 DA:96,1 -DA:97,1 +DA:97,0 DA:99,1 -DA:100,1 +DA:100,0 DA:102,1 -DA:103,1 +DA:103,0 DA:105,1 -DA:106,1 +DA:106,0 DA:108,1 -DA:109,1 +DA:109,0 DA:111,1 -DA:112,1 +DA:112,0 DA:114,1 -DA:115,1 -DA:117,1 -DA:127,1 -DA:128,1 -DA:129,1 -DA:132,1 -DA:133,1 -DA:134,1 -DA:136,1 -DA:146,1 -DA:147,1 -DA:149,1 -DA:150,1 -DA:152,1 -DA:154,1 -DA:165,1 -DA:168,1 -DA:169,1 -DA:170,1 -DA:171,1 -DA:173,1 -DA:175,1 -DA:176,1 -DA:178,1 -DA:187,1 -DA:196,1 -DA:197,1 -DA:198,1 -DA:199,1 -DA:201,1 -DA:202,1 -DA:203,1 -DA:205,1 +DA:124,0 +DA:125,0 +DA:126,0 +DA:129,0 +DA:130,0 +DA:131,0 +DA:133,0 +DA:143,0 +DA:144,0 +DA:146,0 +DA:147,0 +DA:149,0 +DA:151,1 +DA:162,0 +DA:165,0 +DA:166,0 +DA:167,0 +DA:168,0 +DA:170,0 +DA:172,0 +DA:173,0 +DA:175,0 +DA:184,0 +DA:193,0 +DA:194,0 +DA:195,0 +DA:196,0 +DA:198,0 +DA:199,0 +DA:200,0 +DA:202,0 +DA:203,0 +DA:204,0 DA:206,1 -DA:207,1 -DA:209,1 -DA:210,1 -DA:211,1 -DA:212,1 -DA:213,1 -DA:214,1 -DA:216,1 -DA:217,1 -DA:218,1 -LF:105 -LH:105 -FN:24,30,to_dict -FNDA:1,to_dict -FN:33,55,create_group_index -FNDA:1,create_group_index -FN:58,80,groupby -FNDA:1,groupby -FN:88,97,GroupBy.__init__ -FNDA:1,GroupBy.__init__ -FN:99,100,GroupBy.__len__ -FNDA:1,GroupBy.__len__ -FN:102,103,GroupBy.keys -FNDA:1,GroupBy.keys -FN:105,106,GroupBy.values -FNDA:1,GroupBy.values -FN:108,109,GroupBy.items -FNDA:1,GroupBy.items -FN:111,112,GroupBy.__iter__ -FNDA:1,GroupBy.__iter__ -FN:114,115,GroupBy.__getitem__ -FNDA:1,GroupBy.__getitem__ -FN:117,152,GroupBy.index -FNDA:1,GroupBy.index -FN:154,207,GroupBy.agg -FNDA:1,GroupBy.agg -FN:209,218,GroupBy._agg -FNDA:1,GroupBy._agg +DA:207,0 +DA:208,0 +DA:209,0 +DA:210,0 +DA:211,0 +DA:213,0 +DA:214,0 +DA:215,0 +LF:103 +LH:27 +FN:21,27,to_dict +FNDA:0,to_dict +FN:30,52,create_group_index +FNDA:0,create_group_index +FN:55,77,groupby +FNDA:0,groupby +FN:85,94,GroupBy.__init__ +FNDA:0,GroupBy.__init__ +FN:96,97,GroupBy.__len__ +FNDA:0,GroupBy.__len__ +FN:99,100,GroupBy.keys +FNDA:0,GroupBy.keys +FN:102,103,GroupBy.values +FNDA:0,GroupBy.values +FN:105,106,GroupBy.items +FNDA:0,GroupBy.items +FN:108,109,GroupBy.__iter__ +FNDA:0,GroupBy.__iter__ +FN:111,112,GroupBy.__getitem__ +FNDA:0,GroupBy.__getitem__ +FN:114,149,GroupBy.index +FNDA:0,GroupBy.index +FN:151,204,GroupBy.agg +FNDA:0,GroupBy.agg +FN:206,215,GroupBy._agg +FNDA:0,GroupBy._agg FNF:13 -FNH:13 +FNH:0 end_of_record SF:src\xlviews\dataframes\heat_frame.py DA:1,1 DA:3,1 DA:5,1 -DA:7,1 +DA:6,1 DA:8,1 DA:9,1 DA:10,1 DA:11,1 -DA:13,1 +DA:12,1 DA:14,1 +DA:15,1 +DA:25,1 DA:26,1 DA:27,1 DA:28,1 -DA:29,1 +DA:30,1 DA:31,1 -DA:32,1 +DA:40,0 +DA:42,0 +DA:44,0 +DA:46,0 +DA:47,0 +DA:48,0 +DA:50,0 +DA:51,0 +DA:53,1 +DA:58,0 +DA:60,0 +DA:61,0 +DA:62,0 +DA:63,0 +DA:65,0 +DA:66,0 +DA:68,1 +DA:76,0 +DA:77,0 +DA:79,1 +DA:80,0 +DA:81,0 +DA:83,1 +DA:90,0 +DA:91,0 +DA:92,0 +DA:94,0 +DA:95,0 +DA:96,0 +DA:97,0 +DA:99,0 +DA:100,0 +DA:101,0 +DA:103,1 +DA:104,1 +DA:113,0 +DA:114,0 +DA:115,0 +DA:116,0 +DA:118,1 +DA:119,1 +DA:131,0 +DA:132,0 +DA:133,0 +DA:134,0 +DA:136,0 +DA:137,0 +DA:139,0 +DA:140,0 +DA:142,0 +DA:143,0 +DA:145,0 +DA:146,0 +DA:147,0 +DA:148,0 +DA:150,0 +DA:152,0 +DA:153,0 +DA:156,1 +DA:157,0 +DA:159,0 +DA:160,0 +DA:162,0 +DA:163,0 +DA:165,0 +DA:167,0 +DA:170,1 +DA:176,0 +DA:177,0 +DA:178,0 +DA:180,0 +DA:181,0 +DA:183,0 +DA:184,0 +DA:185,0 +DA:187,0 +DA:188,0 +DA:191,0 +DA:194,1 +DA:199,0 +DA:200,0 +DA:202,0 +DA:203,0 +DA:205,0 +LF:101 +LH:28 +FN:31,51,HeatFrame.__init__ +FNDA:0,HeatFrame.__init__ +FN:53,66,HeatFrame.set +FNDA:0,HeatFrame.set +FN:68,77,HeatFrame.style +FNDA:0,HeatFrame.style +FN:79,81,HeatFrame.number_format +FNDA:0,HeatFrame.number_format +FN:83,101,HeatFrame.colorbar +FNDA:0,HeatFrame.colorbar +FN:104,116,HeatFrame.facet +FNDA:0,HeatFrame.facet +FN:119,153,HeatFrame.pair +FNDA:0,HeatFrame.pair +FN:156,167,clean_data +FNDA:0,clean_data +FN:170,191,iterrows +FNDA:0,iterrows +FN:194,205,xs +FNDA:0,xs +FNF:10 +FNH:0 +end_of_record +SF:src\xlviews\dataframes\sheet_frame.py +DA:3,1 +DA:5,1 +DA:6,1 +DA:7,1 +DA:8,1 +DA:10,1 +DA:11,1 +DA:12,1 +DA:13,1 +DA:14,1 +DA:15,1 +DA:16,1 +DA:18,1 +DA:19,1 +DA:20,1 +DA:21,1 +DA:22,1 +DA:23,1 +DA:25,1 +DA:26,1 +DA:27,1 +DA:35,1 +DA:38,1 +DA:39,1 +DA:40,1 DA:41,1 -DA:43,1 +DA:42,1 +DA:44,1 DA:45,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:51,1 -DA:52,1 -DA:54,1 -DA:59,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:64,1 -DA:66,1 -DA:67,1 -DA:69,1 -DA:77,1 -DA:78,1 -DA:80,1 +DA:60,0 +DA:61,0 +DA:63,0 +DA:64,0 +DA:66,0 +DA:68,0 +DA:69,0 +DA:71,1 +DA:72,0 +DA:73,0 +DA:74,0 +DA:76,1 +DA:77,0 +DA:78,0 +DA:79,0 DA:81,1 -DA:82,1 +DA:82,0 DA:84,1 -DA:91,1 -DA:92,1 +DA:85,0 +DA:86,0 +DA:88,0 +DA:90,1 +DA:91,0 DA:93,1 -DA:95,1 -DA:96,1 -DA:97,1 -DA:98,1 -DA:100,1 -DA:101,1 -DA:102,1 -DA:104,1 -DA:105,1 -DA:114,1 -DA:115,1 -DA:116,1 -DA:117,1 -DA:119,1 -DA:120,1 -DA:132,1 -DA:133,1 -DA:134,1 -DA:135,1 -DA:137,1 -DA:138,1 -DA:140,1 -DA:141,1 -DA:143,1 -DA:144,1 -DA:146,1 -DA:147,1 -DA:148,1 -DA:149,1 -DA:151,1 -DA:153,1 -DA:154,1 -DA:157,1 -DA:158,1 -DA:160,1 -DA:161,1 -DA:163,1 -DA:164,1 -DA:166,1 -DA:168,1 -DA:171,1 -DA:177,1 -DA:178,1 -DA:179,1 -DA:181,1 -DA:182,1 -DA:184,1 -DA:185,1 -DA:186,1 -DA:188,1 -DA:189,1 -DA:192,1 -DA:195,1 -DA:200,1 -DA:201,1 -DA:203,1 -DA:204,1 -DA:206,1 -LF:100 -LH:100 -FN:32,52,HeatFrame.__init__ -FNDA:1,HeatFrame.__init__ -FN:54,67,HeatFrame.set -FNDA:1,HeatFrame.set -FN:69,78,HeatFrame.style -FNDA:1,HeatFrame.style -FN:80,82,HeatFrame.number_format -FNDA:1,HeatFrame.number_format -FN:84,102,HeatFrame.colorbar -FNDA:1,HeatFrame.colorbar -FN:105,117,HeatFrame.facet -FNDA:1,HeatFrame.facet -FN:120,154,HeatFrame.pair -FNDA:1,HeatFrame.pair -FN:157,168,clean_data -FNDA:1,clean_data -FN:171,192,iterrows -FNDA:1,iterrows -FN:195,206,xs -FNDA:1,xs -FNF:10 -FNH:10 -end_of_record -SF:src\xlviews\dataframes\sheet_frame.py -DA:3,1 -DA:5,1 -DA:6,1 -DA:7,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:13,1 -DA:14,1 -DA:15,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:35,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:44,1 -DA:45,1 -DA:60,1 -DA:61,1 -DA:63,1 -DA:64,1 -DA:66,1 -DA:68,1 -DA:69,1 -DA:71,1 -DA:72,1 -DA:73,1 -DA:74,1 -DA:76,1 -DA:77,1 -DA:78,1 -DA:79,1 -DA:81,1 -DA:82,1 -DA:84,1 -DA:85,1 -DA:86,1 -DA:88,1 -DA:90,1 -DA:91,1 -DA:93,1 -DA:94,1 -DA:96,1 +DA:94,1 +DA:96,0 DA:98,1 DA:99,1 -DA:101,1 +DA:101,0 DA:103,1 DA:104,1 -DA:105,1 +DA:105,0 DA:107,1 DA:108,1 -DA:109,1 +DA:109,0 DA:111,1 DA:112,1 -DA:113,1 +DA:113,0 DA:115,1 DA:116,1 -DA:117,1 -DA:118,1 -DA:119,1 -DA:120,1 -DA:122,1 -DA:125,1 +DA:117,0 +DA:118,0 +DA:119,0 +DA:120,0 +DA:122,0 +DA:125,0 DA:127,1 -DA:128,1 -DA:129,1 -DA:131,1 +DA:128,0 +DA:129,0 +DA:131,0 DA:133,1 -DA:134,1 -DA:136,1 -DA:137,1 -DA:139,1 -DA:144,1 -DA:145,1 -DA:151,1 -DA:152,1 -DA:153,1 -DA:154,1 +DA:138,0 +DA:139,0 +DA:145,0 +DA:146,0 +DA:147,0 +DA:148,0 +DA:149,0 +DA:150,0 +DA:152,0 +DA:153,0 DA:155,1 DA:156,1 -DA:158,1 -DA:159,1 -DA:161,1 DA:162,1 -DA:168,1 +DA:163,1 DA:169,1 -DA:175,1 -DA:180,1 -DA:183,1 -DA:184,1 -DA:185,1 -DA:186,1 -DA:187,1 -DA:188,1 -DA:189,1 -DA:190,1 -DA:191,1 -DA:192,1 -DA:193,1 +DA:174,0 +DA:177,0 +DA:178,0 +DA:179,0 +DA:180,0 +DA:181,0 +DA:182,0 +DA:183,0 +DA:184,0 +DA:186,0 +DA:187,0 +DA:188,0 +DA:189,0 +DA:190,0 +DA:192,0 +DA:193,0 DA:195,1 -DA:196,1 -DA:197,1 -DA:198,1 -DA:199,1 -DA:201,1 -DA:202,1 -DA:204,1 -DA:205,1 -DA:206,1 -DA:207,1 -DA:208,1 -DA:210,1 -DA:211,1 -DA:213,1 -DA:214,1 -DA:215,1 -DA:216,1 -DA:218,1 -DA:219,1 -DA:222,1 -DA:224,1 -DA:233,1 -DA:236,1 -DA:237,1 -DA:238,1 -DA:240,1 -DA:241,1 +DA:196,0 +DA:197,0 +DA:198,0 +DA:199,0 +DA:201,0 +DA:202,0 +DA:205,0 +DA:206,0 +DA:207,0 +DA:209,0 +DA:210,0 +DA:212,1 +DA:221,0 +DA:224,0 +DA:225,0 +DA:226,0 +DA:228,0 +DA:229,0 +DA:231,0 +DA:232,0 +DA:233,0 +DA:234,0 +DA:236,0 +DA:237,0 +DA:238,0 +DA:240,0 +DA:241,0 DA:243,1 -DA:244,1 -DA:245,1 -DA:246,1 -DA:248,1 -DA:249,1 -DA:250,1 -DA:252,1 -DA:253,1 -DA:255,1 -DA:273,1 -DA:276,1 -DA:277,1 -DA:278,1 -DA:279,1 -DA:280,1 -DA:282,1 -DA:283,1 -DA:284,1 -DA:285,1 -DA:287,1 -DA:288,1 -DA:290,1 -DA:291,1 -DA:293,1 -DA:310,1 -DA:313,1 -DA:314,1 -DA:315,1 -DA:316,1 -DA:318,1 -DA:319,1 -DA:320,1 -DA:323,1 -DA:324,1 -DA:326,1 -DA:328,1 -DA:329,1 +DA:261,0 +DA:264,0 +DA:265,0 +DA:266,0 +DA:267,0 +DA:268,0 +DA:270,0 +DA:271,0 +DA:272,0 +DA:273,0 +DA:275,0 +DA:276,0 +DA:278,0 +DA:279,0 +DA:281,1 +DA:298,0 +DA:301,0 +DA:302,0 +DA:303,0 +DA:304,0 +DA:306,0 +DA:307,0 +DA:308,0 +DA:311,0 +DA:312,0 +DA:314,0 +DA:316,0 +DA:317,0 +DA:319,0 +DA:320,0 +DA:322,0 +DA:323,0 +DA:325,0 +DA:326,0 +DA:328,0 +DA:329,0 DA:331,1 DA:332,1 -DA:334,1 -DA:335,1 -DA:337,1 -DA:338,1 -DA:340,1 -DA:341,1 +DA:342,1 DA:343,1 -DA:344,1 -DA:354,1 -DA:355,1 -DA:365,1 -DA:374,1 -DA:375,1 -DA:376,1 -DA:378,1 -DA:380,1 -DA:382,1 -DA:383,1 -DA:385,1 -DA:395,1 -DA:396,1 -DA:398,1 +DA:353,1 +DA:362,0 +DA:363,0 +DA:364,0 +DA:366,0 +DA:368,0 +DA:370,0 +DA:371,0 +DA:373,0 +DA:383,0 +DA:384,0 +DA:386,0 +DA:388,1 +DA:389,1 DA:400,1 DA:401,1 DA:412,1 -DA:413,1 -DA:424,1 -DA:434,1 -DA:435,1 -DA:436,1 -DA:447,1 -DA:448,1 -DA:449,1 -DA:450,1 -DA:452,1 -DA:453,1 -DA:454,1 -DA:455,1 -DA:456,1 -DA:458,1 -DA:460,1 -DA:461,1 -DA:463,1 -DA:472,1 +DA:422,0 +DA:423,0 +DA:424,0 +DA:435,0 +DA:436,0 +DA:437,0 +DA:438,0 +DA:440,0 +DA:441,0 +DA:442,0 +DA:443,0 +DA:444,0 +DA:445,0 +DA:446,0 +DA:448,0 +DA:450,0 +DA:451,0 +DA:453,0 +DA:462,0 +DA:463,0 +DA:464,0 +DA:466,0 +DA:467,0 +DA:468,0 +DA:470,0 +DA:471,0 DA:473,1 DA:474,1 -DA:476,1 -DA:477,1 -DA:478,1 -DA:480,1 +DA:475,0 +DA:476,0 +DA:477,0 +DA:479,0 DA:481,1 -DA:483,1 -DA:484,1 -DA:485,1 -DA:486,1 -DA:488,1 -DA:490,1 -DA:501,1 -DA:511,1 -DA:512,1 -DA:513,1 -DA:515,1 -DA:516,1 -DA:517,1 -DA:518,1 -DA:519,1 -DA:521,1 -DA:523,1 -DA:535,1 -DA:536,1 -DA:551,1 -DA:552,1 -DA:554,1 -DA:555,1 -DA:564,1 -DA:565,1 -DA:567,1 -DA:569,1 -DA:570,1 -DA:571,1 -DA:573,1 -DA:575,1 +DA:492,0 +DA:502,0 +DA:503,0 +DA:504,0 +DA:506,0 +DA:507,0 +DA:508,0 +DA:509,0 +DA:510,0 +DA:512,0 +DA:514,1 +DA:526,0 +DA:527,0 +DA:542,0 +DA:543,0 +DA:545,0 +DA:546,0 +DA:555,0 +DA:557,0 +DA:558,0 +DA:559,0 +DA:560,0 +DA:562,0 +DA:564,0 +DA:574,0 +DA:576,1 +DA:577,0 +DA:579,1 +DA:580,0 +DA:581,0 +DA:582,0 +DA:583,0 DA:585,1 -DA:587,1 -DA:588,1 -DA:590,1 -DA:591,1 -DA:592,1 -DA:593,1 -DA:594,1 -DA:596,1 -DA:603,1 -DA:604,1 -DA:606,1 -DA:607,1 -DA:609,1 -DA:610,1 -DA:611,1 -DA:612,1 -DA:614,1 -DA:615,1 -DA:616,1 -DA:617,1 -DA:618,1 -DA:619,1 -DA:620,1 -DA:622,1 +DA:592,0 +DA:593,0 +DA:595,0 +DA:596,0 +DA:598,0 +DA:599,0 +DA:600,0 +DA:601,0 +DA:603,0 +DA:604,0 +DA:605,0 +DA:606,0 +DA:607,0 +DA:608,0 +DA:609,0 +DA:611,0 +DA:612,0 +DA:613,0 +DA:614,0 +DA:615,0 +DA:616,0 +DA:621,0 DA:623,1 -DA:624,1 -DA:625,1 -DA:626,1 -DA:627,1 -DA:632,1 +DA:624,0 +DA:625,0 +DA:626,0 +DA:628,1 +DA:629,0 +DA:630,0 +DA:631,0 +DA:632,0 DA:634,1 -DA:635,1 -DA:636,1 -DA:637,1 -DA:639,1 -DA:640,1 +DA:635,0 +DA:636,0 +DA:637,0 +DA:638,0 +DA:639,0 DA:641,1 -DA:642,1 -DA:643,1 -DA:645,1 +DA:643,0 +DA:644,0 DA:646,1 -DA:647,1 -DA:648,1 -DA:649,1 +DA:648,0 DA:650,1 -DA:652,1 -DA:654,1 -DA:655,1 -DA:657,1 -DA:659,1 -DA:661,1 -DA:662,1 -DA:664,1 -DA:671,1 -DA:672,1 -DA:674,1 -DA:677,1 -DA:679,1 -DA:680,1 +DA:651,0 +DA:653,1 +DA:660,0 +DA:661,0 +DA:663,0 +DA:666,0 +DA:668,0 +DA:669,0 +DA:671,0 +DA:678,0 +DA:680,0 DA:682,1 -DA:689,1 -DA:691,1 -DA:693,1 -DA:694,1 -DA:695,1 -DA:696,1 -DA:698,1 -DA:701,1 -DA:713,1 -DA:714,1 -DA:715,1 -DA:717,1 -DA:718,1 -DA:720,1 -DA:723,1 -DA:724,1 -DA:725,1 -DA:727,1 -DA:728,1 -DA:730,1 -DA:731,1 -DA:733,1 -DA:736,1 -DA:737,1 -DA:738,1 -DA:740,1 -DA:741,1 -DA:742,1 -DA:744,1 -DA:745,1 -DA:747,1 -DA:748,1 -DA:749,1 -DA:751,1 -LF:355 -LH:355 +DA:683,0 +DA:684,0 +DA:685,0 +DA:687,0 +DA:690,1 +DA:702,0 +DA:703,0 +DA:704,0 +DA:706,0 +DA:707,0 +DA:709,0 +DA:710,0 +DA:712,0 +DA:713,0 +DA:716,1 +DA:717,0 +DA:718,0 +DA:720,0 +DA:721,0 +DA:723,0 +DA:724,0 +DA:726,0 +DA:729,1 +DA:730,0 +DA:731,0 +DA:733,0 +DA:734,0 +DA:735,0 +DA:737,0 +DA:738,0 +DA:740,0 +DA:741,0 +DA:742,0 +DA:744,0 +LF:352 +LH:85 FN:45,69,SheetFrame.__init__ -FNDA:1,SheetFrame.__init__ +FNDA:0,SheetFrame.__init__ FN:71,74,SheetFrame.expand -FNDA:1,SheetFrame.expand +FNDA:0,SheetFrame.expand FN:76,79,SheetFrame.__repr__ -FNDA:1,SheetFrame.__repr__ +FNDA:0,SheetFrame.__repr__ FN:81,82,SheetFrame.__len__ -FNDA:1,SheetFrame.__len__ +FNDA:0,SheetFrame.__len__ FN:84,88,SheetFrame.__contains__ -FNDA:1,SheetFrame.__contains__ +FNDA:0,SheetFrame.__contains__ FN:90,91,SheetFrame.__iter__ -FNDA:1,SheetFrame.__iter__ +FNDA:0,SheetFrame.__iter__ FN:94,96,SheetFrame.row -FNDA:1,SheetFrame.row +FNDA:0,SheetFrame.row FN:99,101,SheetFrame.column -FNDA:1,SheetFrame.column +FNDA:0,SheetFrame.column FN:104,105,SheetFrame.shape -FNDA:1,SheetFrame.shape +FNDA:0,SheetFrame.shape FN:108,109,SheetFrame.height -FNDA:1,SheetFrame.height +FNDA:0,SheetFrame.height FN:112,113,SheetFrame.width -FNDA:1,SheetFrame.width +FNDA:0,SheetFrame.width FN:116,125,SheetFrame.value -FNDA:1,SheetFrame.value +FNDA:0,SheetFrame.value FN:127,131,SheetFrame.get_loc -FNDA:1,SheetFrame.get_loc -FN:134,134,SheetFrame.get_indexer -FNDA:1,SheetFrame.get_indexer -FN:137,137,SheetFrame.get_indexer -FNDA:1,SheetFrame.get_indexer -FN:139,159,SheetFrame.get_indexer -FNDA:1,SheetFrame.get_indexer -FN:162,166,SheetFrame.get_range +FNDA:0,SheetFrame.get_loc +FN:133,153,SheetFrame.get_indexer +FNDA:0,SheetFrame.get_indexer +FN:156,160,SheetFrame.get_range FNDA:0,SheetFrame.get_range -FN:169,173,SheetFrame.get_range +FN:163,167,SheetFrame.get_range FNDA:0,SheetFrame.get_range -FN:175,202,SheetFrame.get_range -FNDA:1,SheetFrame.get_range -FN:204,222,SheetFrame.iter_ranges -FNDA:1,SheetFrame.iter_ranges -FN:224,253,SheetFrame.add_column -FNDA:1,SheetFrame.add_column -FN:255,291,SheetFrame.add_wide_column -FNDA:1,SheetFrame.add_wide_column -FN:293,341,SheetFrame.add_formula_column -FNDA:1,SheetFrame.add_formula_column -FN:344,352,SheetFrame.get_address +FN:169,193,SheetFrame.get_range +FNDA:0,SheetFrame.get_range +FN:195,210,SheetFrame.iter_ranges +FNDA:0,SheetFrame.iter_ranges +FN:212,241,SheetFrame.add_column +FNDA:0,SheetFrame.add_column +FN:243,279,SheetFrame.add_wide_column +FNDA:0,SheetFrame.add_wide_column +FN:281,329,SheetFrame.add_formula_column +FNDA:0,SheetFrame.add_formula_column +FN:332,340,SheetFrame.get_address +FNDA:0,SheetFrame.get_address +FN:343,351,SheetFrame.get_address FNDA:0,SheetFrame.get_address -FN:355,363,SheetFrame.get_address +FN:353,386,SheetFrame.get_address FNDA:0,SheetFrame.get_address -FN:365,398,SheetFrame.get_address -FNDA:1,SheetFrame.get_address +FN:389,398,SheetFrame.agg +FNDA:0,SheetFrame.agg FN:401,410,SheetFrame.agg FNDA:0,SheetFrame.agg -FN:413,422,SheetFrame.agg +FN:412,471,SheetFrame.agg FNDA:0,SheetFrame.agg -FN:424,481,SheetFrame.agg -FNDA:1,SheetFrame.agg -FN:483,488,SheetFrame._agg -FNDA:1,SheetFrame._agg -FN:490,521,SheetFrame.melt -FNDA:1,SheetFrame.melt -FN:523,585,SheetFrame.pivot_table -FNDA:1,SheetFrame.pivot_table -FN:587,588,SheetFrame.groupby -FNDA:1,SheetFrame.groupby -FN:590,594,SheetFrame.get_number_format -FNDA:1,SheetFrame.get_number_format -FN:596,632,SheetFrame.number_format -FNDA:1,SheetFrame.number_format -FN:634,637,SheetFrame.style -FNDA:1,SheetFrame.style -FN:639,643,SheetFrame.autofit -FNDA:1,SheetFrame.autofit -FN:645,650,SheetFrame.alignment -FNDA:1,SheetFrame.alignment -FN:652,655,SheetFrame.set_adjacent_column_width -FNDA:1,SheetFrame.set_adjacent_column_width -FN:657,659,SheetFrame.get_adjacent_cell -FNDA:1,SheetFrame.get_adjacent_cell -FN:661,662,SheetFrame.move -FNDA:1,SheetFrame.move -FN:664,691,SheetFrame.as_table -FNDA:1,SheetFrame.as_table -FN:693,698,SheetFrame.unlist -FNDA:1,SheetFrame.unlist -FN:701,720,move -FNDA:1,move -FN:723,733,_move_down -FNDA:1,_move_down -FN:736,751,_move_right -FNDA:1,_move_right -FNF:46 -FNH:40 +FN:474,479,SheetFrame._agg +FNDA:0,SheetFrame._agg +FN:481,512,SheetFrame.melt +FNDA:0,SheetFrame.melt +FN:514,574,SheetFrame.pivot_table +FNDA:0,SheetFrame.pivot_table +FN:576,577,SheetFrame.groupby +FNDA:0,SheetFrame.groupby +FN:579,583,SheetFrame.get_number_format +FNDA:0,SheetFrame.get_number_format +FN:585,621,SheetFrame.number_format +FNDA:0,SheetFrame.number_format +FN:623,626,SheetFrame.style +FNDA:0,SheetFrame.style +FN:628,632,SheetFrame.autofit +FNDA:0,SheetFrame.autofit +FN:634,639,SheetFrame.alignment +FNDA:0,SheetFrame.alignment +FN:641,644,SheetFrame.set_adjacent_column_width +FNDA:0,SheetFrame.set_adjacent_column_width +FN:646,648,SheetFrame.get_adjacent_cell +FNDA:0,SheetFrame.get_adjacent_cell +FN:650,651,SheetFrame.move +FNDA:0,SheetFrame.move +FN:653,680,SheetFrame.as_table +FNDA:0,SheetFrame.as_table +FN:682,687,SheetFrame.unlist +FNDA:0,SheetFrame.unlist +FN:690,713,move +FNDA:0,move +FN:716,726,_move_down +FNDA:0,_move_down +FN:729,744,_move_right +FNDA:0,_move_right +FNF:44 +FNH:0 end_of_record SF:src\xlviews\dataframes\stats_frame.py DA:1,1 DA:3,1 -DA:4,1 DA:5,1 +DA:6,1 DA:7,1 -DA:8,1 DA:9,1 DA:10,1 DA:11,1 +DA:12,1 DA:13,1 -DA:14,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:52,1 -DA:54,1 -DA:55,1 -DA:57,1 -DA:59,1 -DA:60,1 -DA:62,1 -DA:63,1 -DA:65,1 -DA:67,1 -DA:68,1 -DA:69,1 -DA:72,1 -DA:73,1 +DA:15,1 +DA:16,1 +DA:22,1 +DA:23,1 +DA:24,1 +DA:47,0 +DA:48,0 +DA:49,0 +DA:52,0 +DA:53,0 +DA:55,0 +DA:57,0 +DA:58,0 +DA:60,0 +DA:62,0 +DA:63,0 +DA:65,0 +DA:67,0 +DA:69,0 +DA:70,0 +DA:71,0 DA:74,1 -DA:75,1 -DA:76,1 -DA:77,1 -DA:79,1 -DA:82,1 -DA:83,1 +DA:75,0 +DA:76,0 +DA:77,0 +DA:78,0 +DA:79,0 +DA:81,0 DA:84,1 -DA:86,1 -DA:89,1 -DA:90,1 -DA:92,1 -DA:93,1 -DA:95,1 +DA:85,0 +DA:86,0 +DA:88,0 +DA:91,1 +DA:92,0 +DA:93,0 +DA:95,0 DA:98,1 -DA:103,1 -DA:104,1 -DA:106,1 -DA:107,1 -DA:109,1 -DA:110,1 -DA:111,1 -DA:113,1 -DA:114,1 +DA:103,0 +DA:104,0 +DA:106,0 +DA:107,0 +DA:109,0 +DA:110,0 +DA:111,0 +DA:113,0 +DA:114,0 DA:117,1 -DA:118,1 -DA:119,1 -DA:120,1 -DA:122,1 -DA:125,1 -DA:128,1 -DA:129,1 -DA:130,1 -DA:132,1 -DA:133,1 -DA:135,1 -DA:136,1 +DA:118,0 +DA:119,0 +DA:120,0 +DA:121,0 +DA:124,1 +DA:125,0 +DA:126,0 +DA:128,0 +DA:129,0 +DA:131,0 +DA:132,0 +DA:133,0 +DA:134,0 DA:137,1 -DA:138,1 -DA:141,1 -DA:142,1 -DA:144,1 -DA:145,1 -DA:147,1 -DA:148,1 -DA:149,1 -DA:151,1 -DA:152,1 -DA:154,1 -DA:155,1 -DA:156,1 -DA:158,1 -DA:159,1 -DA:161,1 -DA:162,1 +DA:139,0 +DA:140,0 +DA:141,0 +DA:142,0 +DA:144,0 +DA:145,0 +DA:146,0 +DA:148,0 +DA:149,0 +DA:150,0 +DA:152,0 +DA:153,0 +DA:155,0 +DA:156,0 +DA:157,0 +DA:159,0 +DA:160,0 +DA:162,0 +DA:163,0 LF:90 -LH:90 -FN:19,69,StatsFrame.__init__ -FNDA:1,StatsFrame.__init__ -FN:72,79,get_func -FNDA:1,get_func -FN:82,86,get_by -FNDA:1,get_by -FN:89,95,get_length -FNDA:1,get_length +LH:22 +FN:24,71,StatsFrame.__init__ +FNDA:0,StatsFrame.__init__ +FN:74,81,get_func +FNDA:0,get_func +FN:84,88,get_by +FNDA:0,get_by +FN:91,95,get_length +FNDA:0,get_length FN:98,114,get_frame -FNDA:1,get_frame -FN:117,125,has_header -FNDA:1,has_header -FN:128,138,move_down -FNDA:1,move_down -FN:141,162,set_style -FNDA:1,set_style -FNF:8 -FNH:8 +FNDA:0,get_frame +FN:117,121,has_header +FNDA:0,has_header +FN:124,134,move_down +FNDA:0,move_down +FN:137,163,set_style +FNDA:0,set_style +FN:139,142,set_style.get_number_format +FNDA:0,set_style.get_number_format +FNF:9 +FNH:0 end_of_record SF:src\xlviews\dataframes\style.py DA:3,1 @@ -2198,144 +2197,144 @@ DA:11,1 DA:12,1 DA:23,1 DA:36,1 -DA:46,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:53,1 -DA:54,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 +DA:46,0 +DA:48,0 +DA:49,0 +DA:50,0 +DA:51,0 +DA:53,0 +DA:54,0 +DA:56,0 +DA:57,0 +DA:58,0 +DA:59,0 +DA:60,0 DA:63,1 DA:64,1 -DA:87,1 -DA:88,1 -DA:90,1 -DA:98,1 -DA:99,1 -DA:100,1 -DA:102,1 -DA:103,1 -DA:104,1 -DA:106,1 -DA:108,1 -DA:109,1 -DA:110,1 -DA:112,1 -DA:113,1 -DA:114,1 -DA:116,1 -DA:117,1 -DA:118,1 -DA:119,1 -DA:121,1 -DA:123,1 -DA:124,1 -DA:125,1 -DA:127,1 -DA:128,1 -DA:129,1 -DA:131,1 -DA:133,1 -DA:134,1 -DA:136,1 -DA:138,1 -DA:139,1 -DA:140,1 -DA:141,1 -DA:143,1 -DA:144,1 +DA:87,0 +DA:88,0 +DA:90,0 +DA:98,0 +DA:99,0 +DA:100,0 +DA:102,0 +DA:103,0 +DA:104,0 +DA:106,0 +DA:108,0 +DA:109,0 +DA:110,0 +DA:112,0 +DA:113,0 +DA:114,0 +DA:116,0 +DA:117,0 +DA:118,0 +DA:119,0 +DA:121,0 +DA:123,0 +DA:124,0 +DA:125,0 +DA:127,0 +DA:128,0 +DA:129,0 +DA:131,0 +DA:133,0 +DA:134,0 +DA:136,0 +DA:138,0 +DA:139,0 +DA:140,0 +DA:141,0 +DA:143,0 +DA:144,0 DA:147,1 -DA:148,1 -DA:149,1 -DA:151,1 -DA:152,1 -DA:153,1 -DA:154,1 -DA:157,1 -DA:159,1 -DA:160,1 -DA:161,1 -DA:162,1 -DA:164,1 -DA:166,1 -DA:167,1 -DA:168,1 -DA:169,1 +DA:148,0 +DA:149,0 +DA:151,0 +DA:152,0 +DA:153,0 +DA:154,0 +DA:157,0 +DA:159,0 +DA:160,0 +DA:161,0 +DA:162,0 +DA:164,0 +DA:166,0 +DA:167,0 +DA:168,0 +DA:169,0 DA:172,1 -DA:177,1 -DA:179,1 -DA:180,1 -DA:181,1 -DA:182,1 -DA:183,1 -DA:184,1 -DA:185,1 -DA:186,1 -DA:188,1 +DA:177,0 +DA:179,0 +DA:180,0 +DA:181,0 +DA:182,0 +DA:183,0 +DA:184,0 +DA:185,0 +DA:186,0 +DA:188,0 DA:191,1 DA:192,1 -DA:211,1 -DA:212,1 -DA:214,1 -DA:222,1 -DA:223,1 -DA:224,1 -DA:226,1 -DA:227,1 -DA:228,1 -DA:230,1 -DA:232,1 -DA:233,1 -DA:234,1 -DA:236,1 -DA:237,1 -DA:238,1 -DA:240,1 -DA:242,1 -DA:243,1 -DA:245,1 -DA:246,1 -DA:247,1 +DA:211,0 +DA:212,0 +DA:214,0 +DA:222,0 +DA:223,0 +DA:224,0 +DA:226,0 +DA:227,0 +DA:228,0 +DA:230,0 +DA:232,0 +DA:233,0 +DA:234,0 +DA:236,0 +DA:237,0 +DA:238,0 +DA:240,0 +DA:242,0 +DA:243,0 +DA:245,0 +DA:246,0 +DA:247,0 DA:250,1 -DA:251,1 -DA:252,1 -DA:253,1 -DA:254,1 -DA:255,1 -DA:257,1 +DA:251,0 +DA:252,0 +DA:253,0 +DA:254,0 +DA:255,0 +DA:257,0 DA:260,1 -DA:261,1 -DA:262,1 -DA:264,1 -DA:266,1 -DA:267,1 -DA:268,1 -DA:269,1 -DA:271,1 -DA:272,1 +DA:261,0 +DA:262,0 +DA:264,0 +DA:266,0 +DA:267,0 +DA:268,0 +DA:269,0 +DA:271,0 +DA:272,0 LF:129 -LH:129 +LH:17 FN:36,60,_set_style -FNDA:1,_set_style +FNDA:0,_set_style FN:64,144,set_frame_style -FNDA:1,set_frame_style +FNDA:0,set_frame_style FN:147,169,set_wide_column_style -FNDA:1,set_wide_column_style +FNDA:0,set_wide_column_style FN:172,188,set_table_style -FNDA:1,set_table_style +FNDA:0,set_table_style FN:192,247,set_heat_frame_style -FNDA:1,set_heat_frame_style +FNDA:0,set_heat_frame_style FN:250,257,_merge_index -FNDA:1,_merge_index +FNDA:0,_merge_index FN:260,272,_set_heat_border -FNDA:1,_set_heat_border +FNDA:0,_set_heat_border FNF:7 -FNH:7 +FNH:0 end_of_record SF:src\xlviews\dataframes\table.py DA:1,1 @@ -2345,219 +2344,210 @@ DA:6,1 DA:8,1 DA:9,1 DA:11,1 +DA:17,1 DA:18,1 DA:19,1 DA:20,1 -DA:21,1 -DA:23,1 -DA:34,1 -DA:35,1 -DA:37,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:47,1 -DA:49,1 -DA:51,1 -DA:52,1 -DA:54,1 -DA:55,1 -DA:57,1 -DA:58,1 +DA:22,1 +DA:33,0 +DA:34,0 +DA:36,0 +DA:42,0 +DA:43,0 +DA:44,0 +DA:46,0 +DA:47,0 +DA:49,0 +DA:51,0 +DA:52,0 +DA:54,0 +DA:55,0 +DA:57,0 +DA:58,0 DA:60,1 DA:61,1 -DA:62,1 -DA:63,1 -DA:64,1 +DA:62,0 +DA:63,0 +DA:64,0 DA:66,1 DA:67,1 -DA:68,1 -DA:69,1 +DA:68,0 +DA:69,0 DA:71,1 DA:72,1 -DA:73,1 +DA:73,0 DA:75,1 DA:76,1 -DA:77,1 +DA:77,0 DA:79,1 -DA:82,1 -DA:84,1 -DA:97,1 -DA:98,1 -DA:100,1 +DA:92,0 +DA:93,0 +DA:95,0 +DA:96,0 +DA:97,0 +DA:98,0 +DA:99,0 DA:101,1 -DA:102,1 -DA:103,1 -DA:104,1 -DA:106,1 -DA:120,1 -DA:121,1 -DA:122,1 -DA:123,1 -DA:125,1 -DA:126,1 -DA:128,1 -DA:129,1 -DA:131,1 -DA:133,1 -DA:135,1 -DA:136,1 -DA:138,1 -DA:139,1 -DA:145,1 -DA:146,1 -DA:153,1 -DA:154,1 -DA:157,1 +DA:120,0 +DA:121,0 +DA:122,0 +DA:123,0 +DA:125,0 +DA:126,0 +DA:128,0 +DA:129,0 +DA:131,0 +DA:133,0 +DA:135,0 +DA:136,0 +DA:138,0 +DA:139,0 +DA:145,0 +DA:146,0 +DA:153,0 +DA:154,0 +DA:157,0 DA:159,1 -DA:161,1 -DA:162,1 -DA:163,1 -LF:75 -LH:75 -FN:23,58,Table.__init__ -FNDA:1,Table.__init__ +DA:161,0 +DA:162,0 +DA:163,0 +LF:74 +LH:23 +FN:22,58,Table.__init__ +FNDA:0,Table.__init__ FN:61,64,Table.column -FNDA:1,Table.column +FNDA:0,Table.column FN:67,69,Table.header -FNDA:1,Table.header +FNDA:0,Table.header FN:72,73,Table.const_header -FNDA:1,Table.const_header -FN:76,82,Table.columns -FNDA:1,Table.columns -FN:84,104,Table.add_const_header -FNDA:1,Table.add_const_header -FN:106,157,Table.auto_filter -FNDA:1,Table.auto_filter +FNDA:0,Table.const_header +FN:76,77,Table.columns +FNDA:0,Table.columns +FN:79,99,Table.add_const_header +FNDA:0,Table.add_const_header +FN:101,157,Table.auto_filter +FNDA:0,Table.auto_filter FN:159,163,Table.unlist -FNDA:1,Table.unlist +FNDA:0,Table.unlist FNF:8 -FNH:8 +FNH:0 end_of_record SF:src\xlviews\figure\__init__.py end_of_record SF:src\xlviews\figure\grid.py DA:1,1 DA:3,1 +DA:11,1 DA:12,1 -DA:13,1 -DA:15,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:26,1 -DA:27,1 +DA:14,1 +DA:21,0 +DA:22,0 +DA:23,0 +DA:25,0 +DA:26,0 DA:28,1 DA:29,1 DA:31,1 DA:32,1 DA:34,1 -DA:36,1 -DA:37,1 -DA:39,1 +DA:35,0 +DA:36,0 +DA:38,0 DA:40,1 -DA:42,1 +DA:41,0 DA:43,1 -DA:44,1 -DA:46,1 +DA:44,0 DA:47,1 -DA:49,1 +DA:48,1 DA:50,1 -DA:52,1 -DA:53,1 -DA:55,1 -DA:56,1 -DA:59,1 -DA:60,1 -DA:62,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:72,1 -DA:73,1 -DA:74,1 -DA:75,1 +DA:56,0 +DA:57,0 +DA:58,0 +DA:60,0 +DA:61,0 +DA:62,0 +DA:63,0 +DA:65,0 +DA:66,0 +DA:67,0 +DA:68,0 +DA:69,0 +DA:70,0 +DA:72,0 +DA:73,0 +DA:74,0 +DA:75,0 DA:77,1 DA:78,1 -DA:79,1 -DA:80,1 -DA:81,1 -DA:82,1 +DA:79,0 +DA:80,0 +DA:81,0 +DA:83,1 DA:84,1 -DA:85,1 DA:86,1 DA:87,1 DA:89,1 DA:90,1 -DA:91,1 DA:92,1 DA:93,1 DA:95,1 DA:96,1 DA:98,1 -DA:99,1 -DA:101,1 -DA:102,1 -DA:104,1 -DA:105,1 -DA:107,1 -DA:108,1 -DA:110,1 -DA:111,1 -DA:112,1 -DA:114,1 -DA:115,1 -DA:116,1 -DA:117,1 -DA:119,1 -DA:120,1 +DA:102,0 +DA:103,0 +DA:105,0 +DA:106,0 +DA:107,0 +DA:108,0 +DA:110,0 +DA:111,0 +DA:113,0 +DA:114,0 +DA:116,0 +DA:117,0 +DA:119,0 +DA:120,0 DA:122,1 -DA:123,1 +DA:123,0 DA:125,1 -DA:126,1 -DA:128,1 -DA:129,1 -DA:131,1 -DA:132,1 -DA:134,1 -DA:135,1 -DA:136,1 -LF:85 -LH:85 -FN:15,34,Series.__init__ -FNDA:1,Series.__init__ -FN:37,37,Series.__getitem__ -FNDA:1,Series.__getitem__ -FN:40,40,Series.__getitem__ -FNDA:1,Series.__getitem__ -FN:42,50,Series.__getitem__ -FNDA:1,Series.__getitem__ -FN:52,53,Series.__len__ -FNDA:1,Series.__len__ -FN:55,56,Series.__iter__ -FNDA:1,Series.__iter__ -FN:62,87,Grid.__init__ -FNDA:1,Grid.__init__ -FN:90,93,Grid.shape -FNDA:1,Grid.shape -FN:96,96,Grid.__getitem__ -FNDA:1,Grid.__getitem__ -FN:99,99,Grid.__getitem__ +DA:126,0 +DA:127,0 +LF:77 +LH:30 +FN:14,26,AxesSeries.__init__ +FNDA:0,AxesSeries.__init__ +FN:29,29,AxesSeries.__getitem__ +FNDA:1,AxesSeries.__getitem__ +FN:32,32,AxesSeries.__getitem__ +FNDA:1,AxesSeries.__getitem__ +FN:34,38,AxesSeries.__getitem__ +FNDA:0,AxesSeries.__getitem__ +FN:40,41,AxesSeries.__len__ +FNDA:0,AxesSeries.__len__ +FN:43,44,AxesSeries.__iter__ +FNDA:0,AxesSeries.__iter__ +FN:50,75,Grid.__init__ +FNDA:0,Grid.__init__ +FN:78,81,Grid.shape +FNDA:0,Grid.shape +FN:84,84,Grid.__getitem__ FNDA:1,Grid.__getitem__ -FN:102,102,Grid.__getitem__ +FN:87,87,Grid.__getitem__ FNDA:1,Grid.__getitem__ -FN:105,105,Grid.__getitem__ +FN:90,90,Grid.__getitem__ FNDA:1,Grid.__getitem__ -FN:108,108,Grid.__getitem__ +FN:93,93,Grid.__getitem__ FNDA:1,Grid.__getitem__ -FN:110,129,Grid.__getitem__ +FN:96,96,Grid.__getitem__ FNDA:1,Grid.__getitem__ -FN:131,132,Grid.__len__ -FNDA:1,Grid.__len__ -FN:134,136,Grid.__iter__ -FNDA:1,Grid.__iter__ +FN:98,120,Grid.__getitem__ +FNDA:0,Grid.__getitem__ +FN:122,123,Grid.__len__ +FNDA:0,Grid.__len__ +FN:125,127,Grid.__iter__ +FNDA:0,Grid.__iter__ FNF:16 -FNH:16 +FNH:7 end_of_record SF:src\xlviews\figure\palette.py DA:1,1 @@ -2568,155 +2558,166 @@ DA:6,1 DA:8,1 DA:10,1 DA:18,1 -DA:21,1 +DA:19,1 DA:26,1 DA:27,1 -DA:29,1 -DA:30,1 -DA:32,1 -DA:33,1 +DA:34,1 DA:35,1 -DA:36,1 -DA:37,1 -DA:39,1 DA:42,1 -DA:46,1 -DA:47,1 -DA:49,1 -DA:50,1 -DA:52,1 -DA:53,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:61,1 +DA:47,0 +DA:48,0 +DA:50,0 +DA:51,0 +DA:53,0 +DA:54,0 +DA:56,0 +DA:57,0 +DA:58,0 +DA:60,0 DA:63,1 -DA:64,1 -DA:65,1 -DA:67,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:72,1 -DA:75,1 -DA:78,1 -DA:79,1 -DA:80,1 -DA:82,1 -DA:88,1 -DA:89,1 -DA:90,1 -DA:92,1 -DA:93,1 -DA:95,1 +DA:67,0 +DA:68,0 +DA:70,0 +DA:71,0 +DA:73,0 +DA:74,0 +DA:76,0 +DA:77,0 +DA:78,0 +DA:79,0 +DA:80,0 +DA:82,0 +DA:84,0 +DA:85,0 +DA:86,0 +DA:88,0 +DA:89,0 +DA:90,0 +DA:91,0 +DA:93,0 DA:96,1 DA:99,1 DA:100,1 DA:101,1 DA:103,1 -DA:105,1 -DA:106,1 -DA:107,1 -DA:109,1 -DA:111,1 -DA:114,1 -DA:115,1 +DA:109,0 +DA:110,0 +DA:111,0 +DA:113,0 +DA:114,0 +DA:116,1 DA:117,1 DA:120,1 -DA:122,1 -DA:123,1 -DA:125,1 +DA:121,0 +DA:122,0 +DA:124,0 DA:126,1 -DA:127,1 -DA:128,1 -DA:131,1 -DA:132,1 -DA:134,1 -DA:137,1 -DA:139,1 -DA:140,1 -DA:142,1 -DA:143,1 -DA:144,1 -DA:147,1 -DA:148,1 -DA:149,1 -DA:151,1 +DA:127,0 +DA:128,0 +DA:130,0 +DA:132,0 +DA:135,1 +DA:136,1 +DA:138,0 +DA:141,1 +DA:143,0 +DA:144,0 +DA:146,0 +DA:147,0 +DA:148,0 +DA:149,0 DA:152,1 DA:153,1 -DA:155,1 -DA:156,1 -DA:157,1 -DA:159,1 -DA:160,1 -DA:163,1 -DA:175,1 -DA:181,1 -DA:182,1 -DA:184,1 -DA:185,1 -DA:187,1 +DA:155,0 +DA:158,1 +DA:160,0 +DA:161,0 +DA:163,0 +DA:164,0 +DA:165,0 +DA:168,1 +DA:169,1 +DA:170,1 +DA:172,1 +DA:177,0 +DA:178,0 +DA:180,1 +DA:181,0 +DA:182,0 +DA:184,0 +DA:185,0 DA:188,1 -DA:189,1 -DA:190,1 -DA:192,1 -DA:193,1 -DA:195,1 -DA:196,1 -DA:198,1 -DA:199,1 DA:200,1 -DA:201,1 -DA:203,1 -DA:205,1 -DA:207,1 -DA:208,1 -DA:210,1 -DA:211,1 -DA:212,1 -DA:213,1 -DA:214,1 -DA:216,1 -DA:219,1 -DA:223,1 -DA:226,1 -DA:230,1 -LF:123 -LH:123 -FN:21,39,get_columns_default -FNDA:1,get_columns_default -FN:42,72,get_index -FNDA:1,get_index -FN:82,93,Palette.__init__ -FNDA:1,Palette.__init__ -FN:96,97,Palette.cycle +DA:206,0 +DA:207,0 +DA:209,0 +DA:210,0 +DA:212,0 +DA:213,0 +DA:214,0 +DA:215,0 +DA:217,0 +DA:218,0 +DA:220,0 +DA:221,0 +DA:223,0 +DA:224,0 +DA:225,0 +DA:226,0 +DA:228,0 +DA:230,0 +DA:232,0 +DA:233,0 +DA:235,0 +DA:236,0 +DA:237,0 +DA:238,0 +DA:239,0 +DA:241,0 +DA:244,1 +DA:248,0 +DA:251,1 +DA:255,0 +LF:128 +LH:39 +FN:19,23,get_columns_default +FNDA:0,get_columns_default +FN:27,31,get_columns_default +FNDA:0,get_columns_default +FN:35,39,get_columns_default +FNDA:0,get_columns_default +FN:42,60,get_columns_default +FNDA:0,get_columns_default +FN:63,93,get_index +FNDA:0,get_index +FN:103,114,Palette.__init__ +FNDA:0,Palette.__init__ +FN:117,118,Palette.cycle FNDA:0,Palette.cycle -FN:99,103,Palette.get -FNDA:1,Palette.get -FN:105,111,Palette.__getitem__ -FNDA:1,Palette.__getitem__ -FN:115,117,MarkerPalette.cycle -FNDA:1,MarkerPalette.cycle -FN:120,128,cycle_markers -FNDA:1,cycle_markers -FN:132,134,ColorPalette.cycle -FNDA:1,ColorPalette.cycle -FN:137,144,cycle_colors -FNDA:1,cycle_colors -FN:151,153,FunctionPalette.__init__ -FNDA:1,FunctionPalette.__init__ -FN:155,160,FunctionPalette.__getitem__ -FNDA:1,FunctionPalette.__getitem__ -FN:175,216,get_palette -FNDA:1,get_palette -FN:219,223,get_marker_palette -FNDA:1,get_marker_palette -FN:226,230,get_color_palette -FNDA:1,get_color_palette -FNF:15 -FNH:14 +FN:120,124,Palette.get +FNDA:0,Palette.get +FN:126,132,Palette.__getitem__ +FNDA:0,Palette.__getitem__ +FN:136,138,MarkerPalette.cycle +FNDA:0,MarkerPalette.cycle +FN:141,149,cycle_markers +FNDA:0,cycle_markers +FN:153,155,ColorPalette.cycle +FNDA:0,ColorPalette.cycle +FN:158,165,cycle_colors +FNDA:0,cycle_colors +FN:172,178,FunctionPalette.__init__ +FNDA:0,FunctionPalette.__init__ +FN:180,185,FunctionPalette.__getitem__ +FNDA:0,FunctionPalette.__getitem__ +FN:200,241,get_palette +FNDA:0,get_palette +FN:244,248,get_marker_palette +FNDA:0,get_marker_palette +FN:251,255,get_color_palette +FNDA:0,get_color_palette +FNF:18 +FNH:0 end_of_record SF:src\xlviews\figure\plot.py DA:1,1 @@ -2726,97 +2727,93 @@ DA:5,1 DA:7,1 DA:8,1 DA:10,1 -DA:19,1 +DA:18,1 +DA:21,1 DA:22,1 DA:23,1 DA:24,1 DA:25,1 -DA:26,1 -DA:28,1 -DA:29,1 -DA:31,1 -DA:32,1 -DA:34,1 -DA:36,1 -DA:42,1 -DA:43,1 -DA:45,1 -DA:46,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:53,1 +DA:27,1 +DA:28,0 +DA:30,0 +DA:31,0 +DA:33,0 +DA:34,0 +DA:35,0 +DA:37,1 +DA:43,0 +DA:44,0 +DA:46,0 +DA:47,0 +DA:48,0 +DA:49,0 +DA:50,0 +DA:51,0 +DA:53,0 DA:55,1 -DA:57,1 -DA:58,1 -DA:60,1 +DA:56,0 +DA:58,0 +DA:59,0 DA:61,1 -DA:63,1 -DA:72,1 -DA:73,1 -DA:75,1 -DA:76,1 +DA:70,0 +DA:71,0 +DA:73,0 +DA:74,0 +DA:83,0 DA:85,1 -DA:87,1 -DA:88,1 -DA:95,1 -DA:96,1 -DA:97,1 -DA:98,1 -DA:100,1 -DA:101,1 -DA:102,1 -DA:103,1 -DA:105,1 -DA:106,1 -DA:108,1 -DA:109,1 -DA:111,1 -DA:113,1 -DA:116,1 -DA:117,1 -DA:118,1 -DA:120,1 -DA:121,1 -DA:123,1 -DA:124,1 -DA:127,1 -DA:131,1 -DA:132,1 -DA:133,1 -DA:135,1 -DA:136,1 +DA:86,1 +DA:93,0 +DA:94,0 +DA:95,0 +DA:96,0 +DA:98,0 +DA:99,0 +DA:100,0 +DA:101,0 +DA:103,0 +DA:104,0 +DA:106,0 +DA:107,0 +DA:109,0 +DA:111,0 +DA:114,1 +DA:115,0 +DA:116,0 +DA:119,1 +DA:123,0 +DA:124,0 +DA:125,0 +DA:127,0 +DA:128,0 +DA:130,0 +DA:131,0 +DA:132,0 +DA:134,0 +DA:135,0 DA:138,1 -DA:139,1 -DA:140,1 -DA:142,1 -DA:143,1 -DA:146,1 -DA:147,1 -DA:148,1 -DA:150,1 -LF:78 -LH:78 -FN:28,34,Plot.__init__ -FNDA:1,Plot.__init__ -FN:36,55,Plot.add -FNDA:1,Plot.add -FN:57,61,Plot.keys -FNDA:1,Plot.keys -FN:63,85,Plot.set -FNDA:1,Plot.set -FN:88,113,Plot.facet -FNDA:1,Plot.facet -FN:116,124,get_label -FNDA:1,get_label -FN:127,143,iterrows -FNDA:1,iterrows -FN:146,150,xs -FNDA:1,xs +DA:139,0 +DA:140,0 +DA:142,0 +LF:74 +LH:22 +FN:27,35,Plot.__init__ +FNDA:0,Plot.__init__ +FN:37,53,Plot.add +FNDA:0,Plot.add +FN:55,59,Plot.keys +FNDA:0,Plot.keys +FN:61,83,Plot.set +FNDA:0,Plot.set +FN:86,111,Plot.facet +FNDA:0,Plot.facet +FN:114,116,get_label +FNDA:0,get_label +FN:119,135,iterrows +FNDA:0,iterrows +FN:138,142,xs +FNDA:0,xs FNF:8 -FNH:8 +FNH:0 end_of_record SF:src\xlviews\style.py DA:3,1 @@ -2829,161 +2826,161 @@ DA:17,1 DA:18,1 DA:19,1 DA:20,1 -DA:28,1 -DA:34,1 -DA:35,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:44,1 -DA:49,1 -DA:50,1 -DA:52,1 -DA:54,1 -DA:55,1 -DA:57,1 -DA:58,1 -DA:60,1 -DA:61,1 -DA:63,1 -DA:64,1 -DA:66,1 -DA:67,1 -DA:70,1 -DA:75,1 -DA:76,1 -DA:79,1 -DA:86,1 -DA:87,1 -DA:89,1 -DA:90,1 -DA:93,1 -DA:97,1 -DA:98,1 -DA:101,1 -DA:110,1 -DA:111,1 -DA:112,1 -DA:113,1 -DA:114,1 -DA:115,1 -DA:116,1 -DA:117,1 -DA:118,1 -DA:119,1 -DA:120,1 -DA:123,1 -DA:132,1 -DA:133,1 -DA:136,1 -DA:141,1 -DA:142,1 -DA:144,1 -DA:145,1 -DA:148,1 -DA:149,1 -DA:152,1 -DA:153,1 -DA:156,1 -DA:162,1 -DA:163,1 -DA:164,1 -DA:166,1 -DA:167,1 -DA:169,1 -DA:170,1 -DA:171,1 -DA:172,1 -DA:174,1 -DA:176,1 -DA:177,1 -DA:180,1 -DA:183,1 -DA:187,1 -DA:189,1 -DA:190,1 -DA:191,1 -DA:198,1 -DA:203,1 -DA:205,1 -DA:206,1 -DA:207,1 -DA:208,1 -DA:209,1 -DA:212,1 -DA:215,1 -DA:220,1 -DA:221,1 -DA:223,1 -DA:224,1 -DA:225,1 -DA:226,1 -DA:227,1 -DA:229,1 -DA:230,1 -DA:231,1 -DA:232,1 -DA:233,1 -DA:234,1 -DA:237,1 -DA:238,1 -DA:239,1 -DA:242,1 -DA:247,1 -DA:248,1 -DA:250,1 -DA:251,1 -DA:252,1 -DA:253,1 -DA:254,1 -DA:257,1 -DA:262,1 -DA:263,1 -DA:265,1 -DA:266,1 -DA:268,1 -DA:269,1 -DA:271,1 +DA:26,1 +DA:32,0 +DA:33,0 +DA:35,0 +DA:36,0 +DA:37,0 +DA:38,0 +DA:39,0 +DA:42,1 +DA:47,0 +DA:48,0 +DA:50,0 +DA:52,0 +DA:53,0 +DA:55,0 +DA:56,0 +DA:58,0 +DA:59,0 +DA:61,0 +DA:62,0 +DA:64,0 +DA:65,0 +DA:68,1 +DA:73,0 +DA:74,0 +DA:77,1 +DA:84,0 +DA:85,0 +DA:87,0 +DA:88,0 +DA:91,1 +DA:95,0 +DA:96,0 +DA:99,1 +DA:108,0 +DA:109,0 +DA:110,0 +DA:111,0 +DA:112,0 +DA:113,0 +DA:114,0 +DA:115,0 +DA:116,0 +DA:117,0 +DA:118,0 +DA:121,1 +DA:130,0 +DA:131,0 +DA:134,1 +DA:139,0 +DA:140,0 +DA:142,0 +DA:143,0 +DA:146,1 +DA:147,0 +DA:150,1 +DA:151,1 +DA:154,1 +DA:160,0 +DA:161,0 +DA:162,0 +DA:164,0 +DA:165,0 +DA:167,0 +DA:168,0 +DA:169,0 +DA:170,0 +DA:172,0 +DA:174,0 +DA:175,0 +DA:178,1 +DA:181,1 +DA:185,0 +DA:187,0 +DA:188,0 +DA:189,0 +DA:196,0 +DA:201,0 +DA:203,0 +DA:204,0 +DA:205,0 +DA:206,0 +DA:207,0 +DA:210,1 +DA:213,1 +DA:218,0 +DA:219,0 +DA:221,0 +DA:222,0 +DA:223,0 +DA:224,0 +DA:225,0 +DA:227,0 +DA:228,0 +DA:229,0 +DA:230,0 +DA:231,0 +DA:232,0 +DA:235,1 +DA:236,0 +DA:237,0 +DA:240,1 +DA:245,0 +DA:246,0 +DA:248,0 +DA:249,0 +DA:250,0 +DA:251,0 +DA:252,0 +DA:255,1 +DA:260,0 +DA:261,0 +DA:263,0 +DA:264,0 +DA:266,0 +DA:267,0 +DA:269,0 LF:127 -LH:127 -FN:28,41,set_border_line -FNDA:1,set_border_line -FN:44,67,set_border_edge -FNDA:1,set_border_edge -FN:70,76,set_border_inside -FNDA:1,set_border_inside -FN:79,90,set_border -FNDA:1,set_border -FN:93,98,set_fill -FNDA:1,set_fill -FN:101,120,set_font_api -FNDA:1,set_font_api -FN:123,133,set_font -FNDA:1,set_font -FN:136,145,set_alignment -FNDA:1,set_alignment -FN:148,149,set_number_format -FNDA:1,set_number_format -FN:156,177,set_banding -FNDA:1,set_banding -FN:162,172,set_banding.banding -FNDA:1,set_banding.banding -FN:183,209,hide_succession -FNDA:1,hide_succession -FN:215,234,hide_unique -FNDA:1,hide_unique -FN:220,221,hide_unique.address -FNDA:1,hide_unique.address -FN:237,239,hide_gridlines -FNDA:1,hide_gridlines -FN:242,254,set_color_condition -FNDA:1,set_color_condition -FN:257,271,set_color_scale -FNDA:1,set_color_scale +LH:29 +FN:26,39,set_border_line +FNDA:0,set_border_line +FN:42,65,set_border_edge +FNDA:0,set_border_edge +FN:68,74,set_border_inside +FNDA:0,set_border_inside +FN:77,88,set_border +FNDA:0,set_border +FN:91,96,set_fill +FNDA:0,set_fill +FN:99,118,set_font_api +FNDA:0,set_font_api +FN:121,131,set_font +FNDA:0,set_font +FN:134,143,set_alignment +FNDA:0,set_alignment +FN:146,147,set_number_format +FNDA:0,set_number_format +FN:154,175,set_banding +FNDA:0,set_banding +FN:160,170,set_banding.banding +FNDA:0,set_banding.banding +FN:181,207,hide_succession +FNDA:0,hide_succession +FN:213,232,hide_unique +FNDA:0,hide_unique +FN:218,219,hide_unique.address +FNDA:0,hide_unique.address +FN:235,237,hide_gridlines +FNDA:0,hide_gridlines +FN:240,252,set_color_condition +FNDA:0,set_color_condition +FN:255,269,set_color_scale +FNDA:0,set_color_scale FNF:17 -FNH:17 +FNH:0 end_of_record SF:src\xlviews\utils.py DA:1,1 @@ -2992,66 +2989,64 @@ DA:4,1 DA:6,1 DA:7,1 DA:8,1 -DA:20,1 -DA:31,1 -DA:32,1 -DA:33,1 -DA:35,1 -DA:37,1 -DA:38,1 -DA:40,1 -DA:42,1 -DA:45,1 -DA:61,1 -DA:62,1 -DA:64,1 -DA:66,1 -DA:67,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:72,1 -DA:75,1 -DA:99,1 -DA:100,1 -DA:102,1 -DA:103,1 -DA:104,1 -DA:107,1 -DA:112,1 -DA:113,1 -DA:115,1 -DA:116,1 -DA:117,1 -DA:119,1 -DA:122,1 +DA:21,1 +DA:32,0 +DA:33,0 +DA:34,0 +DA:36,0 +DA:38,0 +DA:39,0 +DA:41,0 +DA:43,0 +DA:46,1 +DA:62,0 +DA:63,0 +DA:65,0 +DA:67,0 +DA:68,0 +DA:69,0 +DA:70,0 +DA:71,0 +DA:73,0 +DA:76,1 +DA:100,0 +DA:101,0 +DA:103,0 +DA:104,0 +DA:105,0 +DA:108,1 +DA:113,0 +DA:114,0 +DA:116,0 +DA:117,0 +DA:118,0 +DA:120,0 DA:123,1 DA:126,1 -DA:129,1 -DA:130,1 -DA:131,1 -DA:133,1 -DA:134,1 -DA:135,1 -DA:137,1 -DA:138,1 +DA:127,1 +DA:128,0 +DA:130,0 +DA:131,0 +DA:132,0 +DA:134,0 +DA:135,0 +DA:137,0 +DA:138,0 DA:140,1 -DA:141,1 -DA:143,1 -LF:52 -LH:52 -FN:20,42,constant -FNDA:1,constant -FN:45,72,iter_columns -FNDA:1,iter_columns -FN:75,104,iter_group_locs -FNDA:1,iter_group_locs -FN:107,119,add_validate_list -FNDA:1,add_validate_list -FN:126,143,suspend_screen_updates +LF:50 +LH:14 +FN:21,43,constant +FNDA:0,constant +FN:46,73,iter_columns +FNDA:0,iter_columns +FN:76,105,iter_group_locs +FNDA:0,iter_group_locs +FN:108,120,add_validate_list +FNDA:0,add_validate_list +FN:123,140,suspend_screen_updates FNDA:1,suspend_screen_updates -FN:130,141,suspend_screen_updates._func -FNDA:1,suspend_screen_updates._func +FN:127,138,suspend_screen_updates._func +FNDA:0,suspend_screen_updates._func FNF:6 -FNH:6 +FNH:1 end_of_record diff --git a/src/xlviews/figure/palette.py b/src/xlviews/figure/palette.py index 9d47f33..902885a 100644 --- a/src/xlviews/figure/palette.py +++ b/src/xlviews/figure/palette.py @@ -1,9 +1,9 @@ from __future__ import annotations from abc import ABC, abstractmethod -from collections.abc import Callable, Hashable +from collections.abc import Callable, Hashable, Mapping from itertools import cycle, islice -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any, overload from pandas import MultiIndex @@ -15,45 +15,69 @@ from pandas import DataFrame +@overload +def get_columns_default( + data: DataFrame, + columns: str | list[str], + default: None = None, +) -> tuple[list[str], dict[Any, Any]]: ... + + +@overload def get_columns_default[T]( data: DataFrame, columns: str | list[str], - default: dict[Hashable, T] | list[T] | None = None, -) -> tuple[list[str], dict[Hashable, T]]: + default: list[T], +) -> tuple[list[str], dict[Any, T]]: ... + + +@overload +def get_columns_default[T, K]( + data: DataFrame, + columns: str | list[str], + default: Mapping[K, T], +) -> tuple[list[str], dict[K, T]]: ... + + +def get_columns_default[T, K]( + data: DataFrame, + columns: str | list[str], + default: Mapping[K, T] | list[T] | None = None, +) -> tuple[list[str], dict[Any, Any]]: if isinstance(columns, str): columns = [columns] if default is None: return columns, {} - if isinstance(default, dict): - return columns, default + if isinstance(default, Mapping): + return columns, default if isinstance(default, dict) else dict(default) data = data[columns].drop_duplicates() values = [tuple(t) for t in data.itertuples(index=False)] - default = dict(zip(values, cycle(default), strict=False)) + default_ = dict(zip(values, cycle(default), strict=False)) - return columns, default + return columns, default_ def get_index( data: DataFrame, - default: Iterable[Hashable] | None = None, -) -> dict[tuple[Hashable, ...], int]: + default: Iterable[Any] | None = None, +) -> dict[tuple[Any, ...], int]: data = data.drop_duplicates() values = [tuple(t) for t in data.itertuples(index=False)] if default is None: return dict(zip(values, range(len(data)), strict=True)) - index: dict[tuple[Hashable, ...], int] = {} + index: dict[tuple[Any, ...], int] = {} current_index = 0 for default_value in default: if isinstance(default_value, tuple): value = default_value # pyright: ignore[reportUnknownVariableType] elif isinstance(default_value, list): - value = tuple(default_value) # pyright: ignore[reportUnknownVariableType] + value = tuple(default_value) # pyright: ignore[reportUnknownArgumentType, reportUnknownVariableType] else: value = (default_value,) @@ -73,14 +97,14 @@ class Palette[T](ABC): """A palette of items.""" columns: list[str] - index: dict[tuple[Hashable, ...], int] + index: dict[tuple[Any, ...], int] items: list[T] def __init__( self, data: DataFrame, columns: str | list[str], - default: dict[Hashable, T] | list[T] | None = None, + default: Mapping[Any, T] | list[T] | None = None, ) -> None: self.columns, default = get_columns_default(data, columns, default) self.index = get_index(data[self.columns], default) @@ -93,13 +117,13 @@ def __init__( def cycle(self, defaults: Iterable[T]) -> Iterator[T]: """Generate an infinite iterator of items.""" - def get(self, value: Hashable) -> int: + def get(self, value: Any) -> int: if not isinstance(value, tuple): value = (value,) return self.index[value] - def __getitem__(self, key: dict[str | None, Hashable]) -> T: + def __getitem__(self, key: Mapping[Any, Any]) -> T: if key == {None: 0}: # from series return self.items[0] @@ -142,15 +166,19 @@ def cycle_colors(skips: Iterable[str] | None = None) -> Iterator[str]: class FunctionPalette[T]: - columns: str | list[str] - func: Callable[[Hashable], T] + columns: Hashable | list[Hashable | None] | None + func: Callable[[Any], T] - def __init__(self, columns: str | list[str], func: Callable[[Hashable], T]) -> None: + def __init__( + self, + columns: Hashable | list[Hashable | None] | None, + func: Callable[[Any], T], + ) -> None: self.columns = columns self.func = func - def __getitem__(self, key: dict[str, Hashable]) -> T: - if isinstance(self.columns, str): + def __getitem__(self, key: Mapping[Any, Any]) -> T: + if not isinstance(self.columns, list): return self.func(key[self.columns]) value = tuple(key[k] for k in self.columns) @@ -160,17 +188,14 @@ def __getitem__(self, key: dict[str, Hashable]) -> T: type PaletteStyle[T] = ( str | list[str] - | dict[Hashable, str] - | Callable[[Hashable], str] - | tuple[str | list[str], list[str] | dict[Hashable, str]] - | tuple[str | list[str], Callable[[Hashable], str]] + | dict[Hashable, T] + | Callable[[Any], T] + | tuple[Any, list[T] | dict[Hashable, T]] + | tuple[Any, Callable[[Any], T]] | Palette[T] | FunctionPalette[T] ) -# pyright: reportArgumentType=false -# pyright: reportReturnType=false - def get_palette[T]( cls: type[Palette[T]], @@ -211,7 +236,7 @@ def get_palette[T]( data = data.drop_duplicates() values = [tuple(t) for t in data.itertuples(index=False)] default = dict(zip(values, cycle(columns), strict=False)) - return cls(data, data.columns.tolist(), default) + return cls(data, data.columns.tolist(), default) # pyright: ignore[reportArgumentType] return cls(data, columns) @@ -220,11 +245,11 @@ def get_marker_palette( data: DataFrame, marker: PaletteStyle[str] | None, ) -> MarkerPalette | FunctionPalette[str] | None: - return get_palette(MarkerPalette, data, marker) + return get_palette(MarkerPalette, data, marker) # pyright: ignore[reportReturnType] def get_color_palette( data: DataFrame, color: PaletteStyle[str] | None, ) -> ColorPalette | FunctionPalette[str] | None: - return get_palette(ColorPalette, data, color) + return get_palette(ColorPalette, data, color) # pyright: ignore[reportReturnType] diff --git a/src/xlviews/figure/plot.py b/src/xlviews/figure/plot.py index 58aa786..75599e6 100644 --- a/src/xlviews/figure/plot.py +++ b/src/xlviews/figure/plot.py @@ -73,8 +73,8 @@ def set( for key, s in zip(self.keys(), self.series_collection, strict=True): s.set( label=label and get_label(label, key), - color=color_palette and color_palette[key], # pyright: ignore[reportArgumentType] - marker=marker_palette and marker_palette[key], # pyright: ignore[reportArgumentType] + color=color_palette and color_palette[key], + marker=marker_palette and marker_palette[key], alpha=alpha, weight=weight, size=size, diff --git a/tests/figure/test_palette.py b/tests/figure/test_palette.py index 3a26e67..3789b42 100644 --- a/tests/figure/test_palette.py +++ b/tests/figure/test_palette.py @@ -1,7 +1,27 @@ +from __future__ import annotations + from itertools import islice +from operator import itemgetter +from typing import TYPE_CHECKING import pytest -from pandas import DataFrame +from pandas import DataFrame, Series + +from xlviews.figure.palette import ( + ColorPalette, + FunctionPalette, + MarkerPalette, + cycle_colors, + cycle_markers, + get_color_palette, + get_columns_default, + get_index, + get_marker_palette, + get_palette, +) + +if TYPE_CHECKING: + from collections.abc import Iterable @pytest.fixture(scope="module") @@ -16,21 +36,23 @@ def df(): def test_get_columns_default(df: DataFrame): - from xlviews.figure.palette import get_columns_default - columns, default = get_columns_default(df, "a") assert columns == ["a"] assert default == {} def test_get_columns_default_with_default_list(df: DataFrame): - from xlviews.figure.palette import get_columns_default - columns, default = get_columns_default(df, "a", ["red", "blue"]) assert columns == ["a"] - assert default[(1,)] == "red" - assert default[(2,)] == "blue" - assert default[(3,)] == "red" + assert default[1,] == "red" + assert default[2,] == "blue" + assert default[3,] == "red" + + +def test_get_columns_default_with_default_dict(df: DataFrame): + columns, default = get_columns_default(df, ["a", "b"], {"x": 0}) + assert columns == ["a", "b"] + assert default == {"x": 0} @pytest.mark.parametrize( @@ -44,9 +66,11 @@ def test_get_columns_default_with_default_list(df: DataFrame): (["b", "c"], {(4, 10): 0, (5, 10): 1, (6, 11): 2, (7, 11): 3}), ], ) -def test_get_index(df: DataFrame, columns, index): - from xlviews.figure.palette import get_index - +def test_get_index( + df: DataFrame, + columns: list[str], + index: dict[tuple[int, ...], int], +): assert get_index(df[columns]) == index @@ -65,36 +89,31 @@ def test_get_index(df: DataFrame, columns, index): (["b", "c"], [], {(4, 10): 0, (5, 10): 1, (6, 11): 2, (7, 11): 3}), ], ) -def test_get_index_default(df: DataFrame, columns, default, index): - from xlviews.figure.palette import get_index - +def test_get_index_default( + df: DataFrame, + columns: list[str], + default: list[int] | list[Iterable[int]], + index: dict[tuple[int, ...], int], +): assert get_index(df[columns], default) == index def test_cycle_colors(): - from xlviews.figure.palette import cycle_colors - x = list(islice(cycle_colors(), 3)) assert x == ["#1f77b4", "#ff7f0e", "#2ca02c"] def test_cycle_colors_skips(): - from xlviews.figure.palette import cycle_colors - x = list(islice(cycle_colors(["#ff7f0e"]), 3)) assert x == ["#1f77b4", "#2ca02c", "#d62728"] def test_cycle_markers(): - from xlviews.figure.palette import cycle_markers - x = list(islice(cycle_markers(), 3)) assert x == ["o", "^", "s"] def test_cycle_markers_skips(): - from xlviews.figure.palette import cycle_markers - x = list(islice(cycle_markers(["o"]), 3)) assert x == ["^", "s", "d"] @@ -103,9 +122,7 @@ def test_cycle_markers_skips(): ("key", "value"), [(1, 0), ((1,), 0), (3, 2), ((3,), 2)], ) -def test_marker_palette_get(df: DataFrame, key, value): - from xlviews.figure.palette import MarkerPalette - +def test_marker_palette_get(df: DataFrame, key: int | tuple[int], value: int): p = MarkerPalette(df, "a") assert p.get(key) == value @@ -114,9 +131,7 @@ def test_marker_palette_get(df: DataFrame, key, value): ("key", "value"), [({"a": 1}, "o"), ({"a": 2}, "^"), ({"a": 3}, "s")], ) -def test_marker_palette(df: DataFrame, key, value): - from xlviews.figure.palette import MarkerPalette - +def test_marker_palette(df: DataFrame, key: dict[str, int], value: str): p = MarkerPalette(df, "a") assert p[key] == value @@ -125,9 +140,7 @@ def test_marker_palette(df: DataFrame, key, value): ("key", "value"), [({"a": 1, "b": 0}, "o"), ({"x": 0, "a": 2}, "^"), ({"a": 3}, "s")], ) -def test_marker_palette_dict(df: DataFrame, key, value): - from xlviews.figure.palette import MarkerPalette - +def test_marker_palette_dict(df: DataFrame, key: dict[str, int], value: str): p = MarkerPalette(df, "a") assert p[key] == value @@ -136,9 +149,7 @@ def test_marker_palette_dict(df: DataFrame, key, value): ("key", "value"), [({"a": 1, "b": 0}, "^"), ({"a": 2, "b": 0}, "o"), ({"a": 3, "b": 0}, "x")], ) -def test_marker_palette_default(df: DataFrame, key, value): - from xlviews.figure.palette import MarkerPalette - +def test_marker_palette_default(df: DataFrame, key: dict[str, int], value: str): p = MarkerPalette(df, "a", {2: "o", 3: "x"}) assert p[key] == value @@ -147,9 +158,7 @@ def test_marker_palette_default(df: DataFrame, key, value): ("key", "value"), [({"a": 1, "b": 4}, "o"), ({"a": 2, "b": 5}, "^"), ({"a": 2, "b": 6}, "s")], ) -def test_marker_palette_multi(df: DataFrame, key, value): - from xlviews.figure.palette import MarkerPalette - +def test_marker_palette_multi(df: DataFrame, key: dict[str, int], value: str): p = MarkerPalette(df, ["a", "b"]) assert p[key] == value @@ -158,9 +167,11 @@ def test_marker_palette_multi(df: DataFrame, key, value): ("key", "value"), [({"a": 1, "b": 4}, "o"), ({"a": 2, "b": 5}, "x"), ({"a": 2, "b": 6}, "o")], ) -def test_marker_palette_multi_default_list(df: DataFrame, key, value): - from xlviews.figure.palette import MarkerPalette - +def test_marker_palette_multi_default_list( + df: DataFrame, + key: dict[str, int], + value: str, +): p = MarkerPalette(df, ["a", "b"], ["o", "x"]) assert p[key] == value @@ -173,38 +184,28 @@ def test_marker_palette_multi_default_list(df: DataFrame, key, value): ({"a": 2, "b": 6, "c": 2}, "s"), ], ) -def test_marker_palette_multi_dict(df: DataFrame, key, value): - from xlviews.figure.palette import MarkerPalette - +def test_marker_palette_multi_dict(df: DataFrame, key: dict[str, int], value: str): p = MarkerPalette(df, ["a", "b"]) assert p[key] == value @pytest.mark.parametrize(("key", "value"), [(4, "#1f77b4"), (5, "red"), (6, "blue")]) -def test_color_palette(df: DataFrame, key, value): - from xlviews.figure.palette import ColorPalette - +def test_color_palette(df: DataFrame, key: int, value: str): p = ColorPalette(df, "b", {5: "red", 6: "blue", 7: "green"}) assert p[{"b": key}] == value @pytest.mark.parametrize(("key", "value"), [(4, "red"), (5, "blue"), (6, "red")]) -def test_color_palette_default_list(df: DataFrame, key, value): - from xlviews.figure.palette import ColorPalette - +def test_color_palette_default_list(df: DataFrame, key: int, value: str): p = ColorPalette(df, "b", ["red", "blue"]) assert p[{"b": key}] == value def test_get_palette_none(df: DataFrame): - from xlviews.figure.palette import MarkerPalette, get_palette - assert get_palette(MarkerPalette, df, None) is None def test_get_palette(df: DataFrame): - from xlviews.figure.palette import MarkerPalette, get_palette - p = get_palette(MarkerPalette, df, "a") assert isinstance(p, MarkerPalette) assert p[{"a": 1}] == "o" @@ -215,8 +216,6 @@ def test_get_palette(df: DataFrame): def test_get_palette_dict(df: DataFrame): - from xlviews.figure.palette import MarkerPalette, get_palette - p = get_palette(MarkerPalette, df, {(1, 4, 10): "x"}) assert isinstance(p, MarkerPalette) assert p[{"a": 1, "b": 4, "c": 10}] == "x" @@ -224,8 +223,6 @@ def test_get_palette_dict(df: DataFrame): def test_get_palette_tuple_list(df: DataFrame): - from xlviews.figure.palette import MarkerPalette, get_palette - p = get_palette(MarkerPalette, df, ("b", ["o", "x"])) assert isinstance(p, MarkerPalette) assert p[{"b": 4}] == "o" @@ -235,8 +232,6 @@ def test_get_palette_tuple_list(df: DataFrame): def test_get_palette_tuple_dict(df: DataFrame): - from xlviews.figure.palette import MarkerPalette, get_palette - p = get_palette(MarkerPalette, df, ("b", {"4": "X", "5": "Y"})) assert isinstance(p, MarkerPalette) assert p[{"b": 4}] == "X" @@ -246,10 +241,6 @@ def test_get_palette_tuple_dict(df: DataFrame): def test_series(): - from pandas import Series - - from xlviews.figure.palette import MarkerPalette, get_palette - s = Series([1, 2, 3], index=["a", "b", "c"]) data = s.to_frame().T p = get_palette(MarkerPalette, data, "x") @@ -258,8 +249,6 @@ def test_series(): def test_get_palette_new_default(df: DataFrame): - from xlviews.figure.palette import ColorPalette, get_palette - p = get_palette(ColorPalette, df, "red") assert p assert p[{"a": 1, "b": 4, "c": 10}] == "red" @@ -267,8 +256,6 @@ def test_get_palette_new_default(df: DataFrame): def test_get_palette_new_default_list(df: DataFrame): - from xlviews.figure.palette import ColorPalette, get_palette - p = get_palette(ColorPalette, df, ["red", "blue", "green"]) assert p assert p[{"a": 1, "b": 4, "c": 10}] == "red" @@ -278,49 +265,37 @@ def test_get_palette_new_default_list(df: DataFrame): def test_function_palette_str(): - from xlviews.figure.palette import FunctionPalette - p = FunctionPalette("a", lambda x: x) assert p[{"a": 1}] == 1 def test_function_palette_list(): - from xlviews.figure.palette import FunctionPalette - - p = FunctionPalette(["a"], lambda x: x[0]) # type: ignore + p = FunctionPalette(["a"], itemgetter(0)) assert p[{"a": 1}] == 1 def test_get_palette_callable_str(df: DataFrame): - from xlviews.figure.palette import ColorPalette, get_palette - df = df.set_index("a") - p = get_palette(ColorPalette, df, lambda x: str(x)) + p = get_palette(ColorPalette, df, str) assert p assert p[{"a": 1}] == "1" def test_get_palette_callable_list(df: DataFrame): - from xlviews.figure.palette import ColorPalette, get_palette - df = df.set_index(["a", "b"]) - p = get_palette(ColorPalette, df, lambda x: str(x)) + p = get_palette(ColorPalette, df, str) assert p assert p[{"a": 1, "b": 4}] == "(1, 4)" def test_get_palette_callable_multi_index(df: DataFrame): - from xlviews.figure.palette import ColorPalette, get_palette - df = df.set_index(["a", "b"]) - p = get_palette(ColorPalette, df, ("a", lambda x: str(x))) + p = get_palette(ColorPalette, df, ("a", str)) assert p assert p[{"a": 1, "b": 4}] == "1" def test_get_marker_palette_callable(df: DataFrame): - from xlviews.figure.palette import get_marker_palette - df = df.set_index(["a", "b"]) p = get_marker_palette(df, "a") assert p @@ -330,8 +305,6 @@ def test_get_marker_palette_callable(df: DataFrame): def test_get_color_palette_callable(df: DataFrame): - from xlviews.figure.palette import get_color_palette - df = df.set_index(["a", "b"]) p = get_color_palette(df, "b") assert p From 68d2216ecc80ec114a7b15e2cc46d66fa6eb2411 Mon Sep 17 00:00:00 2001 From: Daizu Date: Wed, 11 Feb 2026 07:11:44 +0900 Subject: [PATCH 39/40] Update tests --- lcov.info | 3970 ++++++++++++++++++++++++++--------------------------- 1 file changed, 1985 insertions(+), 1985 deletions(-) diff --git a/lcov.info b/lcov.info index 7d54dd6..0803d04 100644 --- a/lcov.info +++ b/lcov.info @@ -29,32 +29,32 @@ DA:11,1 DA:13,1 DA:14,1 DA:30,1 -DA:36,0 -DA:37,0 -DA:39,0 -DA:40,0 -DA:42,0 -DA:43,0 -DA:44,0 -DA:45,0 -DA:46,0 -DA:47,0 -DA:48,0 -DA:49,0 -DA:50,0 -DA:52,0 -DA:53,0 -DA:54,0 -DA:55,0 -DA:56,0 -DA:57,0 -DA:58,0 -DA:59,0 -DA:60,0 -DA:62,0 -DA:63,0 -DA:64,0 -DA:66,0 +DA:36,1 +DA:37,1 +DA:39,1 +DA:40,1 +DA:42,1 +DA:43,1 +DA:44,1 +DA:45,1 +DA:46,1 +DA:47,1 +DA:48,1 +DA:49,1 +DA:50,1 +DA:52,1 +DA:53,1 +DA:54,1 +DA:55,1 +DA:56,1 +DA:57,1 +DA:58,1 +DA:59,1 +DA:60,1 +DA:62,1 +DA:63,1 +DA:64,1 +DA:66,1 DA:69,1 DA:70,1 DA:71,1 @@ -62,309 +62,309 @@ DA:72,1 DA:73,1 DA:75,1 DA:76,1 -DA:92,0 -DA:94,0 -DA:95,0 -DA:96,0 -DA:97,0 -DA:99,0 -DA:101,0 -DA:102,0 -DA:104,0 -DA:106,0 -DA:107,0 -DA:110,0 -DA:111,0 -DA:112,0 -DA:114,0 -DA:115,0 -DA:117,0 -DA:118,0 -DA:120,0 +DA:92,1 +DA:94,1 +DA:95,1 +DA:96,1 +DA:97,1 +DA:99,1 +DA:101,1 +DA:102,1 +DA:104,1 +DA:106,1 +DA:107,1 +DA:110,1 +DA:111,1 +DA:112,1 +DA:114,1 +DA:115,1 +DA:117,1 +DA:118,1 +DA:120,1 DA:122,1 DA:123,1 -DA:131,0 -DA:132,0 -DA:133,0 -DA:134,0 -DA:136,0 -DA:137,0 -DA:138,0 -DA:140,0 -DA:141,0 -DA:142,0 -DA:144,0 +DA:131,1 +DA:132,1 +DA:133,1 +DA:134,1 +DA:136,1 +DA:137,1 +DA:138,1 +DA:140,1 +DA:141,1 +DA:142,1 +DA:144,1 DA:159,1 DA:160,1 -DA:161,0 -DA:162,0 +DA:161,1 +DA:162,1 DA:164,1 DA:165,1 -DA:166,0 -DA:167,0 +DA:166,1 +DA:167,1 DA:169,1 DA:170,1 -DA:177,0 -DA:178,0 -DA:180,0 -DA:181,0 -DA:183,0 +DA:177,1 +DA:178,1 +DA:180,1 +DA:181,1 +DA:183,1 DA:185,1 DA:186,1 -DA:187,0 -DA:189,0 -DA:190,0 -DA:192,0 +DA:187,1 +DA:189,1 +DA:190,1 +DA:192,1 DA:194,1 DA:195,1 -DA:196,0 +DA:196,1 DA:198,1 -DA:206,0 -DA:208,0 -DA:209,0 -DA:210,0 -DA:212,0 -DA:213,0 -DA:214,0 -DA:216,0 -DA:217,0 -DA:218,0 +DA:206,1 +DA:208,1 +DA:209,1 +DA:210,1 +DA:212,1 +DA:213,1 +DA:214,1 +DA:216,1 +DA:217,1 +DA:218,1 DA:220,1 DA:221,1 -DA:222,0 +DA:222,1 DA:224,1 DA:225,1 -DA:226,0 +DA:226,1 DA:228,1 DA:229,1 -DA:230,0 +DA:230,1 DA:232,1 DA:233,1 -DA:234,0 +DA:234,1 DA:236,1 -DA:237,0 +DA:237,1 DA:239,1 -DA:240,0 +DA:240,1 DA:242,1 DA:243,1 -DA:244,0 +DA:244,1 DA:246,1 DA:247,1 -DA:248,0 +DA:248,1 DA:250,1 DA:251,1 -DA:252,0 +DA:252,1 DA:254,1 DA:255,1 -DA:256,0 +DA:256,1 DA:258,1 -DA:264,0 +DA:264,1 DA:266,1 -DA:272,0 +DA:272,1 DA:274,1 -DA:275,0 +DA:275,1 DA:277,1 -DA:278,0 +DA:278,1 DA:280,1 DA:281,1 -DA:282,0 +DA:282,1 DA:284,1 DA:285,1 -DA:286,0 +DA:286,1 DA:288,1 DA:289,1 -DA:290,0 +DA:290,1 DA:292,1 DA:293,1 -DA:294,0 +DA:294,1 DA:296,1 DA:297,1 -DA:310,0 -DA:311,0 -DA:312,0 -DA:313,0 -DA:314,0 -DA:315,0 -DA:316,0 -DA:317,0 -DA:318,0 -DA:319,0 -DA:320,0 -DA:321,0 -DA:322,0 -DA:323,0 -DA:324,0 -DA:325,0 -DA:326,0 -DA:327,0 -DA:329,0 -DA:330,0 -DA:331,0 -DA:332,0 -DA:334,0 +DA:310,1 +DA:311,1 +DA:312,1 +DA:313,1 +DA:314,1 +DA:315,1 +DA:316,1 +DA:317,1 +DA:318,1 +DA:319,1 +DA:320,1 +DA:321,1 +DA:322,1 +DA:323,1 +DA:324,1 +DA:325,1 +DA:326,1 +DA:327,1 +DA:329,1 +DA:330,1 +DA:331,1 +DA:332,1 +DA:334,1 DA:336,1 -DA:337,0 -DA:338,0 -DA:339,0 +DA:337,1 +DA:338,1 +DA:339,1 DA:341,1 DA:342,1 -DA:358,0 -DA:359,0 -DA:360,0 -DA:362,0 -DA:363,0 -DA:365,0 -DA:366,0 -DA:367,0 -DA:368,0 -DA:369,0 -DA:372,0 -DA:373,0 -DA:375,0 -DA:376,0 -DA:377,0 -DA:379,0 -DA:380,0 -DA:381,0 -DA:382,0 -DA:383,0 -DA:384,0 -DA:386,0 -DA:387,0 -DA:388,0 -DA:389,0 -DA:390,0 -DA:391,0 -DA:393,0 -DA:395,0 -DA:396,0 -DA:397,0 -DA:398,0 -DA:399,0 -DA:400,0 -DA:401,0 -DA:403,0 -DA:404,0 -DA:405,0 -DA:406,0 -DA:408,0 -DA:409,0 -DA:410,0 -DA:411,0 -DA:412,0 -DA:414,0 -DA:415,0 -DA:417,0 -DA:419,0 +DA:358,1 +DA:359,1 +DA:360,1 +DA:362,1 +DA:363,1 +DA:365,1 +DA:366,1 +DA:367,1 +DA:368,1 +DA:369,1 +DA:372,1 +DA:373,1 +DA:375,1 +DA:376,1 +DA:377,1 +DA:379,1 +DA:380,1 +DA:381,1 +DA:382,1 +DA:383,1 +DA:384,1 +DA:386,1 +DA:387,1 +DA:388,1 +DA:389,1 +DA:390,1 +DA:391,1 +DA:393,1 +DA:395,1 +DA:396,1 +DA:397,1 +DA:398,1 +DA:399,1 +DA:400,1 +DA:401,1 +DA:403,1 +DA:404,1 +DA:405,1 +DA:406,1 +DA:408,1 +DA:409,1 +DA:410,1 +DA:411,1 +DA:412,1 +DA:414,1 +DA:415,1 +DA:417,1 +DA:419,1 DA:421,1 -DA:422,0 -DA:423,0 -DA:424,0 -DA:426,0 -DA:427,0 -DA:429,0 -DA:430,0 -DA:431,0 -DA:433,0 -DA:434,0 -DA:435,0 -DA:437,0 -DA:438,0 -DA:439,0 -DA:440,0 -DA:442,0 -DA:444,0 -DA:447,0 -DA:451,0 +DA:422,1 +DA:423,1 +DA:424,1 +DA:426,1 +DA:427,1 +DA:429,1 +DA:430,1 +DA:431,1 +DA:433,1 +DA:434,1 +DA:435,1 +DA:437,1 +DA:438,1 +DA:439,1 +DA:440,1 +DA:442,1 +DA:444,1 +DA:447,1 +DA:451,1 DA:453,1 -DA:455,0 -DA:456,0 -DA:458,0 -DA:460,0 -DA:461,0 -DA:462,0 -DA:463,0 -DA:464,0 -DA:465,0 -DA:467,0 -DA:468,0 -DA:469,0 -DA:470,0 -DA:471,0 -DA:473,0 -DA:474,0 -DA:475,0 -DA:476,0 -DA:477,0 -DA:479,0 +DA:455,1 +DA:456,1 +DA:458,1 +DA:460,1 +DA:461,1 +DA:462,1 +DA:463,1 +DA:464,1 +DA:465,1 +DA:467,1 +DA:468,1 +DA:469,1 +DA:470,1 +DA:471,1 +DA:473,1 +DA:474,1 +DA:475,1 +DA:476,1 +DA:477,1 +DA:479,1 LF:279 -LH:68 +LH:279 FN:30,66,chart_position -FNDA:0,chart_position +FNDA:1,chart_position FN:76,120,Axes.__init__ -FNDA:0,Axes.__init__ +FNDA:1,Axes.__init__ FN:123,157,Axes.copy -FNDA:0,Axes.copy +FNDA:1,Axes.copy FN:160,162,Axes.xaxis -FNDA:0,Axes.xaxis +FNDA:1,Axes.xaxis FN:165,167,Axes.yaxis -FNDA:0,Axes.yaxis +FNDA:1,Axes.yaxis FN:170,183,Axes.add_series -FNDA:0,Axes.add_series +FNDA:1,Axes.add_series FN:186,192,Axes.title -FNDA:0,Axes.title +FNDA:1,Axes.title FN:195,196,Axes.title -FNDA:0,Axes.title +FNDA:1,Axes.title FN:198,218,Axes.set_title -FNDA:0,Axes.set_title +FNDA:1,Axes.set_title FN:221,222,Axes.xlabel -FNDA:0,Axes.xlabel +FNDA:1,Axes.xlabel FN:225,226,Axes.xlabel -FNDA:0,Axes.xlabel +FNDA:1,Axes.xlabel FN:229,230,Axes.ylabel -FNDA:0,Axes.ylabel +FNDA:1,Axes.ylabel FN:233,234,Axes.ylabel -FNDA:0,Axes.ylabel +FNDA:1,Axes.ylabel FN:236,237,Axes.set_xlabel -FNDA:0,Axes.set_xlabel +FNDA:1,Axes.set_xlabel FN:239,240,Axes.set_ylabel -FNDA:0,Axes.set_ylabel +FNDA:1,Axes.set_ylabel FN:243,244,Axes.xticks -FNDA:0,Axes.xticks +FNDA:1,Axes.xticks FN:247,248,Axes.xticks -FNDA:0,Axes.xticks +FNDA:1,Axes.xticks FN:251,252,Axes.yticks -FNDA:0,Axes.yticks +FNDA:1,Axes.yticks FN:255,256,Axes.yticks -FNDA:0,Axes.yticks +FNDA:1,Axes.yticks FN:258,264,Axes.set_xticks -FNDA:0,Axes.set_xticks +FNDA:1,Axes.set_xticks FN:266,272,Axes.set_yticks -FNDA:0,Axes.set_yticks +FNDA:1,Axes.set_yticks FN:274,275,Axes.set_xtick_labels -FNDA:0,Axes.set_xtick_labels +FNDA:1,Axes.set_xtick_labels FN:277,278,Axes.set_ytick_labels -FNDA:0,Axes.set_ytick_labels +FNDA:1,Axes.set_ytick_labels FN:281,282,Axes.xscale -FNDA:0,Axes.xscale +FNDA:1,Axes.xscale FN:285,286,Axes.xscale -FNDA:0,Axes.xscale +FNDA:1,Axes.xscale FN:289,290,Axes.yscale -FNDA:0,Axes.yscale +FNDA:1,Axes.yscale FN:293,294,Axes.yscale -FNDA:0,Axes.yscale +FNDA:1,Axes.yscale FN:297,334,Axes.set -FNDA:0,Axes.set +FNDA:1,Axes.set FN:336,339,Axes.delete_legend -FNDA:0,Axes.delete_legend +FNDA:1,Axes.delete_legend FN:342,419,Axes.legend -FNDA:0,Axes.legend +FNDA:1,Axes.legend FN:421,451,Axes.tight_layout -FNDA:0,Axes.tight_layout +FNDA:1,Axes.tight_layout FN:453,479,Axes.style -FNDA:0,Axes.style +FNDA:1,Axes.style FNF:32 -FNH:0 +FNH:32 end_of_record SF:src\xlviews\chart\series.py DA:1,1 @@ -379,126 +379,126 @@ DA:18,1 DA:19,1 DA:20,1 DA:22,1 -DA:30,0 -DA:31,0 -DA:32,0 -DA:34,0 -DA:35,0 -DA:37,0 -DA:38,0 -DA:39,0 -DA:42,0 +DA:30,1 +DA:31,1 +DA:32,1 +DA:34,1 +DA:35,1 +DA:37,1 +DA:38,1 +DA:39,1 +DA:42,1 DA:44,1 DA:45,1 -DA:46,0 +DA:46,1 DA:48,1 DA:49,1 -DA:50,0 +DA:50,1 DA:52,1 DA:53,1 -DA:54,0 +DA:54,1 DA:56,1 DA:57,1 -DA:58,0 +DA:58,1 DA:60,1 DA:61,1 -DA:62,0 +DA:62,1 DA:64,1 DA:65,1 -DA:66,0 -DA:67,0 -DA:69,0 +DA:66,1 +DA:67,1 +DA:69,1 DA:71,1 DA:72,1 -DA:73,0 +DA:73,1 DA:75,1 DA:76,1 -DA:77,0 -DA:78,0 -DA:80,0 +DA:77,1 +DA:78,1 +DA:80,1 DA:82,1 -DA:83,0 +DA:83,1 DA:85,1 -DA:96,0 -DA:97,0 -DA:99,0 -DA:100,0 -DA:101,0 -DA:103,0 -DA:104,0 +DA:96,1 +DA:97,1 +DA:99,1 +DA:100,1 +DA:101,1 +DA:103,1 +DA:104,1 DA:106,1 -DA:114,0 -DA:116,0 -DA:117,0 -DA:118,0 -DA:119,0 -DA:121,0 +DA:114,1 +DA:116,1 +DA:117,1 +DA:118,1 +DA:119,1 +DA:121,1 DA:123,1 -DA:132,0 -DA:133,0 -DA:135,0 -DA:137,0 -DA:138,0 -DA:139,0 -DA:140,0 -DA:142,0 +DA:132,1 +DA:133,1 +DA:135,1 +DA:137,1 +DA:138,1 +DA:139,1 +DA:140,1 +DA:142,1 DA:145,1 -DA:146,0 -DA:147,0 -DA:148,0 -DA:149,0 +DA:146,1 +DA:147,1 +DA:148,1 +DA:149,1 DA:152,1 -DA:153,0 -DA:154,0 -DA:155,0 -DA:156,0 -DA:157,0 +DA:153,1 +DA:154,1 +DA:155,1 +DA:156,1 +DA:157,1 DA:160,1 -DA:167,0 -DA:168,0 -DA:170,0 -DA:171,0 -DA:172,0 -DA:173,0 -DA:174,0 -DA:175,0 -DA:177,0 +DA:167,1 +DA:168,1 +DA:170,1 +DA:171,1 +DA:172,1 +DA:173,1 +DA:174,1 +DA:175,1 +DA:177,1 LF:96 -LH:35 +LH:96 FN:22,42,Series.__init__ -FNDA:0,Series.__init__ +FNDA:1,Series.__init__ FN:45,46,Series.label -FNDA:0,Series.label +FNDA:1,Series.label FN:49,50,Series.label -FNDA:0,Series.label +FNDA:1,Series.label FN:53,54,Series.chart_type -FNDA:0,Series.chart_type +FNDA:1,Series.chart_type FN:57,58,Series.chart_type -FNDA:0,Series.chart_type +FNDA:1,Series.chart_type FN:61,62,Series.x -FNDA:0,Series.x +FNDA:1,Series.x FN:65,69,Series.x -FNDA:0,Series.x +FNDA:1,Series.x FN:72,73,Series.y -FNDA:0,Series.y +FNDA:1,Series.y FN:76,80,Series.y -FNDA:0,Series.y +FNDA:1,Series.y FN:82,83,Series.delete -FNDA:0,Series.delete +FNDA:1,Series.delete FN:85,104,Series.set -FNDA:0,Series.set +FNDA:1,Series.set FN:106,121,Series.marker -FNDA:0,Series.marker +FNDA:1,Series.marker FN:123,142,Series.line -FNDA:0,Series.line +FNDA:1,Series.line FN:145,149,set_marker -FNDA:0,set_marker +FNDA:1,set_marker FN:152,157,set_fill -FNDA:0,set_fill +FNDA:1,set_fill FN:160,177,set_line -FNDA:0,set_line +FNDA:1,set_line FNF:16 -FNH:0 +FNH:16 end_of_record SF:src\xlviews\chart\style.py DA:3,1 @@ -511,136 +511,136 @@ DA:13,1 DA:26,1 DA:39,1 DA:48,1 -DA:49,0 -DA:50,0 -DA:52,0 +DA:49,1 +DA:50,1 +DA:52,1 DA:55,1 -DA:56,0 -DA:57,0 -DA:59,0 +DA:56,1 +DA:57,1 +DA:59,1 DA:62,1 -DA:63,0 -DA:64,0 -DA:66,0 +DA:63,1 +DA:64,1 +DA:66,1 DA:69,1 -DA:76,0 -DA:77,0 -DA:78,0 -DA:80,0 -DA:81,0 -DA:82,0 -DA:84,0 -DA:85,0 -DA:87,0 +DA:76,1 +DA:77,1 +DA:78,1 +DA:80,1 +DA:81,1 +DA:82,1 +DA:84,1 +DA:85,1 +DA:87,1 DA:90,1 -DA:91,0 +DA:91,1 DA:99,1 -DA:108,0 -DA:110,0 -DA:111,0 -DA:112,0 -DA:113,0 -DA:115,0 -DA:116,0 -DA:118,0 -DA:119,0 -DA:121,0 -DA:122,0 -DA:124,0 -DA:125,0 -DA:127,0 -DA:129,0 -DA:130,0 -DA:132,0 -DA:133,0 -DA:135,0 -DA:137,0 -DA:138,0 +DA:108,1 +DA:110,1 +DA:111,1 +DA:112,1 +DA:113,1 +DA:115,1 +DA:116,1 +DA:118,1 +DA:119,1 +DA:121,1 +DA:122,1 +DA:124,1 +DA:125,1 +DA:127,1 +DA:129,1 +DA:130,1 +DA:132,1 +DA:133,1 +DA:135,1 +DA:137,1 +DA:138,1 DA:141,1 -DA:147,0 -DA:148,0 -DA:149,0 -DA:151,0 -DA:152,0 +DA:147,1 +DA:148,1 +DA:149,1 +DA:151,1 +DA:152,1 DA:155,1 -DA:156,0 -DA:157,0 -DA:159,0 -DA:160,0 +DA:156,1 +DA:157,1 +DA:159,1 +DA:160,1 DA:165,1 -DA:166,0 -DA:167,0 -DA:168,0 -DA:170,0 -DA:171,0 -DA:172,0 +DA:166,1 +DA:167,1 +DA:168,1 +DA:170,1 +DA:171,1 +DA:172,1 DA:177,1 -DA:184,0 -DA:185,0 -DA:187,0 -DA:188,0 -DA:190,0 -DA:191,0 -DA:193,0 -DA:194,0 +DA:184,1 +DA:185,1 +DA:187,1 +DA:188,1 +DA:190,1 +DA:191,1 +DA:193,1 +DA:194,1 DA:197,1 -DA:203,0 -DA:204,0 -DA:205,0 -DA:207,0 -DA:208,0 -DA:209,0 -DA:211,0 -DA:212,0 -DA:213,0 +DA:203,1 +DA:204,1 +DA:205,1 +DA:207,1 +DA:208,1 +DA:209,1 +DA:211,1 +DA:212,1 +DA:213,1 LF:92 -LH:20 +LH:92 FN:48,52,get_marker_style -FNDA:0,get_marker_style +FNDA:1,get_marker_style FN:55,59,get_line_style -FNDA:0,get_line_style +FNDA:1,get_line_style FN:62,66,get_axis_label -FNDA:0,get_axis_label +FNDA:1,get_axis_label FN:69,87,set_axis_label -FNDA:0,set_axis_label +FNDA:1,set_axis_label FN:90,96,get_ticks -FNDA:0,get_ticks +FNDA:1,get_ticks FN:99,138,set_ticks -FNDA:0,set_ticks +FNDA:1,set_ticks FN:141,152,set_tick_labels -FNDA:0,set_tick_labels +FNDA:1,set_tick_labels FN:155,162,get_axis_scale -FNDA:0,get_axis_scale +FNDA:1,get_axis_scale FN:165,174,set_axis_scale -FNDA:0,set_axis_scale +FNDA:1,set_axis_scale FN:177,194,set_dimensions -FNDA:0,set_dimensions +FNDA:1,set_dimensions FN:197,213,set_area_format -FNDA:0,set_area_format +FNDA:1,set_area_format FNF:11 -FNH:0 +FNH:11 end_of_record SF:src\xlviews\colors.py DA:1,1 DA:3,1 DA:6,1 DA:31,1 -DA:32,0 +DA:32,1 DA:34,1 DA:35,1 -DA:37,0 -DA:38,0 -DA:40,0 -DA:41,0 -DA:42,0 -DA:44,0 -DA:46,0 -DA:47,0 -DA:49,0 -DA:50,0 +DA:37,1 +DA:38,1 +DA:40,1 +DA:41,1 +DA:42,1 +DA:44,1 +DA:46,1 +DA:47,1 +DA:49,1 +DA:50,1 DA:53,1 LF:18 -LH:7 +LH:18 FN:6,50,rgb FNDA:1,rgb FNF:1 @@ -666,19 +666,19 @@ DA:33,1 DA:34,1 DA:36,1 DA:38,1 -DA:39,0 -DA:40,0 -DA:42,0 -DA:43,0 -DA:45,0 +DA:39,1 +DA:40,1 +DA:42,1 +DA:43,1 +DA:45,1 DA:47,1 -DA:48,0 -DA:49,0 -DA:50,0 -DA:51,0 +DA:48,1 +DA:49,1 +DA:50,1 +DA:51,1 DA:54,1 LF:30 -LH:21 +LH:30 FN:18,20,load_config FNDA:1,load_config FN:26,27,Config.__init__ @@ -686,11 +686,11 @@ FNDA:1,Config.__init__ FN:29,36,Config.__getitem__ FNDA:1,Config.__getitem__ FN:38,45,Config.__setitem__ -FNDA:0,Config.__setitem__ +FNDA:1,Config.__setitem__ FN:47,51,Config.get -FNDA:0,Config.get +FNDA:1,Config.get FNF:5 -FNH:3 +FNH:5 end_of_record SF:src\xlviews\core\__init__.py end_of_record @@ -699,26 +699,26 @@ DA:1,1 DA:3,1 DA:6,1 DA:7,1 -DA:20,0 -DA:21,0 -DA:22,0 -DA:23,0 -DA:24,0 -DA:26,0 +DA:20,1 +DA:21,1 +DA:22,1 +DA:23,1 +DA:24,1 +DA:26,1 DA:29,1 DA:30,1 -DA:43,0 -DA:44,0 -DA:45,0 -DA:47,0 +DA:43,1 +DA:44,1 +DA:45,1 +DA:47,1 LF:16 -LH:6 +LH:16 FN:7,26,index_to_column_name -FNDA:0,index_to_column_name +FNDA:1,index_to_column_name FN:30,47,column_name_to_index -FNDA:0,column_name_to_index +FNDA:1,column_name_to_index FNF:2 -FNH:0 +FNH:2 end_of_record SF:src\xlviews\core\formula.py DA:1,1 @@ -729,56 +729,56 @@ DA:8,1 DA:14,1 DA:16,1 DA:19,1 -DA:21,0 -DA:22,0 -DA:24,0 -DA:25,0 -DA:26,0 -DA:27,0 -DA:29,0 -DA:30,0 -DA:31,0 -DA:33,0 +DA:21,1 +DA:22,1 +DA:24,1 +DA:25,1 +DA:26,1 +DA:27,1 +DA:29,1 +DA:30,1 +DA:31,1 +DA:33,1 DA:36,1 DA:47,1 DA:48,1 DA:49,1 DA:52,1 -DA:58,0 -DA:59,0 -DA:60,0 -DA:61,0 -DA:63,0 -DA:64,0 -DA:66,0 -DA:67,0 -DA:69,0 -DA:71,0 -DA:72,0 -DA:74,0 -DA:75,0 -DA:76,0 -DA:78,0 -DA:79,0 -DA:81,0 -DA:82,0 -DA:83,0 -DA:84,0 +DA:58,1 +DA:59,1 +DA:60,1 +DA:61,1 +DA:63,1 +DA:64,1 +DA:66,1 +DA:67,1 +DA:69,1 +DA:71,1 +DA:72,1 +DA:74,1 +DA:75,1 +DA:76,1 +DA:78,1 +DA:79,1 +DA:81,1 +DA:82,1 +DA:83,1 +DA:84,1 DA:87,1 -DA:98,0 -DA:108,0 -DA:109,0 -DA:111,0 +DA:98,1 +DA:108,1 +DA:109,1 +DA:111,1 LF:48 -LH:14 +LH:48 FN:19,33,const -FNDA:0,const +FNDA:1,const FN:52,84,_aggregate -FNDA:0,_aggregate +FNDA:1,_aggregate FN:87,111,aggregate -FNDA:0,aggregate +FNDA:1,aggregate FNF:3 -FNH:0 +FNH:3 end_of_record SF:src\xlviews\core\index.py DA:1,1 @@ -788,104 +788,104 @@ DA:6,1 DA:7,1 DA:16,1 DA:19,1 -DA:20,0 +DA:20,1 DA:22,1 DA:23,1 -DA:24,0 +DA:24,1 DA:26,1 -DA:27,0 +DA:27,1 DA:29,1 -DA:30,0 -DA:31,0 -DA:32,0 +DA:30,1 +DA:31,1 +DA:32,1 DA:34,1 -DA:35,0 -DA:36,0 -DA:37,0 -DA:39,0 +DA:35,1 +DA:36,1 +DA:37,1 +DA:39,1 DA:42,1 DA:43,1 DA:44,1 DA:46,1 -DA:51,0 -DA:53,0 -DA:54,0 -DA:55,0 -DA:56,0 -DA:58,0 -DA:60,1 -DA:61,0 -DA:63,1 -DA:64,1 -DA:65,0 -DA:67,1 +DA:51,1 +DA:53,1 +DA:54,1 +DA:55,1 +DA:56,1 +DA:58,1 +DA:60,1 +DA:61,1 +DA:63,1 +DA:64,1 +DA:65,1 +DA:67,1 DA:68,1 -DA:80,0 +DA:80,1 DA:82,1 -DA:90,0 +DA:90,1 DA:92,1 -DA:100,0 -DA:101,0 +DA:100,1 +DA:101,1 DA:103,1 -DA:117,0 -DA:118,0 -DA:120,0 +DA:117,1 +DA:118,1 +DA:120,1 DA:122,1 -DA:139,0 -DA:140,0 -DA:142,0 +DA:139,1 +DA:140,1 +DA:142,1 DA:144,1 -DA:158,0 -DA:159,0 -DA:160,0 -DA:161,0 -DA:163,0 -DA:164,0 -DA:165,0 +DA:158,1 +DA:159,1 +DA:160,1 +DA:161,1 +DA:163,1 +DA:164,1 +DA:165,1 DA:169,1 -DA:175,0 -DA:178,0 -DA:179,0 -DA:181,0 -DA:183,0 +DA:175,1 +DA:178,1 +DA:179,1 +DA:181,1 +DA:183,1 DA:185,1 -DA:186,0 +DA:186,1 LF:69 -LH:28 +LH:69 FN:19,20,WideIndex.__len__ -FNDA:0,WideIndex.__len__ +FNDA:1,WideIndex.__len__ FN:23,24,WideIndex.names -FNDA:0,WideIndex.names +FNDA:1,WideIndex.names FN:26,27,WideIndex.to_list -FNDA:0,WideIndex.to_list +FNDA:1,WideIndex.to_list FN:29,32,WideIndex.get_loc -FNDA:0,WideIndex.get_loc +FNDA:1,WideIndex.get_loc FN:34,39,WideIndex.append -FNDA:0,WideIndex.append +FNDA:1,WideIndex.append FN:46,58,Index.__init__ -FNDA:0,Index.__init__ +FNDA:1,Index.__init__ FN:60,61,Index.__len__ -FNDA:0,Index.__len__ +FNDA:1,Index.__len__ FN:64,65,Index.names -FNDA:0,Index.names +FNDA:1,Index.names FN:68,80,Index.nlevels -FNDA:0,Index.nlevels +FNDA:1,Index.nlevels FN:82,90,Index.to_list -FNDA:0,Index.to_list +FNDA:1,Index.to_list FN:92,101,Index.__iter__ -FNDA:0,Index.__iter__ +FNDA:1,Index.__iter__ FN:103,120,Index.__contains__ -FNDA:0,Index.__contains__ +FNDA:1,Index.__contains__ FN:122,142,Index.append -FNDA:0,Index.append +FNDA:1,Index.append FN:144,167,Index.get_loc -FNDA:0,Index.get_loc +FNDA:1,Index.get_loc FN:169,183,Index.get_indexer -FNDA:0,Index.get_indexer +FNDA:1,Index.get_indexer FN:185,186,Index.to_frame -FNDA:0,Index.to_frame +FNDA:1,Index.to_frame FNF:16 -FNH:0 +FNH:16 end_of_record SF:src\xlviews\core\range.py DA:1,1 @@ -902,153 +902,153 @@ DA:22,1 DA:23,1 DA:24,1 DA:26,1 -DA:32,0 -DA:34,0 -DA:35,0 -DA:36,0 -DA:37,0 -DA:39,0 -DA:40,0 -DA:42,0 -DA:43,0 -DA:44,0 -DA:47,0 -DA:48,0 +DA:32,1 +DA:34,1 +DA:35,1 +DA:36,1 +DA:37,1 +DA:39,1 +DA:40,1 +DA:42,1 +DA:43,1 +DA:44,1 +DA:47,1 +DA:48,1 DA:50,1 DA:51,1 -DA:52,0 -DA:53,0 -DA:54,0 +DA:52,1 +DA:53,1 +DA:54,1 DA:56,1 -DA:57,0 +DA:57,1 DA:59,1 -DA:60,0 -DA:61,0 -DA:62,0 +DA:60,1 +DA:61,1 +DA:62,1 DA:64,1 -DA:65,0 -DA:66,0 -DA:68,0 -DA:69,0 -DA:70,0 -DA:72,0 -DA:73,0 -DA:74,0 +DA:65,1 +DA:66,1 +DA:68,1 +DA:69,1 +DA:70,1 +DA:72,1 +DA:73,1 +DA:74,1 DA:76,1 DA:77,1 -DA:78,0 +DA:78,1 DA:80,1 -DA:81,0 -DA:82,0 +DA:81,1 +DA:82,1 DA:84,1 -DA:85,0 +DA:85,1 DA:91,1 -DA:99,0 -DA:107,0 +DA:99,1 +DA:107,1 DA:109,1 -DA:117,0 +DA:117,1 DA:127,1 DA:128,1 -DA:129,0 -DA:130,0 -DA:131,0 +DA:129,1 +DA:130,1 +DA:131,1 DA:133,1 DA:134,1 -DA:135,0 +DA:135,1 DA:137,1 DA:138,1 -DA:139,0 +DA:139,1 DA:141,1 DA:142,1 -DA:143,0 +DA:143,1 DA:145,1 DA:146,1 -DA:147,0 +DA:147,1 DA:154,1 -DA:164,0 -DA:165,0 -DA:167,0 -DA:168,0 -DA:176,0 -DA:177,0 -DA:179,0 +DA:164,1 +DA:165,1 +DA:167,1 +DA:168,1 +DA:176,1 +DA:177,1 +DA:179,1 DA:182,1 -DA:191,0 -DA:192,0 -DA:194,0 -DA:195,0 -DA:196,0 -DA:197,0 -DA:199,0 -DA:201,0 -DA:202,0 -DA:203,0 -DA:204,0 -DA:206,0 -DA:207,0 -DA:208,0 -DA:209,0 -DA:211,0 -DA:212,0 -DA:215,0 -DA:216,0 -DA:217,0 +DA:191,1 +DA:192,1 +DA:194,1 +DA:195,1 +DA:196,1 +DA:197,1 +DA:199,1 +DA:201,1 +DA:202,1 +DA:203,1 +DA:204,1 +DA:206,1 +DA:207,1 +DA:208,1 +DA:209,1 +DA:211,1 +DA:212,1 +DA:215,1 +DA:216,1 +DA:217,1 DA:220,1 DA:221,1 -DA:231,0 -DA:232,0 -DA:233,0 -DA:235,0 -DA:236,0 -DA:237,0 -DA:238,0 -DA:240,0 -DA:242,0 -DA:243,0 -DA:245,0 -DA:246,0 -DA:247,0 -DA:249,0 +DA:231,1 +DA:232,1 +DA:233,1 +DA:235,1 +DA:236,1 +DA:237,1 +DA:238,1 +DA:240,1 +DA:242,1 +DA:243,1 +DA:245,1 +DA:246,1 +DA:247,1 +DA:249,1 LF:121 -LH:39 +LH:121 FN:26,48,Range.__init__ -FNDA:0,Range.__init__ +FNDA:1,Range.__init__ FN:51,54,Range.from_range -FNDA:0,Range.from_range +FNDA:1,Range.from_range FN:56,57,Range.__len__ -FNDA:0,Range.__len__ +FNDA:1,Range.__len__ FN:59,62,Range.__iter__ -FNDA:0,Range.__iter__ +FNDA:1,Range.__iter__ FN:64,74,Range.__getitem__ -FNDA:0,Range.__getitem__ +FNDA:1,Range.__getitem__ FN:77,78,Range.last_cell -FNDA:0,Range.last_cell +FNDA:1,Range.last_cell FN:80,82,Range.__repr__ -FNDA:0,Range.__repr__ +FNDA:1,Range.__repr__ FN:84,89,Range.offset -FNDA:0,Range.offset +FNDA:1,Range.offset FN:91,107,Range.get_address -FNDA:0,Range.get_address +FNDA:1,Range.get_address FN:109,125,Range.iter_addresses -FNDA:0,Range.iter_addresses +FNDA:1,Range.iter_addresses FN:128,131,Range.impl -FNDA:0,Range.impl +FNDA:1,Range.impl FN:134,135,Range.value -FNDA:0,Range.value +FNDA:1,Range.value FN:138,139,Range.value -FNDA:0,Range.value +FNDA:1,Range.value FN:142,143,Range.api -FNDA:0,Range.api +FNDA:1,Range.api FN:146,151,Range.frame -FNDA:0,Range.frame +FNDA:1,Range.frame FN:154,179,iter_addresses -FNDA:0,iter_addresses +FNDA:1,iter_addresses FN:182,217,_iter_addresses -FNDA:0,_iter_addresses +FNDA:1,_iter_addresses FN:221,249,FrameRange.get_address -FNDA:0,FrameRange.get_address +FNDA:1,FrameRange.get_address FNF:18 -FNH:0 +FNH:18 end_of_record SF:src\xlviews\core\range_collection.py DA:1,1 @@ -1058,63 +1058,63 @@ DA:6,1 DA:14,1 DA:15,1 DA:17,1 -DA:23,0 +DA:23,1 DA:25,1 -DA:26,0 -DA:27,0 -DA:28,0 +DA:26,1 +DA:27,1 +DA:28,1 DA:30,1 -DA:31,0 +DA:31,1 DA:33,1 -DA:34,0 +DA:34,1 DA:36,1 -DA:43,0 -DA:49,0 +DA:43,1 +DA:49,1 DA:51,1 -DA:60,0 +DA:60,1 DA:70,1 DA:71,1 -DA:72,0 -DA:74,0 -DA:75,0 -DA:77,0 -DA:78,0 -DA:80,0 -DA:81,0 -DA:83,0 +DA:72,1 +DA:74,1 +DA:75,1 +DA:77,1 +DA:78,1 +DA:80,1 +DA:81,1 +DA:83,1 DA:86,1 -DA:92,0 -DA:93,0 -DA:95,0 -DA:96,0 -DA:97,0 -DA:98,0 -DA:100,0 -DA:101,0 -DA:102,0 -DA:103,0 -DA:106,0 -DA:107,0 +DA:92,1 +DA:93,1 +DA:95,1 +DA:96,1 +DA:97,1 +DA:98,1 +DA:100,1 +DA:101,1 +DA:102,1 +DA:103,1 +DA:106,1 +DA:107,1 LF:44 -LH:15 +LH:44 FN:17,23,RangeCollection.__init__ -FNDA:0,RangeCollection.__init__ +FNDA:1,RangeCollection.__init__ FN:25,28,RangeCollection.__repr__ -FNDA:0,RangeCollection.__repr__ +FNDA:1,RangeCollection.__repr__ FN:30,31,RangeCollection.__len__ -FNDA:0,RangeCollection.__len__ +FNDA:1,RangeCollection.__len__ FN:33,34,RangeCollection.__iter__ -FNDA:0,RangeCollection.__iter__ +FNDA:1,RangeCollection.__iter__ FN:36,49,RangeCollection.get_address -FNDA:0,RangeCollection.get_address +FNDA:1,RangeCollection.get_address FN:51,68,RangeCollection.iter_addresses -FNDA:0,RangeCollection.iter_addresses +FNDA:1,RangeCollection.iter_addresses FN:71,83,RangeCollection.api -FNDA:0,RangeCollection.api +FNDA:1,RangeCollection.api FN:86,107,_iter_ranges_from_index -FNDA:0,_iter_ranges_from_index +FNDA:1,_iter_ranges_from_index FNF:8 -FNH:0 +FNH:8 end_of_record SF:src\xlviews\dataframes\__init__.py end_of_record @@ -1135,118 +1135,118 @@ DA:27,1 DA:28,1 DA:29,1 DA:31,1 -DA:39,0 -DA:40,0 -DA:42,0 -DA:43,0 -DA:44,0 -DA:45,0 -DA:46,0 -DA:49,0 -DA:50,0 -DA:51,0 -DA:52,0 +DA:39,1 +DA:40,1 +DA:42,1 +DA:43,1 +DA:44,1 +DA:45,1 +DA:46,1 +DA:49,1 +DA:50,1 +DA:51,1 +DA:52,1 DA:54,1 -DA:61,0 -DA:62,0 -DA:63,0 -DA:64,0 -DA:65,0 -DA:66,0 -DA:68,0 -DA:70,0 -DA:71,0 -DA:73,0 +DA:61,1 +DA:62,1 +DA:63,1 +DA:64,1 +DA:65,1 +DA:66,1 +DA:68,1 +DA:70,1 +DA:71,1 +DA:73,1 DA:75,1 DA:76,1 -DA:77,0 -DA:78,0 +DA:77,1 +DA:78,1 DA:80,1 DA:81,1 -DA:82,0 -DA:83,0 +DA:82,1 +DA:83,1 DA:85,1 DA:86,1 -DA:87,0 -DA:88,0 -DA:89,0 -DA:91,0 +DA:87,1 +DA:88,1 +DA:89,1 +DA:91,1 DA:93,1 DA:94,1 -DA:95,0 -DA:96,0 -DA:97,0 -DA:99,0 +DA:95,1 +DA:96,1 +DA:97,1 +DA:99,1 DA:101,1 DA:102,1 -DA:103,0 -DA:104,0 +DA:103,1 +DA:104,1 DA:106,1 DA:107,1 -DA:108,0 -DA:109,0 -DA:110,0 -DA:111,0 +DA:108,1 +DA:109,1 +DA:110,1 +DA:111,1 DA:113,1 -DA:114,0 -DA:115,0 -DA:116,0 -DA:117,0 -DA:118,0 -DA:119,0 -DA:121,0 -DA:122,0 -DA:124,0 -DA:125,0 -DA:126,0 -DA:127,0 -DA:128,0 -DA:130,0 -DA:132,0 -DA:133,0 -DA:134,0 +DA:114,1 +DA:115,1 +DA:116,1 +DA:117,1 +DA:118,1 +DA:119,1 +DA:121,1 +DA:122,1 +DA:124,1 +DA:125,1 +DA:126,1 +DA:127,1 +DA:128,1 +DA:130,1 +DA:132,1 +DA:133,1 +DA:134,1 DA:136,1 -DA:137,0 +DA:137,1 DA:139,1 -DA:140,0 -DA:141,0 -DA:142,0 -DA:144,0 -DA:145,0 -DA:147,0 -DA:148,0 +DA:140,1 +DA:141,1 +DA:142,1 +DA:144,1 +DA:145,1 +DA:147,1 +DA:148,1 DA:150,1 -DA:152,0 -DA:153,0 -DA:155,0 +DA:152,1 +DA:153,1 +DA:155,1 LF:100 -LH:33 +LH:100 FN:31,52,Colorbar.__init__ -FNDA:0,Colorbar.__init__ +FNDA:1,Colorbar.__init__ FN:54,73,Colorbar.set -FNDA:0,Colorbar.set +FNDA:1,Colorbar.set FN:76,78,Colorbar.vmin -FNDA:0,Colorbar.vmin +FNDA:1,Colorbar.vmin FN:81,83,Colorbar.vmax -FNDA:0,Colorbar.vmax +FNDA:1,Colorbar.vmax FN:86,91,Colorbar.vmin -FNDA:0,Colorbar.vmin +FNDA:1,Colorbar.vmin FN:94,99,Colorbar.vmax -FNDA:0,Colorbar.vmax +FNDA:1,Colorbar.vmax FN:102,104,Colorbar.label -FNDA:0,Colorbar.label +FNDA:1,Colorbar.label FN:107,111,Colorbar.label -FNDA:0,Colorbar.label +FNDA:1,Colorbar.label FN:113,134,Colorbar.draw -FNDA:0,Colorbar.draw +FNDA:1,Colorbar.draw FN:136,137,Colorbar.apply -FNDA:0,Colorbar.apply +FNDA:1,Colorbar.apply FN:139,148,Colorbar.autofit -FNDA:0,Colorbar.autofit +FNDA:1,Colorbar.autofit FN:150,155,Colorbar.set_adjacent_column_width -FNDA:0,Colorbar.set_adjacent_column_width +FNDA:1,Colorbar.set_adjacent_column_width FNF:12 -FNH:0 +FNH:12 end_of_record SF:src\xlviews\dataframes\dist_frame.py DA:1,1 @@ -1260,110 +1260,110 @@ DA:14,1 DA:15,1 DA:17,1 DA:18,1 -DA:25,0 -DA:26,0 -DA:27,0 -DA:28,0 -DA:30,0 -DA:32,0 -DA:33,0 -DA:34,0 -DA:35,0 -DA:36,0 -DA:38,0 -DA:40,0 -DA:41,0 -DA:42,0 +DA:25,1 +DA:26,1 +DA:27,1 +DA:28,1 +DA:30,1 +DA:32,1 +DA:33,1 +DA:34,1 +DA:35,1 +DA:36,1 +DA:38,1 +DA:40,1 +DA:41,1 +DA:42,1 DA:44,1 -DA:50,0 -DA:51,0 -DA:52,0 -DA:54,0 -DA:55,0 -DA:56,0 -DA:58,0 -DA:59,0 -DA:60,0 -DA:61,0 -DA:63,0 -DA:64,0 -DA:66,0 -DA:67,0 -DA:69,0 -DA:70,0 -DA:72,0 -DA:73,0 -DA:75,0 -DA:76,0 -DA:78,0 -DA:79,0 -DA:80,0 -DA:81,0 +DA:50,1 +DA:51,1 +DA:52,1 +DA:54,1 +DA:55,1 +DA:56,1 +DA:58,1 +DA:59,1 +DA:60,1 +DA:61,1 +DA:63,1 +DA:64,1 +DA:66,1 +DA:67,1 +DA:69,1 +DA:70,1 +DA:72,1 +DA:73,1 +DA:75,1 +DA:76,1 +DA:78,1 +DA:79,1 +DA:80,1 +DA:81,1 DA:179,1 -DA:180,0 -DA:181,0 -DA:183,0 -DA:184,0 -DA:185,0 -DA:186,0 -DA:188,0 -DA:189,0 -DA:190,0 -DA:192,0 +DA:180,1 +DA:181,1 +DA:183,1 +DA:184,1 +DA:185,1 +DA:186,1 +DA:188,1 +DA:189,1 +DA:190,1 +DA:192,1 DA:195,1 -DA:196,0 -DA:197,0 -DA:198,0 +DA:196,1 +DA:197,1 +DA:198,1 DA:201,1 -DA:202,0 -DA:203,0 -DA:205,0 -DA:206,0 -DA:207,0 -DA:209,0 +DA:202,1 +DA:203,1 +DA:205,1 +DA:206,1 +DA:207,1 +DA:209,1 DA:212,1 -DA:213,0 -DA:214,0 -DA:215,0 +DA:213,1 +DA:214,1 +DA:215,1 DA:218,1 -DA:219,0 -DA:220,0 -DA:221,0 -DA:222,0 +DA:219,1 +DA:220,1 +DA:221,1 +DA:222,1 DA:225,1 -DA:226,0 -DA:227,0 -DA:229,0 -DA:230,0 -DA:232,0 -DA:233,0 -DA:235,0 -DA:236,0 +DA:226,1 +DA:227,1 +DA:229,1 +DA:230,1 +DA:232,1 +DA:233,1 +DA:235,1 +DA:236,1 DA:239,1 -DA:240,0 -DA:241,0 +DA:240,1 +DA:241,1 LF:93 -LH:19 +LH:93 FN:18,42,DistFrame.__init__ -FNDA:0,DistFrame.__init__ +FNDA:1,DistFrame.__init__ FN:44,81,DistFrame.set_values -FNDA:0,DistFrame.set_values +FNDA:1,DistFrame.set_values FN:179,192,select_index -FNDA:0,select_index +FNDA:1,select_index FN:195,198,get_init_data -FNDA:0,get_init_data +FNDA:1,get_init_data FN:201,209,get_dist_func -FNDA:0,get_dist_func +FNDA:1,get_dist_func FN:212,215,counter -FNDA:0,counter +FNDA:1,counter FN:218,222,sorted_value -FNDA:0,sorted_value +FNDA:1,sorted_value FN:225,236,sigma_value -FNDA:0,sigma_value +FNDA:1,sigma_value FN:239,241,set_formula -FNDA:0,set_formula +FNDA:1,set_formula FNF:9 -FNH:0 +FNH:9 end_of_record SF:src\xlviews\dataframes\groupby.py DA:1,1 @@ -1377,128 +1377,128 @@ DA:11,1 DA:12,1 DA:13,1 DA:21,1 -DA:22,0 -DA:24,0 -DA:25,0 -DA:27,0 +DA:22,1 +DA:24,1 +DA:25,1 +DA:27,1 DA:30,1 -DA:34,0 -DA:35,0 -DA:37,0 -DA:39,0 -DA:41,0 -DA:42,0 -DA:44,0 -DA:45,0 -DA:47,0 -DA:49,0 -DA:50,0 -DA:52,0 +DA:34,1 +DA:35,1 +DA:37,1 +DA:39,1 +DA:41,1 +DA:42,1 +DA:44,1 +DA:45,1 +DA:47,1 +DA:49,1 +DA:50,1 +DA:52,1 DA:55,1 -DA:62,0 -DA:65,0 -DA:66,0 -DA:67,0 -DA:68,0 -DA:70,0 -DA:71,0 -DA:73,0 -DA:74,0 -DA:76,0 -DA:77,0 +DA:62,1 +DA:65,1 +DA:66,1 +DA:67,1 +DA:68,1 +DA:70,1 +DA:71,1 +DA:73,1 +DA:74,1 +DA:76,1 +DA:77,1 DA:80,1 DA:81,1 DA:82,1 DA:83,1 DA:85,1 -DA:92,0 -DA:93,0 -DA:94,0 +DA:92,1 +DA:93,1 +DA:94,1 DA:96,1 -DA:97,0 +DA:97,1 DA:99,1 -DA:100,0 +DA:100,1 DA:102,1 -DA:103,0 +DA:103,1 DA:105,1 -DA:106,0 +DA:106,1 DA:108,1 -DA:109,0 +DA:109,1 DA:111,1 -DA:112,0 +DA:112,1 DA:114,1 -DA:124,0 -DA:125,0 -DA:126,0 -DA:129,0 -DA:130,0 -DA:131,0 -DA:133,0 -DA:143,0 -DA:144,0 -DA:146,0 -DA:147,0 -DA:149,0 +DA:124,1 +DA:125,1 +DA:126,1 +DA:129,1 +DA:130,1 +DA:131,1 +DA:133,1 +DA:143,1 +DA:144,1 +DA:146,1 +DA:147,1 +DA:149,1 DA:151,1 -DA:162,0 -DA:165,0 -DA:166,0 -DA:167,0 -DA:168,0 -DA:170,0 -DA:172,0 -DA:173,0 -DA:175,0 -DA:184,0 -DA:193,0 -DA:194,0 -DA:195,0 -DA:196,0 -DA:198,0 -DA:199,0 -DA:200,0 -DA:202,0 -DA:203,0 -DA:204,0 +DA:162,1 +DA:165,1 +DA:166,1 +DA:167,1 +DA:168,1 +DA:170,1 +DA:172,1 +DA:173,1 +DA:175,1 +DA:184,1 +DA:193,1 +DA:194,1 +DA:195,1 +DA:196,1 +DA:198,1 +DA:199,1 +DA:200,1 +DA:202,1 +DA:203,1 +DA:204,1 DA:206,1 -DA:207,0 -DA:208,0 -DA:209,0 -DA:210,0 -DA:211,0 -DA:213,0 -DA:214,0 -DA:215,0 +DA:207,1 +DA:208,1 +DA:209,1 +DA:210,1 +DA:211,1 +DA:213,1 +DA:214,1 +DA:215,1 LF:103 -LH:27 +LH:103 FN:21,27,to_dict -FNDA:0,to_dict +FNDA:1,to_dict FN:30,52,create_group_index -FNDA:0,create_group_index +FNDA:1,create_group_index FN:55,77,groupby -FNDA:0,groupby +FNDA:1,groupby FN:85,94,GroupBy.__init__ -FNDA:0,GroupBy.__init__ +FNDA:1,GroupBy.__init__ FN:96,97,GroupBy.__len__ -FNDA:0,GroupBy.__len__ +FNDA:1,GroupBy.__len__ FN:99,100,GroupBy.keys -FNDA:0,GroupBy.keys +FNDA:1,GroupBy.keys FN:102,103,GroupBy.values -FNDA:0,GroupBy.values +FNDA:1,GroupBy.values FN:105,106,GroupBy.items -FNDA:0,GroupBy.items +FNDA:1,GroupBy.items FN:108,109,GroupBy.__iter__ -FNDA:0,GroupBy.__iter__ +FNDA:1,GroupBy.__iter__ FN:111,112,GroupBy.__getitem__ -FNDA:0,GroupBy.__getitem__ +FNDA:1,GroupBy.__getitem__ FN:114,149,GroupBy.index -FNDA:0,GroupBy.index +FNDA:1,GroupBy.index FN:151,204,GroupBy.agg -FNDA:0,GroupBy.agg +FNDA:1,GroupBy.agg FN:206,215,GroupBy._agg -FNDA:0,GroupBy._agg +FNDA:1,GroupBy._agg FNF:13 -FNH:0 +FNH:13 end_of_record SF:src\xlviews\dataframes\heat_frame.py DA:1,1 @@ -1518,114 +1518,114 @@ DA:27,1 DA:28,1 DA:30,1 DA:31,1 -DA:40,0 -DA:42,0 -DA:44,0 -DA:46,0 -DA:47,0 -DA:48,0 -DA:50,0 -DA:51,0 +DA:40,1 +DA:42,1 +DA:44,1 +DA:46,1 +DA:47,1 +DA:48,1 +DA:50,1 +DA:51,1 DA:53,1 -DA:58,0 -DA:60,0 -DA:61,0 -DA:62,0 -DA:63,0 -DA:65,0 -DA:66,0 +DA:58,1 +DA:60,1 +DA:61,1 +DA:62,1 +DA:63,1 +DA:65,1 +DA:66,1 DA:68,1 -DA:76,0 -DA:77,0 +DA:76,1 +DA:77,1 DA:79,1 -DA:80,0 -DA:81,0 +DA:80,1 +DA:81,1 DA:83,1 -DA:90,0 -DA:91,0 -DA:92,0 -DA:94,0 -DA:95,0 -DA:96,0 -DA:97,0 -DA:99,0 -DA:100,0 -DA:101,0 +DA:90,1 +DA:91,1 +DA:92,1 +DA:94,1 +DA:95,1 +DA:96,1 +DA:97,1 +DA:99,1 +DA:100,1 +DA:101,1 DA:103,1 DA:104,1 -DA:113,0 -DA:114,0 -DA:115,0 -DA:116,0 +DA:113,1 +DA:114,1 +DA:115,1 +DA:116,1 DA:118,1 DA:119,1 -DA:131,0 -DA:132,0 -DA:133,0 -DA:134,0 -DA:136,0 -DA:137,0 -DA:139,0 -DA:140,0 -DA:142,0 -DA:143,0 -DA:145,0 -DA:146,0 -DA:147,0 -DA:148,0 -DA:150,0 -DA:152,0 -DA:153,0 +DA:131,1 +DA:132,1 +DA:133,1 +DA:134,1 +DA:136,1 +DA:137,1 +DA:139,1 +DA:140,1 +DA:142,1 +DA:143,1 +DA:145,1 +DA:146,1 +DA:147,1 +DA:148,1 +DA:150,1 +DA:152,1 +DA:153,1 DA:156,1 -DA:157,0 -DA:159,0 -DA:160,0 -DA:162,0 -DA:163,0 -DA:165,0 -DA:167,0 +DA:157,1 +DA:159,1 +DA:160,1 +DA:162,1 +DA:163,1 +DA:165,1 +DA:167,1 DA:170,1 -DA:176,0 -DA:177,0 -DA:178,0 -DA:180,0 -DA:181,0 -DA:183,0 -DA:184,0 -DA:185,0 -DA:187,0 -DA:188,0 -DA:191,0 +DA:176,1 +DA:177,1 +DA:178,1 +DA:180,1 +DA:181,1 +DA:183,1 +DA:184,1 +DA:185,1 +DA:187,1 +DA:188,1 +DA:191,1 DA:194,1 -DA:199,0 -DA:200,0 -DA:202,0 -DA:203,0 -DA:205,0 +DA:199,1 +DA:200,1 +DA:202,1 +DA:203,1 +DA:205,1 LF:101 -LH:28 +LH:101 FN:31,51,HeatFrame.__init__ -FNDA:0,HeatFrame.__init__ +FNDA:1,HeatFrame.__init__ FN:53,66,HeatFrame.set -FNDA:0,HeatFrame.set +FNDA:1,HeatFrame.set FN:68,77,HeatFrame.style -FNDA:0,HeatFrame.style +FNDA:1,HeatFrame.style FN:79,81,HeatFrame.number_format -FNDA:0,HeatFrame.number_format +FNDA:1,HeatFrame.number_format FN:83,101,HeatFrame.colorbar -FNDA:0,HeatFrame.colorbar +FNDA:1,HeatFrame.colorbar FN:104,116,HeatFrame.facet -FNDA:0,HeatFrame.facet +FNDA:1,HeatFrame.facet FN:119,153,HeatFrame.pair -FNDA:0,HeatFrame.pair +FNDA:1,HeatFrame.pair FN:156,167,clean_data -FNDA:0,clean_data +FNDA:1,clean_data FN:170,191,iterrows -FNDA:0,iterrows +FNDA:1,iterrows FN:194,205,xs -FNDA:0,xs +FNDA:1,xs FNF:10 -FNH:0 +FNH:10 end_of_record SF:src\xlviews\dataframes\sheet_frame.py DA:3,1 @@ -1657,421 +1657,421 @@ DA:41,1 DA:42,1 DA:44,1 DA:45,1 -DA:60,0 -DA:61,0 -DA:63,0 -DA:64,0 -DA:66,0 -DA:68,0 -DA:69,0 +DA:60,1 +DA:61,1 +DA:63,1 +DA:64,1 +DA:66,1 +DA:68,1 +DA:69,1 DA:71,1 -DA:72,0 -DA:73,0 -DA:74,0 +DA:72,1 +DA:73,1 +DA:74,1 DA:76,1 -DA:77,0 -DA:78,0 -DA:79,0 +DA:77,1 +DA:78,1 +DA:79,1 DA:81,1 -DA:82,0 +DA:82,1 DA:84,1 -DA:85,0 -DA:86,0 -DA:88,0 +DA:85,1 +DA:86,1 +DA:88,1 DA:90,1 -DA:91,0 +DA:91,1 DA:93,1 DA:94,1 -DA:96,0 +DA:96,1 DA:98,1 DA:99,1 -DA:101,0 +DA:101,1 DA:103,1 DA:104,1 -DA:105,0 +DA:105,1 DA:107,1 DA:108,1 -DA:109,0 +DA:109,1 DA:111,1 DA:112,1 -DA:113,0 +DA:113,1 DA:115,1 DA:116,1 -DA:117,0 -DA:118,0 -DA:119,0 -DA:120,0 -DA:122,0 -DA:125,0 +DA:117,1 +DA:118,1 +DA:119,1 +DA:120,1 +DA:122,1 +DA:125,1 DA:127,1 -DA:128,0 -DA:129,0 -DA:131,0 +DA:128,1 +DA:129,1 +DA:131,1 DA:133,1 -DA:138,0 -DA:139,0 -DA:145,0 -DA:146,0 -DA:147,0 -DA:148,0 -DA:149,0 -DA:150,0 -DA:152,0 -DA:153,0 +DA:138,1 +DA:139,1 +DA:145,1 +DA:146,1 +DA:147,1 +DA:148,1 +DA:149,1 +DA:150,1 +DA:152,1 +DA:153,1 DA:155,1 DA:156,1 DA:162,1 DA:163,1 DA:169,1 -DA:174,0 -DA:177,0 -DA:178,0 -DA:179,0 -DA:180,0 -DA:181,0 -DA:182,0 -DA:183,0 -DA:184,0 -DA:186,0 -DA:187,0 -DA:188,0 -DA:189,0 -DA:190,0 -DA:192,0 -DA:193,0 +DA:174,1 +DA:177,1 +DA:178,1 +DA:179,1 +DA:180,1 +DA:181,1 +DA:182,1 +DA:183,1 +DA:184,1 +DA:186,1 +DA:187,1 +DA:188,1 +DA:189,1 +DA:190,1 +DA:192,1 +DA:193,1 DA:195,1 -DA:196,0 -DA:197,0 -DA:198,0 -DA:199,0 -DA:201,0 -DA:202,0 -DA:205,0 -DA:206,0 -DA:207,0 -DA:209,0 -DA:210,0 +DA:196,1 +DA:197,1 +DA:198,1 +DA:199,1 +DA:201,1 +DA:202,1 +DA:205,1 +DA:206,1 +DA:207,1 +DA:209,1 +DA:210,1 DA:212,1 -DA:221,0 -DA:224,0 -DA:225,0 -DA:226,0 -DA:228,0 -DA:229,0 -DA:231,0 -DA:232,0 -DA:233,0 -DA:234,0 -DA:236,0 -DA:237,0 -DA:238,0 -DA:240,0 -DA:241,0 +DA:221,1 +DA:224,1 +DA:225,1 +DA:226,1 +DA:228,1 +DA:229,1 +DA:231,1 +DA:232,1 +DA:233,1 +DA:234,1 +DA:236,1 +DA:237,1 +DA:238,1 +DA:240,1 +DA:241,1 DA:243,1 -DA:261,0 -DA:264,0 -DA:265,0 -DA:266,0 -DA:267,0 -DA:268,0 -DA:270,0 -DA:271,0 -DA:272,0 -DA:273,0 -DA:275,0 -DA:276,0 -DA:278,0 -DA:279,0 +DA:261,1 +DA:264,1 +DA:265,1 +DA:266,1 +DA:267,1 +DA:268,1 +DA:270,1 +DA:271,1 +DA:272,1 +DA:273,1 +DA:275,1 +DA:276,1 +DA:278,1 +DA:279,1 DA:281,1 -DA:298,0 -DA:301,0 -DA:302,0 -DA:303,0 -DA:304,0 -DA:306,0 -DA:307,0 -DA:308,0 -DA:311,0 -DA:312,0 -DA:314,0 -DA:316,0 -DA:317,0 -DA:319,0 -DA:320,0 -DA:322,0 -DA:323,0 -DA:325,0 -DA:326,0 -DA:328,0 -DA:329,0 +DA:298,1 +DA:301,1 +DA:302,1 +DA:303,1 +DA:304,1 +DA:306,1 +DA:307,1 +DA:308,1 +DA:311,1 +DA:312,1 +DA:314,1 +DA:316,1 +DA:317,1 +DA:319,1 +DA:320,1 +DA:322,1 +DA:323,1 +DA:325,1 +DA:326,1 +DA:328,1 +DA:329,1 DA:331,1 DA:332,1 DA:342,1 DA:343,1 DA:353,1 -DA:362,0 -DA:363,0 -DA:364,0 -DA:366,0 -DA:368,0 -DA:370,0 -DA:371,0 -DA:373,0 -DA:383,0 -DA:384,0 -DA:386,0 +DA:362,1 +DA:363,1 +DA:364,1 +DA:366,1 +DA:368,1 +DA:370,1 +DA:371,1 +DA:373,1 +DA:383,1 +DA:384,1 +DA:386,1 DA:388,1 DA:389,1 DA:400,1 DA:401,1 DA:412,1 -DA:422,0 -DA:423,0 -DA:424,0 -DA:435,0 -DA:436,0 -DA:437,0 -DA:438,0 -DA:440,0 -DA:441,0 -DA:442,0 -DA:443,0 -DA:444,0 -DA:445,0 -DA:446,0 -DA:448,0 -DA:450,0 -DA:451,0 -DA:453,0 -DA:462,0 -DA:463,0 -DA:464,0 -DA:466,0 -DA:467,0 -DA:468,0 -DA:470,0 -DA:471,0 +DA:422,1 +DA:423,1 +DA:424,1 +DA:435,1 +DA:436,1 +DA:437,1 +DA:438,1 +DA:440,1 +DA:441,1 +DA:442,1 +DA:443,1 +DA:444,1 +DA:445,1 +DA:446,1 +DA:448,1 +DA:450,1 +DA:451,1 +DA:453,1 +DA:462,1 +DA:463,1 +DA:464,1 +DA:466,1 +DA:467,1 +DA:468,1 +DA:470,1 +DA:471,1 DA:473,1 DA:474,1 -DA:475,0 -DA:476,0 -DA:477,0 -DA:479,0 +DA:475,1 +DA:476,1 +DA:477,1 +DA:479,1 DA:481,1 -DA:492,0 -DA:502,0 -DA:503,0 -DA:504,0 -DA:506,0 -DA:507,0 -DA:508,0 -DA:509,0 -DA:510,0 -DA:512,0 +DA:492,1 +DA:502,1 +DA:503,1 +DA:504,1 +DA:506,1 +DA:507,1 +DA:508,1 +DA:509,1 +DA:510,1 +DA:512,1 DA:514,1 -DA:526,0 -DA:527,0 -DA:542,0 -DA:543,0 -DA:545,0 -DA:546,0 -DA:555,0 -DA:557,0 -DA:558,0 -DA:559,0 -DA:560,0 -DA:562,0 -DA:564,0 -DA:574,0 +DA:526,1 +DA:527,1 +DA:542,1 +DA:543,1 +DA:545,1 +DA:546,1 +DA:555,1 +DA:557,1 +DA:558,1 +DA:559,1 +DA:560,1 +DA:562,1 +DA:564,1 +DA:574,1 DA:576,1 -DA:577,0 +DA:577,1 DA:579,1 -DA:580,0 -DA:581,0 -DA:582,0 -DA:583,0 +DA:580,1 +DA:581,1 +DA:582,1 +DA:583,1 DA:585,1 -DA:592,0 -DA:593,0 -DA:595,0 -DA:596,0 -DA:598,0 -DA:599,0 -DA:600,0 -DA:601,0 -DA:603,0 -DA:604,0 -DA:605,0 -DA:606,0 -DA:607,0 -DA:608,0 -DA:609,0 -DA:611,0 -DA:612,0 -DA:613,0 -DA:614,0 -DA:615,0 -DA:616,0 -DA:621,0 +DA:592,1 +DA:593,1 +DA:595,1 +DA:596,1 +DA:598,1 +DA:599,1 +DA:600,1 +DA:601,1 +DA:603,1 +DA:604,1 +DA:605,1 +DA:606,1 +DA:607,1 +DA:608,1 +DA:609,1 +DA:611,1 +DA:612,1 +DA:613,1 +DA:614,1 +DA:615,1 +DA:616,1 +DA:621,1 DA:623,1 -DA:624,0 -DA:625,0 -DA:626,0 +DA:624,1 +DA:625,1 +DA:626,1 DA:628,1 -DA:629,0 -DA:630,0 -DA:631,0 -DA:632,0 +DA:629,1 +DA:630,1 +DA:631,1 +DA:632,1 DA:634,1 -DA:635,0 -DA:636,0 -DA:637,0 -DA:638,0 -DA:639,0 +DA:635,1 +DA:636,1 +DA:637,1 +DA:638,1 +DA:639,1 DA:641,1 -DA:643,0 -DA:644,0 +DA:643,1 +DA:644,1 DA:646,1 -DA:648,0 +DA:648,1 DA:650,1 -DA:651,0 +DA:651,1 DA:653,1 -DA:660,0 -DA:661,0 -DA:663,0 -DA:666,0 -DA:668,0 -DA:669,0 -DA:671,0 -DA:678,0 -DA:680,0 +DA:660,1 +DA:661,1 +DA:663,1 +DA:666,1 +DA:668,1 +DA:669,1 +DA:671,1 +DA:678,1 +DA:680,1 DA:682,1 -DA:683,0 -DA:684,0 -DA:685,0 -DA:687,0 +DA:683,1 +DA:684,1 +DA:685,1 +DA:687,1 DA:690,1 -DA:702,0 -DA:703,0 -DA:704,0 -DA:706,0 -DA:707,0 -DA:709,0 -DA:710,0 -DA:712,0 -DA:713,0 +DA:702,1 +DA:703,1 +DA:704,1 +DA:706,1 +DA:707,1 +DA:709,1 +DA:710,1 +DA:712,1 +DA:713,1 DA:716,1 -DA:717,0 -DA:718,0 -DA:720,0 -DA:721,0 -DA:723,0 -DA:724,0 -DA:726,0 +DA:717,1 +DA:718,1 +DA:720,1 +DA:721,1 +DA:723,1 +DA:724,1 +DA:726,1 DA:729,1 -DA:730,0 -DA:731,0 -DA:733,0 -DA:734,0 -DA:735,0 -DA:737,0 -DA:738,0 -DA:740,0 -DA:741,0 -DA:742,0 -DA:744,0 +DA:730,1 +DA:731,1 +DA:733,1 +DA:734,1 +DA:735,1 +DA:737,1 +DA:738,1 +DA:740,1 +DA:741,1 +DA:742,1 +DA:744,1 LF:352 -LH:85 +LH:352 FN:45,69,SheetFrame.__init__ -FNDA:0,SheetFrame.__init__ +FNDA:1,SheetFrame.__init__ FN:71,74,SheetFrame.expand -FNDA:0,SheetFrame.expand +FNDA:1,SheetFrame.expand FN:76,79,SheetFrame.__repr__ -FNDA:0,SheetFrame.__repr__ +FNDA:1,SheetFrame.__repr__ FN:81,82,SheetFrame.__len__ -FNDA:0,SheetFrame.__len__ +FNDA:1,SheetFrame.__len__ FN:84,88,SheetFrame.__contains__ -FNDA:0,SheetFrame.__contains__ +FNDA:1,SheetFrame.__contains__ FN:90,91,SheetFrame.__iter__ -FNDA:0,SheetFrame.__iter__ +FNDA:1,SheetFrame.__iter__ FN:94,96,SheetFrame.row -FNDA:0,SheetFrame.row +FNDA:1,SheetFrame.row FN:99,101,SheetFrame.column -FNDA:0,SheetFrame.column +FNDA:1,SheetFrame.column FN:104,105,SheetFrame.shape -FNDA:0,SheetFrame.shape +FNDA:1,SheetFrame.shape FN:108,109,SheetFrame.height -FNDA:0,SheetFrame.height +FNDA:1,SheetFrame.height FN:112,113,SheetFrame.width -FNDA:0,SheetFrame.width +FNDA:1,SheetFrame.width FN:116,125,SheetFrame.value -FNDA:0,SheetFrame.value +FNDA:1,SheetFrame.value FN:127,131,SheetFrame.get_loc -FNDA:0,SheetFrame.get_loc +FNDA:1,SheetFrame.get_loc FN:133,153,SheetFrame.get_indexer -FNDA:0,SheetFrame.get_indexer +FNDA:1,SheetFrame.get_indexer FN:156,160,SheetFrame.get_range FNDA:0,SheetFrame.get_range FN:163,167,SheetFrame.get_range FNDA:0,SheetFrame.get_range FN:169,193,SheetFrame.get_range -FNDA:0,SheetFrame.get_range +FNDA:1,SheetFrame.get_range FN:195,210,SheetFrame.iter_ranges -FNDA:0,SheetFrame.iter_ranges +FNDA:1,SheetFrame.iter_ranges FN:212,241,SheetFrame.add_column -FNDA:0,SheetFrame.add_column +FNDA:1,SheetFrame.add_column FN:243,279,SheetFrame.add_wide_column -FNDA:0,SheetFrame.add_wide_column +FNDA:1,SheetFrame.add_wide_column FN:281,329,SheetFrame.add_formula_column -FNDA:0,SheetFrame.add_formula_column +FNDA:1,SheetFrame.add_formula_column FN:332,340,SheetFrame.get_address FNDA:0,SheetFrame.get_address FN:343,351,SheetFrame.get_address FNDA:0,SheetFrame.get_address FN:353,386,SheetFrame.get_address -FNDA:0,SheetFrame.get_address +FNDA:1,SheetFrame.get_address FN:389,398,SheetFrame.agg FNDA:0,SheetFrame.agg FN:401,410,SheetFrame.agg FNDA:0,SheetFrame.agg FN:412,471,SheetFrame.agg -FNDA:0,SheetFrame.agg +FNDA:1,SheetFrame.agg FN:474,479,SheetFrame._agg -FNDA:0,SheetFrame._agg +FNDA:1,SheetFrame._agg FN:481,512,SheetFrame.melt -FNDA:0,SheetFrame.melt +FNDA:1,SheetFrame.melt FN:514,574,SheetFrame.pivot_table -FNDA:0,SheetFrame.pivot_table +FNDA:1,SheetFrame.pivot_table FN:576,577,SheetFrame.groupby -FNDA:0,SheetFrame.groupby +FNDA:1,SheetFrame.groupby FN:579,583,SheetFrame.get_number_format -FNDA:0,SheetFrame.get_number_format +FNDA:1,SheetFrame.get_number_format FN:585,621,SheetFrame.number_format -FNDA:0,SheetFrame.number_format +FNDA:1,SheetFrame.number_format FN:623,626,SheetFrame.style -FNDA:0,SheetFrame.style +FNDA:1,SheetFrame.style FN:628,632,SheetFrame.autofit -FNDA:0,SheetFrame.autofit +FNDA:1,SheetFrame.autofit FN:634,639,SheetFrame.alignment -FNDA:0,SheetFrame.alignment +FNDA:1,SheetFrame.alignment FN:641,644,SheetFrame.set_adjacent_column_width -FNDA:0,SheetFrame.set_adjacent_column_width +FNDA:1,SheetFrame.set_adjacent_column_width FN:646,648,SheetFrame.get_adjacent_cell -FNDA:0,SheetFrame.get_adjacent_cell +FNDA:1,SheetFrame.get_adjacent_cell FN:650,651,SheetFrame.move -FNDA:0,SheetFrame.move +FNDA:1,SheetFrame.move FN:653,680,SheetFrame.as_table -FNDA:0,SheetFrame.as_table +FNDA:1,SheetFrame.as_table FN:682,687,SheetFrame.unlist -FNDA:0,SheetFrame.unlist +FNDA:1,SheetFrame.unlist FN:690,713,move -FNDA:0,move +FNDA:1,move FN:716,726,_move_down -FNDA:0,_move_down +FNDA:1,_move_down FN:729,744,_move_right -FNDA:0,_move_right +FNDA:1,_move_right FNF:44 -FNH:0 +FNH:38 end_of_record SF:src\xlviews\dataframes\stats_frame.py DA:1,1 @@ -2089,103 +2089,103 @@ DA:16,1 DA:22,1 DA:23,1 DA:24,1 -DA:47,0 -DA:48,0 -DA:49,0 -DA:52,0 -DA:53,0 -DA:55,0 -DA:57,0 -DA:58,0 -DA:60,0 -DA:62,0 -DA:63,0 -DA:65,0 -DA:67,0 -DA:69,0 -DA:70,0 -DA:71,0 +DA:47,1 +DA:48,1 +DA:49,1 +DA:52,1 +DA:53,1 +DA:55,1 +DA:57,1 +DA:58,1 +DA:60,1 +DA:62,1 +DA:63,1 +DA:65,1 +DA:67,1 +DA:69,1 +DA:70,1 +DA:71,1 DA:74,1 -DA:75,0 -DA:76,0 -DA:77,0 -DA:78,0 -DA:79,0 -DA:81,0 +DA:75,1 +DA:76,1 +DA:77,1 +DA:78,1 +DA:79,1 +DA:81,1 DA:84,1 -DA:85,0 -DA:86,0 -DA:88,0 +DA:85,1 +DA:86,1 +DA:88,1 DA:91,1 -DA:92,0 -DA:93,0 -DA:95,0 +DA:92,1 +DA:93,1 +DA:95,1 DA:98,1 -DA:103,0 -DA:104,0 -DA:106,0 -DA:107,0 -DA:109,0 -DA:110,0 -DA:111,0 -DA:113,0 -DA:114,0 +DA:103,1 +DA:104,1 +DA:106,1 +DA:107,1 +DA:109,1 +DA:110,1 +DA:111,1 +DA:113,1 +DA:114,1 DA:117,1 -DA:118,0 -DA:119,0 -DA:120,0 -DA:121,0 +DA:118,1 +DA:119,1 +DA:120,1 +DA:121,1 DA:124,1 -DA:125,0 -DA:126,0 -DA:128,0 -DA:129,0 -DA:131,0 -DA:132,0 -DA:133,0 -DA:134,0 +DA:125,1 +DA:126,1 +DA:128,1 +DA:129,1 +DA:131,1 +DA:132,1 +DA:133,1 +DA:134,1 DA:137,1 -DA:139,0 -DA:140,0 -DA:141,0 +DA:139,1 +DA:140,1 +DA:141,1 DA:142,0 -DA:144,0 -DA:145,0 -DA:146,0 -DA:148,0 -DA:149,0 -DA:150,0 -DA:152,0 -DA:153,0 -DA:155,0 -DA:156,0 -DA:157,0 -DA:159,0 -DA:160,0 -DA:162,0 -DA:163,0 +DA:144,1 +DA:145,1 +DA:146,1 +DA:148,1 +DA:149,1 +DA:150,1 +DA:152,1 +DA:153,1 +DA:155,1 +DA:156,1 +DA:157,1 +DA:159,1 +DA:160,1 +DA:162,1 +DA:163,1 LF:90 -LH:22 +LH:89 FN:24,71,StatsFrame.__init__ -FNDA:0,StatsFrame.__init__ +FNDA:1,StatsFrame.__init__ FN:74,81,get_func -FNDA:0,get_func +FNDA:1,get_func FN:84,88,get_by -FNDA:0,get_by +FNDA:1,get_by FN:91,95,get_length -FNDA:0,get_length +FNDA:1,get_length FN:98,114,get_frame -FNDA:0,get_frame +FNDA:1,get_frame FN:117,121,has_header -FNDA:0,has_header +FNDA:1,has_header FN:124,134,move_down -FNDA:0,move_down +FNDA:1,move_down FN:137,163,set_style -FNDA:0,set_style +FNDA:1,set_style FN:139,142,set_style.get_number_format -FNDA:0,set_style.get_number_format +FNDA:1,set_style.get_number_format FNF:9 -FNH:0 +FNH:9 end_of_record SF:src\xlviews\dataframes\style.py DA:3,1 @@ -2197,144 +2197,144 @@ DA:11,1 DA:12,1 DA:23,1 DA:36,1 -DA:46,0 -DA:48,0 -DA:49,0 -DA:50,0 -DA:51,0 -DA:53,0 -DA:54,0 -DA:56,0 -DA:57,0 -DA:58,0 -DA:59,0 -DA:60,0 +DA:46,1 +DA:48,1 +DA:49,1 +DA:50,1 +DA:51,1 +DA:53,1 +DA:54,1 +DA:56,1 +DA:57,1 +DA:58,1 +DA:59,1 +DA:60,1 DA:63,1 DA:64,1 -DA:87,0 -DA:88,0 -DA:90,0 -DA:98,0 -DA:99,0 -DA:100,0 -DA:102,0 -DA:103,0 -DA:104,0 -DA:106,0 -DA:108,0 -DA:109,0 -DA:110,0 -DA:112,0 -DA:113,0 -DA:114,0 -DA:116,0 -DA:117,0 -DA:118,0 -DA:119,0 -DA:121,0 -DA:123,0 -DA:124,0 -DA:125,0 -DA:127,0 -DA:128,0 -DA:129,0 -DA:131,0 -DA:133,0 -DA:134,0 -DA:136,0 -DA:138,0 -DA:139,0 -DA:140,0 -DA:141,0 -DA:143,0 -DA:144,0 +DA:87,1 +DA:88,1 +DA:90,1 +DA:98,1 +DA:99,1 +DA:100,1 +DA:102,1 +DA:103,1 +DA:104,1 +DA:106,1 +DA:108,1 +DA:109,1 +DA:110,1 +DA:112,1 +DA:113,1 +DA:114,1 +DA:116,1 +DA:117,1 +DA:118,1 +DA:119,1 +DA:121,1 +DA:123,1 +DA:124,1 +DA:125,1 +DA:127,1 +DA:128,1 +DA:129,1 +DA:131,1 +DA:133,1 +DA:134,1 +DA:136,1 +DA:138,1 +DA:139,1 +DA:140,1 +DA:141,1 +DA:143,1 +DA:144,1 DA:147,1 -DA:148,0 -DA:149,0 -DA:151,0 -DA:152,0 -DA:153,0 -DA:154,0 -DA:157,0 -DA:159,0 -DA:160,0 -DA:161,0 -DA:162,0 -DA:164,0 -DA:166,0 -DA:167,0 -DA:168,0 -DA:169,0 +DA:148,1 +DA:149,1 +DA:151,1 +DA:152,1 +DA:153,1 +DA:154,1 +DA:157,1 +DA:159,1 +DA:160,1 +DA:161,1 +DA:162,1 +DA:164,1 +DA:166,1 +DA:167,1 +DA:168,1 +DA:169,1 DA:172,1 -DA:177,0 -DA:179,0 -DA:180,0 -DA:181,0 -DA:182,0 -DA:183,0 -DA:184,0 -DA:185,0 -DA:186,0 -DA:188,0 +DA:177,1 +DA:179,1 +DA:180,1 +DA:181,1 +DA:182,1 +DA:183,1 +DA:184,1 +DA:185,1 +DA:186,1 +DA:188,1 DA:191,1 DA:192,1 -DA:211,0 -DA:212,0 -DA:214,0 -DA:222,0 -DA:223,0 -DA:224,0 -DA:226,0 -DA:227,0 -DA:228,0 -DA:230,0 -DA:232,0 -DA:233,0 -DA:234,0 -DA:236,0 -DA:237,0 -DA:238,0 -DA:240,0 -DA:242,0 -DA:243,0 -DA:245,0 -DA:246,0 -DA:247,0 +DA:211,1 +DA:212,1 +DA:214,1 +DA:222,1 +DA:223,1 +DA:224,1 +DA:226,1 +DA:227,1 +DA:228,1 +DA:230,1 +DA:232,1 +DA:233,1 +DA:234,1 +DA:236,1 +DA:237,1 +DA:238,1 +DA:240,1 +DA:242,1 +DA:243,1 +DA:245,1 +DA:246,1 +DA:247,1 DA:250,1 -DA:251,0 -DA:252,0 -DA:253,0 -DA:254,0 -DA:255,0 -DA:257,0 +DA:251,1 +DA:252,1 +DA:253,1 +DA:254,1 +DA:255,1 +DA:257,1 DA:260,1 -DA:261,0 -DA:262,0 -DA:264,0 -DA:266,0 -DA:267,0 -DA:268,0 -DA:269,0 -DA:271,0 -DA:272,0 +DA:261,1 +DA:262,1 +DA:264,1 +DA:266,1 +DA:267,1 +DA:268,1 +DA:269,1 +DA:271,1 +DA:272,1 LF:129 -LH:17 +LH:129 FN:36,60,_set_style -FNDA:0,_set_style +FNDA:1,_set_style FN:64,144,set_frame_style -FNDA:0,set_frame_style +FNDA:1,set_frame_style FN:147,169,set_wide_column_style -FNDA:0,set_wide_column_style +FNDA:1,set_wide_column_style FN:172,188,set_table_style -FNDA:0,set_table_style +FNDA:1,set_table_style FN:192,247,set_heat_frame_style -FNDA:0,set_heat_frame_style +FNDA:1,set_heat_frame_style FN:250,257,_merge_index -FNDA:0,_merge_index +FNDA:1,_merge_index FN:260,272,_set_heat_border -FNDA:0,_set_heat_border +FNDA:1,_set_heat_border FNF:7 -FNH:0 +FNH:7 end_of_record SF:src\xlviews\dataframes\table.py DA:1,1 @@ -2349,88 +2349,88 @@ DA:18,1 DA:19,1 DA:20,1 DA:22,1 -DA:33,0 -DA:34,0 -DA:36,0 -DA:42,0 -DA:43,0 -DA:44,0 -DA:46,0 -DA:47,0 -DA:49,0 -DA:51,0 -DA:52,0 -DA:54,0 -DA:55,0 -DA:57,0 -DA:58,0 +DA:33,1 +DA:34,1 +DA:36,1 +DA:42,1 +DA:43,1 +DA:44,1 +DA:46,1 +DA:47,1 +DA:49,1 +DA:51,1 +DA:52,1 +DA:54,1 +DA:55,1 +DA:57,1 +DA:58,1 DA:60,1 DA:61,1 -DA:62,0 -DA:63,0 -DA:64,0 +DA:62,1 +DA:63,1 +DA:64,1 DA:66,1 DA:67,1 -DA:68,0 -DA:69,0 +DA:68,1 +DA:69,1 DA:71,1 DA:72,1 -DA:73,0 +DA:73,1 DA:75,1 DA:76,1 -DA:77,0 +DA:77,1 DA:79,1 -DA:92,0 -DA:93,0 -DA:95,0 -DA:96,0 -DA:97,0 -DA:98,0 -DA:99,0 +DA:92,1 +DA:93,1 +DA:95,1 +DA:96,1 +DA:97,1 +DA:98,1 +DA:99,1 DA:101,1 -DA:120,0 -DA:121,0 -DA:122,0 -DA:123,0 -DA:125,0 -DA:126,0 -DA:128,0 -DA:129,0 -DA:131,0 -DA:133,0 -DA:135,0 -DA:136,0 -DA:138,0 -DA:139,0 -DA:145,0 -DA:146,0 -DA:153,0 -DA:154,0 -DA:157,0 +DA:120,1 +DA:121,1 +DA:122,1 +DA:123,1 +DA:125,1 +DA:126,1 +DA:128,1 +DA:129,1 +DA:131,1 +DA:133,1 +DA:135,1 +DA:136,1 +DA:138,1 +DA:139,1 +DA:145,1 +DA:146,1 +DA:153,1 +DA:154,1 +DA:157,1 DA:159,1 -DA:161,0 -DA:162,0 -DA:163,0 +DA:161,1 +DA:162,1 +DA:163,1 LF:74 -LH:23 +LH:74 FN:22,58,Table.__init__ -FNDA:0,Table.__init__ +FNDA:1,Table.__init__ FN:61,64,Table.column -FNDA:0,Table.column +FNDA:1,Table.column FN:67,69,Table.header -FNDA:0,Table.header +FNDA:1,Table.header FN:72,73,Table.const_header -FNDA:0,Table.const_header +FNDA:1,Table.const_header FN:76,77,Table.columns -FNDA:0,Table.columns +FNDA:1,Table.columns FN:79,99,Table.add_const_header -FNDA:0,Table.add_const_header +FNDA:1,Table.add_const_header FN:101,157,Table.auto_filter -FNDA:0,Table.auto_filter +FNDA:1,Table.auto_filter FN:159,163,Table.unlist -FNDA:0,Table.unlist +FNDA:1,Table.unlist FNF:8 -FNH:0 +FNH:8 end_of_record SF:src\xlviews\figure\__init__.py end_of_record @@ -2440,48 +2440,48 @@ DA:3,1 DA:11,1 DA:12,1 DA:14,1 -DA:21,0 -DA:22,0 -DA:23,0 -DA:25,0 -DA:26,0 +DA:21,1 +DA:22,1 +DA:23,1 +DA:25,1 +DA:26,1 DA:28,1 DA:29,1 DA:31,1 DA:32,1 DA:34,1 -DA:35,0 -DA:36,0 -DA:38,0 +DA:35,1 +DA:36,1 +DA:38,1 DA:40,1 -DA:41,0 +DA:41,1 DA:43,1 -DA:44,0 +DA:44,1 DA:47,1 DA:48,1 DA:50,1 -DA:56,0 -DA:57,0 -DA:58,0 -DA:60,0 -DA:61,0 -DA:62,0 -DA:63,0 -DA:65,0 -DA:66,0 -DA:67,0 -DA:68,0 -DA:69,0 -DA:70,0 -DA:72,0 -DA:73,0 -DA:74,0 -DA:75,0 +DA:56,1 +DA:57,1 +DA:58,1 +DA:60,1 +DA:61,1 +DA:62,1 +DA:63,1 +DA:65,1 +DA:66,1 +DA:67,1 +DA:68,1 +DA:69,1 +DA:70,1 +DA:72,1 +DA:73,1 +DA:74,1 +DA:75,1 DA:77,1 DA:78,1 -DA:79,0 -DA:80,0 -DA:81,0 +DA:79,1 +DA:80,1 +DA:81,1 DA:83,1 DA:84,1 DA:86,1 @@ -2493,43 +2493,43 @@ DA:93,1 DA:95,1 DA:96,1 DA:98,1 -DA:102,0 -DA:103,0 -DA:105,0 -DA:106,0 -DA:107,0 -DA:108,0 -DA:110,0 -DA:111,0 -DA:113,0 -DA:114,0 -DA:116,0 -DA:117,0 -DA:119,0 -DA:120,0 +DA:102,1 +DA:103,1 +DA:105,1 +DA:106,1 +DA:107,1 +DA:108,1 +DA:110,1 +DA:111,1 +DA:113,1 +DA:114,1 +DA:116,1 +DA:117,1 +DA:119,1 +DA:120,1 DA:122,1 -DA:123,0 +DA:123,1 DA:125,1 -DA:126,0 -DA:127,0 +DA:126,1 +DA:127,1 LF:77 -LH:30 +LH:77 FN:14,26,AxesSeries.__init__ -FNDA:0,AxesSeries.__init__ +FNDA:1,AxesSeries.__init__ FN:29,29,AxesSeries.__getitem__ FNDA:1,AxesSeries.__getitem__ FN:32,32,AxesSeries.__getitem__ FNDA:1,AxesSeries.__getitem__ FN:34,38,AxesSeries.__getitem__ -FNDA:0,AxesSeries.__getitem__ +FNDA:1,AxesSeries.__getitem__ FN:40,41,AxesSeries.__len__ -FNDA:0,AxesSeries.__len__ +FNDA:1,AxesSeries.__len__ FN:43,44,AxesSeries.__iter__ -FNDA:0,AxesSeries.__iter__ +FNDA:1,AxesSeries.__iter__ FN:50,75,Grid.__init__ -FNDA:0,Grid.__init__ +FNDA:1,Grid.__init__ FN:78,81,Grid.shape -FNDA:0,Grid.shape +FNDA:1,Grid.shape FN:84,84,Grid.__getitem__ FNDA:1,Grid.__getitem__ FN:87,87,Grid.__getitem__ @@ -2541,13 +2541,13 @@ FNDA:1,Grid.__getitem__ FN:96,96,Grid.__getitem__ FNDA:1,Grid.__getitem__ FN:98,120,Grid.__getitem__ -FNDA:0,Grid.__getitem__ +FNDA:1,Grid.__getitem__ FN:122,123,Grid.__len__ -FNDA:0,Grid.__len__ +FNDA:1,Grid.__len__ FN:125,127,Grid.__iter__ -FNDA:0,Grid.__iter__ +FNDA:1,Grid.__iter__ FNF:16 -FNH:7 +FNH:16 end_of_record SF:src\xlviews\figure\palette.py DA:1,1 @@ -2564,122 +2564,122 @@ DA:27,1 DA:34,1 DA:35,1 DA:42,1 -DA:47,0 -DA:48,0 -DA:50,0 -DA:51,0 -DA:53,0 -DA:54,0 -DA:56,0 -DA:57,0 -DA:58,0 -DA:60,0 +DA:47,1 +DA:48,1 +DA:50,1 +DA:51,1 +DA:53,1 +DA:54,1 +DA:56,1 +DA:57,1 +DA:58,1 +DA:60,1 DA:63,1 -DA:67,0 -DA:68,0 -DA:70,0 -DA:71,0 -DA:73,0 -DA:74,0 -DA:76,0 -DA:77,0 -DA:78,0 -DA:79,0 -DA:80,0 -DA:82,0 -DA:84,0 -DA:85,0 -DA:86,0 -DA:88,0 -DA:89,0 -DA:90,0 -DA:91,0 -DA:93,0 +DA:67,1 +DA:68,1 +DA:70,1 +DA:71,1 +DA:73,1 +DA:74,1 +DA:76,1 +DA:77,1 +DA:78,1 +DA:79,1 +DA:80,1 +DA:82,1 +DA:84,1 +DA:85,1 +DA:86,1 +DA:88,1 +DA:89,1 +DA:90,1 +DA:91,1 +DA:93,1 DA:96,1 DA:99,1 DA:100,1 DA:101,1 DA:103,1 -DA:109,0 -DA:110,0 -DA:111,0 -DA:113,0 -DA:114,0 +DA:109,1 +DA:110,1 +DA:111,1 +DA:113,1 +DA:114,1 DA:116,1 DA:117,1 DA:120,1 -DA:121,0 -DA:122,0 -DA:124,0 +DA:121,1 +DA:122,1 +DA:124,1 DA:126,1 -DA:127,0 -DA:128,0 -DA:130,0 -DA:132,0 +DA:127,1 +DA:128,1 +DA:130,1 +DA:132,1 DA:135,1 DA:136,1 -DA:138,0 +DA:138,1 DA:141,1 -DA:143,0 -DA:144,0 -DA:146,0 -DA:147,0 -DA:148,0 -DA:149,0 +DA:143,1 +DA:144,1 +DA:146,1 +DA:147,1 +DA:148,1 +DA:149,1 DA:152,1 DA:153,1 -DA:155,0 +DA:155,1 DA:158,1 -DA:160,0 -DA:161,0 -DA:163,0 -DA:164,0 -DA:165,0 +DA:160,1 +DA:161,1 +DA:163,1 +DA:164,1 +DA:165,1 DA:168,1 DA:169,1 DA:170,1 DA:172,1 -DA:177,0 -DA:178,0 +DA:177,1 +DA:178,1 DA:180,1 -DA:181,0 -DA:182,0 -DA:184,0 -DA:185,0 +DA:181,1 +DA:182,1 +DA:184,1 +DA:185,1 DA:188,1 DA:200,1 -DA:206,0 -DA:207,0 -DA:209,0 -DA:210,0 -DA:212,0 -DA:213,0 -DA:214,0 -DA:215,0 -DA:217,0 -DA:218,0 -DA:220,0 -DA:221,0 -DA:223,0 -DA:224,0 -DA:225,0 -DA:226,0 -DA:228,0 -DA:230,0 -DA:232,0 -DA:233,0 -DA:235,0 -DA:236,0 -DA:237,0 -DA:238,0 -DA:239,0 -DA:241,0 +DA:206,1 +DA:207,1 +DA:209,1 +DA:210,1 +DA:212,1 +DA:213,1 +DA:214,1 +DA:215,1 +DA:217,1 +DA:218,1 +DA:220,1 +DA:221,1 +DA:223,1 +DA:224,1 +DA:225,1 +DA:226,1 +DA:228,1 +DA:230,1 +DA:232,1 +DA:233,1 +DA:235,1 +DA:236,1 +DA:237,1 +DA:238,1 +DA:239,1 +DA:241,1 DA:244,1 -DA:248,0 +DA:248,1 DA:251,1 -DA:255,0 +DA:255,1 LF:128 -LH:39 +LH:128 FN:19,23,get_columns_default FNDA:0,get_columns_default FN:27,31,get_columns_default @@ -2687,37 +2687,37 @@ FNDA:0,get_columns_default FN:35,39,get_columns_default FNDA:0,get_columns_default FN:42,60,get_columns_default -FNDA:0,get_columns_default +FNDA:1,get_columns_default FN:63,93,get_index -FNDA:0,get_index +FNDA:1,get_index FN:103,114,Palette.__init__ -FNDA:0,Palette.__init__ +FNDA:1,Palette.__init__ FN:117,118,Palette.cycle FNDA:0,Palette.cycle FN:120,124,Palette.get -FNDA:0,Palette.get +FNDA:1,Palette.get FN:126,132,Palette.__getitem__ -FNDA:0,Palette.__getitem__ +FNDA:1,Palette.__getitem__ FN:136,138,MarkerPalette.cycle -FNDA:0,MarkerPalette.cycle +FNDA:1,MarkerPalette.cycle FN:141,149,cycle_markers -FNDA:0,cycle_markers +FNDA:1,cycle_markers FN:153,155,ColorPalette.cycle -FNDA:0,ColorPalette.cycle +FNDA:1,ColorPalette.cycle FN:158,165,cycle_colors -FNDA:0,cycle_colors +FNDA:1,cycle_colors FN:172,178,FunctionPalette.__init__ -FNDA:0,FunctionPalette.__init__ +FNDA:1,FunctionPalette.__init__ FN:180,185,FunctionPalette.__getitem__ -FNDA:0,FunctionPalette.__getitem__ +FNDA:1,FunctionPalette.__getitem__ FN:200,241,get_palette -FNDA:0,get_palette +FNDA:1,get_palette FN:244,248,get_marker_palette -FNDA:0,get_marker_palette +FNDA:1,get_marker_palette FN:251,255,get_color_palette -FNDA:0,get_color_palette +FNDA:1,get_color_palette FNF:18 -FNH:0 +FNH:14 end_of_record SF:src\xlviews\figure\plot.py DA:1,1 @@ -2734,86 +2734,86 @@ DA:23,1 DA:24,1 DA:25,1 DA:27,1 -DA:28,0 -DA:30,0 -DA:31,0 -DA:33,0 -DA:34,0 -DA:35,0 +DA:28,1 +DA:30,1 +DA:31,1 +DA:33,1 +DA:34,1 +DA:35,1 DA:37,1 -DA:43,0 -DA:44,0 -DA:46,0 -DA:47,0 -DA:48,0 -DA:49,0 -DA:50,0 -DA:51,0 -DA:53,0 +DA:43,1 +DA:44,1 +DA:46,1 +DA:47,1 +DA:48,1 +DA:49,1 +DA:50,1 +DA:51,1 +DA:53,1 DA:55,1 -DA:56,0 -DA:58,0 -DA:59,0 +DA:56,1 +DA:58,1 +DA:59,1 DA:61,1 -DA:70,0 -DA:71,0 -DA:73,0 -DA:74,0 -DA:83,0 +DA:70,1 +DA:71,1 +DA:73,1 +DA:74,1 +DA:83,1 DA:85,1 DA:86,1 -DA:93,0 -DA:94,0 -DA:95,0 -DA:96,0 -DA:98,0 -DA:99,0 -DA:100,0 -DA:101,0 -DA:103,0 -DA:104,0 -DA:106,0 -DA:107,0 -DA:109,0 -DA:111,0 +DA:93,1 +DA:94,1 +DA:95,1 +DA:96,1 +DA:98,1 +DA:99,1 +DA:100,1 +DA:101,1 +DA:103,1 +DA:104,1 +DA:106,1 +DA:107,1 +DA:109,1 +DA:111,1 DA:114,1 -DA:115,0 -DA:116,0 +DA:115,1 +DA:116,1 DA:119,1 -DA:123,0 -DA:124,0 -DA:125,0 -DA:127,0 -DA:128,0 -DA:130,0 -DA:131,0 -DA:132,0 -DA:134,0 -DA:135,0 +DA:123,1 +DA:124,1 +DA:125,1 +DA:127,1 +DA:128,1 +DA:130,1 +DA:131,1 +DA:132,1 +DA:134,1 +DA:135,1 DA:138,1 -DA:139,0 -DA:140,0 -DA:142,0 +DA:139,1 +DA:140,1 +DA:142,1 LF:74 -LH:22 +LH:74 FN:27,35,Plot.__init__ -FNDA:0,Plot.__init__ +FNDA:1,Plot.__init__ FN:37,53,Plot.add -FNDA:0,Plot.add +FNDA:1,Plot.add FN:55,59,Plot.keys -FNDA:0,Plot.keys +FNDA:1,Plot.keys FN:61,83,Plot.set -FNDA:0,Plot.set +FNDA:1,Plot.set FN:86,111,Plot.facet -FNDA:0,Plot.facet +FNDA:1,Plot.facet FN:114,116,get_label -FNDA:0,get_label +FNDA:1,get_label FN:119,135,iterrows -FNDA:0,iterrows +FNDA:1,iterrows FN:138,142,xs -FNDA:0,xs +FNDA:1,xs FNF:8 -FNH:0 +FNH:8 end_of_record SF:src\xlviews\style.py DA:3,1 @@ -2827,160 +2827,160 @@ DA:18,1 DA:19,1 DA:20,1 DA:26,1 -DA:32,0 -DA:33,0 -DA:35,0 -DA:36,0 -DA:37,0 -DA:38,0 -DA:39,0 +DA:32,1 +DA:33,1 +DA:35,1 +DA:36,1 +DA:37,1 +DA:38,1 +DA:39,1 DA:42,1 -DA:47,0 -DA:48,0 -DA:50,0 -DA:52,0 -DA:53,0 -DA:55,0 -DA:56,0 -DA:58,0 -DA:59,0 -DA:61,0 -DA:62,0 -DA:64,0 -DA:65,0 +DA:47,1 +DA:48,1 +DA:50,1 +DA:52,1 +DA:53,1 +DA:55,1 +DA:56,1 +DA:58,1 +DA:59,1 +DA:61,1 +DA:62,1 +DA:64,1 +DA:65,1 DA:68,1 -DA:73,0 -DA:74,0 +DA:73,1 +DA:74,1 DA:77,1 -DA:84,0 -DA:85,0 -DA:87,0 -DA:88,0 +DA:84,1 +DA:85,1 +DA:87,1 +DA:88,1 DA:91,1 -DA:95,0 -DA:96,0 +DA:95,1 +DA:96,1 DA:99,1 -DA:108,0 -DA:109,0 -DA:110,0 -DA:111,0 -DA:112,0 -DA:113,0 -DA:114,0 -DA:115,0 -DA:116,0 -DA:117,0 -DA:118,0 +DA:108,1 +DA:109,1 +DA:110,1 +DA:111,1 +DA:112,1 +DA:113,1 +DA:114,1 +DA:115,1 +DA:116,1 +DA:117,1 +DA:118,1 DA:121,1 -DA:130,0 -DA:131,0 +DA:130,1 +DA:131,1 DA:134,1 -DA:139,0 -DA:140,0 -DA:142,0 -DA:143,0 +DA:139,1 +DA:140,1 +DA:142,1 +DA:143,1 DA:146,1 -DA:147,0 +DA:147,1 DA:150,1 DA:151,1 DA:154,1 -DA:160,0 -DA:161,0 -DA:162,0 -DA:164,0 -DA:165,0 -DA:167,0 -DA:168,0 -DA:169,0 -DA:170,0 -DA:172,0 -DA:174,0 -DA:175,0 +DA:160,1 +DA:161,1 +DA:162,1 +DA:164,1 +DA:165,1 +DA:167,1 +DA:168,1 +DA:169,1 +DA:170,1 +DA:172,1 +DA:174,1 +DA:175,1 DA:178,1 DA:181,1 -DA:185,0 -DA:187,0 -DA:188,0 -DA:189,0 -DA:196,0 -DA:201,0 -DA:203,0 -DA:204,0 -DA:205,0 -DA:206,0 -DA:207,0 +DA:185,1 +DA:187,1 +DA:188,1 +DA:189,1 +DA:196,1 +DA:201,1 +DA:203,1 +DA:204,1 +DA:205,1 +DA:206,1 +DA:207,1 DA:210,1 DA:213,1 -DA:218,0 -DA:219,0 -DA:221,0 -DA:222,0 -DA:223,0 -DA:224,0 -DA:225,0 -DA:227,0 -DA:228,0 -DA:229,0 -DA:230,0 -DA:231,0 -DA:232,0 +DA:218,1 +DA:219,1 +DA:221,1 +DA:222,1 +DA:223,1 +DA:224,1 +DA:225,1 +DA:227,1 +DA:228,1 +DA:229,1 +DA:230,1 +DA:231,1 +DA:232,1 DA:235,1 -DA:236,0 -DA:237,0 +DA:236,1 +DA:237,1 DA:240,1 -DA:245,0 -DA:246,0 -DA:248,0 -DA:249,0 -DA:250,0 -DA:251,0 -DA:252,0 +DA:245,1 +DA:246,1 +DA:248,1 +DA:249,1 +DA:250,1 +DA:251,1 +DA:252,1 DA:255,1 -DA:260,0 -DA:261,0 -DA:263,0 -DA:264,0 -DA:266,0 -DA:267,0 -DA:269,0 +DA:260,1 +DA:261,1 +DA:263,1 +DA:264,1 +DA:266,1 +DA:267,1 +DA:269,1 LF:127 -LH:29 +LH:127 FN:26,39,set_border_line -FNDA:0,set_border_line +FNDA:1,set_border_line FN:42,65,set_border_edge -FNDA:0,set_border_edge +FNDA:1,set_border_edge FN:68,74,set_border_inside -FNDA:0,set_border_inside +FNDA:1,set_border_inside FN:77,88,set_border -FNDA:0,set_border +FNDA:1,set_border FN:91,96,set_fill -FNDA:0,set_fill +FNDA:1,set_fill FN:99,118,set_font_api -FNDA:0,set_font_api +FNDA:1,set_font_api FN:121,131,set_font -FNDA:0,set_font +FNDA:1,set_font FN:134,143,set_alignment -FNDA:0,set_alignment +FNDA:1,set_alignment FN:146,147,set_number_format -FNDA:0,set_number_format +FNDA:1,set_number_format FN:154,175,set_banding -FNDA:0,set_banding +FNDA:1,set_banding FN:160,170,set_banding.banding -FNDA:0,set_banding.banding +FNDA:1,set_banding.banding FN:181,207,hide_succession -FNDA:0,hide_succession +FNDA:1,hide_succession FN:213,232,hide_unique -FNDA:0,hide_unique +FNDA:1,hide_unique FN:218,219,hide_unique.address -FNDA:0,hide_unique.address +FNDA:1,hide_unique.address FN:235,237,hide_gridlines -FNDA:0,hide_gridlines +FNDA:1,hide_gridlines FN:240,252,set_color_condition -FNDA:0,set_color_condition +FNDA:1,set_color_condition FN:255,269,set_color_scale -FNDA:0,set_color_scale +FNDA:1,set_color_scale FNF:17 -FNH:0 +FNH:17 end_of_record SF:src\xlviews\utils.py DA:1,1 @@ -2990,63 +2990,63 @@ DA:6,1 DA:7,1 DA:8,1 DA:21,1 -DA:32,0 -DA:33,0 -DA:34,0 -DA:36,0 -DA:38,0 -DA:39,0 -DA:41,0 -DA:43,0 +DA:32,1 +DA:33,1 +DA:34,1 +DA:36,1 +DA:38,1 +DA:39,1 +DA:41,1 +DA:43,1 DA:46,1 -DA:62,0 -DA:63,0 -DA:65,0 -DA:67,0 -DA:68,0 -DA:69,0 -DA:70,0 -DA:71,0 -DA:73,0 +DA:62,1 +DA:63,1 +DA:65,1 +DA:67,1 +DA:68,1 +DA:69,1 +DA:70,1 +DA:71,1 +DA:73,1 DA:76,1 -DA:100,0 -DA:101,0 -DA:103,0 -DA:104,0 -DA:105,0 +DA:100,1 +DA:101,1 +DA:103,1 +DA:104,1 +DA:105,1 DA:108,1 -DA:113,0 -DA:114,0 -DA:116,0 -DA:117,0 -DA:118,0 -DA:120,0 +DA:113,1 +DA:114,1 +DA:116,1 +DA:117,1 +DA:118,1 +DA:120,1 DA:123,1 DA:126,1 DA:127,1 -DA:128,0 -DA:130,0 -DA:131,0 -DA:132,0 -DA:134,0 -DA:135,0 -DA:137,0 -DA:138,0 +DA:128,1 +DA:130,1 +DA:131,1 +DA:132,1 +DA:134,1 +DA:135,1 +DA:137,1 +DA:138,1 DA:140,1 LF:50 -LH:14 +LH:50 FN:21,43,constant -FNDA:0,constant +FNDA:1,constant FN:46,73,iter_columns -FNDA:0,iter_columns +FNDA:1,iter_columns FN:76,105,iter_group_locs -FNDA:0,iter_group_locs +FNDA:1,iter_group_locs FN:108,120,add_validate_list -FNDA:0,add_validate_list +FNDA:1,add_validate_list FN:123,140,suspend_screen_updates FNDA:1,suspend_screen_updates FN:127,138,suspend_screen_updates._func -FNDA:0,suspend_screen_updates._func +FNDA:1,suspend_screen_updates._func FNF:6 -FNH:1 +FNH:6 end_of_record From ef9a032193d14f36e8753bcba4d048a2c31a890b Mon Sep 17 00:00:00 2001 From: Daizu Date: Wed, 11 Feb 2026 08:07:56 +0900 Subject: [PATCH 40/40] fix prek --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index e9943dc..661d068 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ .venv/ /dist/ __pycache__/ -uv.lock \ No newline at end of file +uv.lock