Parent issue
#194 — function purification
Problem
Statement.__init__ (statements.py:347) is a monolithic constructor that:
- Opens the PDF file (
pdf_open)
- Validates/initialises the project directory (
validate_or_initialise_project)
- Reads config from disk (
ImportConfigManager)
- Runs the full extraction pipeline (
get_results)
- Writes debug files (
_write_debug_json, _write_debug_excel)
- Prints errors to stderr
- Never raises, masking errors via
self.success/self.error_message
Testing any single step requires real PDFs and a real project directory.
Proposal
Split into a pure factory/classmethod parse(file, config, ...) -> StatementResult that returns a dataclass with all extracted fields, and a separate side-effecting persist() method for file I/O and debug writes. The validation logic (is_successfull()) and debug writing should be decoupled from construction.
Code relationships
Target:
Statement.__init__() — statements.py:347
Callers (will need updating):
process_pdf_statement() — statements.py:828 (creates Statement)
StatementBatch.debug() — statements.py:1682 (re-creates Statement objects)
Related (called from init):
validate_or_initialise_project() — paths.py
pdf_open() — pdf_functions.py:42
ImportConfigManager.__init__() — import_config.py:147
Statement.get_results() — statements.py:631
_write_debug_json() — statements.py:198
Existing tests:
tests/test_statements.py::TestGoodStatements — integration tests create Statement via StatementBatch (indirect coverage only)
tests/conftest.py — session fixtures use StatementBatch which creates Statements
No direct unit tests exist for Statement.__init__.
Siblings
Parent issue
#194 — function purification
Problem
Statement.__init__(statements.py:347) is a monolithic constructor that:pdf_open)validate_or_initialise_project)ImportConfigManager)get_results)_write_debug_json,_write_debug_excel)self.success/self.error_messageTesting any single step requires real PDFs and a real project directory.
Proposal
Split into a pure factory/classmethod
parse(file, config, ...) -> StatementResultthat returns a dataclass with all extracted fields, and a separate side-effectingpersist()method for file I/O and debug writes. The validation logic (is_successfull()) and debug writing should be decoupled from construction.Code relationships
Target:
Statement.__init__()—statements.py:347Callers (will need updating):
process_pdf_statement()—statements.py:828(creates Statement)StatementBatch.debug()—statements.py:1682(re-creates Statement objects)Related (called from init):
validate_or_initialise_project()—paths.pypdf_open()—pdf_functions.py:42ImportConfigManager.__init__()—import_config.py:147Statement.get_results()—statements.py:631_write_debug_json()—statements.py:198Existing tests:
tests/test_statements.py::TestGoodStatements— integration tests create Statement via StatementBatch (indirect coverage only)tests/conftest.py— session fixtures use StatementBatch which creates StatementsNo direct unit tests exist for
Statement.__init__.Siblings