From d75b085bcb46b3645cfbd7a6deb7a08366703ef6 Mon Sep 17 00:00:00 2001 From: Jake Cadwell Date: Sun, 14 Jan 2024 14:27:44 -0800 Subject: [PATCH 01/34] Add InvestStatmentLine as possible reutrn to fix typing check errors. --- src/ofxstatement/parser.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ofxstatement/parser.py b/src/ofxstatement/parser.py index e045cf5..19f9d9c 100644 --- a/src/ofxstatement/parser.py +++ b/src/ofxstatement/parser.py @@ -4,7 +4,7 @@ from decimal import Decimal, Decimal as D from datetime import datetime -from ofxstatement.statement import Statement, StatementLine +from ofxstatement.statement import Statement, StatementLine, InvestStatementLine LT = TypeVar("LT") @@ -53,7 +53,7 @@ def split_records(self) -> Iterable[LT]: # pragma: no cover """Return iterable object consisting of a line per transaction""" raise NotImplementedError - def parse_record(self, line: LT) -> Optional[StatementLine]: # pragma: no cover + def parse_record(self, line: LT) -> Optional[StatementLine|InvestStatementLine]: # pragma: no cover """Parse given transaction line and return StatementLine object""" raise NotImplementedError From 498485b69d15ec642f71a02a7e76e5b5611acf11 Mon Sep 17 00:00:00 2001 From: Andrey Lebedev Date: Wed, 17 Jan 2024 21:56:29 +0200 Subject: [PATCH 02/34] Return pkg_resources namespaces back We can't get rid of them, because all the plugins rely on this namespace style. --- setup.cfg | 3 +++ src/ofxstatement/__init__.py | 1 + src/ofxstatement/plugins/__init__.py | 1 + 3 files changed, 5 insertions(+) diff --git a/setup.cfg b/setup.cfg index c25c1ad..88f0f7c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -22,6 +22,9 @@ project_urls = [options] package_dir = =src packages = find: +namespace_packages = + ofxstatement + ofxstatement.plugins python_requires = >=3.8, <4 install_requires = appdirs>=1.3.0 diff --git a/src/ofxstatement/__init__.py b/src/ofxstatement/__init__.py index e69de29..5284146 100644 --- a/src/ofxstatement/__init__.py +++ b/src/ofxstatement/__init__.py @@ -0,0 +1 @@ +__import__("pkg_resources").declare_namespace(__name__) diff --git a/src/ofxstatement/plugins/__init__.py b/src/ofxstatement/plugins/__init__.py index e69de29..5284146 100644 --- a/src/ofxstatement/plugins/__init__.py +++ b/src/ofxstatement/plugins/__init__.py @@ -0,0 +1 @@ +__import__("pkg_resources").declare_namespace(__name__) From 1e2abea8a13fcc0bee3df57a6c6525212ba6a562 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 3 Feb 2024 03:36:35 +0000 Subject: [PATCH 03/34] Bump pytest from 7.4.4 to 8.0.0 Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.4.4 to 8.0.0. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.4.4...8.0.0) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- Pipfile.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index f56bba1..a3d53f4 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -245,20 +245,20 @@ }, "pluggy": { "hashes": [ - "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12", - "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7" + "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981", + "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be" ], "markers": "python_version >= '3.8'", - "version": "==1.3.0" + "version": "==1.4.0" }, "pytest": { "hashes": [ - "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", - "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8" + "sha256:249b1b0864530ba251b7438274c4d251c58d868edaaec8762893ad4a0d71c36c", + "sha256:50fb9cbe836c3f20f0dfa99c565201fb75dc54c8d76373cd1bde06b06657bdb6" ], "index": "pypi", - "markers": "python_version >= '3.7'", - "version": "==7.4.4" + "markers": "python_version >= '3.8'", + "version": "==8.0.0" }, "pytest-cov": { "hashes": [ From 214bb9c63d3e0539f070e715a67a977cd17a7a8f Mon Sep 17 00:00:00 2001 From: Jake Cadwell Date: Sun, 4 Feb 2024 12:14:35 -0800 Subject: [PATCH 04/34] Use union instead of pipe for older python versions --- src/ofxstatement/parser.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ofxstatement/parser.py b/src/ofxstatement/parser.py index 19f9d9c..1685687 100644 --- a/src/ofxstatement/parser.py +++ b/src/ofxstatement/parser.py @@ -1,4 +1,4 @@ -from typing import Dict, Optional, Any, Iterable, List, TextIO, TypeVar, Generic +from typing import Dict, Optional, Any, Iterable, List, TextIO, TypeVar, Generic, Union from abc import abstractmethod import csv from decimal import Decimal, Decimal as D @@ -53,7 +53,7 @@ def split_records(self) -> Iterable[LT]: # pragma: no cover """Return iterable object consisting of a line per transaction""" raise NotImplementedError - def parse_record(self, line: LT) -> Optional[StatementLine|InvestStatementLine]: # pragma: no cover + def parse_record(self, line: LT) -> Optional[Union[StatementLine,InvestStatementLine]]: # pragma: no cover """Parse given transaction line and return StatementLine object""" raise NotImplementedError From d506798b18bca7626f1c3f21b63b9e674b2b8c46 Mon Sep 17 00:00:00 2001 From: Jake Cadwell Date: Sun, 4 Feb 2024 12:15:20 -0800 Subject: [PATCH 05/34] Ignore type checking due to ambiguous declaration --- src/ofxstatement/parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ofxstatement/parser.py b/src/ofxstatement/parser.py index 1685687..b28e512 100644 --- a/src/ofxstatement/parser.py +++ b/src/ofxstatement/parser.py @@ -46,7 +46,7 @@ def parse(self) -> Statement: stmt_line = self.parse_record(line) if stmt_line: stmt_line.assert_valid() - self.statement.lines.append(stmt_line) + self.statement.lines.append(stmt_line) # type: ignore return self.statement def split_records(self) -> Iterable[LT]: # pragma: no cover From 8dc608519a47c879e1fe3dc00bb263040d5cc298 Mon Sep 17 00:00:00 2001 From: Jake Cadwell Date: Sun, 4 Feb 2024 12:48:16 -0800 Subject: [PATCH 06/34] Fix formatting via black --- src/ofxstatement/parser.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ofxstatement/parser.py b/src/ofxstatement/parser.py index b28e512..b5cf9aa 100644 --- a/src/ofxstatement/parser.py +++ b/src/ofxstatement/parser.py @@ -46,14 +46,16 @@ def parse(self) -> Statement: stmt_line = self.parse_record(line) if stmt_line: stmt_line.assert_valid() - self.statement.lines.append(stmt_line) # type: ignore + self.statement.lines.append(stmt_line) # type: ignore return self.statement def split_records(self) -> Iterable[LT]: # pragma: no cover """Return iterable object consisting of a line per transaction""" raise NotImplementedError - def parse_record(self, line: LT) -> Optional[Union[StatementLine,InvestStatementLine]]: # pragma: no cover + def parse_record( + self, line: LT + ) -> Optional[Union[StatementLine, InvestStatementLine]]: # pragma: no cover """Parse given transaction line and return StatementLine object""" raise NotImplementedError From c58177709cd7bd631c63163f61904481654aa532 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 17 Feb 2024 03:57:13 +0000 Subject: [PATCH 07/34] Bump pytest from 8.0.0 to 8.0.1 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.0.0 to 8.0.1. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.0.0...8.0.1) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Pipfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index a3d53f4..ad273f9 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -253,12 +253,12 @@ }, "pytest": { "hashes": [ - "sha256:249b1b0864530ba251b7438274c4d251c58d868edaaec8762893ad4a0d71c36c", - "sha256:50fb9cbe836c3f20f0dfa99c565201fb75dc54c8d76373cd1bde06b06657bdb6" + "sha256:267f6563751877d772019b13aacbe4e860d73fe8f651f28112e9ac37de7513ae", + "sha256:3e4f16fe1c0a9dc9d9389161c127c3edc5d810c38d6793042fb81d9f48a59fca" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==8.0.0" + "version": "==8.0.1" }, "pytest-cov": { "hashes": [ From ac317a71312c9ce9d4fbe70c86f2c3b7e6f9021d Mon Sep 17 00:00:00 2001 From: Andrey Lebedev Date: Thu, 22 Feb 2024 21:22:39 +0200 Subject: [PATCH 08/34] Switch metadata to pyproject.toml --- pyproject.toml | 38 ++++++++++++++++++++++++++++++++++++++ setup.cfg | 46 +--------------------------------------------- 2 files changed, 39 insertions(+), 45 deletions(-) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..e4b5d13 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,38 @@ +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "ofxstatement" +version = "0.9.2.dev0" +authors = [ + { name="Andrey Lebedev", email="andrey@lebedev.lt" }, +] +description = "Tool to convert proprietary bank statement to OFX format, suitable for importing to GnuCash" +readme = "README.rst" +requires-python = ">=3.9" +license = { file="LICENSE.txt" } +classifiers = [ + "Development Status :: 3 - Alpha", + "Programming Language :: Python :: 3", + "Natural Language :: English", + "Topic :: Office/Business :: Financial :: Accounting", + "Topic :: Utilities", + "Environment :: Console", + "Operating System :: OS Independent", + "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", +] +keywords = ["ofx", "banking", "statement"] +dependencies = [ + "appdirs>=1.3.0", + "importlib_metadata>=3.8;python_version<'3.10'" +] + +[project.urls] +Homepage = "https://github.com/kedder/ofxstatement" + +[project.scripts] +ofxstatement = "ofxstatement.tool:run" + +[tool.setuptools.package-data] +ofxstatement = ["tests/samples"] \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index 88f0f7c..561057d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,54 +1,10 @@ -[metadata] -name = ofxstatement -version = 0.9.2.dev0 -description = Tool to convert proprietary bank statement to OFX format, suitable for importing to GnuCash -long_description = file: README.rst -long_description_content_type = text/x-rst -url = https://github.com/kedder/ofxstatement -author = Andrey Lebedev -author_email = andrey@lebedev.lt -classifiers = - Development Status :: 3 - Alpha - Programming Language :: Python :: 3 - Natural Language :: English - Topic :: Office/Business :: Financial :: Accounting - Topic :: Utilities - Environment :: Console - Operating System :: OS Independent - License :: OSI Approved :: GNU General Public License v3 (GPLv3) -keywords = ofx banking statement -project_urls = - [options] package_dir = =src packages = find: namespace_packages = ofxstatement ofxstatement.plugins -python_requires = >=3.8, <4 -install_requires = - appdirs>=1.3.0 - importlib_metadata>=3.8;python_version<'3.10' -data_files = + [options.packages.find] where = src - -[options.entry_points] -console_scripts = - ofxstatement=ofxstatement.tool:run - -[options.extras_require] -dev = - black - mypy -test = - mock - pytest - pytest-coverage - -[mypy] -ignore_missing_imports = True - -[pycodestyle] -max-line-length=88 From a852d23884e30aefbf55a6f82a977cc0cdd20f6e Mon Sep 17 00:00:00 2001 From: Andrey Lebedev Date: Thu, 22 Feb 2024 21:23:55 +0200 Subject: [PATCH 09/34] Install type hints for appdirs --- Pipfile | 3 +- Pipfile.lock | 185 +++++++++++++++++++++++++-------------------------- 2 files changed, 92 insertions(+), 96 deletions(-) diff --git a/Pipfile b/Pipfile index 2284bd1..ea4f840 100644 --- a/Pipfile +++ b/Pipfile @@ -12,8 +12,9 @@ mypy = "*" types-mock = "*" exceptiongroup = {markers="python_version < '3.11'"} tomli = {markers="python_version < '3.11'"} +types-appdirs = "*" [packages] ofxstatement = {editable = true,path = "."} exceptiongroup = "*" -importlib_metadata = {version = ">=3.8", markers="python_version < '3.10'"} \ No newline at end of file +importlib_metadata = {version = ">=3.8", markers="python_version < '3.10'"} diff --git a/Pipfile.lock b/Pipfile.lock index ad273f9..41e0d91 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "9eff26da7c0885e82355bd0e9d77d60f3ebee69507ba41b063a5a5599ccc6f6f" + "sha256": "57fc2b5e4dddcc97dc0061254ba0b975bd616ba89b36cdaff756d997e95bf3b8" }, "pipfile-spec": 6, "requires": {}, @@ -30,57 +30,44 @@ "markers": "python_version >= '3.7'", "version": "==1.2.0" }, - "importlib-metadata": { - "hashes": [ - "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e", - "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc" - ], - "index": "pypi", + "importlib_metadata": { "markers": "python_version < '3.10'", - "version": "==7.0.1" + "version": "==3.8" }, "ofxstatement": { "editable": true, "path": "." - }, - "zipp": { - "hashes": [ - "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31", - "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0" - ], - "markers": "python_version < '3.10' and python_version >= '3.8'", - "version": "==3.17.0" } }, "develop": { "black": { "hashes": [ - "sha256:0808494f2b2df923ffc5723ed3c7b096bd76341f6213989759287611e9837d50", - "sha256:1fa88a0f74e50e4487477bc0bb900c6781dbddfdfa32691e780bf854c3b4a47f", - "sha256:25e57fd232a6d6ff3f4478a6fd0580838e47c93c83eaf1ccc92d4faf27112c4e", - "sha256:2d9e13db441c509a3763a7a3d9a49ccc1b4e974a47be4e08ade2a228876500ec", - "sha256:3e1b38b3135fd4c025c28c55ddfc236b05af657828a8a6abe5deec419a0b7055", - "sha256:3fa4be75ef2a6b96ea8d92b1587dd8cb3a35c7e3d51f0738ced0781c3aa3a5a3", - "sha256:4ce3ef14ebe8d9509188014d96af1c456a910d5b5cbf434a09fef7e024b3d0d5", - "sha256:4f0031eaa7b921db76decd73636ef3a12c942ed367d8c3841a0739412b260a54", - "sha256:602cfb1196dc692424c70b6507593a2b29aac0547c1be9a1d1365f0d964c353b", - "sha256:6d1bd9c210f8b109b1762ec9fd36592fdd528485aadb3f5849b2740ef17e674e", - "sha256:78baad24af0f033958cad29731e27363183e140962595def56423e626f4bee3e", - "sha256:8d4df77958a622f9b5a4c96edb4b8c0034f8434032ab11077ec6c56ae9f384ba", - "sha256:97e56155c6b737854e60a9ab1c598ff2533d57e7506d97af5481141671abf3ea", - "sha256:9c4352800f14be5b4864016882cdba10755bd50805c95f728011bcb47a4afd59", - "sha256:a4d6a9668e45ad99d2f8ec70d5c8c04ef4f32f648ef39048d010b0689832ec6d", - "sha256:a920b569dc6b3472513ba6ddea21f440d4b4c699494d2e972a1753cdc25df7b0", - "sha256:ae76c22bde5cbb6bfd211ec343ded2163bba7883c7bc77f6b756a1049436fbb9", - "sha256:b18fb2ae6c4bb63eebe5be6bd869ba2f14fd0259bda7d18a46b764d8fb86298a", - "sha256:c04b6d9d20e9c13f43eee8ea87d44156b8505ca8a3c878773f68b4e4812a421e", - "sha256:c88b3711d12905b74206227109272673edce0cb29f27e1385f33b0163c414bba", - "sha256:dd15245c8b68fe2b6bd0f32c1556509d11bb33aec9b5d0866dd8e2ed3dba09c2", - "sha256:e0aaf6041986767a5e0ce663c7a2f0e9eaf21e6ff87a5f95cbf3675bfd4c41d2" + "sha256:057c3dc602eaa6fdc451069bd027a1b2635028b575a6c3acfd63193ced20d9c8", + "sha256:08654d0797e65f2423f850fc8e16a0ce50925f9337fb4a4a176a7aa4026e63f8", + "sha256:163baf4ef40e6897a2a9b83890e59141cc8c2a98f2dda5080dc15c00ee1e62cd", + "sha256:1e08fb9a15c914b81dd734ddd7fb10513016e5ce7e6704bdd5e1251ceee51ac9", + "sha256:4dd76e9468d5536abd40ffbc7a247f83b2324f0c050556d9c371c2b9a9a95e31", + "sha256:4f9de21bafcba9683853f6c96c2d515e364aee631b178eaa5145fc1c61a3cc92", + "sha256:61a0391772490ddfb8a693c067df1ef5227257e72b0e4108482b8d41b5aee13f", + "sha256:6981eae48b3b33399c8757036c7f5d48a535b962a7c2310d19361edeef64ce29", + "sha256:7e53a8c630f71db01b28cd9602a1ada68c937cbf2c333e6ed041390d6968faf4", + "sha256:810d445ae6069ce64030c78ff6127cd9cd178a9ac3361435708b907d8a04c693", + "sha256:93601c2deb321b4bad8f95df408e3fb3943d85012dddb6121336b8e24a0d1218", + "sha256:992e451b04667116680cb88f63449267c13e1ad134f30087dec8527242e9862a", + "sha256:9db528bccb9e8e20c08e716b3b09c6bdd64da0dd129b11e160bf082d4642ac23", + "sha256:a0057f800de6acc4407fe75bb147b0c2b5cbb7c3ed110d3e5999cd01184d53b0", + "sha256:ba15742a13de85e9b8f3239c8f807723991fbfae24bad92d34a2b12e81904982", + "sha256:bce4f25c27c3435e4dace4815bcb2008b87e167e3bf4ee47ccdc5ce906eb4894", + "sha256:ca610d29415ee1a30a3f30fab7a8f4144e9d34c89a235d81292a1edb2b55f540", + "sha256:d533d5e3259720fdbc1b37444491b024003e012c5173f7d06825a77508085430", + "sha256:d84f29eb3ee44859052073b7636533ec995bd0f64e2fb43aeceefc70090e752b", + "sha256:e37c99f89929af50ffaf912454b3e3b47fd64109659026b678c091a4cd450fb2", + "sha256:e8a6ae970537e67830776488bca52000eaa37fa63b9988e8c487458d9cd5ace6", + "sha256:faf2ee02e6612577ba0181f4347bcbcf591eb122f7841ae5ba233d12c39dcb4d" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==23.12.1" + "version": "==24.2.0" }, "click": { "hashes": [ @@ -95,61 +82,61 @@ "toml" ], "hashes": [ - "sha256:04387a4a6ecb330c1878907ce0dc04078ea72a869263e53c72a1ba5bbdf380ca", - "sha256:0676cd0ba581e514b7f726495ea75aba3eb20899d824636c6f59b0ed2f88c471", - "sha256:0e8d06778e8fbffccfe96331a3946237f87b1e1d359d7fbe8b06b96c95a5407a", - "sha256:0eb3c2f32dabe3a4aaf6441dde94f35687224dfd7eb2a7f47f3fd9428e421058", - "sha256:109f5985182b6b81fe33323ab4707011875198c41964f014579cf82cebf2bb85", - "sha256:13eaf476ec3e883fe3e5fe3707caeb88268a06284484a3daf8250259ef1ba143", - "sha256:164fdcc3246c69a6526a59b744b62e303039a81e42cfbbdc171c91a8cc2f9446", - "sha256:26776ff6c711d9d835557ee453082025d871e30b3fd6c27fcef14733f67f0590", - "sha256:26f66da8695719ccf90e794ed567a1549bb2644a706b41e9f6eae6816b398c4a", - "sha256:29f3abe810930311c0b5d1a7140f6395369c3db1be68345638c33eec07535105", - "sha256:316543f71025a6565677d84bc4df2114e9b6a615aa39fb165d697dba06a54af9", - "sha256:36b0ea8ab20d6a7564e89cb6135920bc9188fb5f1f7152e94e8300b7b189441a", - "sha256:3cc9d4bc55de8003663ec94c2f215d12d42ceea128da8f0f4036235a119c88ac", - "sha256:485e9f897cf4856a65a57c7f6ea3dc0d4e6c076c87311d4bc003f82cfe199d25", - "sha256:5040148f4ec43644702e7b16ca864c5314ccb8ee0751ef617d49aa0e2d6bf4f2", - "sha256:51456e6fa099a8d9d91497202d9563a320513fcf59f33991b0661a4a6f2ad450", - "sha256:53d7d9158ee03956e0eadac38dfa1ec8068431ef8058fe6447043db1fb40d932", - "sha256:5a10a4920def78bbfff4eff8a05c51be03e42f1c3735be42d851f199144897ba", - "sha256:5b14b4f8760006bfdb6e08667af7bc2d8d9bfdb648351915315ea17645347137", - "sha256:5b2ccb7548a0b65974860a78c9ffe1173cfb5877460e5a229238d985565574ae", - "sha256:697d1317e5290a313ef0d369650cfee1a114abb6021fa239ca12b4849ebbd614", - "sha256:6ae8c9d301207e6856865867d762a4b6fd379c714fcc0607a84b92ee63feff70", - "sha256:707c0f58cb1712b8809ece32b68996ee1e609f71bd14615bd8f87a1293cb610e", - "sha256:74775198b702868ec2d058cb92720a3c5a9177296f75bd97317c787daf711505", - "sha256:756ded44f47f330666843b5781be126ab57bb57c22adbb07d83f6b519783b870", - "sha256:76f03940f9973bfaee8cfba70ac991825611b9aac047e5c80d499a44079ec0bc", - "sha256:79287fd95585ed36e83182794a57a46aeae0b64ca53929d1176db56aacc83451", - "sha256:799c8f873794a08cdf216aa5d0531c6a3747793b70c53f70e98259720a6fe2d7", - "sha256:7d360587e64d006402b7116623cebf9d48893329ef035278969fa3bbf75b697e", - "sha256:80b5ee39b7f0131ebec7968baa9b2309eddb35b8403d1869e08f024efd883566", - "sha256:815ac2d0f3398a14286dc2cea223a6f338109f9ecf39a71160cd1628786bc6f5", - "sha256:83c2dda2666fe32332f8e87481eed056c8b4d163fe18ecc690b02802d36a4d26", - "sha256:846f52f46e212affb5bcf131c952fb4075b55aae6b61adc9856222df89cbe3e2", - "sha256:936d38794044b26c99d3dd004d8af0035ac535b92090f7f2bb5aa9c8e2f5cd42", - "sha256:9864463c1c2f9cb3b5db2cf1ff475eed2f0b4285c2aaf4d357b69959941aa555", - "sha256:995ea5c48c4ebfd898eacb098164b3cc826ba273b3049e4a889658548e321b43", - "sha256:a1526d265743fb49363974b7aa8d5899ff64ee07df47dd8d3e37dcc0818f09ed", - "sha256:a56de34db7b7ff77056a37aedded01b2b98b508227d2d0979d373a9b5d353daa", - "sha256:a7c97726520f784239f6c62506bc70e48d01ae71e9da128259d61ca5e9788516", - "sha256:b8e99f06160602bc64da35158bb76c73522a4010f0649be44a4e167ff8555952", - "sha256:bb1de682da0b824411e00a0d4da5a784ec6496b6850fdf8c865c1d68c0e318dd", - "sha256:bf477c355274a72435ceb140dc42de0dc1e1e0bf6e97195be30487d8eaaf1a09", - "sha256:bf635a52fc1ea401baf88843ae8708591aa4adff875e5c23220de43b1ccf575c", - "sha256:bfd5db349d15c08311702611f3dccbef4b4e2ec148fcc636cf8739519b4a5c0f", - "sha256:c530833afc4707fe48524a44844493f36d8727f04dcce91fb978c414a8556cc6", - "sha256:cc6d65b21c219ec2072c1293c505cf36e4e913a3f936d80028993dd73c7906b1", - "sha256:cd3c1e4cb2ff0083758f09be0f77402e1bdf704adb7f89108007300a6da587d0", - "sha256:cfd2a8b6b0d8e66e944d47cdec2f47c48fef2ba2f2dff5a9a75757f64172857e", - "sha256:d0ca5c71a5a1765a0f8f88022c52b6b8be740e512980362f7fdbb03725a0d6b9", - "sha256:e7defbb9737274023e2d7af02cac77043c86ce88a907c58f42b580a97d5bcca9", - "sha256:e9d1bf53c4c8de58d22e0e956a79a5b37f754ed1ffdbf1a260d9dcfa2d8a325e", - "sha256:ea81d8f9691bb53f4fb4db603203029643caffc82bf998ab5b59ca05560f4c06" + "sha256:006d220ba2e1a45f1de083d5022d4955abb0aedd78904cd5a779b955b019ec73", + "sha256:06fe398145a2e91edaf1ab4eee66149c6776c6b25b136f4a86fcbbb09512fd10", + "sha256:175f56572f25e1e1201d2b3e07b71ca4d201bf0b9cb8fad3f1dfae6a4188de86", + "sha256:18cac867950943fe93d6cd56a67eb7dcd2d4a781a40f4c1e25d6f1ed98721a55", + "sha256:1a5ee18e3a8d766075ce9314ed1cb695414bae67df6a4b0805f5137d93d6f1cb", + "sha256:20a875bfd8c282985c4720c32aa05056f77a68e6d8bbc5fe8632c5860ee0b49b", + "sha256:2412e98e70f16243be41d20836abd5f3f32edef07cbf8f407f1b6e1ceae783ac", + "sha256:2599972b21911111114100d362aea9e70a88b258400672626efa2b9e2179609c", + "sha256:2ed37e16cf35c8d6e0b430254574b8edd242a367a1b1531bd1adc99c6a5e00fe", + "sha256:32b4ab7e6c924f945cbae5392832e93e4ceb81483fd6dc4aa8fb1a97b9d3e0e1", + "sha256:34423abbaad70fea9d0164add189eabaea679068ebdf693baa5c02d03e7db244", + "sha256:3507427d83fa961cbd73f11140f4a5ce84208d31756f7238d6257b2d3d868405", + "sha256:3733545eb294e5ad274abe131d1e7e7de4ba17a144505c12feca48803fea5f64", + "sha256:3ff5bdb08d8938d336ce4088ca1a1e4b6c8cd3bef8bb3a4c0eb2f37406e49643", + "sha256:3ff7f92ae5a456101ca8f48387fd3c56eb96353588e686286f50633a611afc95", + "sha256:42a9e754aa250fe61f0f99986399cec086d7e7a01dd82fd863a20af34cbce962", + "sha256:51593a1f05c39332f623d64d910445fdec3d2ac2d96b37ce7f331882d5678ddf", + "sha256:5b11f9c6587668e495cc7365f85c93bed34c3a81f9f08b0920b87a89acc13469", + "sha256:69f1665165ba2fe7614e2f0c1aed71e14d83510bf67e2ee13df467d1c08bf1e8", + "sha256:78cdcbf7b9cb83fe047ee09298e25b1cd1636824067166dc97ad0543b079d22f", + "sha256:7df95fdd1432a5d2675ce630fef5f239939e2b3610fe2f2b5bf21fa505256fa3", + "sha256:81a5fb41b0d24447a47543b749adc34d45a2cf77b48ca74e5bf3de60a7bd9edc", + "sha256:840456cb1067dc350af9080298c7c2cfdddcedc1cb1e0b30dceecdaf7be1a2d3", + "sha256:8562ca91e8c40864942615b1d0b12289d3e745e6b2da901d133f52f2d510a1e3", + "sha256:861d75402269ffda0b33af94694b8e0703563116b04c681b1832903fac8fd647", + "sha256:8b98c89db1b150d851a7840142d60d01d07677a18f0f46836e691c38134ed18b", + "sha256:a178b7b1ac0f1530bb28d2e51f88c0bab3e5949835851a60dda80bff6052510c", + "sha256:a8ddbd158e069dded57738ea69b9744525181e99974c899b39f75b2b29a624e2", + "sha256:ac4bab32f396b03ebecfcf2971668da9275b3bb5f81b3b6ba96622f4ef3f6e17", + "sha256:ac9e95cefcf044c98d4e2c829cd0669918585755dd9a92e28a1a7012322d0a95", + "sha256:adbdfcda2469d188d79771d5696dc54fab98a16d2ef7e0875013b5f56a251047", + "sha256:b3c8bbb95a699c80a167478478efe5e09ad31680931ec280bf2087905e3b95ec", + "sha256:b3f2b1eb229f23c82898eedfc3296137cf1f16bb145ceab3edfd17cbde273fb7", + "sha256:b4ae777bebaed89e3a7e80c4a03fac434a98a8abb5251b2a957d38fe3fd30088", + "sha256:b953275d4edfab6cc0ed7139fa773dfb89e81fee1569a932f6020ce7c6da0e8f", + "sha256:bf54c3e089179d9d23900e3efc86d46e4431188d9a657f345410eecdd0151f50", + "sha256:bf711d517e21fb5bc429f5c4308fbc430a8585ff2a43e88540264ae87871e36a", + "sha256:c00e54f0bd258ab25e7f731ca1d5144b0bf7bec0051abccd2bdcff65fa3262c9", + "sha256:c11ca2df2206a4e3e4c4567f52594637392ed05d7c7fb73b4ea1c658ba560265", + "sha256:c5f9683be6a5b19cd776ee4e2f2ffb411424819c69afab6b2db3a0a364ec6642", + "sha256:cf89ab85027427d351f1de918aff4b43f4eb5f33aff6835ed30322a86ac29c9e", + "sha256:d1b750a8409bec61caa7824bfd64a8074b6d2d420433f64c161a8335796c7c6b", + "sha256:d779a48fac416387dd5673fc5b2d6bd903ed903faaa3247dc1865c65eaa5a93e", + "sha256:d9a1ef0f173e1a19738f154fb3644f90d0ada56fe6c9b422f992b04266c55d5a", + "sha256:ddb79414c15c6f03f56cc68fa06994f047cf20207c31b5dad3f6bab54a0f66ef", + "sha256:ef00d31b7569ed3cb2036f26565f1984b9fc08541731ce01012b02a4c238bf03", + "sha256:f40ac873045db4fd98a6f40387d242bde2708a3f8167bd967ccd43ad46394ba2", + "sha256:f593a4a90118d99014517c2679e04a4ef5aee2d81aa05c26c734d271065efcb6", + "sha256:f5df76c58977bc35a49515b2fbba84a1d952ff0ec784a4070334dfbec28a2def", + "sha256:f72cdd2586f9a769570d4b5714a3837b3a59a53b096bb954f1811f6a0afad305", + "sha256:f8e845d894e39fb53834da826078f6dc1a933b32b1478cf437007367efaf6f6a", + "sha256:fe6e43c8b510719b48af7db9631b5fbac910ade4bd90e6378c85ac5ac706382c" ], "markers": "python_version >= '3.8'", - "version": "==7.4.0" + "version": "==7.4.2" }, "exceptiongroup": { "hashes": [ @@ -237,11 +224,11 @@ }, "platformdirs": { "hashes": [ - "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380", - "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420" + "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068", + "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768" ], "markers": "python_version >= '3.8'", - "version": "==4.1.0" + "version": "==4.2.0" }, "pluggy": { "hashes": [ @@ -278,6 +265,14 @@ "markers": "python_version < '3.11'", "version": "==2.0.1" }, + "types-appdirs": { + "hashes": [ + "sha256:337c750e423c40911d389359b4edabe5bbc2cdd5cd0bd0518b71d2839646273b", + "sha256:83268da64585361bfa291f8f506a209276212a0497bd37f0512a939b3d69ff14" + ], + "index": "pypi", + "version": "==1.4.3.5" + }, "types-mock": { "hashes": [ "sha256:13ca379d5710ccb3f18f69ade5b08881874cb83383d8fb49b1d4dac9d5c5d090", From 777f66295277606dc3fd60880f100dc3b7586d0c Mon Sep 17 00:00:00 2001 From: Andrey Lebedev Date: Thu, 22 Feb 2024 21:25:09 +0200 Subject: [PATCH 10/34] Reformat with newer black --- src/ofxstatement/plugin.py | 1 + src/ofxstatement/statement.py | 1 + src/ofxstatement/tool.py | 1 + 3 files changed, 3 insertions(+) diff --git a/src/ofxstatement/plugin.py b/src/ofxstatement/plugin.py index 9eaf532..6875c39 100644 --- a/src/ofxstatement/plugin.py +++ b/src/ofxstatement/plugin.py @@ -2,6 +2,7 @@ Plugins are objects that configures and coordinates conversion machinery. """ + from typing import List, Tuple, Type from collections.abc import MutableMapping import sys diff --git a/src/ofxstatement/statement.py b/src/ofxstatement/statement.py index 922cd87..8124621 100644 --- a/src/ofxstatement/statement.py +++ b/src/ofxstatement/statement.py @@ -1,4 +1,5 @@ """Statement model""" + from typing import List, Optional from datetime import datetime from decimal import Decimal as D diff --git a/src/ofxstatement/tool.py b/src/ofxstatement/tool.py index 90bd0b6..4fdfc7d 100644 --- a/src/ofxstatement/tool.py +++ b/src/ofxstatement/tool.py @@ -1,5 +1,6 @@ """Command line tool for converting statements to OFX format """ + import os import argparse import shlex From 338a9f690c2181d07a4bd7fd880ed5a3b9c5a717 Mon Sep 17 00:00:00 2001 From: Andrey Lebedev Date: Thu, 22 Feb 2024 21:26:56 +0200 Subject: [PATCH 11/34] Drop support for 3.8, add 3.12 --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9b43b18..5acc08b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11"] + python-version: ["3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v2 From 280bc407740afb544b4060bafd090164619fb065 Mon Sep 17 00:00:00 2001 From: Andrey Lebedev Date: Thu, 22 Feb 2024 21:33:07 +0200 Subject: [PATCH 12/34] Install zipp for older pythons --- Pipfile | 1 + Pipfile.lock | 6 +++++- pyproject.toml | 3 ++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Pipfile b/Pipfile index ea4f840..3fbaad5 100644 --- a/Pipfile +++ b/Pipfile @@ -18,3 +18,4 @@ types-appdirs = "*" ofxstatement = {editable = true,path = "."} exceptiongroup = "*" importlib_metadata = {version = ">=3.8", markers="python_version < '3.10'"} +zipp = {version = ">=3.8", markers="python_version < '3.10'"} diff --git a/Pipfile.lock b/Pipfile.lock index 41e0d91..c5020d6 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "57fc2b5e4dddcc97dc0061254ba0b975bd616ba89b36cdaff756d997e95bf3b8" + "sha256": "d01ad0c4b47d2fff1cffed79da795c043f9e96086adac9594cc73053658fa6ed" }, "pipfile-spec": 6, "requires": {}, @@ -37,6 +37,10 @@ "ofxstatement": { "editable": true, "path": "." + }, + "zipp": { + "markers": "python_version < '3.10'", + "version": "==3.8" } }, "develop": { diff --git a/pyproject.toml b/pyproject.toml index e4b5d13..6b889f4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,8 @@ classifiers = [ keywords = ["ofx", "banking", "statement"] dependencies = [ "appdirs>=1.3.0", - "importlib_metadata>=3.8;python_version<'3.10'" + "importlib_metadata>=3.8;python_version<'3.10'", + "zipp;python_version<'3.10'" ] [project.urls] From 8f8008dd5be8f82ca4209a98826d6f6a8212e1cf Mon Sep 17 00:00:00 2001 From: Ed Wagner Date: Sun, 18 Feb 2024 15:20:15 -0600 Subject: [PATCH 13/34] Don't add a blank security to the list For some investment transactions (e.g. INTEREST) there is no security, so don't add a blank that will get rejected by Gnucash. --- src/ofxstatement/ofx.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ofxstatement/ofx.py b/src/ofxstatement/ofx.py index 888c7d5..f746572 100644 --- a/src/ofxstatement/ofx.py +++ b/src/ofxstatement/ofx.py @@ -155,6 +155,8 @@ def buildInvestTransactionList(self) -> None: for security_id in dict.fromkeys( map(lambda x: x.security_id, self.statement.invest_lines) ): + if security_id is None: + continue tb.start("STOCKINFO", {}) tb.start("SECINFO", {}) tb.start("SECID", {}) From 1944606fa584fc84aeebbcf79cddc5b1e64e62f8 Mon Sep 17 00:00:00 2001 From: Ed Wagner Date: Sun, 18 Feb 2024 15:21:23 -0600 Subject: [PATCH 14/34] Decrease precision of total to 2 decimal places Total doesn't need more than 2 decimal places. --- src/ofxstatement/ofx.py | 1 - src/ofxstatement/tests/test_ofx_invest.py | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ofxstatement/ofx.py b/src/ofxstatement/ofx.py index f746572..e370374 100644 --- a/src/ofxstatement/ofx.py +++ b/src/ofxstatement/ofx.py @@ -272,7 +272,6 @@ def buildInvestTransaction(self, line: InvestStatementLine) -> None: "TOTAL", line.amount, False, - precision=self.invest_transactions_float_precision, ) if inner_tran_type_tag_name: diff --git a/src/ofxstatement/tests/test_ofx_invest.py b/src/ofxstatement/tests/test_ofx_invest.py index 433a5af..3f6c9a3 100644 --- a/src/ofxstatement/tests/test_ofx_invest.py +++ b/src/ofxstatement/tests/test_ofx_invest.py @@ -88,7 +88,7 @@ 1.24000 138.28000 3.00000 - -416.08000 + -416.08 @@ -108,7 +108,7 @@ 0.28000 225.63000 -5.00000 - 1127.87000 + 1127.87 @@ -125,7 +125,7 @@ OTHER OTHER 0.50000 - 0.79000 + 0.79 From 05e26992206be455ed5bec51dfc9cad8b9714c25 Mon Sep 17 00:00:00 2001 From: Ed Wagner Date: Sun, 18 Feb 2024 15:55:18 -0600 Subject: [PATCH 15/34] Add cap gain income types --- src/ofxstatement/statement.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ofxstatement/statement.py b/src/ofxstatement/statement.py index 8124621..0cc5712 100644 --- a/src/ofxstatement/statement.py +++ b/src/ofxstatement/statement.py @@ -44,6 +44,8 @@ "SELLSHORT", # open short sale "DIV", # only for INCOME "INTEREST", # only for INCOME + "CGLONG", # only for INCOME + "CGSHORT", # only for INCOME ] ACCOUNT_TYPE = [ From 86560e70ca5c45814b8d6a76cc24cedd6334da87 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 2 Mar 2024 03:09:59 +0000 Subject: [PATCH 16/34] Bump zipp from 3.8 to 3.17.0 Bumps [zipp](https://github.com/jaraco/zipp) from 3.8 to 3.17.0. - [Release notes](https://github.com/jaraco/zipp/releases) - [Changelog](https://github.com/jaraco/zipp/blob/main/NEWS.rst) - [Commits](https://github.com/jaraco/zipp/compare/v3.8.0...v3.17.0) --- updated-dependencies: - dependency-name: zipp dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Pipfile.lock | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index c5020d6..b7a609d 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -30,7 +30,7 @@ "markers": "python_version >= '3.7'", "version": "==1.2.0" }, - "importlib_metadata": { + "importlib-metadata": { "markers": "python_version < '3.10'", "version": "==3.8" }, @@ -39,8 +39,13 @@ "path": "." }, "zipp": { - "markers": "python_version < '3.10'", - "version": "==3.8" + "hashes": [ + "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31", + "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==3.17.0" } }, "develop": { From cfd9002d437edc48f432fad245f72b021a2580ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 2 Mar 2024 03:10:43 +0000 Subject: [PATCH 17/34] Bump pytest from 8.0.1 to 8.0.2 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.0.1 to 8.0.2. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.0.1...8.0.2) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Pipfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index b7a609d..28f5132 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -249,12 +249,12 @@ }, "pytest": { "hashes": [ - "sha256:267f6563751877d772019b13aacbe4e860d73fe8f651f28112e9ac37de7513ae", - "sha256:3e4f16fe1c0a9dc9d9389161c127c3edc5d810c38d6793042fb81d9f48a59fca" + "sha256:d4051d623a2e0b7e51960ba963193b09ce6daeb9759a451844a21e4ddedfc1bd", + "sha256:edfaaef32ce5172d5466b5127b42e0d6d35ebbe4453f0e3505d96afd93f6b096" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==8.0.1" + "version": "==8.0.2" }, "pytest-cov": { "hashes": [ From 78cba7e998dd2ea0e05b3f814fb51806d85cba2c Mon Sep 17 00:00:00 2001 From: Ed Wagner Date: Sun, 3 Mar 2024 18:51:47 -0600 Subject: [PATCH 18/34] Handle INVBANKTRAN For INTEREST, XFER, and other cash transactions that are not associated with a security, INVBANKTRAN is the appropriate transaction type. The body is like a bank transaction (STMTTRN), not an INVTRAN. --- src/ofxstatement/ofx.py | 9 +++ src/ofxstatement/statement.py | 46 ++++++++++++---- src/ofxstatement/tests/test_ofx_invest.py | 17 ++++++ src/ofxstatement/tests/test_statement.py | 67 +++++++++++++++++++++++ 4 files changed, 129 insertions(+), 10 deletions(-) diff --git a/src/ofxstatement/ofx.py b/src/ofxstatement/ofx.py index e370374..38b7bb2 100644 --- a/src/ofxstatement/ofx.py +++ b/src/ofxstatement/ofx.py @@ -207,6 +207,15 @@ def buildInvestTransaction(self, line: InvestStatementLine) -> None: tb = self.tb + if line.trntype == "INVBANKTRAN": + tb.start(line.trntype, {}) + bankTran = StatementLine(line.id, line.date, line.memo, line.amount) + bankTran.trntype = line.trntype_detailed + self.buildBankTransaction(bankTran) + self.buildText("SUBACCTFUND", "OTHER") + tb.end(line.trntype) + return + tran_type_detailed_tag_name = None inner_tran_type_tag_name = None if line.trntype.startswith("BUY"): diff --git a/src/ofxstatement/statement.py b/src/ofxstatement/statement.py index 0cc5712..e79044e 100644 --- a/src/ofxstatement/statement.py +++ b/src/ofxstatement/statement.py @@ -35,6 +35,7 @@ "SELLSTOCK", "SELLDEBT", "INCOME", + "INVBANKTRAN", ] INVEST_TRANSACTION_TYPES_DETAILED = [ @@ -48,6 +49,15 @@ "CGSHORT", # only for INCOME ] +INVBANKTRAN_TYPES_DETAILED = [ + "INT", + "XFER", + "DEBIT", + "CREDIT", + "SRVCHG", + "OTHER", +] + ACCOUNT_TYPE = [ "CHECKING", # Checking "SAVINGS", # Savings @@ -277,19 +287,35 @@ def assert_valid(self) -> None: INVEST_TRANSACTION_TYPES, ) - assert ( - self.trntype_detailed in INVEST_TRANSACTION_TYPES_DETAILED - ), "trntype_detailed %s is not valid, must be one of %s" % ( - self.trntype_detailed, - INVEST_TRANSACTION_TYPES_DETAILED, - ) + if self.trntype == "INVBANKTRAN": + assert self.trntype_detailed in INVBANKTRAN_TYPES_DETAILED, ( + "trntype_detailed %s is not valid for INVBANKTRAN, must be one of %s" + % ( + self.trntype_detailed, + INVBANKTRAN_TYPES_DETAILED, + ) + ) + else: + assert ( + self.trntype_detailed in INVEST_TRANSACTION_TYPES_DETAILED + ), "trntype_detailed %s is not valid, must be one of %s" % ( + self.trntype_detailed, + INVEST_TRANSACTION_TYPES_DETAILED, + ) assert self.id - assert self.security_id + assert self.date assert self.amount - - assert self.trntype == "INCOME" or self.units - assert self.trntype == "INCOME" or self.unit_price + assert self.trntype == "INVBANKTRAN" or self.security_id + + if self.trntype == "INVBANKTRAN": + pass + elif self.trntype == "INCOME": + assert self.security_id + else: + assert self.security_id + assert self.units + assert self.unit_price class BankAccount(Printable): diff --git a/src/ofxstatement/tests/test_ofx_invest.py b/src/ofxstatement/tests/test_ofx_invest.py index 3f6c9a3..bda3329 100644 --- a/src/ofxstatement/tests/test_ofx_invest.py +++ b/src/ofxstatement/tests/test_ofx_invest.py @@ -127,6 +127,16 @@ 0.50000 0.79 + + + INT + 20210102 + 0.45 + 6 + Bank Interest + + OTHER + @@ -190,6 +200,13 @@ def test_ofxWriter(self) -> None: invest_line.assert_valid() statement.invest_lines.append(invest_line) + invest_line = InvestStatementLine( + "6", datetime(2021, 1, 2), "Bank Interest", "INVBANKTRAN", "INT" + ) + invest_line.amount = Decimal("0.45") + invest_line.assert_valid() + statement.invest_lines.append(invest_line) + # Create writer: writer = ofx.OfxWriter(statement) diff --git a/src/ofxstatement/tests/test_statement.py b/src/ofxstatement/tests/test_statement.py index 730bc94..7cea900 100644 --- a/src/ofxstatement/tests/test_statement.py +++ b/src/ofxstatement/tests/test_statement.py @@ -50,3 +50,70 @@ def test_generate_unique_transaction_id(self) -> None: self.assertTrue(tid2.endswith("-1")) self.assertEqual(len(txnids), 2) + + def test_invbank_line_validation(self) -> None: + line = statement.InvestStatementLine("id", datetime(2020, 3, 25)) + line.trntype = "INVBANKTRAN" + line.trntype_detailed = "INT" + line.amount = Decimal(1) + line.assert_valid() + with self.assertRaises(AssertionError): + line.amount = None + line.assert_valid() + line.amount = Decimal(1) + with self.assertRaises(AssertionError): + line.trntype_detailed = "BLAH" + line.assert_valid() + + def test_income_line_validation(self) -> None: + line = statement.InvestStatementLine("id", datetime(2020, 3, 25)) + line.trntype = "INCOME" + line.trntype_detailed = "INTEREST" + line.amount = Decimal(1) + line.security_id = "AAPL" + line.assert_valid() + with self.assertRaises(AssertionError): + line.amount = None + line.assert_valid() + line.amount = Decimal(1) + with self.assertRaises(AssertionError): + line.trntype_detailed = "BLAH" + line.assert_valid() + line.trntype_detailed = "INTEREST" + with self.assertRaises(AssertionError): + line.security_id = None + line.assert_valid() + + def test_buy_line_validation(self) -> None: + line = statement.InvestStatementLine("id", datetime(2020, 3, 25)) + line.trntype = "BUYSTOCK" + line.trntype_detailed = "BUY" + line.amount = Decimal(1) + line.security_id = "AAPL" + line.units = Decimal(3) + line.unit_price = Decimal(1.1) + line.assert_valid() + + with self.assertRaises(AssertionError): + line.amount = None + line.assert_valid() + line.amount = Decimal(1) + + with self.assertRaises(AssertionError): + line.trntype_detailed = "BLAH" + line.assert_valid() + line.trntype_detailed = "INTEREST" + + with self.assertRaises(AssertionError): + line.security_id = None + line.assert_valid() + line.security_id = "AAPL" + + with self.assertRaises(AssertionError): + line.units = None + line.assert_valid() + line.units = Decimal(3) + + with self.assertRaises(AssertionError): + line.unit_price = None + line.assert_valid() From 8c1112c2a31bad3726360618b02e8f9160d4cc65 Mon Sep 17 00:00:00 2001 From: Ed Wagner Date: Sun, 3 Mar 2024 19:00:46 -0600 Subject: [PATCH 19/34] Handle TRANSFER type For share transfers, TRANSFER is the appropriate type with no trntype_detailed, no amount and an optional unit_price. --- src/ofxstatement/ofx.py | 17 ++++++++-------- src/ofxstatement/statement.py | 13 ++++++++---- src/ofxstatement/tests/test_ofx_invest.py | 24 +++++++++++++++++++++++ src/ofxstatement/tests/test_statement.py | 18 +++++++++++++++++ 4 files changed, 60 insertions(+), 12 deletions(-) diff --git a/src/ofxstatement/ofx.py b/src/ofxstatement/ofx.py index 38b7bb2..8b034c6 100644 --- a/src/ofxstatement/ofx.py +++ b/src/ofxstatement/ofx.py @@ -201,8 +201,8 @@ def buildInvestTransactionList(self) -> None: tb.end("INVSTMTMSGSRSV1") def buildInvestTransaction(self, line: InvestStatementLine) -> None: - # invest transactions must always have trntype and trntype_detailed - if line.trntype is None or line.trntype_detailed is None: + # invest transactions must always have trntype + if line.trntype is None: return tb = self.tb @@ -224,6 +224,10 @@ def buildInvestTransaction(self, line: InvestStatementLine) -> None: elif line.trntype.startswith("SELL"): tran_type_detailed_tag_name = "SELLTYPE" inner_tran_type_tag_name = "INVSELL" + elif line.trntype == "TRANSFER": + # Transfer transactions don't have details or an envelope + tran_type_detailed_tag_name = None + inner_tran_type_tag_name = None else: tran_type_detailed_tag_name = "INCOMETYPE" inner_tran_type_tag_name = ( @@ -231,7 +235,8 @@ def buildInvestTransaction(self, line: InvestStatementLine) -> None: ) tb.start(line.trntype, {}) - self.buildText(tran_type_detailed_tag_name, line.trntype_detailed, False) + if tran_type_detailed_tag_name: + self.buildText(tran_type_detailed_tag_name, line.trntype_detailed, False) if inner_tran_type_tag_name: tb.start(inner_tran_type_tag_name, {}) @@ -277,11 +282,7 @@ def buildInvestTransaction(self, line: InvestStatementLine) -> None: precision=self.invest_transactions_float_precision, ) - self.buildAmount( - "TOTAL", - line.amount, - False, - ) + self.buildAmount("TOTAL", line.amount) if inner_tran_type_tag_name: tb.end(inner_tran_type_tag_name) diff --git a/src/ofxstatement/statement.py b/src/ofxstatement/statement.py index e79044e..859b8b7 100644 --- a/src/ofxstatement/statement.py +++ b/src/ofxstatement/statement.py @@ -32,10 +32,11 @@ INVEST_TRANSACTION_TYPES = [ "BUYSTOCK", "BUYDEBT", - "SELLSTOCK", - "SELLDEBT", "INCOME", "INVBANKTRAN", + "SELLSTOCK", + "SELLDEBT", + "TRANSFER", ] INVEST_TRANSACTION_TYPES_DETAILED = [ @@ -295,6 +296,10 @@ def assert_valid(self) -> None: INVBANKTRAN_TYPES_DETAILED, ) ) + elif self.trntype == "TRANSFER": + assert ( + self.trntype_detailed is None + ), f"trntype_detailed '{self.trntype_detailed}' should be empty for TRANSFERS" else: assert ( self.trntype_detailed in INVEST_TRANSACTION_TYPES_DETAILED @@ -305,7 +310,7 @@ def assert_valid(self) -> None: assert self.id assert self.date - assert self.amount + assert self.trntype == "TRANSFER" or self.amount assert self.trntype == "INVBANKTRAN" or self.security_id if self.trntype == "INVBANKTRAN": @@ -315,7 +320,7 @@ def assert_valid(self) -> None: else: assert self.security_id assert self.units - assert self.unit_price + assert self.trntype == "TRANSFER" or self.unit_price class BankAccount(Printable): diff --git a/src/ofxstatement/tests/test_ofx_invest.py b/src/ofxstatement/tests/test_ofx_invest.py index bda3329..82ba15b 100644 --- a/src/ofxstatement/tests/test_ofx_invest.py +++ b/src/ofxstatement/tests/test_ofx_invest.py @@ -137,6 +137,21 @@ OTHER + + + 7 + 20210103 + Journaled Shares + + + MSFT + TICKER + + OTHER + OTHER + 225.63000 + 4.00000 + @@ -207,6 +222,15 @@ def test_ofxWriter(self) -> None: invest_line.assert_valid() statement.invest_lines.append(invest_line) + invest_line = InvestStatementLine( + "7", datetime(2021, 1, 3), "Journaled Shares", "TRANSFER" + ) + invest_line.security_id = "MSFT" + invest_line.units = Decimal("4") + invest_line.unit_price = Decimal("225.63") + invest_line.assert_valid() + statement.invest_lines.append(invest_line) + # Create writer: writer = ofx.OfxWriter(statement) diff --git a/src/ofxstatement/tests/test_statement.py b/src/ofxstatement/tests/test_statement.py index 7cea900..cb63320 100644 --- a/src/ofxstatement/tests/test_statement.py +++ b/src/ofxstatement/tests/test_statement.py @@ -51,6 +51,24 @@ def test_generate_unique_transaction_id(self) -> None: self.assertTrue(tid2.endswith("-1")) self.assertEqual(len(txnids), 2) + def test_transfer_line_validation(self) -> None: + line = statement.InvestStatementLine("id", datetime(2020, 3, 25)) + line.trntype = "TRANSFER" + line.security_id = "ABC" + line.units = Decimal(2) + line.assert_valid() + with self.assertRaises(AssertionError): + line.security_id = None + line.assert_valid() + line.security_id = "ABC" + with self.assertRaises(AssertionError): + line.units = None + line.assert_valid() + line.units = Decimal(2) + with self.assertRaises(AssertionError): + line.trntype_detailed = "DETAIL" + line.assert_valid() + def test_invbank_line_validation(self) -> None: line = statement.InvestStatementLine("id", datetime(2020, 3, 25)) line.trntype = "INVBANKTRAN" From c659d45eefa60ddfb3ae8d61c0d9f0f1f0473d0e Mon Sep 17 00:00:00 2001 From: Ed Wagner Date: Tue, 5 Mar 2024 23:28:28 -0600 Subject: [PATCH 20/34] Fix plugin loading After the switch to importlib, plugins are retrieved by name, not integer index. For details see importlib.metadata.EntryPoints.__getitem__() Also update the mock.patch to match: entry_points() -> EntryPoints --- src/ofxstatement/plugin.py | 2 +- src/ofxstatement/tests/test_plugin.py | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/ofxstatement/plugin.py b/src/ofxstatement/plugin.py index 6875c39..ea81f34 100644 --- a/src/ofxstatement/plugin.py +++ b/src/ofxstatement/plugin.py @@ -22,7 +22,7 @@ def get_plugin(name: str, ui: UI, settings: MutableMapping) -> "Plugin": raise PluginNotRegistered(name) if len(plugins) > 1: raise PluginNameConflict(plugins) - plugin = plugins[0].load() # type: ignore[index] # index requires a int but class expects a string + plugin = plugins[name].load() return plugin(ui, settings) diff --git a/src/ofxstatement/tests/test_plugin.py b/src/ofxstatement/tests/test_plugin.py index 34618d1..2d156de 100644 --- a/src/ofxstatement/tests/test_plugin.py +++ b/src/ofxstatement/tests/test_plugin.py @@ -2,6 +2,13 @@ import mock +import sys + +if sys.version_info < (3, 10): + from importlib_metadata import EntryPoints +else: + from importlib.metadata import EntryPoints + from ofxstatement import plugin @@ -13,7 +20,9 @@ def get_parser(self): ep = mock.Mock() ep.load.return_value = SamplePlugin - ep_patch = mock.patch("ofxstatement.plugin.entry_points", return_value=[ep]) + ep_patch = mock.patch( + "ofxstatement.plugin.entry_points", return_value=EntryPoints([ep]) + ) with ep_patch: p = plugin.get_plugin("sample", mock.Mock("UI"), mock.Mock("Settings")) self.assertIsInstance(p, SamplePlugin) @@ -21,7 +30,9 @@ def get_parser(self): def test_get_plugin_conflict(self) -> None: ep = mock.Mock() - ep_patch = mock.patch("ofxstatement.plugin.entry_points", return_value=[ep, ep]) + ep_patch = mock.patch( + "ofxstatement.plugin.entry_points", return_value=EntryPoints([ep, ep]) + ) with ep_patch: with self.assertRaises(plugin.PluginNameConflict): plugin.get_plugin("conflicting", mock.Mock("UI"), mock.Mock("Settings")) From f7e5b1f8cec2c61eabf3b4de2190e2c48c6bcf6e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 9 Mar 2024 03:33:52 +0000 Subject: [PATCH 21/34] Bump mypy from 1.8.0 to 1.9.0 Bumps [mypy](https://github.com/python/mypy) from 1.8.0 to 1.9.0. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v1.8.0...1.9.0) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Pipfile.lock | 62 ++++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 28f5132..452d23a 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -175,37 +175,37 @@ }, "mypy": { "hashes": [ - "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6", - "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d", - "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02", - "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d", - "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3", - "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3", - "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3", - "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66", - "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259", - "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835", - "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd", - "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d", - "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8", - "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07", - "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b", - "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e", - "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6", - "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae", - "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9", - "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d", - "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a", - "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592", - "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218", - "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817", - "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4", - "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410", - "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55" + "sha256:0235391f1c6f6ce487b23b9dbd1327b4ec33bb93934aa986efe8a9563d9349e6", + "sha256:190da1ee69b427d7efa8aa0d5e5ccd67a4fb04038c380237a0d96829cb157913", + "sha256:2418488264eb41f69cc64a69a745fad4a8f86649af4b1041a4c64ee61fc61129", + "sha256:3a3c007ff3ee90f69cf0a15cbcdf0995749569b86b6d2f327af01fd1b8aee9dc", + "sha256:3cc5da0127e6a478cddd906068496a97a7618a21ce9b54bde5bf7e539c7af974", + "sha256:48533cdd345c3c2e5ef48ba3b0d3880b257b423e7995dada04248725c6f77374", + "sha256:49c87c15aed320de9b438ae7b00c1ac91cd393c1b854c2ce538e2a72d55df150", + "sha256:4d3dbd346cfec7cb98e6cbb6e0f3c23618af826316188d587d1c1bc34f0ede03", + "sha256:571741dc4194b4f82d344b15e8837e8c5fcc462d66d076748142327626a1b6e9", + "sha256:587ce887f75dd9700252a3abbc9c97bbe165a4a630597845c61279cf32dfbf02", + "sha256:5d741d3fc7c4da608764073089e5f58ef6352bedc223ff58f2f038c2c4698a89", + "sha256:5e6061f44f2313b94f920e91b204ec600982961e07a17e0f6cd83371cb23f5c2", + "sha256:61758fabd58ce4b0720ae1e2fea5cfd4431591d6d590b197775329264f86311d", + "sha256:653265f9a2784db65bfca694d1edd23093ce49740b2244cde583aeb134c008f3", + "sha256:68edad3dc7d70f2f17ae4c6c1b9471a56138ca22722487eebacfd1eb5321d612", + "sha256:81a10926e5473c5fc3da8abb04119a1f5811a236dc3a38d92015cb1e6ba4cb9e", + "sha256:85ca5fcc24f0b4aeedc1d02f93707bccc04733f21d41c88334c5482219b1ccb3", + "sha256:a260627a570559181a9ea5de61ac6297aa5af202f06fd7ab093ce74e7181e43e", + "sha256:aceb1db093b04db5cd390821464504111b8ec3e351eb85afd1433490163d60cd", + "sha256:b685154e22e4e9199fc95f298661deea28aaede5ae16ccc8cbb1045e716b3e04", + "sha256:d357423fa57a489e8c47b7c85dfb96698caba13d66e086b412298a1a0ea3b0ed", + "sha256:d4d5ddc13421ba3e2e082a6c2d74c2ddb3979c39b582dacd53dd5d9431237185", + "sha256:e49499be624dead83927e70c756970a0bc8240e9f769389cdf5714b0784ca6bf", + "sha256:e54396d70be04b34f31d2edf3362c1edd023246c82f1730bbf8768c28db5361b", + "sha256:f88566144752999351725ac623471661c9d1cd8caa0134ff98cceeea181789f4", + "sha256:f8a67616990062232ee4c3952f41c779afac41405806042a8126fe96e098419f", + "sha256:fe28657de3bfec596bbeef01cb219833ad9d38dd5393fc649f4b366840baefe6" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.8.0" + "version": "==1.9.0" }, "mypy-extensions": { "hashes": [ @@ -293,11 +293,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", - "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" + "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475", + "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb" ], "markers": "python_version >= '3.8'", - "version": "==4.9.0" + "version": "==4.10.0" } } } From fd8f502dc320eb8ae10375ab5147e677a243037b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 16 Mar 2024 03:33:00 +0000 Subject: [PATCH 22/34] Bump black from 24.2.0 to 24.3.0 Bumps [black](https://github.com/psf/black) from 24.2.0 to 24.3.0. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/24.2.0...24.3.0) --- updated-dependencies: - dependency-name: black dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Pipfile.lock | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 452d23a..916e5df 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -51,32 +51,32 @@ "develop": { "black": { "hashes": [ - "sha256:057c3dc602eaa6fdc451069bd027a1b2635028b575a6c3acfd63193ced20d9c8", - "sha256:08654d0797e65f2423f850fc8e16a0ce50925f9337fb4a4a176a7aa4026e63f8", - "sha256:163baf4ef40e6897a2a9b83890e59141cc8c2a98f2dda5080dc15c00ee1e62cd", - "sha256:1e08fb9a15c914b81dd734ddd7fb10513016e5ce7e6704bdd5e1251ceee51ac9", - "sha256:4dd76e9468d5536abd40ffbc7a247f83b2324f0c050556d9c371c2b9a9a95e31", - "sha256:4f9de21bafcba9683853f6c96c2d515e364aee631b178eaa5145fc1c61a3cc92", - "sha256:61a0391772490ddfb8a693c067df1ef5227257e72b0e4108482b8d41b5aee13f", - "sha256:6981eae48b3b33399c8757036c7f5d48a535b962a7c2310d19361edeef64ce29", - "sha256:7e53a8c630f71db01b28cd9602a1ada68c937cbf2c333e6ed041390d6968faf4", - "sha256:810d445ae6069ce64030c78ff6127cd9cd178a9ac3361435708b907d8a04c693", - "sha256:93601c2deb321b4bad8f95df408e3fb3943d85012dddb6121336b8e24a0d1218", - "sha256:992e451b04667116680cb88f63449267c13e1ad134f30087dec8527242e9862a", - "sha256:9db528bccb9e8e20c08e716b3b09c6bdd64da0dd129b11e160bf082d4642ac23", - "sha256:a0057f800de6acc4407fe75bb147b0c2b5cbb7c3ed110d3e5999cd01184d53b0", - "sha256:ba15742a13de85e9b8f3239c8f807723991fbfae24bad92d34a2b12e81904982", - "sha256:bce4f25c27c3435e4dace4815bcb2008b87e167e3bf4ee47ccdc5ce906eb4894", - "sha256:ca610d29415ee1a30a3f30fab7a8f4144e9d34c89a235d81292a1edb2b55f540", - "sha256:d533d5e3259720fdbc1b37444491b024003e012c5173f7d06825a77508085430", - "sha256:d84f29eb3ee44859052073b7636533ec995bd0f64e2fb43aeceefc70090e752b", - "sha256:e37c99f89929af50ffaf912454b3e3b47fd64109659026b678c091a4cd450fb2", - "sha256:e8a6ae970537e67830776488bca52000eaa37fa63b9988e8c487458d9cd5ace6", - "sha256:faf2ee02e6612577ba0181f4347bcbcf591eb122f7841ae5ba233d12c39dcb4d" + "sha256:2818cf72dfd5d289e48f37ccfa08b460bf469e67fb7c4abb07edc2e9f16fb63f", + "sha256:41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93", + "sha256:4acf672def7eb1725f41f38bf6bf425c8237248bb0804faa3965c036f7672d11", + "sha256:4be5bb28e090456adfc1255e03967fb67ca846a03be7aadf6249096100ee32d0", + "sha256:4f1373a7808a8f135b774039f61d59e4be7eb56b2513d3d2f02a8b9365b8a8a9", + "sha256:56f52cfbd3dabe2798d76dbdd299faa046a901041faf2cf33288bc4e6dae57b5", + "sha256:65b76c275e4c1c5ce6e9870911384bff5ca31ab63d19c76811cb1fb162678213", + "sha256:65c02e4ea2ae09d16314d30912a58ada9a5c4fdfedf9512d23326128ac08ac3d", + "sha256:6905238a754ceb7788a73f02b45637d820b2f5478b20fec82ea865e4f5d4d9f7", + "sha256:79dcf34b33e38ed1b17434693763301d7ccbd1c5860674a8f871bd15139e7837", + "sha256:7bb041dca0d784697af4646d3b62ba4a6b028276ae878e53f6b4f74ddd6db99f", + "sha256:7d5e026f8da0322b5662fa7a8e752b3fa2dac1c1cbc213c3d7ff9bdd0ab12395", + "sha256:9f50ea1132e2189d8dff0115ab75b65590a3e97de1e143795adb4ce317934995", + "sha256:a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f", + "sha256:aadf7a02d947936ee418777e0247ea114f78aff0d0959461057cae8a04f20597", + "sha256:b5991d523eee14756f3c8d5df5231550ae8993e2286b8014e2fdea7156ed0959", + "sha256:bf21b7b230718a5f08bd32d5e4f1db7fc8788345c8aea1d155fc17852b3410f5", + "sha256:c45f8dff244b3c431b36e3224b6be4a127c6aca780853574c00faf99258041eb", + "sha256:c7ed6668cbbfcd231fa0dc1b137d3e40c04c7f786e626b405c62bcd5db5857e4", + "sha256:d7de8d330763c66663661a1ffd432274a2f92f07feeddd89ffd085b5744f85e7", + "sha256:e19cb1c6365fd6dc38a6eae2dcb691d7d83935c10215aef8e6c38edee3f77abd", + "sha256:e2af80566f43c85f5797365077fb64a393861a3730bd110971ab7a0c94e873e7" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==24.2.0" + "version": "==24.3.0" }, "click": { "hashes": [ @@ -217,11 +217,11 @@ }, "packaging": { "hashes": [ - "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", - "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" + "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" ], "markers": "python_version >= '3.7'", - "version": "==23.2" + "version": "==24.0" }, "pathspec": { "hashes": [ From 5de9b516e9cb9d49133f4e20e36adf27b4464bc9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 16 Mar 2024 03:31:30 +0000 Subject: [PATCH 23/34] Bump zipp from 3.17.0 to 3.18.1 Bumps [zipp](https://github.com/jaraco/zipp) from 3.17.0 to 3.18.1. - [Release notes](https://github.com/jaraco/zipp/releases) - [Changelog](https://github.com/jaraco/zipp/blob/main/NEWS.rst) - [Commits](https://github.com/jaraco/zipp/compare/v3.17.0...v3.18.1) --- updated-dependencies: - dependency-name: zipp dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Pipfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 916e5df..2525135 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -40,12 +40,12 @@ }, "zipp": { "hashes": [ - "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31", - "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0" + "sha256:206f5a15f2af3dbaee80769fb7dc6f249695e940acca08dfb2a4769fe61e538b", + "sha256:2884ed22e7d8961de1c9a05142eb69a247f120291bc0206a00a7642f09b5b715" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==3.17.0" + "version": "==3.18.1" } }, "develop": { From f0dd25ced19247d167eefa6599908c82409803b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 16 Mar 2024 03:31:59 +0000 Subject: [PATCH 24/34] Bump pytest from 8.0.2 to 8.1.1 Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.0.2 to 8.1.1. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.0.2...8.1.1) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Pipfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 2525135..a15e3a0 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -249,12 +249,12 @@ }, "pytest": { "hashes": [ - "sha256:d4051d623a2e0b7e51960ba963193b09ce6daeb9759a451844a21e4ddedfc1bd", - "sha256:edfaaef32ce5172d5466b5127b42e0d6d35ebbe4453f0e3505d96afd93f6b096" + "sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7", + "sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==8.0.2" + "version": "==8.1.1" }, "pytest-cov": { "hashes": [ From 4e4e716535e4cc5090492c6caaff92bf6a5d8ac2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 16 Mar 2024 03:32:21 +0000 Subject: [PATCH 25/34] Bump types-mock from 5.1.0.20240106 to 5.1.0.20240311 Bumps [types-mock](https://github.com/python/typeshed) from 5.1.0.20240106 to 5.1.0.20240311. - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-mock dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Pipfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index a15e3a0..08a7e97 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -284,12 +284,12 @@ }, "types-mock": { "hashes": [ - "sha256:13ca379d5710ccb3f18f69ade5b08881874cb83383d8fb49b1d4dac9d5c5d090", - "sha256:3d116955495935b0bcba14954b38d97e507cd43eca3e3700fc1b8e4f5c6bf2c7" + "sha256:0769cb376dfc75b45215619f17a9fd6333d771cc29ce4a38937f060b1e45530f", + "sha256:7472797986d83016f96fde7f73577d129b0cd8a8d0b783487a7be330d57ba431" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==5.1.0.20240106" + "version": "==5.1.0.20240311" }, "typing-extensions": { "hashes": [ From 44a0c18cec09bd589598cd7f07ebc96ceb741a4b Mon Sep 17 00:00:00 2001 From: Jake Cadwell Date: Sat, 30 Mar 2024 09:13:14 -0700 Subject: [PATCH 26/34] break out parse_invest_record that returns an InvestStatementLine object --- src/ofxstatement/parser.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ofxstatement/parser.py b/src/ofxstatement/parser.py index b5cf9aa..304948b 100644 --- a/src/ofxstatement/parser.py +++ b/src/ofxstatement/parser.py @@ -53,12 +53,14 @@ def split_records(self) -> Iterable[LT]: # pragma: no cover """Return iterable object consisting of a line per transaction""" raise NotImplementedError - def parse_record( - self, line: LT - ) -> Optional[Union[StatementLine, InvestStatementLine]]: # pragma: no cover + def parse_record(self, line: LT) -> StatementLine: # pragma: no cover """Parse given transaction line and return StatementLine object""" raise NotImplementedError + def parse_invest_record (self, line: LT) -> InvestStatementLine: # pragma: no cover + """Parse given investement transaction line and return InvetStatementLine object""" + raise NotImplementedError + def parse_value(self, value: Optional[str], field: str) -> Any: tp = StatementLine.__annotations__.get(field) if value is None: From 6d93bcf352bbe56790af1803940fcb742f4303f5 Mon Sep 17 00:00:00 2001 From: Jake Cadwell Date: Sun, 14 Jan 2024 14:27:44 -0800 Subject: [PATCH 27/34] Add InvestStatmentLine as possible reutrn to fix typing check errors. --- src/ofxstatement/parser.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ofxstatement/parser.py b/src/ofxstatement/parser.py index e045cf5..19f9d9c 100644 --- a/src/ofxstatement/parser.py +++ b/src/ofxstatement/parser.py @@ -4,7 +4,7 @@ from decimal import Decimal, Decimal as D from datetime import datetime -from ofxstatement.statement import Statement, StatementLine +from ofxstatement.statement import Statement, StatementLine, InvestStatementLine LT = TypeVar("LT") @@ -53,7 +53,7 @@ def split_records(self) -> Iterable[LT]: # pragma: no cover """Return iterable object consisting of a line per transaction""" raise NotImplementedError - def parse_record(self, line: LT) -> Optional[StatementLine]: # pragma: no cover + def parse_record(self, line: LT) -> Optional[StatementLine|InvestStatementLine]: # pragma: no cover """Parse given transaction line and return StatementLine object""" raise NotImplementedError From 0be6f567fe97ca8a7243c3656223a33d9b5ece80 Mon Sep 17 00:00:00 2001 From: Jake Cadwell Date: Sun, 4 Feb 2024 12:14:35 -0800 Subject: [PATCH 28/34] Use union instead of pipe for older python versions --- src/ofxstatement/parser.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ofxstatement/parser.py b/src/ofxstatement/parser.py index 19f9d9c..1685687 100644 --- a/src/ofxstatement/parser.py +++ b/src/ofxstatement/parser.py @@ -1,4 +1,4 @@ -from typing import Dict, Optional, Any, Iterable, List, TextIO, TypeVar, Generic +from typing import Dict, Optional, Any, Iterable, List, TextIO, TypeVar, Generic, Union from abc import abstractmethod import csv from decimal import Decimal, Decimal as D @@ -53,7 +53,7 @@ def split_records(self) -> Iterable[LT]: # pragma: no cover """Return iterable object consisting of a line per transaction""" raise NotImplementedError - def parse_record(self, line: LT) -> Optional[StatementLine|InvestStatementLine]: # pragma: no cover + def parse_record(self, line: LT) -> Optional[Union[StatementLine,InvestStatementLine]]: # pragma: no cover """Parse given transaction line and return StatementLine object""" raise NotImplementedError From 651fce263a21ff8fd587391f3cf63d3b63f6f0ae Mon Sep 17 00:00:00 2001 From: Jake Cadwell Date: Sun, 4 Feb 2024 12:15:20 -0800 Subject: [PATCH 29/34] Ignore type checking due to ambiguous declaration --- src/ofxstatement/parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ofxstatement/parser.py b/src/ofxstatement/parser.py index 1685687..b28e512 100644 --- a/src/ofxstatement/parser.py +++ b/src/ofxstatement/parser.py @@ -46,7 +46,7 @@ def parse(self) -> Statement: stmt_line = self.parse_record(line) if stmt_line: stmt_line.assert_valid() - self.statement.lines.append(stmt_line) + self.statement.lines.append(stmt_line) # type: ignore return self.statement def split_records(self) -> Iterable[LT]: # pragma: no cover From 0bdfa59fce665dce470d20298d0e79a4d2efcd73 Mon Sep 17 00:00:00 2001 From: Jake Cadwell Date: Sun, 4 Feb 2024 12:48:16 -0800 Subject: [PATCH 30/34] Fix formatting via black --- src/ofxstatement/parser.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ofxstatement/parser.py b/src/ofxstatement/parser.py index b28e512..b5cf9aa 100644 --- a/src/ofxstatement/parser.py +++ b/src/ofxstatement/parser.py @@ -46,14 +46,16 @@ def parse(self) -> Statement: stmt_line = self.parse_record(line) if stmt_line: stmt_line.assert_valid() - self.statement.lines.append(stmt_line) # type: ignore + self.statement.lines.append(stmt_line) # type: ignore return self.statement def split_records(self) -> Iterable[LT]: # pragma: no cover """Return iterable object consisting of a line per transaction""" raise NotImplementedError - def parse_record(self, line: LT) -> Optional[Union[StatementLine,InvestStatementLine]]: # pragma: no cover + def parse_record( + self, line: LT + ) -> Optional[Union[StatementLine, InvestStatementLine]]: # pragma: no cover """Parse given transaction line and return StatementLine object""" raise NotImplementedError From 831f6e9df8ece5a67f75262a1d5ab8a42fd9f504 Mon Sep 17 00:00:00 2001 From: Jake Cadwell Date: Sat, 30 Mar 2024 09:13:14 -0700 Subject: [PATCH 31/34] break out parse_invest_record that returns an InvestStatementLine object --- src/ofxstatement/parser.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ofxstatement/parser.py b/src/ofxstatement/parser.py index b5cf9aa..304948b 100644 --- a/src/ofxstatement/parser.py +++ b/src/ofxstatement/parser.py @@ -53,12 +53,14 @@ def split_records(self) -> Iterable[LT]: # pragma: no cover """Return iterable object consisting of a line per transaction""" raise NotImplementedError - def parse_record( - self, line: LT - ) -> Optional[Union[StatementLine, InvestStatementLine]]: # pragma: no cover + def parse_record(self, line: LT) -> StatementLine: # pragma: no cover """Parse given transaction line and return StatementLine object""" raise NotImplementedError + def parse_invest_record (self, line: LT) -> InvestStatementLine: # pragma: no cover + """Parse given investement transaction line and return InvetStatementLine object""" + raise NotImplementedError + def parse_value(self, value: Optional[str], field: str) -> Any: tp = StatementLine.__annotations__.get(field) if value is None: From 6a6cf3daa480b6c8835e5a8f4228a9b287884d8c Mon Sep 17 00:00:00 2001 From: Jake Cadwell Date: Sun, 31 Mar 2024 11:36:00 -0700 Subject: [PATCH 32/34] fix this back to original structure --- src/ofxstatement/parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ofxstatement/parser.py b/src/ofxstatement/parser.py index 304948b..bd71cdc 100644 --- a/src/ofxstatement/parser.py +++ b/src/ofxstatement/parser.py @@ -53,7 +53,7 @@ def split_records(self) -> Iterable[LT]: # pragma: no cover """Return iterable object consisting of a line per transaction""" raise NotImplementedError - def parse_record(self, line: LT) -> StatementLine: # pragma: no cover + def parse_record(self, line: LT) -> Optional[StatementLine]: # pragma: no cover """Parse given transaction line and return StatementLine object""" raise NotImplementedError From 3b6e19cf570de78139202ae208d0a3909f92419e Mon Sep 17 00:00:00 2001 From: Jake Cadwell Date: Sun, 31 Mar 2024 11:36:42 -0700 Subject: [PATCH 33/34] add parse_invest_record line --- src/ofxstatement/parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ofxstatement/parser.py b/src/ofxstatement/parser.py index bd71cdc..387b050 100644 --- a/src/ofxstatement/parser.py +++ b/src/ofxstatement/parser.py @@ -57,7 +57,7 @@ def parse_record(self, line: LT) -> Optional[StatementLine]: # pragma: no cover """Parse given transaction line and return StatementLine object""" raise NotImplementedError - def parse_invest_record (self, line: LT) -> InvestStatementLine: # pragma: no cover + def parse_invest_record (self, line: LT) -> Optional[InvestStatementLine]: # pragma: no cover """Parse given investement transaction line and return InvetStatementLine object""" raise NotImplementedError From 9688f8fc781879c31b7cb05873fec6282407eaf0 Mon Sep 17 00:00:00 2001 From: Jake Cadwell Date: Sun, 31 Mar 2024 11:49:23 -0700 Subject: [PATCH 34/34] black run --- src/ofxstatement/parser.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ofxstatement/parser.py b/src/ofxstatement/parser.py index 387b050..1ef47d6 100644 --- a/src/ofxstatement/parser.py +++ b/src/ofxstatement/parser.py @@ -57,7 +57,9 @@ def parse_record(self, line: LT) -> Optional[StatementLine]: # pragma: no cover """Parse given transaction line and return StatementLine object""" raise NotImplementedError - def parse_invest_record (self, line: LT) -> Optional[InvestStatementLine]: # pragma: no cover + def parse_invest_record( + self, line: LT + ) -> Optional[InvestStatementLine]: # pragma: no cover """Parse given investement transaction line and return InvetStatementLine object""" raise NotImplementedError