I'm working on making a program to read a chart of accounts and turn it into a tree of Account objects, which I will be doing stuff with later. The chart of accounts in question has several levels of sub-accounts, with the name of each account being indented three spaces more than its parent account. For example: Current Assets Cash 1000000.00 - Cash 1000010.00 - Bank Account #1 ... Other Current Assets Receivables 100800.00 - Accounts Receivable ... I've created a class to represent an account, as follows: class Account: parent = None num: int | None name: str # Name after stripping whitespace and splitting off account number raw: str # Name prior to ^ ... # Assorted irrelevant class variables acct_type: str | None detail_type: str | None _header: bool = False # Flags whether an account's a header account descendants: list = list() # Holds account's children. Should be empty if _header == False. def __init__(self, instr: str, parent=None, acct_type: str = None, detail_type: str = None): ''' Initialize an Account. - parent: Account. `None` if top-level. - instr: raw string from ACS CoA. - acct_type: QBO Account Type - detail_type: QBO Detail Type ''' self.raw = instr self.parent = parent self.acct_type = acct_type self.detail_type = detail_type stripped = instr.strip() ... # Assorted initialization code, incl. manipulating stripped # to get values for self.num and self.name ... # Assorted irrelevant methods def is_header(self) -> bool: return self._header def depth(self) -> int: return (len(self.raw) - len(self.raw.strip())) / 3 # self.raw def add_descendant(self, instr, acct_t: str = None, detail: str = None): '''Add descendant to account. If `acct_type` and `detail_type` are supplied, will override parent account type. ''' if len(self.descendants) > 0: if calc_depth(instr) > self.descendants[-1].depth(): self.descendants[-1].add_descendant(instr, acct_t = acct_t, detail = detail) else: self.descendants.append(Account( instr, parent=self, acct_type = self.acct_type if acct_t is None else acct_t, detail_type = self.detail_type if detail is None else detail )) else: self.descendants.append(Account( instr, parent=self, acct_type = self.acct_type if acct_t is None else acct_t, detail_type = self.detail_type if detail is None else detail )) return if __name__ == "__main__": accounts: list[Account] = list() for (acs_name, account_type, detail_type) in get_data(): # Gets data as list[tuple[str, str, str]] d = len(acs_name) - len(acs_name.lstrip())) / 3 # Depth of current row's account if d == 0: # Overall header accounts.append(Account(acs_name, parent=None, acct_type=account_type, detail_type=detail_type)) else: if account_type is not None: # Account metadata supplied in CoA spreadsheet accounts[-1].add_descendant( acs_name, acct_t = account_type, detail = detail_type) else: # Impute account metadata from parent accounts[-1].add_descendant(acs_name) However, when I run this, I get a rather nasty RecursionError: Exception has occurred: RecursionError maximum recursion depth exceeded KeyError: 'C:\\Users\\...\\Account.py' During handling of the above exception, another exception occurred: KeyError: 'C:\\Users\\...\\Account.py' During handling of the above exception, another exception occurred: KeyError: 'C:\\Users\\...\\Account.py' During handling of the above exception, another exception occurred: KeyError: 'C:\\Users\\...\\Account.py' During handling of the above exception, another exception occurred: File "C:\Users\...\Account.py", line 104, in add_descendant self.descendants[-1].add_descendant(instr, acct_t = acct_t, detail = detail) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\...\Account.py", line 104, in add_descendant self.descendants[-1].add_descendant(instr, acct_t = acct_t, detail = detail) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\...\Account.py", line 104, in add_descendant self.descendants[-1].add_descendant(instr, acct_t = acct_t, detail = detail) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [Previous line repeated 980 more times] File "C:\Users\...\Account.py", line 155, in <module> acs_name, ^^^^^^^^^ ...<3 lines>... detail=detail_type RecursionError: maximum recursion depth exceeded I've spent the last 1.5 hours trying to fix this, but to no avail. Looking in my debugger, it appears that while the first two levels get added properly, that second level makes itself its own descendant ad infinitum. For example, in my most recent debugging run the tree looks like this: <__main__.Account object at 0x0000015631511BE0> # Current Assets <__main__.Account object at 0x0000015631796710> # Cash <__main__.Account object at 0x0000015631796710> # Cash <__main__.Account object at 0x0000015631796710> # Yet more Cash ... # 980-ish more Cash For reference, it should actually look like this: <__main__.Account object at 0x0000015631511BE0> # Current Assets <__main__.Account object at 0x0000015631796710> # Cash <__main__.Account object at 0x0000015631XXXXXX> # 1000000.00 - Cash What am I doing wrong? As far as I can tell, there isn't anywhere where I am adding self to self.descendants. (As a final note, this isn't my full code; irrelevant bits have been omitted or simplified.) Continue reading...