diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 993f72c..be097d2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,17 +1,14 @@ repos: - - repo: 'https://github.com/pre-commit/pre-commit-hooks' - rev: v4.4.0 + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml - id: check-added-large-files - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.0.287 + rev: v0.8.4 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - - repo: 'https://github.com/psf/black' - rev: 23.7.0 - hooks: - - id: black + - id: ruff-format diff --git a/casparser/cli.py b/casparser/cli.py index 50cd517..04ba544 100644 --- a/casparser/cli.py +++ b/casparser/cli.py @@ -13,7 +13,7 @@ from rich.prompt import Prompt from rich.table import Table -from . import read_cas_pdf, __version__ +from . import __version__, read_cas_pdf from .analysis.gains import CapitalGainsReport from .enums import CASFileType from .exceptions import GainsError, IncompleteCASError, ParserException @@ -146,8 +146,9 @@ def print_summary(parsed_data: CASData, output_filename=None, include_zero_folio console_row = { "scheme": scheme_name, "open": scheme["open"], - "close": format_number(scheme_close) if is_summary - else f"{format_number(scheme_close)}\n/\n{calc_close}", + "close": format_number(scheme_close) + if is_summary + else f"{format_number(scheme_close)}\n/\n{calc_close}", "value": f"{formatINR(valuation['value'])}\n@\n{formatINR(valuation['nav'])}", "txns": len(scheme["transactions"]), "status": status, @@ -384,4 +385,4 @@ def cli(output, summary, password, include_all, gains, gains_112a, force_pdfmine if __name__ == "__main__": - cli(prog_name="casparser") \ No newline at end of file + cli(prog_name="casparser") diff --git a/casparser/process/cas_detailed.py b/casparser/process/cas_detailed.py index 37d2ee4..e496a97 100644 --- a/casparser/process/cas_detailed.py +++ b/casparser/process/cas_detailed.py @@ -23,14 +23,14 @@ DESCRIPTION_TAIL_RE, DETAILED_DATE_RE, DIVIDEND_RE, - FOLIO_RE, FOLIO_KV_RE, + FOLIO_RE, NAV_RE, NOMINEE_RE, OPEN_UNITS_RE, REGISTRAR_RE, - SCHEME_RE, SCHEME_KV_RE, + SCHEME_RE, TRANSACTION_RE1, TRANSACTION_RE2, TRANSACTION_RE3, diff --git a/poetry.lock b/poetry.lock index 9cb9e41..8653ba8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -26,52 +26,6 @@ files = [ astroid = ["astroid (>=2,<4)"] test = ["astroid (>=2,<4)", "pytest", "pytest-cov", "pytest-xdist"] -[[package]] -name = "black" -version = "23.12.1" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.8" -files = [ - {file = "black-23.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0aaf6041986767a5e0ce663c7a2f0e9eaf21e6ff87a5f95cbf3675bfd4c41d2"}, - {file = "black-23.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c88b3711d12905b74206227109272673edce0cb29f27e1385f33b0163c414bba"}, - {file = "black-23.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920b569dc6b3472513ba6ddea21f440d4b4c699494d2e972a1753cdc25df7b0"}, - {file = "black-23.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:3fa4be75ef2a6b96ea8d92b1587dd8cb3a35c7e3d51f0738ced0781c3aa3a5a3"}, - {file = "black-23.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8d4df77958a622f9b5a4c96edb4b8c0034f8434032ab11077ec6c56ae9f384ba"}, - {file = "black-23.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:602cfb1196dc692424c70b6507593a2b29aac0547c1be9a1d1365f0d964c353b"}, - {file = "black-23.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c4352800f14be5b4864016882cdba10755bd50805c95f728011bcb47a4afd59"}, - {file = "black-23.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:0808494f2b2df923ffc5723ed3c7b096bd76341f6213989759287611e9837d50"}, - {file = "black-23.12.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:25e57fd232a6d6ff3f4478a6fd0580838e47c93c83eaf1ccc92d4faf27112c4e"}, - {file = "black-23.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2d9e13db441c509a3763a7a3d9a49ccc1b4e974a47be4e08ade2a228876500ec"}, - {file = "black-23.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1bd9c210f8b109b1762ec9fd36592fdd528485aadb3f5849b2740ef17e674e"}, - {file = "black-23.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:ae76c22bde5cbb6bfd211ec343ded2163bba7883c7bc77f6b756a1049436fbb9"}, - {file = "black-23.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1fa88a0f74e50e4487477bc0bb900c6781dbddfdfa32691e780bf854c3b4a47f"}, - {file = "black-23.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4d6a9668e45ad99d2f8ec70d5c8c04ef4f32f648ef39048d010b0689832ec6d"}, - {file = "black-23.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b18fb2ae6c4bb63eebe5be6bd869ba2f14fd0259bda7d18a46b764d8fb86298a"}, - {file = "black-23.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:c04b6d9d20e9c13f43eee8ea87d44156b8505ca8a3c878773f68b4e4812a421e"}, - {file = "black-23.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e1b38b3135fd4c025c28c55ddfc236b05af657828a8a6abe5deec419a0b7055"}, - {file = "black-23.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f0031eaa7b921db76decd73636ef3a12c942ed367d8c3841a0739412b260a54"}, - {file = "black-23.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97e56155c6b737854e60a9ab1c598ff2533d57e7506d97af5481141671abf3ea"}, - {file = "black-23.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:dd15245c8b68fe2b6bd0f32c1556509d11bb33aec9b5d0866dd8e2ed3dba09c2"}, - {file = "black-23.12.1-py3-none-any.whl", hash = "sha256:78baad24af0f033958cad29731e27363183e140962595def56423e626f4bee3e"}, - {file = "black-23.12.1.tar.gz", hash = "sha256:4ce3ef14ebe8d9509188014d96af1c456a910d5b5cbf434a09fef7e024b3d0d5"}, -] - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -packaging = ">=22.0" -pathspec = ">=0.9.0" -platformdirs = ">=2" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] - [[package]] name = "casparser-isin" version = "2024.12.5" @@ -639,17 +593,6 @@ files = [ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] -[[package]] -name = "mypy-extensions" -version = "1.0.0" -description = "Type system extensions for programs checked with the mypy type checker." -optional = false -python-versions = ">=3.5" -files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, -] - [[package]] name = "nodeenv" version = "1.9.1" @@ -687,26 +630,15 @@ files = [ qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] testing = ["docopt", "pytest"] -[[package]] -name = "pathspec" -version = "0.12.1" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, -] - [[package]] name = "pdfminer-six" -version = "20221105" +version = "20240706" description = "PDF parser and analyzer" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "pdfminer.six-20221105-py3-none-any.whl", hash = "sha256:1eaddd712d5b2732f8ac8486824533514f8ba12a0787b3d5fe1e686cd826532d"}, - {file = "pdfminer.six-20221105.tar.gz", hash = "sha256:8448ab7b939d18b64820478ecac5394f482d7a79f5f7eaa7703c6c959c175e1d"}, + {file = "pdfminer.six-20240706-py3-none-any.whl", hash = "sha256:f4f70e74174b4b3542fcb8406a210b6e2e27cd0f0b5fd04534a8cc0d8951e38c"}, + {file = "pdfminer.six-20240706.tar.gz", hash = "sha256:c631a46d5da957a9ffe4460c5dce21e8431dabb615fee5f9f4400603a58d95a6"}, ] [package.dependencies] @@ -714,7 +646,7 @@ charset-normalizer = ">=2.0.0" cryptography = ">=36.0.0" [package.extras] -dev = ["black", "mypy (==0.931)", "nox", "pytest"] +dev = ["atheris", "black", "mypy (==0.931)", "nox", "pytest"] docs = ["sphinx", "sphinx-argparse"] image = ["Pillow"] @@ -996,13 +928,13 @@ files = [ [[package]] name = "pytest" -version = "7.4.4" +version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, - {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, ] [package.dependencies] @@ -1010,29 +942,29 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" -pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} +pluggy = ">=1.5,<2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-cov" -version = "4.1.0" +version = "6.0.0" description = "Pytest plugin for measuring coverage." optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, - {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, + {file = "pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0"}, + {file = "pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35"}, ] [package.dependencies] -coverage = {version = ">=5.2.1", extras = ["toml"]} +coverage = {version = ">=7.5", extras = ["toml"]} pytest = ">=4.6" [package.extras] -testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] [[package]] name = "python-dateutil" @@ -1364,4 +1296,4 @@ mupdf = ["PyMuPDF"] [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "76849e0d8df980f82c2fa8edc07d375edf0effb9f20e340cd39f97cc4a04a58b" +content-hash = "31ff9b5494b537ec468d551e3ae4f78674b49d56245f802fb92f5744a58b50f7" diff --git a/pyproject.toml b/pyproject.toml index f7018a4..cb4a566 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ python = "^3.10" casparser-isin = ">=2024.5.12" click = ">=7.0,<9.0" colorama = "^0.4.6" -"pdfminer.six" = "20221105" +"pdfminer.six" = "20240706" python-dateutil = "^2.8.2" rich = "^13.5.2" pydantic = "^2.3.0" @@ -32,18 +32,15 @@ mupdf = ["PyMuPDF"] fast = ["PyMuPDF"] [tool.poetry.dev-dependencies] -coverage = {version = "^7.1", extras=["toml"]} -ipython = "^8.1.0" -pytest = "^7.4.0" -pytest-cov = "^4.1.0" +coverage = {version = "^7.6", extras=["toml"]} +ipython = "^8.31.0" +pytest = "~8.3.0" +pytest-cov = "~6.0.0" pre-commit = "^4.0.0" [tool.poetry.scripts] casparser = 'casparser.cli:cli' -[tool.poetry.group.dev.dependencies] -black = "^23.3.0" - [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" @@ -69,10 +66,16 @@ omit = [ [tool.poetry-version-plugin] source = "init" -[tool.black] -line-length = 100 -target-version = ['py38'] - [tool.ruff] line-length = 100 target-version = "py38" + + +[tool.ruff.lint] +select = ["E", "F", "I"] + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" +skip-magic-trailing-comma = false +line-ending = "auto" diff --git a/tests/test_mupdf.py b/tests/test_mupdf.py index 899de0a..56c3b88 100644 --- a/tests/test_mupdf.py +++ b/tests/test_mupdf.py @@ -1,11 +1,12 @@ import re import fitz -from click.testing import CliRunner import pytest +from click.testing import CliRunner -from casparser.exceptions import CASParseError from casparser.enums import FileType +from casparser.exceptions import CASParseError + from .base import BaseTestClass diff --git a/tests/test_pdfminer.py b/tests/test_pdfminer.py index 3f211cc..6b8c3e0 100644 --- a/tests/test_pdfminer.py +++ b/tests/test_pdfminer.py @@ -1,7 +1,8 @@ -from pdfminer.layout import LTTextBoxHorizontal import pytest +from pdfminer.layout import LTTextBoxHorizontal from casparser.exceptions import CASParseError + from .base import BaseTestClass diff --git a/tests/test_process.py b/tests/test_process.py index 84e7f88..e6af163 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -2,13 +2,18 @@ import pytest +from casparser.enums import TransactionType from casparser.exceptions import CASParseError, HeaderParseError from casparser.process import process_cas_text -from casparser.process.cas_detailed import parse_header, get_transaction_type, get_parsed_scheme_name -from casparser.process.cas_detailed import ParsedTransaction, parse_transaction +from casparser.process.cas_detailed import ( + ParsedTransaction, + get_parsed_scheme_name, + get_transaction_type, + parse_header, + parse_transaction, +) from casparser.process.cas_summary import parse_header as parse_summary_header from casparser.process.utils import isin_search -from casparser.enums import TransactionType class TestProcessClass: @@ -95,21 +100,35 @@ def test_dividend_transactions(self): ) def test_parsed_scheme_name(self): - assert get_parsed_scheme_name( - "Axis Long Term Equity Fund - Direct Growth") == "Axis Long Term Equity Fund - Direct Growth" - assert get_parsed_scheme_name( - "Axis Bluechip Fund - Regular Growth ") == "Axis Bluechip Fund - Regular Growth" - assert get_parsed_scheme_name( - "HSBC Corporate Bond Fund - Regular Growth (Formerly known as L&T Triple Ace Bond Fund - Growth)") == \ - "HSBC Corporate Bond Fund - Regular Growth" - assert get_parsed_scheme_name( - "Bandhan ELSS Tax saver Fund-Growth-(Regular Plan)" - "(erstwhile Bandhan Tax Advantage ELSS Fund-Growth-Regular Plan)") == \ - "Bandhan ELSS Tax saver Fund-Growth-(Regular Plan)" - assert get_parsed_scheme_name( - "Bandhan Liquid Fund-Growth-(Regular Plan) (erstwhile IDFC Cash Fund-Growth-Regular Plan) (Non-Demat) ") == \ - "Bandhan Liquid Fund-Growth-(Regular Plan)" - + assert ( + get_parsed_scheme_name("Axis Long Term Equity Fund - Direct Growth") + == "Axis Long Term Equity Fund - Direct Growth" + ) + assert ( + get_parsed_scheme_name("Axis Bluechip Fund - Regular Growth ") + == "Axis Bluechip Fund - Regular Growth" + ) + assert ( + get_parsed_scheme_name( + "HSBC Corporate Bond Fund - Regular Growth " + "(Formerly known as L&T Triple Ace Bond Fund - Growth)" + ) + == "HSBC Corporate Bond Fund - Regular Growth" + ) + assert ( + get_parsed_scheme_name( + "Bandhan ELSS Tax saver Fund-Growth-(Regular Plan)" + "(erstwhile Bandhan Tax Advantage ELSS Fund-Growth-Regular Plan)" + ) + == "Bandhan ELSS Tax saver Fund-Growth-(Regular Plan)" + ) + assert ( + get_parsed_scheme_name( + "Bandhan Liquid Fund-Growth-(Regular Plan) " + "(erstwhile IDFC Cash Fund-Growth-Regular Plan) (Non-Demat) " + ) + == "Bandhan Liquid Fund-Growth-(Regular Plan)" + ) def test_isin_search(self): isin, amfi, scheme_type = isin_search(