diff --git a/.changes/unreleased/Features-20231114-101555.yaml b/.changes/unreleased/Features-20231114-101555.yaml new file mode 100644 index 00000000000..2ed80f9bee7 --- /dev/null +++ b/.changes/unreleased/Features-20231114-101555.yaml @@ -0,0 +1,6 @@ +kind: Features +body: Use daff to render diff displayed in stdout when unit test fails +time: 2023-11-14T10:15:55.689307-05:00 +custom: + Author: michelleark + Issue: "8558" diff --git a/core/dbt/clients/agate_helper.py b/core/dbt/clients/agate_helper.py index c10d723c4f8..fbe03cb12dd 100644 --- a/core/dbt/clients/agate_helper.py +++ b/core/dbt/clients/agate_helper.py @@ -3,6 +3,7 @@ import agate import datetime import isodate +import io import json import dbt.utils from typing import Iterable, List, Dict, Union, Optional, Any @@ -137,6 +138,23 @@ def table_from_data_flat(data, column_names: Iterable[str]) -> agate.Table: ) +def json_rows_from_table(table: agate.Table) -> List[Dict[str, Any]]: + "Convert a table to a list of row dict objects" + output = io.StringIO() + table.to_json(path=output) # type: ignore + + return json.loads(output.getvalue()) + + +def list_rows_from_table(table: agate.Table) -> List[Any]: + "Convert a table to a list of lists, where the first element represents the header" + rows = [[col.name for col in table.columns]] + for row in table.rows: + rows.append(list(row.values())) + + return rows + + def empty_table(): "Returns an empty Agate table. To be used in place of None" diff --git a/core/dbt/task/unit_test.py b/core/dbt/task/unit_test.py index ea82ff7c206..4a2edb48ca2 100644 --- a/core/dbt/task/unit_test.py +++ b/core/dbt/task/unit_test.py @@ -1,13 +1,16 @@ +import agate from dataclasses import dataclass from dbt.dataclass_schema import dbtClassMixin +import daff import threading -from typing import Dict, Any, Optional, AbstractSet -import io +import re +from typing import Dict, Any, Optional, AbstractSet, List from .compile import CompileRunner from .run import RunTask from dbt.adapters.factory import get_adapter +from dbt.clients.agate_helper import list_rows_from_table, json_rows_from_table from dbt.contracts.graph.nodes import UnitTestNode from dbt.contracts.graph.manifest import Manifest from dbt.contracts.results import TestStatus, RunResult @@ -25,16 +28,26 @@ ) from dbt.node_types import NodeType from dbt.parser.unit_tests import UnitTestManifestLoader +from dbt.ui import green, red + + +@dataclass +class UnitTestDiff(dbtClassMixin): + actual: List[Dict[str, Any]] + expected: List[Dict[str, Any]] + rendered: str @dataclass class UnitTestResultData(dbtClassMixin): should_error: bool adapter_response: Dict[str, Any] - diff: Optional[str] = None + diff: Optional[UnitTestDiff] = None class UnitTestRunner(CompileRunner): + _ANSI_ESCAPE = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])") + def describe_node(self): return f"{self.node.resource_type} {self.node.name}" @@ -95,15 +108,23 @@ def execute_unit_test(self, node: UnitTestNode, manifest: Manifest) -> UnitTestR result = context["load_result"]("main") adapter_response = result["response"].to_dict(omit_none=True) table = result["table"] - actual = self._get_unit_test_table(table, "actual") - expected = self._get_unit_test_table(table, "expected") - should_error = actual.rows != expected.rows - diff = None - if should_error: - actual_output = self._agate_table_to_str(actual) - expected_output = self._agate_table_to_str(expected) - - diff = f"\n\nActual:\n{actual_output}\n\nExpected:\n{expected_output}\n" + actual = self._get_unit_test_agate_table(table, "actual") + expected = self._get_unit_test_agate_table(table, "expected") + + # generate diff, if exists + should_error, diff = False, None + daff_diff = self._get_daff_diff(expected, actual) + if daff_diff.hasDifference(): + should_error = True + rendered = self._render_daff_diff(daff_diff) + rendered = f"\n\n{red('expected')} differs from {green('actual')}:\n\n{rendered}\n" + + diff = UnitTestDiff( + actual=json_rows_from_table(actual), + expected=json_rows_from_table(expected), + rendered=rendered, + ) + return UnitTestResultData( diff=diff, should_error=should_error, @@ -119,7 +140,7 @@ def execute(self, node: UnitTestNode, manifest: Manifest): failures = 0 if result.should_error: status = TestStatus.Fail - message = result.diff + message = result.diff.rendered if result.diff else None failures = 1 return RunResult( @@ -136,7 +157,7 @@ def execute(self, node: UnitTestNode, manifest: Manifest): def after_execute(self, result): self.print_result_line(result) - def _get_unit_test_table(self, result_table, actual_or_expected: str): + def _get_unit_test_agate_table(self, result_table, actual_or_expected: str) -> agate.Table: unit_test_table = result_table.where( lambda row: row["actual_or_expected"] == actual_or_expected ) @@ -144,14 +165,32 @@ def _get_unit_test_table(self, result_table, actual_or_expected: str): columns.remove("actual_or_expected") return unit_test_table.select(columns) - def _agate_table_to_str(self, table) -> str: - # Hack to get Agate table output as string - output = io.StringIO() - if self.config.args.output == "json": - table.to_json(path=output) - else: - table.print_table(output=output, max_rows=None) - return output.getvalue().strip() + def _get_daff_diff( + self, expected: agate.Table, actual: agate.Table, ordered: bool = False + ) -> daff.TableDiff: + + expected_daff_table = daff.PythonTableView(list_rows_from_table(expected)) + actual_daff_table = daff.PythonTableView(list_rows_from_table(actual)) + + alignment = daff.Coopy.compareTables(expected_daff_table, actual_daff_table).align() + result = daff.PythonTableView([]) + + flags = daff.CompareFlags() + flags.ordered = ordered + + diff = daff.TableDiff(alignment, flags) + diff.hilite(result) + return diff + + def _render_daff_diff(self, daff_diff: daff.TableDiff) -> str: + result = daff.PythonTableView([]) + daff_diff.hilite(result) + rendered = daff.TerminalDiffRender().render(result) + # strip colors if necessary + if not self.config.args.use_colors: + rendered = self._ANSI_ESCAPE.sub("", rendered) + + return rendered class UnitTestSelector(ResourceTypeSelector): diff --git a/core/setup.py b/core/setup.py index 0cdf83338d6..3d41bea74bb 100644 --- a/core/setup.py +++ b/core/setup.py @@ -81,6 +81,7 @@ "protobuf>=4.0.0", "pytz>=2015.7", "pyyaml>=6.0", + "daff>=1.3.46", "typing-extensions>=4.4", # ---- # Match snowflake-connector-python, to ensure compatibility in dbt-snowflake diff --git a/third-party-stubs/daff/__init__.pyi b/third-party-stubs/daff/__init__.pyi new file mode 100644 index 00000000000..d75053bae83 --- /dev/null +++ b/third-party-stubs/daff/__init__.pyi @@ -0,0 +1,1545 @@ +import __builtin__ # type: ignore +import builtins +import functools +from _typeshed import Incomplete + +builtins = __builtin__ +hxunicode: Incomplete +hxunichr: Incomplete + +def hxnext(x): ... + +hx_cmp_to_key = functools.cmp_to_key +hxunicode = str +hxrange = range +hxunichr = chr +unichr = chr +unicode = str +hx_cmp_to_key = functools.cmp_to_key +python_lib_Builtin = builtins +String = builtins.str +python_lib_Dict = builtins.dict +python_lib_Set = builtins.set +imap: Incomplete +ifilter: Incomplete + +class _hx_AnonObject: + __dict__: Incomplete + def __init__(self, fields) -> None: ... + def __contains__(self, item) -> bool: ... + def __getitem__(self, item): ... + def __getattr__(self, name) -> None: ... + +class Enum: + tag: Incomplete + index: Incomplete + params: Incomplete + def __init__(self, tag, index, params) -> None: ... + +class Alignment: + has_removal: Incomplete + has_addition: Incomplete + index_columns: Incomplete + order_cache: Incomplete + tb: Incomplete + ta: Incomplete + map_a2b: Incomplete + map_b2a: Incomplete + hb: int + ha: Incomplete + map_count: int + reference: Incomplete + meta: Incomplete + comp: Incomplete + order_cache_has_reference: bool + ia: int + ib: int + marked_as_identical: bool + def __init__(self) -> None: ... + def range(self, ha, hb) -> None: ... + def tables(self, ta, tb) -> None: ... + def headers(self, ia, ib) -> None: ... + def setRowlike(self, flag) -> None: ... + def link(self, a, b) -> None: ... + def addIndexColumns(self, unit) -> None: ... + def getIndexColumns(self): ... + def a2b(self, a): ... + def b2a(self, b): ... + def count(self): ... + def toString(self): ... + def toOrder(self): ... + def addToOrder(self, l, r, p: Incomplete | None = ...) -> None: ... + def getSource(self): ... + def getTarget(self): ... + def getSourceHeader(self): ... + def getTargetHeader(self): ... + def toOrder3(self): ... + def markIdentical(self) -> None: ... + def isMarkedAsIdentical(self): ... + +class CellBuilder: ... + +class CellInfo: + meta: Incomplete + rvalue: Incomplete + lvalue: Incomplete + pvalue: Incomplete + conflicted: Incomplete + updated: Incomplete + pretty_separator: Incomplete + separator: Incomplete + category_given_tr: Incomplete + category: Incomplete + pretty_value: Incomplete + value: Incomplete + raw: Incomplete + def __init__(self) -> None: ... + def toString(self): ... + +class Class: ... + +class ColumnChange: + props: Incomplete + name: Incomplete + prevName: Incomplete + def __init__(self) -> None: ... + +class Table: ... + +class CombinedTable: + meta: Incomplete + body: Incomplete + t: Incomplete + dx: int + dy: int + core: Incomplete + head: Incomplete + def __init__(self, t) -> None: ... + def all(self): ... + def getTable(self): ... + def get_width(self): ... + def get_height(self): ... + def getCell(self, x, y): ... + def setCell(self, x, y, c) -> None: ... + def toString(self): ... + def getCellView(self): ... + def isResizable(self): ... + def resize(self, w, h): ... + def clear(self) -> None: ... + def insertOrDeleteRows(self, fate, hfate): ... + def insertOrDeleteColumns(self, fate, wfate): ... + def trimBlank(self): ... + def getData(self) -> None: ... + def clone(self): ... + def create(self): ... + def getMeta(self): ... + +class CombinedTableBody: + meta: Incomplete + parent: Incomplete + dx: Incomplete + dy: Incomplete + all: Incomplete + def __init__(self, parent, dx, dy) -> None: ... + def getTable(self): ... + def get_width(self): ... + def get_height(self): ... + def getCell(self, x, y): ... + def setCell(self, x, y, c) -> None: ... + def toString(self): ... + def getCellView(self): ... + def isResizable(self): ... + def resize(self, w, h): ... + def clear(self) -> None: ... + def insertOrDeleteRows(self, fate, hfate): ... + def insertOrDeleteColumns(self, fate, wfate): ... + def trimBlank(self): ... + def getData(self) -> None: ... + def clone(self): ... + def create(self): ... + def getMeta(self): ... + +class CombinedTableHead: + parent: Incomplete + dx: Incomplete + dy: Incomplete + all: Incomplete + def __init__(self, parent, dx, dy) -> None: ... + def getTable(self): ... + def get_width(self): ... + def get_height(self): ... + def getCell(self, x, y): ... + def setCell(self, x, y, c) -> None: ... + def toString(self): ... + def getCellView(self): ... + def isResizable(self): ... + def resize(self, w, h): ... + def clear(self) -> None: ... + def insertOrDeleteRows(self, fate, hfate): ... + def insertOrDeleteColumns(self, fate, wfate): ... + def trimBlank(self): ... + def getData(self) -> None: ... + def clone(self) -> None: ... + def create(self) -> None: ... + def getMeta(self) -> None: ... + +class CompareFlags: + padding_strategy: Incomplete + ordered: bool + show_unchanged: bool + unchanged_context: int + always_show_order: bool + never_show_order: bool + show_unchanged_columns: bool + unchanged_column_context: int + always_show_header: bool + acts: Incomplete + ids: Incomplete + columns_to_ignore: Incomplete + allow_nested_cells: bool + warnings: Incomplete + diff_strategy: Incomplete + show_meta: bool + show_unchanged_meta: bool + tables: Incomplete + parent: Incomplete + count_like_a_spreadsheet: bool + ignore_whitespace: bool + ignore_case: bool + ignore_epsilon: int + terminal_format: Incomplete + use_glyphs: bool + quote_html: bool + def __init__(self) -> None: ... + def filter(self, act, allow): ... + def allowUpdate(self): ... + def allowInsert(self): ... + def allowDelete(self): ... + def allowColumn(self): ... + def getIgnoredColumns(self): ... + def addPrimaryKey(self, column) -> None: ... + def ignoreColumn(self, column) -> None: ... + def addTable(self, table) -> None: ... + def addWarning(self, warn) -> None: ... + def getWarning(self): ... + def getNameByRole(self, name, role): ... + def getCanonicalName(self, name): ... + def getIdsByRole(self, role): ... + +class CompareTable: + indexes: Incomplete + comp: Incomplete + def __init__(self, comp) -> None: ... + def run(self): ... + def align(self): ... + def getComparisonState(self): ... + def alignCore(self, align) -> None: ... + def alignCore2(self, align, a, b): ... + def alignColumns(self, align, a, b) -> None: ... + def testHasSameColumns(self): ... + def hasSameColumns2(self, a, b): ... + def testIsEqual(self): ... + def isEqual2(self, a, b): ... + def compareCore(self): ... + def storeIndexes(self) -> None: ... + def getIndexes(self): ... + def useSql(self): ... + +class ConflictInfo: + row: Incomplete + col: Incomplete + pvalue: Incomplete + lvalue: Incomplete + rvalue: Incomplete + def __init__(self, row, col, pvalue, lvalue, rvalue) -> None: ... + +class Coopy: + daff_cmd: Incomplete + status: Incomplete + mv: Incomplete + diffs_found: Incomplete + fail_if_diff: Incomplete + cache_txt: Incomplete + flags: Incomplete + fragment: Incomplete + css_output: Incomplete + strategy: Incomplete + io: Incomplete + order_preference: Incomplete + order_set: Incomplete + nested_output: Incomplete + output_format_set: Incomplete + output_format: Incomplete + extern_preference: Incomplete + csv_eol_preference: Incomplete + delim_preference: Incomplete + format_preference: Incomplete + def __init__(self, io: Incomplete | None = ...) -> None: ... + def init(self) -> None: ... + def checkFormat(self, name): ... + def setFormat(self, name) -> None: ... + def getRenderer(self): ... + def applyRenderer(self, name, renderer): ... + def renderTable(self, name, t): ... + def renderTables(self, name, t): ... + def saveTable(self, name, t, render: Incomplete | None = ...): ... + def encodeTable(self, name, t, render: Incomplete | None = ...): ... + def saveTables(self, name, os, use_color, is_diff): ... + def saveText(self, name, txt): ... + def jsonToTables(self, json): ... + def jsonToTable(self, json): ... + def useColor(self, flags, output): ... + def runDiff(self, parent, a, b, flags, output) -> None: ... + def loadTable(self, name, role): ... + def command(self, io, cmd, args): ... + def installGitDriver(self, io, formats): ... + def run(self, args, io: Incomplete | None = ...): ... + def coopyhx(self, io): ... + @staticmethod + def diffAsHtml(local, remote, flags: Incomplete | None = ...): ... + @staticmethod + def diffAsAnsi(local, remote, flags: Incomplete | None = ...): ... + @staticmethod + def diff(local, remote, flags: Incomplete | None = ...): ... + @staticmethod + def getBlankTable(td, comp): ... + @staticmethod + def align(local, remote, flags, comp): ... + @staticmethod + def patch(local, patch, flags: Incomplete | None = ...): ... + @staticmethod + def compareTables(local, remote, flags: Incomplete | None = ...): ... + @staticmethod + def compareTables3(parent, local, remote, flags: Incomplete | None = ...): ... + @staticmethod + def keepAround(): ... + @staticmethod + def cellFor(x): ... + @staticmethod + def main(): ... + @staticmethod + def show(t) -> None: ... + @staticmethod + def jsonify(t): ... + @staticmethod + def tablify(data): ... + +class CrossMatch: + item_b: Incomplete + item_a: Incomplete + spot_b: Incomplete + spot_a: Incomplete + def __init__(self) -> None: ... + +class Csv: + has_structure: Incomplete + cursor: int + row_ended: bool + delim: Incomplete + discovered_eol: Incomplete + preferred_eol: Incomplete + def __init__(self, delim: Incomplete | None = ..., eol: Incomplete | None = ...) -> None: ... + def renderTable(self, t): ... + def renderCell(self, v, d, force_quote: Incomplete | None = ...): ... + def parseTable(self, txt, tab): ... + def makeTable(self, txt): ... + def parseCellPart(self, txt): ... + def parseCell(self, txt): ... + def getDiscoveredEol(self): ... + def setPreferredEol(self, eol) -> None: ... + +class Date: + dateUTC: Incomplete + date: Incomplete + def __init__(self, year, month, day, hour, _hx_min, sec) -> None: ... + def toString(self): ... + @staticmethod + def makeLocal(date): ... + +class DiffRender: + section: Incomplete + td_close: Incomplete + td_open: Incomplete + text_to_insert: Incomplete + open: bool + pretty_arrows: bool + quote_html: bool + def __init__(self) -> None: ... + def usePrettyArrows(self, flag) -> None: ... + def quoteHtml(self, flag) -> None: ... + def insert(self, _hx_str) -> None: ... + def beginTable(self) -> None: ... + def setSection(self, _hx_str) -> None: ... + def beginRow(self, mode) -> None: ... + def insertCell(self, txt, mode) -> None: ... + def endRow(self) -> None: ... + def endTable(self) -> None: ... + def html(self): ... + def toString(self): ... + def render(self, tab): ... + def renderTables(self, tabs): ... + def sampleCss(self): ... + def completeHtml(self) -> None: ... + @staticmethod + def examineCell( + x, y, view, raw, vcol, vrow, vcorner, cell, offset: Incomplete | None = ... + ): ... + @staticmethod + def markSpaces(sl, sr): ... + @staticmethod + def renderCell(tab, view, x, y): ... + +class DiffSummary: + different: Incomplete + col_count_final: Incomplete + col_count_initial: Incomplete + row_count_final: Incomplete + row_count_initial: Incomplete + row_count_final_with_header: Incomplete + row_count_initial_with_header: Incomplete + col_reorders: Incomplete + col_renames: Incomplete + col_updates: Incomplete + col_inserts: Incomplete + col_deletes: Incomplete + row_reorders: Incomplete + row_updates: Incomplete + row_inserts: Incomplete + row_deletes: Incomplete + def __init__(self) -> None: ... + +class FlatCellBuilder: + conflict_separator: Incomplete + separator: Incomplete + view: Incomplete + flags: Incomplete + def __init__(self, flags) -> None: ... + def needSeparator(self): ... + def setSeparator(self, separator) -> None: ... + def setConflictSeparator(self, separator) -> None: ... + def setView(self, view) -> None: ... + def update(self, local, remote): ... + def conflict(self, parent, local, remote): ... + def marker(self, label): ... + def links(self, unit, row_like): ... + @staticmethod + def quoteForDiff(v, d): ... + +class Row: ... + +class HighlightPatch: + finished_columns: Incomplete + next_meta: Incomplete + prev_meta: Incomplete + process_meta: Incomplete + meta_change: Incomplete + preambleRow: Incomplete + headerRow: Incomplete + haveDroppedColumns: Incomplete + colPermutationRev: Incomplete + colPermutation: Incomplete + rowPermutationRev: Incomplete + rowPermutation: Incomplete + actions: Incomplete + lastSourceRow: Incomplete + patchInSourceRow: Incomplete + patchInDestCol: Incomplete + destInPatchCol: Incomplete + patchInSourceCol: Incomplete + sourceInPatchCol: Incomplete + indexes: Incomplete + rcOffset: Incomplete + cellInfo: Incomplete + rowInfo: Incomplete + cmods: Incomplete + mods: Incomplete + payloadTop: Incomplete + payloadCol: Incomplete + currentRow: Incomplete + modifier: Incomplete + headerMove: Incomplete + headerRename: Incomplete + headerPost: Incomplete + headerPre: Incomplete + header: Incomplete + csv: Incomplete + source: Incomplete + patch: Incomplete + flags: Incomplete + view: Incomplete + sourceView: Incomplete + meta: Incomplete + def __init__(self, source, patch, flags: Incomplete | None = ...) -> None: ... + def reset(self): ... + def processMeta(self) -> None: ... + def apply(self): ... + def needSourceColumns(self) -> None: ... + def needDestColumns(self) -> None: ... + def needSourceIndex(self) -> None: ... + def setMetaProp(self, target, column_name, prop_name, value) -> None: ... + def applyMetaRow(self, code) -> None: ... + def applyRow(self, r): ... + def getDatum(self, c): ... + def getString(self, c): ... + def getStringNull(self, c): ... + def applyMeta(self) -> None: ... + def applyHeader(self) -> None: ... + def lookUp(self, _hx_del: Incomplete | None = ...): ... + def applyActionExternal(self, code) -> None: ... + def applyAction(self, code): ... + def checkAct(self) -> None: ... + def getPreString(self, txt): ... + def getRowString(self, c): ... + def isPreamble(self): ... + def sortMods(self, a, b): ... + def processMods(self, rmods, fate, _hx_len): ... + def useMetaForColumnChanges(self): ... + def useMetaForRowChanges(self): ... + def computeOrdering(self, mods, permutation, permutationRev, dim) -> None: ... + def permuteRows(self) -> None: ... + def fillInNewColumns(self) -> None: ... + def finishRows(self) -> None: ... + def permuteColumns(self) -> None: ... + def finishColumns(self): ... + +class HighlightPatchUnit: + add: bool + rem: bool + update: bool + sourceRow: int + sourceRowOffset: int + sourcePrevRow: int + sourceNextRow: int + destRow: int + patchRow: int + code: str + def __init__(self) -> None: ... + def toString(self): ... + +class Index: + indexed_table: Incomplete + v: Incomplete + items: Incomplete + cols: Incomplete + keys: Incomplete + top_freq: int + height: int + hdr: int + ignore_whitespace: bool + ignore_case: bool + def __init__(self, flags) -> None: ... + def addColumn(self, i) -> None: ... + def indexTable(self, t, hdr) -> None: ... + def toKey(self, t, i): ... + def toKeyByContent(self, row): ... + def getTable(self): ... + +class IndexItem: + lst: Incomplete + def __init__(self) -> None: ... + def add(self, i): ... + def length(self): ... + def value(self): ... + def asList(self): ... + +class IndexPair: + flags: Incomplete + ia: Incomplete + ib: Incomplete + quality: int + hdr: int + def __init__(self, flags) -> None: ... + def addColumns(self, ca, cb) -> None: ... + def indexTables(self, a, b, hdr) -> None: ... + def queryByKey(self, ka): ... + def queryByContent(self, row): ... + def queryLocal(self, row): ... + def localKey(self, row): ... + def remoteKey(self, row): ... + def getTopFreq(self): ... + def getQuality(self): ... + +class Meta: ... + +class JsonTable: + name: Incomplete + idx2col: Incomplete + h: Incomplete + w: Incomplete + data: Incomplete + columns: Incomplete + rows: Incomplete + def __init__(self, data, name) -> None: ... + def getTable(self): ... + def get_width(self): ... + def get_height(self): ... + def getCell(self, x, y): ... + def setCell(self, x, y, c) -> None: ... + def toString(self): ... + def getCellView(self): ... + def isResizable(self): ... + def resize(self, w, h): ... + def clear(self) -> None: ... + def insertOrDeleteRows(self, fate, hfate): ... + def insertOrDeleteColumns(self, fate, wfate): ... + def trimBlank(self): ... + def getData(self) -> None: ... + def clone(self) -> None: ... + def setMeta(self, meta) -> None: ... + def getMeta(self): ... + def create(self) -> None: ... + def alterColumns(self, columns): ... + def changeRow(self, rc): ... + def applyFlags(self, flags): ... + def asTable(self) -> None: ... + def cloneMeta(self, table: Incomplete | None = ...) -> None: ... + def useForColumnChanges(self): ... + def useForRowChanges(self): ... + def getRowStream(self) -> None: ... + def isNested(self): ... + def isSql(self): ... + def getName(self): ... + +class JsonTables: + flags: Incomplete + db: Incomplete + t: Incomplete + def __init__(self, json, flags) -> None: ... + def getCell(self, x, y): ... + def setCell(self, x, y, c) -> None: ... + def getCellView(self): ... + def isResizable(self): ... + def resize(self, w, h): ... + def clear(self) -> None: ... + def insertOrDeleteRows(self, fate, hfate): ... + def insertOrDeleteColumns(self, fate, wfate): ... + def trimBlank(self): ... + def get_width(self): ... + def get_height(self): ... + def getData(self) -> None: ... + def clone(self) -> None: ... + def getMeta(self): ... + def create(self) -> None: ... + +class Lambda: + @staticmethod + def array(it): ... + @staticmethod + def has(it, elt): ... + +class Merger: + conflict_infos: Incomplete + conflicts: Incomplete + column_mix_remote: Incomplete + column_mix_local: Incomplete + row_mix_remote: Incomplete + row_mix_local: Incomplete + column_units: Incomplete + column_order: Incomplete + units: Incomplete + order: Incomplete + parent: Incomplete + local: Incomplete + remote: Incomplete + flags: Incomplete + def __init__(self, parent, local, remote, flags) -> None: ... + def shuffleDimension(self, dim_units, _hx_len, fate, cl, cr): ... + def shuffleColumns(self) -> None: ... + def shuffleRows(self) -> None: ... + def apply(self): ... + def getConflictInfos(self): ... + def addConflictInfo(self, row, col, view, pcell, lcell, rcell) -> None: ... + @staticmethod + def makeConflictedCell(view, pcell, lcell, rcell): ... + +class Mover: + @staticmethod + def moveUnits(units): ... + @staticmethod + def move(isrc, idest): ... + @staticmethod + def moveWithoutExtras(src, dest): ... + +class Ndjson: + columns: Incomplete + tab: Incomplete + view: Incomplete + header_row: int + def __init__(self, tab) -> None: ... + def renderRow(self, r): ... + def render(self): ... + def addRow(self, r, txt) -> None: ... + def addHeaderRow(self, r) -> None: ... + def parse(self, txt) -> None: ... + +class NestedCellBuilder: + view: Incomplete + def __init__(self) -> None: ... + def needSeparator(self): ... + def setSeparator(self, separator) -> None: ... + def setConflictSeparator(self, separator) -> None: ... + def setView(self, view) -> None: ... + def update(self, local, remote): ... + def conflict(self, parent, local, remote): ... + def marker(self, label): ... + def negToNull(self, x): ... + def links(self, unit, row_like): ... + +class Ordering: + order: Incomplete + ignore_parent: bool + def __init__(self) -> None: ... + def add(self, l, r, p: Incomplete | None = ...) -> None: ... + def getList(self): ... + def setList(self, lst) -> None: ... + def toString(self): ... + def ignoreParent(self) -> None: ... + +class PropertyChange: + val: Incomplete + name: Incomplete + prevName: Incomplete + def __init__(self) -> None: ... + +class Reflect: + @staticmethod + def field(o, field): ... + @staticmethod + def isFunction(f): ... + @staticmethod + def compare(a, b): ... + +class RowChange: + action: Incomplete + is_key: Incomplete + conflicted: Incomplete + conflicting_parent_val: Incomplete + conflicting_val: Incomplete + val: Incomplete + cond: Incomplete + def __init__(self) -> None: ... + def showMap(self, m): ... + def toString(self): ... + +class RowStream: ... + +class SimpleMeta: + may_be_nested: Incomplete + row_change_cache: Incomplete + row_active: Incomplete + keys: Incomplete + metadata: Incomplete + has_properties: Incomplete + name2col: Incomplete + name2row: Incomplete + t: Incomplete + def __init__( + self, t, has_properties: Incomplete | None = ..., may_be_nested: Incomplete | None = ... + ) -> None: ... + def storeRowChanges(self, changes) -> None: ... + def rowChange(self) -> None: ... + def colChange(self) -> None: ... + def col(self, key): ... + def row(self, key): ... + def alterColumns(self, columns): ... + def setCell(self, c, r, val): ... + def addMetaData(self, column, property, val) -> None: ... + def asTable(self): ... + def cloneMeta(self, table: Incomplete | None = ...): ... + def useForColumnChanges(self): ... + def useForRowChanges(self): ... + def changeRow(self, rc): ... + def applyFlags(self, flags): ... + def getRowStream(self): ... + def isNested(self): ... + def isSql(self): ... + def getName(self) -> None: ... + +class SimpleTable: + data: Incomplete + w: Incomplete + h: Incomplete + meta: Incomplete + def __init__(self, w, h) -> None: ... + def getTable(self): ... + def get_width(self): ... + def get_height(self): ... + def getCell(self, x, y): ... + def setCell(self, x, y, c) -> None: ... + def toString(self): ... + def getCellView(self): ... + def isResizable(self): ... + def resize(self, w, h): ... + def clear(self) -> None: ... + def insertOrDeleteRows(self, fate, hfate): ... + def insertOrDeleteColumns(self, fate, wfate): ... + def trimBlank(self): ... + def getData(self) -> None: ... + def clone(self): ... + def create(self): ... + def setMeta(self, meta) -> None: ... + def getMeta(self): ... + @staticmethod + def tableToString(tab): ... + @staticmethod + def tableIsSimilar(tab1, tab2): ... + +class View: ... + +class SimpleView: + def __init__(self) -> None: ... + def toString(self, d): ... + def equals(self, d1, d2): ... + def toDatum(self, x): ... + def makeHash(self): ... + def hashSet(self, h, _hx_str, d) -> None: ... + def hashExists(self, h, _hx_str): ... + def hashGet(self, h, _hx_str): ... + def isHash(self, h): ... + def isTable(self, t): ... + def getTable(self, t): ... + def wrapTable(self, t): ... + +class SparseSheet: + zero: Incomplete + row: Incomplete + w: int + h: Incomplete + def __init__(self) -> None: ... + def resize(self, w, h, zero) -> None: ... + def nonDestructiveResize(self, w, h, zero) -> None: ... + def get(self, x, y): ... + def set(self, x, y, val) -> None: ... + +class SqlColumn: + name: str + primary: bool + type_value: Incomplete + type_family: Incomplete + def __init__(self) -> None: ... + def setName(self, name) -> None: ... + def setPrimaryKey(self, primary) -> None: ... + def setType(self, value, family) -> None: ... + def getName(self): ... + def isPrimaryKey(self): ... + def toString(self): ... + +class SqlCompare: + needed: Incomplete + alt_peered: Incomplete + peered: Incomplete + diff_ct: Incomplete + at2: Incomplete + at1: Incomplete + at0: Incomplete + db: Incomplete + local: Incomplete + remote: Incomplete + alt: Incomplete + align: Incomplete + flags: Incomplete + def __init__( + self, + db, + local, + remote, + alt, + align: Incomplete | None = ..., + flags: Incomplete | None = ..., + ) -> None: ... + def equalArray(self, a1, a2): ... + def validateSchema(self): ... + def denull(self, x): ... + def link(self) -> None: ... + def linkQuery(self, query, order) -> None: ... + def where(self, txt): ... + def scanColumns(self, all_cols1, all_cols2, key_cols, present1, present2, align) -> None: ... + def apply(self): ... + +class SqlDatabase: ... +class SqlHelper: ... + +class SqlTable: + columnNames: Incomplete + quotedTableName: Incomplete + columns: Incomplete + db: Incomplete + name: Incomplete + helper: Incomplete + cache: Incomplete + h: int + id2rid: Incomplete + def __init__(self, db, name, helper: Incomplete | None = ...) -> None: ... + def getColumns(self) -> None: ... + def getPrimaryKey(self): ... + def getAllButPrimaryKey(self): ... + def getColumnNames(self): ... + def getQuotedTableName(self): ... + def getQuotedColumnName(self, name): ... + def getCell(self, x, y): ... + def setCellCache(self, x, y, c) -> None: ... + def setCell(self, x, y, c) -> None: ... + def getCellView(self): ... + def isResizable(self): ... + def resize(self, w, h): ... + def clear(self) -> None: ... + def insertOrDeleteRows(self, fate, hfate): ... + def insertOrDeleteColumns(self, fate, wfate): ... + def trimBlank(self): ... + def get_width(self): ... + def get_height(self): ... + def getData(self) -> None: ... + def clone(self) -> None: ... + def create(self) -> None: ... + def getMeta(self): ... + def alterColumns(self, columns): ... + def changeRow(self, rc): ... + def asTable(self): ... + def useForColumnChanges(self): ... + def useForRowChanges(self): ... + def cloneMeta(self, table: Incomplete | None = ...) -> None: ... + def applyFlags(self, flags): ... + def getDatabase(self): ... + def getRowStream(self): ... + def isNested(self): ... + def isSql(self): ... + def fetchRow(self): ... + def fetchColumns(self): ... + def getName(self): ... + +class SqlTableName: + name: Incomplete + prefix: Incomplete + def __init__(self, name: Incomplete | None = ..., prefix: Incomplete | None = ...) -> None: ... + def toString(self): ... + +class SqlTables: + flags: Incomplete + t: Incomplete + db: Incomplete + def __init__(self, db, flags, role) -> None: ... + def getCell(self, x, y): ... + def setCell(self, x, y, c) -> None: ... + def getCellView(self): ... + def isResizable(self): ... + def resize(self, w, h): ... + def clear(self) -> None: ... + def insertOrDeleteRows(self, fate, hfate): ... + def insertOrDeleteColumns(self, fate, wfate): ... + def trimBlank(self): ... + def get_width(self): ... + def get_height(self): ... + def getData(self) -> None: ... + def clone(self) -> None: ... + def create(self) -> None: ... + def getMeta(self): ... + +class SqliteHelper: + def __init__(self) -> None: ... + def getTableNames(self, db): ... + def countRows(self, db, name): ... + def getRowIDs(self, db, name): ... + def update(self, db, name, conds, vals): ... + def delete(self, db, name, conds): ... + def insert(self, db, name, vals): ... + def attach(self, db, tag, resource_name): ... + def columnListSql(self, x): ... + def fetchSchema(self, db, name): ... + def splitSchema(self, db, name, sql): ... + def alterColumns(self, db, name, columns): ... + +class Std: + @staticmethod + def isOfType(v, t): ... + @staticmethod + def string(s): ... + @staticmethod + def parseInt(x): ... + @staticmethod + def shortenPossibleNumber(x): ... + @staticmethod + def parseFloat(x): ... + +class Float: ... +class Int: ... +class Bool: ... +class Dynamic: ... + +class StringBuf: + b: Incomplete + def __init__(self) -> None: ... + def get_length(self): ... + +class StringTools: + @staticmethod + def htmlEscape(s, quotes: Incomplete | None = ...): ... + @staticmethod + def isSpace(s, pos): ... + @staticmethod + def ltrim(s): ... + @staticmethod + def rtrim(s): ... + @staticmethod + def trim(s): ... + @staticmethod + def lpad(s, c, l): ... + @staticmethod + def replace(s, sub, by): ... + +class sys_FileSystem: + @staticmethod + def exists(path): ... + +class haxe_IMap: ... + +class haxe_ds_StringMap: + h: Incomplete + def __init__(self) -> None: ... + def keys(self): ... + def iterator(self): ... + +class python_HaxeIterator: + checked: bool + has: bool + x: Incomplete + it: Incomplete + def __init__(self, it) -> None: ... + def __next__(self): ... + def next(self): ... + def hasNext(self): ... + +class Sys: + @staticmethod + def exit(code) -> None: ... + @staticmethod + def args(): ... + @staticmethod + def getEnv(s): ... + @staticmethod + def command(cmd, args: Incomplete | None = ...): ... + @staticmethod + def stdout(): ... + @staticmethod + def stderr(): ... + +class TableComparisonState: + child_order: Incomplete + children: Incomplete + alignment: Incomplete + b_meta: Incomplete + a_meta: Incomplete + p_meta: Incomplete + compare_flags: Incomplete + has_same_columns_known: Incomplete + has_same_columns: Incomplete + is_equal_known: Incomplete + is_equal: Incomplete + run_to_completion: Incomplete + completed: Incomplete + b: Incomplete + a: Incomplete + p: Incomplete + def __init__(self) -> None: ... + def reset(self) -> None: ... + def getMeta(self) -> None: ... + +class TableDiff: + nesting_present: Incomplete + nested: Incomplete + column_units_updated: Incomplete + col_reorders: Incomplete + col_renames: Incomplete + col_updates: Incomplete + col_inserts: Incomplete + col_deletes: Incomplete + row_reorders: Incomplete + row_updates: Incomplete + row_inserts: Incomplete + row_deletes: Incomplete + schema_diff_found: Incomplete + diff_found: Incomplete + publish: Incomplete + act: Incomplete + have_addition: Incomplete + top_line_done: Incomplete + have_schema: Incomplete + schema: Incomplete + conflict_sep: Incomplete + sep: Incomplete + v: Incomplete + allow_column: Incomplete + allow_update: Incomplete + allow_delete: Incomplete + allow_insert: Incomplete + active_column: Incomplete + active_row: Incomplete + col_moves: Incomplete + row_moves: Incomplete + show_rc_numbers: Incomplete + column_units: Incomplete + row_units: Incomplete + order: Incomplete + is_index_b: Incomplete + is_index_a: Incomplete + is_index_p: Incomplete + rb_header: Incomplete + ra_header: Incomplete + rp_header: Incomplete + p: Incomplete + b: Incomplete + a: Incomplete + has_parent: Incomplete + col_map: Incomplete + row_map: Incomplete + align: Incomplete + flags: Incomplete + builder: Incomplete + preserve_columns: bool + def __init__(self, align, flags) -> None: ... + def setCellBuilder(self, builder) -> None: ... + def getSeparator(self, t, t2, root): ... + def isReordered(self, m, ct): ... + def spreadContext(self, units, _hx_del, active) -> None: ... + def setIgnore(self, ignore, idx_ignore, tab, r_header) -> None: ... + def countActive(self, active): ... + def reset(self): ... + def setupTables(self) -> None: ... + def scanActivity(self) -> None: ... + def setupColumns(self) -> None: ... + def setupMoves(self) -> None: ... + def scanSchema(self) -> None: ... + def checkRcNumbers(self, w, h) -> None: ... + def addRcNumbers(self, output): ... + def elideColumns(self, output, admin_w) -> None: ... + def addSchema(self, output) -> None: ... + def addHeader(self, output) -> None: ... + def checkMeta(self, t, meta): ... + def getMetaTable(self, t): ... + def addMeta(self, output): ... + def refineActivity(self) -> None: ... + def normalizeString(self, v, _hx_str): ... + def isEqual(self, v, aa, bb): ... + def checkNesting(self, v, have_ll, ll, have_rr, rr, have_pp, pp, x, y): ... + def scanRow(self, unit, output, at, i, out) -> None: ... + def hilite(self, output): ... + def hiliteSingle(self, output): ... + def hiliteWithNesting(self, output): ... + def hasDifference(self): ... + def hasSchemaDifference(self): ... + def isNested(self): ... + def getComparisonState(self): ... + def getSummary(self): ... + +class TableIO: + def __init__(self) -> None: ... + def valid(self): ... + def getContent(self, name): ... + def saveContent(self, name, txt): ... + def args(self): ... + def writeStdout(self, txt) -> None: ... + def writeStderr(self, txt) -> None: ... + def command(self, cmd, args): ... + def hasAsync(self): ... + def exists(self, path): ... + def isTtyKnown(self): ... + def isTty(self): ... + def openSqliteDatabase(self, path): ... + def sendToBrowser(self, html) -> None: ... + +class TableModifier: + t: Incomplete + def __init__(self, t) -> None: ... + def removeColumn(self, at): ... + +class TableStream: + row: Incomplete + columns: Incomplete + t: Incomplete + at: int + h: Incomplete + src: Incomplete + def __init__(self, t) -> None: ... + def fetchColumns(self): ... + def fetchRow(self): ... + def fetch(self): ... + def getCell(self, x): ... + def width(self): ... + +class Tables: + alignment: Incomplete + template: Incomplete + tables: Incomplete + table_order: Incomplete + def __init__(self, template) -> None: ... + def add(self, name): ... + def getOrder(self): ... + def get(self, name): ... + def one(self): ... + def hasInsDel(self): ... + +class TerminalDiffRender: + v: Incomplete + csv: Incomplete + t: Incomplete + codes: Incomplete + align_columns: bool + wide_columns: bool + use_glyphs: bool + flags: Incomplete + delim: Incomplete + diff: Incomplete + def __init__( + self, + flags: Incomplete | None = ..., + delim: Incomplete | None = ..., + diff: Incomplete | None = ..., + ) -> None: ... + def alignColumns(self, enable) -> None: ... + def render(self, t): ... + def getText(self, x, y, color): ... + def pickSizes(self, t): ... + +class ValueType(Enum): + @staticmethod + def TClass(c): ... + @staticmethod + def TEnum(e): ... + +class Type: + @staticmethod + def getClass(o): ... + @staticmethod + def typeof(v): ... + +class Unit: + l: Incomplete + r: Incomplete + p: Incomplete + def __init__( + self, l: Incomplete | None = ..., r: Incomplete | None = ..., p: Incomplete | None = ... + ) -> None: ... + def lp(self): ... + def toString(self): ... + def fromString(self, txt): ... + def base26(self, num): ... + def toBase26String(self): ... + @staticmethod + def describe(i): ... + +class Viterbi: + path: Incomplete + src: Incomplete + cost: Incomplete + best_cost: Incomplete + path_valid: Incomplete + mode: Incomplete + index: Incomplete + T: int + K: Incomplete + def __init__(self) -> None: ... + def reset(self) -> None: ... + def setSize(self, states, sequence_length) -> None: ... + def assertMode(self, next) -> None: ... + def addTransition(self, s0, s1, c) -> None: ... + def endTransitions(self) -> None: ... + def beginTransitions(self) -> None: ... + def calculatePath(self) -> None: ... + def toString(self): ... + def length(self): ... + def get(self, i): ... + def getCost(self): ... + +class haxe_Exception(Exception): + def __init__( + self, message, previous: Incomplete | None = ..., native: Incomplete | None = ... + ) -> None: ... + def unwrap(self): ... + def get_native(self): ... + @staticmethod + def caught(value): ... + @staticmethod + def thrown(value): ... + +class haxe_NativeStackTrace: + @staticmethod + def saveStack(exception) -> None: ... + @staticmethod + def exceptionStack(): ... + +class haxe_ValueException(haxe_Exception): + value: Incomplete + def __init__( + self, value, previous: Incomplete | None = ..., native: Incomplete | None = ... + ) -> None: ... + def unwrap(self): ... + +class haxe_ds_IntMap: + h: Incomplete + def __init__(self) -> None: ... + def set(self, key, value) -> None: ... + def remove(self, key): ... + def keys(self): ... + def toString(self): ... + +class haxe_format_JsonPrinter: + replacer: Incomplete + indent: Incomplete + pretty: Incomplete + nind: int + buf: Incomplete + def __init__(self, replacer, space) -> None: ... + def write(self, k, v) -> None: ... + def classString(self, v) -> None: ... + def fieldsString(self, v, fields) -> None: ... + def quote(self, s) -> None: ... + @staticmethod + def print(o, replacer: Incomplete | None = ..., space: Incomplete | None = ...): ... + +class haxe_io_Bytes: + length: Incomplete + b: Incomplete + def __init__(self, length, b) -> None: ... + @staticmethod + def ofString(s, encoding: Incomplete | None = ...): ... + +class haxe_io_Encoding(Enum): ... + +class haxe_io_Error(Enum): + @staticmethod + def Custom(e): ... + +class haxe_io_Output: + def writeByte(self, c) -> None: ... + def writeBytes(self, s, pos, _hx_len): ... + bigEndian: Incomplete + def set_bigEndian(self, b): ... + def writeFullBytes(self, s, pos, _hx_len) -> None: ... + def writeString(self, s, encoding: Incomplete | None = ...) -> None: ... + +class haxe_iterators_ArrayIterator: + current: int + array: Incomplete + def __init__(self, array) -> None: ... + def hasNext(self): ... + def __next__(self): ... + def next(self): ... + +class haxe_iterators_ArrayKeyValueIterator: + current: int + array: Incomplete + def __init__(self, array) -> None: ... + def hasNext(self): ... + def __next__(self): ... + def next(self): ... + +class python_Boot: + @staticmethod + def toString1(o, s): ... + @staticmethod + def fields(o): ... + @staticmethod + def simpleField(o, field): ... + @staticmethod + def hasField(o, field): ... + @staticmethod + def field(o, field): ... + @staticmethod + def getInstanceFields(c): ... + @staticmethod + def getSuperClass(c): ... + @staticmethod + def getClassFields(c): ... + @staticmethod + def unhandleKeywords(name): ... + +class python__KwArgs_KwArgs_Impl_: + @staticmethod + def fromT(d): ... + +class python_Lib: + @staticmethod + def dictToAnon(v): ... + @staticmethod + def anonToDict(o): ... + @staticmethod + def anonAsDict(o): ... + +class python_internal_ArrayImpl: + @staticmethod + def concat(a1, a2): ... + @staticmethod + def copy(x): ... + @staticmethod + def iterator(x): ... + @staticmethod + def keyValueIterator(x): ... + @staticmethod + def indexOf(a, x, fromIndex: Incomplete | None = ...): ... + @staticmethod + def lastIndexOf(a, x, fromIndex: Incomplete | None = ...): ... + @staticmethod + def join(x, sep): ... + @staticmethod + def toString(x): ... + @staticmethod + def pop(x): ... + @staticmethod + def push(x, e): ... + @staticmethod + def unshift(x, e) -> None: ... + @staticmethod + def remove(x, e): ... + @staticmethod + def contains(x, e): ... + @staticmethod + def shift(x): ... + @staticmethod + def slice(x, pos, end: Incomplete | None = ...): ... + @staticmethod + def sort(x, f) -> None: ... + @staticmethod + def splice(x, pos, _hx_len): ... + @staticmethod + def map(x, f): ... + @staticmethod + def filter(x, f): ... + @staticmethod + def insert(a, pos, x) -> None: ... + @staticmethod + def reverse(a) -> None: ... + +class HxOverrides: + @staticmethod + def iterator(x): ... + @staticmethod + def eq(a, b): ... + @staticmethod + def stringOrNull(s): ... + @staticmethod + def modf(a, b): ... + @staticmethod + def mod(a, b): ... + @staticmethod + def mapKwArgs(a, v): ... + +class python_internal_MethodClosure: + obj: Incomplete + func: Incomplete + def __init__(self, obj, func) -> None: ... + def __call__(self, *args): ... + +class HxString: + @staticmethod + def split(s, d): ... + @staticmethod + def charCodeAt(s, index): ... + @staticmethod + def charAt(s, index): ... + @staticmethod + def lastIndexOf(s, _hx_str, startIndex: Incomplete | None = ...): ... + @staticmethod + def toUpperCase(s): ... + @staticmethod + def toLowerCase(s): ... + @staticmethod + def indexOf(s, _hx_str, startIndex: Incomplete | None = ...): ... + @staticmethod + def indexOfImpl(s, _hx_str, startIndex): ... + @staticmethod + def toString(s): ... + @staticmethod + def substring(s, startIndex, endIndex: Incomplete | None = ...): ... + @staticmethod + def substr(s, startIndex, _hx_len: Incomplete | None = ...): ... + +class python_io_NativeOutput(haxe_io_Output): + stream: Incomplete + def __init__(self, stream) -> None: ... + +class python_io_IOutput: ... +class python_io_IFileOutput: ... + +class python_io_NativeTextOutput(python_io_NativeOutput): + def __init__(self, stream) -> None: ... + def writeBytes(self, s, pos, _hx_len): ... + def writeByte(self, c) -> None: ... + +class python_io_FileTextOutput(python_io_NativeTextOutput): + def __init__(self, stream) -> None: ... + +class python_io_IoTools: + @staticmethod + def createFileOutputFromText(t): ... + +class sys_io_File: + @staticmethod + def getContent(path): ... + @staticmethod + def saveContent(path, content) -> None: ... + +class sys_io_FileOutput(haxe_io_Output): + impl: Incomplete + def __init__(self, impl) -> None: ... + def set_bigEndian(self, b): ... + def writeByte(self, c) -> None: ... + def writeBytes(self, s, pos, _hx_len): ... + def writeFullBytes(self, s, pos, _hx_len) -> None: ... + def writeString(self, s, encoding: Incomplete | None = ...) -> None: ... + +class PythonCellView(View): + def __init__(self) -> None: ... + def toString(self, d): ... + def equals(self, d1, d2): ... + def toDatum(self, d): ... + def makeHash(self): ... + def isHash(self, d): ... + def hashSet(self, d, k, v) -> None: ... + def hashGet(self, d, k): ... + def hashExists(self, d, k): ... + +class PythonTableView(Table): + data: Incomplete + height: Incomplete + width: int + def __init__(self, data) -> None: ... + def get_width(self): ... + def get_height(self): ... + def getCell(self, x, y): ... + def setCell(self, x, y, c) -> None: ... + def toString(self): ... + def getCellView(self): ... + def isResizable(self): ... + def resize(self, w, h): ... + def clear(self) -> None: ... + def trimBlank(self): ... + def getData(self): ... + def insertOrDeleteRows(self, fate, hfate): ... + def insertOrDeleteColumns(self, fate, wfate): ... + def isSimilar(self, alt): ... + def clone(self): ... + def create(self): ... + def getMeta(self) -> None: ... + +class SqliteDatabase(SqlDatabase): + db: Incomplete + fname: Incomplete + cursor: Incomplete + row: Incomplete + quoter: Incomplete + view: Incomplete + def __init__(self, db, fname) -> None: ... + def getQuotedColumnName(self, name): ... + def getQuotedTableName(self, name): ... + def getColumns(self, name): ... + def begin(self, query, args=..., order=...): ... + def beginRow(self, tab, row, order=...): ... + def read(self): ... + def get(self, index): ... + def end(self) -> None: ... + def rowid(self): ... + def getHelper(self): ... + def getNameForAttachment(self): ... + +def get_stdout(): ... +def stream_write(s): ... +def main() -> None: ...