From 2f94045a5655bf56017c34705eee224107f6bad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Boisseau-Sierra?= Date: Mon, 7 Oct 2024 13:47:15 +0200 Subject: [PATCH] chore: Fix codebase formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Étienne Boisseau-Sierra --- gsbparse/account_file.py | 34 +++++++------- gsbparse/account_section.py | 94 ++++++++++++++++++++----------------- gsbparse/transactions.py | 41 ++++++++++++---- setup.py | 4 +- 4 files changed, 100 insertions(+), 73 deletions(-) diff --git a/gsbparse/account_file.py b/gsbparse/account_file.py index a07ae68..c508a9c 100644 --- a/gsbparse/account_file.py +++ b/gsbparse/account_file.py @@ -2,9 +2,9 @@ import logging from functools import cached_property -from typing import TextIO, Union +from typing import TextIO -import defusedxml.ElementTree as ET +import defusedxml.ElementTree as Et import pandas as pd from gsbparse.account_section import ( @@ -12,7 +12,7 @@ GsbSectionBudgetary, GsbSectionCategory, GsbSectionCurrency, - GsbSectionFinancial_year, + GsbSectionFinancialYear, GsbSectionParty, GsbSectionPayment, GsbSectionReconcile, @@ -27,7 +27,7 @@ class AccountFile: """Representation of a parsed `.gsb` file.""" - def __init__(self, source: Union[str, TextIO]) -> None: + def __init__(self, source: str | TextIO) -> None: """Initialize an AccountFile object, given its source (file object or path).""" self.source = source @@ -49,42 +49,42 @@ def sections(self) -> list[dict]: sections = {} # Read the .gsb XML content - tree = ET.parse(self.source) + tree = Et.parse(self.source) root = tree.getroot() # Instantiate each GsbSection with tags of the relevant type sections["Account"] = GsbSectionAccount( - [child.attrib for child in root if child.tag == "Account"] + [child.attrib for child in root if child.tag == "Account"], ) sections["Currency"] = GsbSectionCurrency( - [child.attrib for child in root if child.tag == "Currency"] + [child.attrib for child in root if child.tag == "Currency"], ) sections["Party"] = GsbSectionParty( - [child.attrib for child in root if child.tag == "Party"] + [child.attrib for child in root if child.tag == "Party"], ) sections["Category"] = GsbSectionCategory( - [child.attrib for child in root if child.tag == "Category"] + [child.attrib for child in root if child.tag == "Category"], ) sections["Sub_category"] = GsbSectionSubCategory( - [child.attrib for child in root if child.tag == "Sub_category"] + [child.attrib for child in root if child.tag == "Sub_category"], ) sections["Budgetary"] = GsbSectionBudgetary( - [child.attrib for child in root if child.tag == "Budgetary"] + [child.attrib for child in root if child.tag == "Budgetary"], ) sections["Sub_budgetary"] = GsbSectionSubBudgetary( - [child.attrib for child in root if child.tag == "Sub_budgetary"] + [child.attrib for child in root if child.tag == "Sub_budgetary"], ) sections["Transaction"] = GsbSectionTransaction( - [child.attrib for child in root if child.tag == "Transaction"] + [child.attrib for child in root if child.tag == "Transaction"], ) - sections["Financial_year"] = GsbSectionFinancial_year( - [child.attrib for child in root if child.tag == "Financial_year"] + sections["Financial_year"] = GsbSectionFinancialYear( + [child.attrib for child in root if child.tag == "Financial_year"], ) sections["Reconcile"] = GsbSectionReconcile( - [child.attrib for child in root if child.tag == "Reconcile"] + [child.attrib for child in root if child.tag == "Reconcile"], ) sections["Payment"] = GsbSectionPayment( - [child.attrib for child in root if child.tag == "Payment"] + [child.attrib for child in root if child.tag == "Payment"], ) return sections diff --git a/gsbparse/account_section.py b/gsbparse/account_section.py index b67c243..b7955f0 100644 --- a/gsbparse/account_section.py +++ b/gsbparse/account_section.py @@ -72,36 +72,42 @@ def __init__(self, records: list[dict]): def df(self): """Represent the list of records as a pd.DataFrame.""" # Create df - df = pd.DataFrame.from_records(self.records) + dataset = pd.DataFrame.from_records(self.records) # "Improve" df by casting correct columns dtype if self._idx_col is not None: - df.set_index(self._idx_col, inplace=True) + dataset = dataset.set_index(self._idx_col) if self._int_cols: - df[self._int_cols] = df[self._int_cols].apply( - pd.to_numeric, downcast="integer", errors="coerce" + dataset[self._int_cols] = dataset[self._int_cols].apply( + pd.to_numeric, + downcast="integer", + errors="coerce", ) if self._bool_cols: # Strings must be cast as integer first so that casting to bool # doesn't always yield True. # Cf. https://stackoverflow.com/q/52089711/5433628 - df[self._bool_cols] = ( - df[self._bool_cols] + dataset[self._bool_cols] = ( + dataset[self._bool_cols] .apply(pd.to_numeric, downcast="integer") .astype("bool") ) if self._currency_cols: - df[self._currency_cols] = df[self._currency_cols].apply(pd.to_numeric) + dataset[self._currency_cols] = dataset[self._currency_cols].apply( + pd.to_numeric, + ) if self._date_cols: - df[self._date_cols] = df[self._date_cols].apply( - pd.to_datetime, format="%m/%d/%Y", errors="coerce" + dataset[self._date_cols] = dataset[self._date_cols].apply( + pd.to_datetime, + format="%m/%d/%Y", + errors="coerce", ) - return df + return dataset class GsbSectionAccount(AccountSection): @@ -142,14 +148,14 @@ def _currency_cols(self): "Minimum_authorised_balance", ] - def __init__(self, XML_tags_attributes_values): + def __init__(self, xml_tags_attributes_values): """Build self.df from the list of XML tags attributes values. Args: - XML_tags_attributes_values (list(dict)): Values of "Account" tags + xml_tags_attributes_values (list(dict)): Values of "Account" tags attributes. """ - super(GsbSectionAccount, self).__init__(XML_tags_attributes_values) + super().__init__(xml_tags_attributes_values) class GsbSectionCurrency(AccountSection): @@ -173,14 +179,14 @@ def _name_col(self): def _int_cols(self): return ["Fl"] - def __init__(self, XML_tags_attributes_values): + def __init__(self, xml_tags_attributes_values): """Build self.df from the list of XML tags attributes values. Args: - XML_tags_attributes_values (list(dict)): Values of "Currency" tags + xml_tags_attributes_values (list(dict)): Values of "Currency" tags attributes. """ - super(GsbSectionCurrency, self).__init__(XML_tags_attributes_values) + super().__init__(xml_tags_attributes_values) class GsbSectionParty(AccountSection): @@ -204,14 +210,14 @@ def _name_col(self): def _bool_cols(self): return ["IgnCase", "UseRegex"] - def __init__(self, XML_tags_attributes_values): + def __init__(self, xml_tags_attributes_values): """Build self.df from the list of XML tags attributes values. Args: - XML_tags_attributes_values (list(dict)): Values of "Party" tags + xml_tags_attributes_values (list(dict)): Values of "Party" tags attributes. """ - super(GsbSectionParty, self).__init__(XML_tags_attributes_values) + super().__init__(xml_tags_attributes_values) class GsbSectionCategory(AccountSection): @@ -235,14 +241,14 @@ def _name_col(self): def _bool_cols(self): return ["Kd"] - def __init__(self, XML_tags_attributes_values): + def __init__(self, xml_tags_attributes_values): """Build self.df from the list of XML tags attributes values. Args: - XML_tags_attributes_values (list(dict)): Values of "Category" tags + xml_tags_attributes_values (list(dict)): Values of "Category" tags attributes. """ - super(GsbSectionCategory, self).__init__(XML_tags_attributes_values) + super().__init__(xml_tags_attributes_values) class GsbSectionSubCategory(AccountSection): @@ -262,14 +268,14 @@ def _idx_col(self): def _name_col(self): return ["Na"] - def __init__(self, XML_tags_attributes_values): + def __init__(self, xml_tags_attributes_values): """Build self.df from the list of XML tags attributes values. Args: - XML_tags_attributes_values (list(dict)): Values of "SubCategory" + xml_tags_attributes_values (list(dict)): Values of "SubCategory" tags attributes. """ - super(GsbSectionSubCategory, self).__init__(XML_tags_attributes_values) + super().__init__(xml_tags_attributes_values) class GsbSectionBudgetary(AccountSection): @@ -293,14 +299,14 @@ def _name_col(self): def _bool_cols(self): return ["Kd"] - def __init__(self, XML_tags_attributes_values): + def __init__(self, xml_tags_attributes_values): """Build self.df from the list of XML tags attributes values. Args: - XML_tags_attributes_values (list(dict)): Values of "Budgetary" tags + xml_tags_attributes_values (list(dict)): Values of "Budgetary" tags attributes. """ - super(GsbSectionBudgetary, self).__init__(XML_tags_attributes_values) + super().__init__(xml_tags_attributes_values) class GsbSectionSubBudgetary(AccountSection): @@ -320,14 +326,14 @@ def _idx_col(self): def _name_col(self): return ["Na"] - def __init__(self, XML_tags_attributes_values): + def __init__(self, xml_tags_attributes_values): """Build self.df from the list of XML tags attributes values. Args: - XML_tags_attributes_values (list(dict)): Values of "SubBudgetary" + xml_tags_attributes_values (list(dict)): Values of "SubBudgetary" tags attributes. """ - super(GsbSectionSubBudgetary, self).__init__(XML_tags_attributes_values) + super().__init__(xml_tags_attributes_values) class GsbSectionTransaction(AccountSection): @@ -359,14 +365,14 @@ def _currency_cols(self): def _date_cols(self): return ["Dt", "Dv"] - def __init__(self, XML_tags_attributes_values): + def __init__(self, xml_tags_attributes_values): """Build self.df from the list of XML tags attributes values. Args: - XML_tags_attributes_values (list(dict)): Values of "Transaction" + xml_tags_attributes_values (list(dict)): Values of "Transaction" tags attributes. """ - super(GsbSectionTransaction, self).__init__(XML_tags_attributes_values) + super().__init__(xml_tags_attributes_values) class GsbSectionPayment(AccountSection): @@ -398,17 +404,17 @@ def _bool_cols(self): "Automatic_number", ] - def __init__(self, XML_tags_attributes_values): + def __init__(self, xml_tags_attributes_values): """Build self.df from the list of XML tags attributes values. Args: - XML_tags_attributes_values (list(dict)): Values of "Payment" + xml_tags_attributes_values (list(dict)): Values of "Payment" tags attributes. """ - super(GsbSectionPayment, self).__init__(XML_tags_attributes_values) + super().__init__(xml_tags_attributes_values) -class GsbSectionFinancial_year(AccountSection): +class GsbSectionFinancialYear(AccountSection): """Represent the tags of a Grisbi file. Attributes: @@ -433,14 +439,14 @@ def _bool_cols(self): def _date_cols(self): return ["Bdte", "Edte"] - def __init__(self, XML_tags_attributes_values): + def __init__(self, xml_tags_attributes_values): """Build self.df from the list of XML tags attributes values. Args: - XML_tags_attributes_values (list(dict)): Values of "Financial_year" + xml_tags_attributes_values (list(dict)): Values of "Financial_year" tags attributes. """ - super(GsbSectionFinancial_year, self).__init__(XML_tags_attributes_values) + super().__init__(xml_tags_attributes_values) class GsbSectionReconcile(AccountSection): @@ -472,11 +478,11 @@ def _currency_cols(self): def _date_cols(self): return ["Idate", "Fdate"] - def __init__(self, XML_tags_attributes_values): + def __init__(self, xml_tags_attributes_values): """Build self.df from the list of XML tags attributes values. Args: - XML_tags_attributes_values (list(dict)): Values of "Reconcile" + xml_tags_attributes_values (list(dict)): Values of "Reconcile" tags attributes. """ - super(GsbSectionReconcile, self).__init__(XML_tags_attributes_values) + super().__init__(xml_tags_attributes_values) diff --git a/gsbparse/transactions.py b/gsbparse/transactions.py index 2993b12..b55a97d 100644 --- a/gsbparse/transactions.py +++ b/gsbparse/transactions.py @@ -1,7 +1,7 @@ """Define a representation of transactions.""" from functools import cached_property -from typing import TextIO, Union +from typing import TextIO import pandas as pd @@ -20,7 +20,7 @@ class Transactions: df (pd.DataFrame): Transactions of the Grisbi file """ - def __init__(self, source: Union[str, TextIO]) -> None: + def __init__(self, source: str | TextIO) -> None: """Create the user-friendly Transactions df from an AccountFile instance.""" self.source = source @@ -51,24 +51,30 @@ def _df(self) -> pd.DataFrame: def get_transactions( self, - columns: Union[list, dict, None] = None, + columns: list | dict | None = None, ignore_mother_transactions: bool = False, ): """Return all or a subset of the transactions.""" if ignore_mother_transactions: - df = self._df[~self._df[("Transaction", "Br")]] + dataset = self._df[~self._df[("Transaction", "Br")]] else: - df = self._df + dataset = self._df if columns is None: - return df - elif type(columns) is list: - return df[columns] - elif type(columns) is dict: + return dataset + if type(columns) is list: + return dataset[columns] + if type(columns) is dict: # “Columns name mapper doesn't relate with [index] level.” # Cf. https://stackoverflow.com/a/67458211/5433628 cols_rename_mapping = {key[1]: value for key, value in columns.items()} - return df[columns.keys()].rename(columns=cols_rename_mapping) + return dataset[columns.keys()].rename(columns=cols_rename_mapping) + + raise InvalidArgumentTypeError( + arg_name="columns", + expected_arg_type=list | dict | None, + actual_arg_type=type(columns), + ) @staticmethod def index_column_names( @@ -193,3 +199,18 @@ def _format_transactions_columns(self, transactions: pd.DataFrame) -> pd.DataFra df=self.account_file.sections["Transaction"].df, prefix=self.account_file.sections["Transaction"].section, ) + + +class InvalidArgumentTypeError(ValueError): + """Raised when an invalid argument type is passed to a method.""" + + def __init__( + self, + arg_name: str, + expected_arg_type: type, + actual_arg_type: type, + ) -> None: + super().__init__( + f"'{arg_name}' arg must be a {expected_arg_type}, " + f"got {actual_arg_type} instead.", + ) diff --git a/setup.py b/setup.py index 6c8a646..b791e9b 100644 --- a/setup.py +++ b/setup.py @@ -2,10 +2,10 @@ import setuptools -with open("README.md", "r") as fh: +with open("README.md") as fh: long_description = fh.read() -with open("VERSION", "r") as version_file: +with open("VERSION") as version_file: version = version_file.read().strip() setuptools.setup(