Source code for varats.table.table

"""Base table module."""

import abc
import logging
import typing as tp
from functools import reduce
from pathlib import Path

import varats.paper.case_study
from varats.table.tables import TableFormat, TableConfig

if tp.TYPE_CHECKING:
    from varats.paper.case_study import CaseStudy  # pylint: disable=W0611

LOG = logging.getLogger(__name__)


[docs] class TableDataEmpty(Exception): """Throw if there was no input for the table."""
[docs] class Table: """An abstract base class for all tables generated by VaRA-TS.""" NAME = "Table" TABLES: tp.Dict[str, tp.Type['Table']] = {} format_filetypes = { TableFormat.GITHUB: "md", TableFormat.HTML: "html", TableFormat.UNSAFEHTML: "html", TableFormat.LATEX: "tex", TableFormat.LATEX_RAW: "tex", TableFormat.LATEX_BOOKTABS: "tex", TableFormat.RST: "rst", } def __init__(self, table_config: TableConfig, **kwargs: tp.Any) -> None: self.__table_config = table_config self.__saved_extra_args = kwargs @classmethod def __init_subclass__( cls, *, table_name: tp.Optional[str], **kwargs: tp.Any ) -> None: """Register concrete tables.""" super().__init_subclass__(**kwargs) if table_name: cls.NAME = table_name cls.TABLES[table_name] = cls
[docs] @staticmethod def get_table_types_help_string() -> str: """ Generates help string for visualizing all available tables. Returns: a help string that contains all available table names. """ return "The following tables are available:\n " + "\n ".join( list(Table.TABLES) )
[docs] @staticmethod def get_class_for_table_type(table_type: str) -> tp.Type['Table']: """ Get the class for table from the table registry. Args: table_type: The name of the table. Returns: The class implementing the table. """ if table_type not in Table.TABLES: raise LookupError( f"Unknown table '{table_type}'.\n" + Table.get_table_types_help_string() ) table_cls = Table.TABLES[table_type] return table_cls
@property def name(self) -> str: """ Name of the current table. Test: >>> Table(TableConfig.from_kwargs(view=False)).name 'Table' """ return self.NAME @property def table_config(self) -> TableConfig: """Table config for this table.""" return self.__table_config @property def table_kwargs(self) -> tp.Any: """ Access the kwargs passed to the initial table. Test: >>> p = Table(TableConfig.from_kwargs(view=False), foo='bar',\ baz='bazzer') >>> p.table_kwargs['foo'] 'bar' >>> p.table_kwargs['baz'] 'bazzer' """ return self.__saved_extra_args
[docs] @staticmethod def supports_stage_separation() -> bool: """True, if the table supports stage separation, i.e., the table can be drawn separating the different stages in a case study.""" return False
[docs] @abc.abstractmethod def tabulate(self, table_format: TableFormat, wrap_table: bool) -> str: """ Build the table using tabulate. Args: table_format: the format to use for the table wrap_table: whether to wrap the table in a separate document (latex only) """
[docs] def table_file_name(self, table_format: TableFormat) -> str: """ Get the file name this table; will be stored to when calling save. Automatically deduces this tables' filetype from its format. Returns: the file name the table will be stored to Test: >>> p = Table(TableConfig.from_kwargs(view=False), project='bar') >>> p.table_file_name(TableFormat.PLAIN) 'bar_Table.txt' >>> from varats.paper.case_study import CaseStudy >>> p = Table(TableConfig.from_kwargs(view=False),\ project='bar', case_study=CaseStudy('baz', 42)) >>> p.table_file_name(TableFormat.LATEX_BOOKTABS) 'baz_42_Table.tex' """ table_ident = '' if 'case_study' in self.table_kwargs: case_study = self.table_kwargs['case_study'] if isinstance(case_study, varats.paper.case_study.CaseStudy): table_ident = f"{case_study.project_name}_{case_study.version}_" else: table_ident = reduce( lambda x, y: f'{x}{y.project_name}_', case_study, '' ) elif 'project' in self.table_kwargs: table_ident = f"{self.table_kwargs['project']}_" sep_stages = '' if self.supports_stage_separation( ) and self.table_kwargs.get('sep_stages', None): sep_stages = 'S' filetype = self.format_filetypes.get(table_format, "txt") return f"{table_ident}{self.name}{sep_stages}.{filetype}"
[docs] def show(self) -> None: """Show the current table in console.""" try: table = self.tabulate(TableFormat.FANCY_GRID, False) except TableDataEmpty: LOG.warning("No data for the current project.") return print(table)
[docs] def save( self, path: Path, table_format: TableFormat, wrap_table: bool ) -> None: """ Save the current table to a file. Args: path: the path where the file is stored (excluding file name) table_format: the format to use for the table wrap_table: whether to wrap the table in a separate document (latex only) """ try: table = self.tabulate(table_format, wrap_table) except TableDataEmpty: LOG.warning("No data for this table.") return with open(path / self.table_file_name(table_format), "w") as outfile: outfile.write(table)