Compare commits
No commits in common. "886ce2e9cf1e1a001cefd434f7b9906405da7f0c" and "685bc8ad198e3892a3269db2e80a3f48a645a8fd" have entirely different histories.
886ce2e9cf
...
685bc8ad19
29
.gitignore
vendored
29
.gitignore
vendored
|
@ -83,28 +83,6 @@ target/
|
|||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
|
@ -153,10 +131,3 @@ dmypy.json
|
|||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# PyCharm
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
|
||||
|
|
27
.pre-commit-config.yaml
Normal file
27
.pre-commit-config.yaml
Normal file
|
@ -0,0 +1,27 @@
|
|||
repos:
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: autoflake
|
||||
name: Remove unused variables and imports
|
||||
entry: bash -c 'autoflake "$@"; git add -u' --
|
||||
language: python
|
||||
args: [
|
||||
"--in-place",
|
||||
"--remove-all-unused-imports",
|
||||
"--remove-unused-variables",
|
||||
"--expand-star-imports",
|
||||
"--ignore-init-module-imports",
|
||||
]
|
||||
files: \.py$
|
||||
- id: isort
|
||||
name: Sorting import statements
|
||||
entry: bash -c 'isort "$@"; git add -u' --
|
||||
language: python
|
||||
args: ["--filter-files"]
|
||||
files: \.py$
|
||||
- id: black
|
||||
name: Black Python code formatting
|
||||
entry: bash -c 'black "$@"; git add -u' --
|
||||
language: python
|
||||
types: [python]
|
||||
args: ["--line-length=120"]
|
1
Homebank.py
Symbolic link
1
Homebank.py
Symbolic link
|
@ -0,0 +1 @@
|
|||
src/homebank/Homebank.py
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) <year> <copyright holders>
|
||||
Copyright (c) 2022 Jonny007-MKD
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
|
20
Makefile
Normal file
20
Makefile
Normal file
|
@ -0,0 +1,20 @@
|
|||
all: .git/hooks/pre-commit build/cache/virtualenvs/ code_checks test
|
||||
|
||||
build/cache/virtualenvs/: pyproject.toml
|
||||
poetry install
|
||||
|
||||
code_checks: $(shell find src)
|
||||
poetry run python -m mypy src
|
||||
|
||||
test: code_checks $(shell find test)
|
||||
poetry run python -m unittest test
|
||||
|
||||
.git/hooks/pre-commit: build/cache/virtualenvs/
|
||||
poetry run pre-commit install
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf build
|
||||
rm -rf .mypy_cache
|
||||
rm -rf dist
|
||||
|
452
poetry.lock
generated
Normal file
452
poetry.lock
generated
Normal file
|
@ -0,0 +1,452 @@
|
|||
[[package]]
|
||||
name = "cfgv"
|
||||
version = "3.3.1"
|
||||
description = "Validate configuration and produce human readable error messages."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6.1"
|
||||
|
||||
[[package]]
|
||||
name = "distlib"
|
||||
version = "0.3.6"
|
||||
description = "Distribution utilities"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "filelock"
|
||||
version = "3.8.0"
|
||||
description = "A platform independent file lock."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo (>=2022.6.21)", "sphinx (>=5.1.1)", "sphinx-autodoc-typehints (>=1.19.1)"]
|
||||
testing = ["covdefaults (>=2.2)", "coverage (>=6.4.2)", "pytest (>=7.1.2)", "pytest-cov (>=3)", "pytest-timeout (>=2.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "identify"
|
||||
version = "2.5.8"
|
||||
description = "File identification library for Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.extras]
|
||||
license = ["ukkonen"]
|
||||
|
||||
[[package]]
|
||||
name = "importlib-metadata"
|
||||
version = "5.0.0"
|
||||
description = "Read metadata from Python packages"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""}
|
||||
zipp = ">=0.5"
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"]
|
||||
perf = ["ipython"]
|
||||
testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "lxml"
|
||||
version = "4.9.1"
|
||||
description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*"
|
||||
|
||||
[package.extras]
|
||||
cssselect = ["cssselect (>=0.7)"]
|
||||
html5 = ["html5lib"]
|
||||
htmlsoup = ["BeautifulSoup4"]
|
||||
source = ["Cython (>=0.29.7)"]
|
||||
|
||||
[[package]]
|
||||
name = "mypy"
|
||||
version = "0.982"
|
||||
description = "Optional static typing for Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
mypy-extensions = ">=0.4.3"
|
||||
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
||||
typed-ast = {version = ">=1.4.0,<2", markers = "python_version < \"3.8\""}
|
||||
typing-extensions = ">=3.10"
|
||||
|
||||
[package.extras]
|
||||
dmypy = ["psutil (>=4.0)"]
|
||||
python2 = ["typed-ast (>=1.4.0,<2)"]
|
||||
reports = ["lxml"]
|
||||
|
||||
[[package]]
|
||||
name = "mypy-extensions"
|
||||
version = "0.4.3"
|
||||
description = "Experimental type system extensions for programs checked with the mypy typechecker."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "nodeenv"
|
||||
version = "1.7.0"
|
||||
description = "Node.js virtual environment builder"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*"
|
||||
|
||||
[package.dependencies]
|
||||
setuptools = "*"
|
||||
|
||||
[[package]]
|
||||
name = "platformdirs"
|
||||
version = "2.5.2"
|
||||
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx (>=4)", "sphinx-autodoc-typehints (>=1.12)"]
|
||||
test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"]
|
||||
|
||||
[[package]]
|
||||
name = "pre-commit"
|
||||
version = "2.20.0"
|
||||
description = "A framework for managing and maintaining multi-language pre-commit hooks."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
cfgv = ">=2.0.0"
|
||||
identify = ">=1.0.0"
|
||||
importlib-metadata = {version = "*", markers = "python_version < \"3.8\""}
|
||||
nodeenv = ">=0.11.1"
|
||||
pyyaml = ">=5.1"
|
||||
toml = "*"
|
||||
virtualenv = ">=20.0.8"
|
||||
|
||||
[[package]]
|
||||
name = "pyyaml"
|
||||
version = "6.0"
|
||||
description = "YAML parser and emitter for Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[[package]]
|
||||
name = "setuptools"
|
||||
version = "65.5.1"
|
||||
description = "Easily download, build, install, upgrade, and uninstall Python packages"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
|
||||
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
|
||||
testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.10.2"
|
||||
description = "Python Library for Tom's Obvious, Minimal Language"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
|
||||
[[package]]
|
||||
name = "tomli"
|
||||
version = "2.0.1"
|
||||
description = "A lil' TOML parser"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "typed-ast"
|
||||
version = "1.5.4"
|
||||
description = "a fork of Python 2 and 3 ast modules with type comment support"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.4.0"
|
||||
description = "Backported and Experimental Type Hints for Python 3.7+"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "virtualenv"
|
||||
version = "20.16.6"
|
||||
description = "Virtual Python Environment builder"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
distlib = ">=0.3.6,<1"
|
||||
filelock = ">=3.4.1,<4"
|
||||
importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.8\""}
|
||||
platformdirs = ">=2.4,<3"
|
||||
|
||||
[package.extras]
|
||||
docs = ["proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-argparse (>=0.3.2)", "sphinx-rtd-theme (>=1)", "towncrier (>=22.8)"]
|
||||
testing = ["coverage (>=6.2)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=21.3)", "pytest (>=7.0.1)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.6.1)", "pytest-randomly (>=3.10.3)", "pytest-timeout (>=2.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "zipp"
|
||||
version = "3.10.0"
|
||||
description = "Backport of pathlib-compatible object wrapper for zip files"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"]
|
||||
testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"]
|
||||
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = ">=3.7"
|
||||
content-hash = "74b2df2be6c0e9947b034421a946c689eeecad500122eb605cd3109a4c1613df"
|
||||
|
||||
[metadata.files]
|
||||
cfgv = [
|
||||
{file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"},
|
||||
{file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"},
|
||||
]
|
||||
distlib = [
|
||||
{file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"},
|
||||
{file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"},
|
||||
]
|
||||
filelock = [
|
||||
{file = "filelock-3.8.0-py3-none-any.whl", hash = "sha256:617eb4e5eedc82fc5f47b6d61e4d11cb837c56cb4544e39081099fa17ad109d4"},
|
||||
{file = "filelock-3.8.0.tar.gz", hash = "sha256:55447caa666f2198c5b6b13a26d2084d26fa5b115c00d065664b2124680c4edc"},
|
||||
]
|
||||
identify = [
|
||||
{file = "identify-2.5.8-py2.py3-none-any.whl", hash = "sha256:48b7925fe122720088aeb7a6c34f17b27e706b72c61070f27fe3789094233440"},
|
||||
{file = "identify-2.5.8.tar.gz", hash = "sha256:7a214a10313b9489a0d61467db2856ae8d0b8306fc923e03a9effa53d8aedc58"},
|
||||
]
|
||||
importlib-metadata = [
|
||||
{file = "importlib_metadata-5.0.0-py3-none-any.whl", hash = "sha256:ddb0e35065e8938f867ed4928d0ae5bf2a53b7773871bfe6bcc7e4fcdc7dea43"},
|
||||
{file = "importlib_metadata-5.0.0.tar.gz", hash = "sha256:da31db32b304314d044d3c12c79bd59e307889b287ad12ff387b3500835fc2ab"},
|
||||
]
|
||||
lxml = [
|
||||
{file = "lxml-4.9.1-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:98cafc618614d72b02185ac583c6f7796202062c41d2eeecdf07820bad3295ed"},
|
||||
{file = "lxml-4.9.1-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c62e8dd9754b7debda0c5ba59d34509c4688f853588d75b53c3791983faa96fc"},
|
||||
{file = "lxml-4.9.1-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:21fb3d24ab430fc538a96e9fbb9b150029914805d551deeac7d7822f64631dfc"},
|
||||
{file = "lxml-4.9.1-cp27-cp27m-win32.whl", hash = "sha256:86e92728ef3fc842c50a5cb1d5ba2bc66db7da08a7af53fb3da79e202d1b2cd3"},
|
||||
{file = "lxml-4.9.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4cfbe42c686f33944e12f45a27d25a492cc0e43e1dc1da5d6a87cbcaf2e95627"},
|
||||
{file = "lxml-4.9.1-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dad7b164905d3e534883281c050180afcf1e230c3d4a54e8038aa5cfcf312b84"},
|
||||
{file = "lxml-4.9.1-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a614e4afed58c14254e67862456d212c4dcceebab2eaa44d627c2ca04bf86837"},
|
||||
{file = "lxml-4.9.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f9ced82717c7ec65a67667bb05865ffe38af0e835cdd78728f1209c8fffe0cad"},
|
||||
{file = "lxml-4.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:d9fc0bf3ff86c17348dfc5d322f627d78273eba545db865c3cd14b3f19e57fa5"},
|
||||
{file = "lxml-4.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e5f66bdf0976ec667fc4594d2812a00b07ed14d1b44259d19a41ae3fff99f2b8"},
|
||||
{file = "lxml-4.9.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:fe17d10b97fdf58155f858606bddb4e037b805a60ae023c009f760d8361a4eb8"},
|
||||
{file = "lxml-4.9.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8caf4d16b31961e964c62194ea3e26a0e9561cdf72eecb1781458b67ec83423d"},
|
||||
{file = "lxml-4.9.1-cp310-cp310-win32.whl", hash = "sha256:4780677767dd52b99f0af1f123bc2c22873d30b474aa0e2fc3fe5e02217687c7"},
|
||||
{file = "lxml-4.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:b122a188cd292c4d2fcd78d04f863b789ef43aa129b233d7c9004de08693728b"},
|
||||
{file = "lxml-4.9.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:be9eb06489bc975c38706902cbc6888f39e946b81383abc2838d186f0e8b6a9d"},
|
||||
{file = "lxml-4.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:f1be258c4d3dc609e654a1dc59d37b17d7fef05df912c01fc2e15eb43a9735f3"},
|
||||
{file = "lxml-4.9.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:927a9dd016d6033bc12e0bf5dee1dde140235fc8d0d51099353c76081c03dc29"},
|
||||
{file = "lxml-4.9.1-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9232b09f5efee6a495a99ae6824881940d6447debe272ea400c02e3b68aad85d"},
|
||||
{file = "lxml-4.9.1-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:04da965dfebb5dac2619cb90fcf93efdb35b3c6994fea58a157a834f2f94b318"},
|
||||
{file = "lxml-4.9.1-cp35-cp35m-win32.whl", hash = "sha256:4d5bae0a37af799207140652a700f21a85946f107a199bcb06720b13a4f1f0b7"},
|
||||
{file = "lxml-4.9.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4878e667ebabe9b65e785ac8da4d48886fe81193a84bbe49f12acff8f7a383a4"},
|
||||
{file = "lxml-4.9.1-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:1355755b62c28950f9ce123c7a41460ed9743c699905cbe664a5bcc5c9c7c7fb"},
|
||||
{file = "lxml-4.9.1-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:bcaa1c495ce623966d9fc8a187da80082334236a2a1c7e141763ffaf7a405067"},
|
||||
{file = "lxml-4.9.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6eafc048ea3f1b3c136c71a86db393be36b5b3d9c87b1c25204e7d397cee9536"},
|
||||
{file = "lxml-4.9.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:13c90064b224e10c14dcdf8086688d3f0e612db53766e7478d7754703295c7c8"},
|
||||
{file = "lxml-4.9.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206a51077773c6c5d2ce1991327cda719063a47adc02bd703c56a662cdb6c58b"},
|
||||
{file = "lxml-4.9.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e8f0c9d65da595cfe91713bc1222af9ecabd37971762cb830dea2fc3b3bb2acf"},
|
||||
{file = "lxml-4.9.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8f0a4d179c9a941eb80c3a63cdb495e539e064f8054230844dcf2fcb812b71d3"},
|
||||
{file = "lxml-4.9.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:830c88747dce8a3e7525defa68afd742b4580df6aa2fdd6f0855481e3994d391"},
|
||||
{file = "lxml-4.9.1-cp36-cp36m-win32.whl", hash = "sha256:1e1cf47774373777936c5aabad489fef7b1c087dcd1f426b621fda9dcc12994e"},
|
||||
{file = "lxml-4.9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:5974895115737a74a00b321e339b9c3f45c20275d226398ae79ac008d908bff7"},
|
||||
{file = "lxml-4.9.1-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:1423631e3d51008871299525b541413c9b6c6423593e89f9c4cfbe8460afc0a2"},
|
||||
{file = "lxml-4.9.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:2aaf6a0a6465d39b5ca69688fce82d20088c1838534982996ec46633dc7ad6cc"},
|
||||
{file = "lxml-4.9.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:9f36de4cd0c262dd9927886cc2305aa3f2210db437aa4fed3fb4940b8bf4592c"},
|
||||
{file = "lxml-4.9.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:ae06c1e4bc60ee076292e582a7512f304abdf6c70db59b56745cca1684f875a4"},
|
||||
{file = "lxml-4.9.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:57e4d637258703d14171b54203fd6822fda218c6c2658a7d30816b10995f29f3"},
|
||||
{file = "lxml-4.9.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6d279033bf614953c3fc4a0aa9ac33a21e8044ca72d4fa8b9273fe75359d5cca"},
|
||||
{file = "lxml-4.9.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a60f90bba4c37962cbf210f0188ecca87daafdf60271f4c6948606e4dabf8785"},
|
||||
{file = "lxml-4.9.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6ca2264f341dd81e41f3fffecec6e446aa2121e0b8d026fb5130e02de1402785"},
|
||||
{file = "lxml-4.9.1-cp37-cp37m-win32.whl", hash = "sha256:27e590352c76156f50f538dbcebd1925317a0f70540f7dc8c97d2931c595783a"},
|
||||
{file = "lxml-4.9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:eea5d6443b093e1545ad0210e6cf27f920482bfcf5c77cdc8596aec73523bb7e"},
|
||||
{file = "lxml-4.9.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f05251bbc2145349b8d0b77c0d4e5f3b228418807b1ee27cefb11f69ed3d233b"},
|
||||
{file = "lxml-4.9.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:487c8e61d7acc50b8be82bda8c8d21d20e133c3cbf41bd8ad7eb1aaeb3f07c97"},
|
||||
{file = "lxml-4.9.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8d1a92d8e90b286d491e5626af53afef2ba04da33e82e30744795c71880eaa21"},
|
||||
{file = "lxml-4.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:b570da8cd0012f4af9fa76a5635cd31f707473e65a5a335b186069d5c7121ff2"},
|
||||
{file = "lxml-4.9.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ef87fca280fb15342726bd5f980f6faf8b84a5287fcc2d4962ea8af88b35130"},
|
||||
{file = "lxml-4.9.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:93e414e3206779ef41e5ff2448067213febf260ba747fc65389a3ddaa3fb8715"},
|
||||
{file = "lxml-4.9.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6653071f4f9bac46fbc30f3c7838b0e9063ee335908c5d61fb7a4a86c8fd2036"},
|
||||
{file = "lxml-4.9.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:32a73c53783becdb7eaf75a2a1525ea8e49379fb7248c3eeefb9412123536387"},
|
||||
{file = "lxml-4.9.1-cp38-cp38-win32.whl", hash = "sha256:1a7c59c6ffd6ef5db362b798f350e24ab2cfa5700d53ac6681918f314a4d3b94"},
|
||||
{file = "lxml-4.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:1436cf0063bba7888e43f1ba8d58824f085410ea2025befe81150aceb123e345"},
|
||||
{file = "lxml-4.9.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:4beea0f31491bc086991b97517b9683e5cfb369205dac0148ef685ac12a20a67"},
|
||||
{file = "lxml-4.9.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:41fb58868b816c202e8881fd0f179a4644ce6e7cbbb248ef0283a34b73ec73bb"},
|
||||
{file = "lxml-4.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:bd34f6d1810d9354dc7e35158aa6cc33456be7706df4420819af6ed966e85448"},
|
||||
{file = "lxml-4.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:edffbe3c510d8f4bf8640e02ca019e48a9b72357318383ca60e3330c23aaffc7"},
|
||||
{file = "lxml-4.9.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6d949f53ad4fc7cf02c44d6678e7ff05ec5f5552b235b9e136bd52e9bf730b91"},
|
||||
{file = "lxml-4.9.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:079b68f197c796e42aa80b1f739f058dcee796dc725cc9a1be0cdb08fc45b000"},
|
||||
{file = "lxml-4.9.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9c3a88d20e4fe4a2a4a84bf439a5ac9c9aba400b85244c63a1ab7088f85d9d25"},
|
||||
{file = "lxml-4.9.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4e285b5f2bf321fc0857b491b5028c5f276ec0c873b985d58d7748ece1d770dd"},
|
||||
{file = "lxml-4.9.1-cp39-cp39-win32.whl", hash = "sha256:ef72013e20dd5ba86a8ae1aed7f56f31d3374189aa8b433e7b12ad182c0d2dfb"},
|
||||
{file = "lxml-4.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:10d2017f9150248563bb579cd0d07c61c58da85c922b780060dcc9a3aa9f432d"},
|
||||
{file = "lxml-4.9.1-pp37-pypy37_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0538747a9d7827ce3e16a8fdd201a99e661c7dee3c96c885d8ecba3c35d1032c"},
|
||||
{file = "lxml-4.9.1-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:0645e934e940107e2fdbe7c5b6fb8ec6232444260752598bc4d09511bd056c0b"},
|
||||
{file = "lxml-4.9.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:6daa662aba22ef3258934105be2dd9afa5bb45748f4f702a3b39a5bf53a1f4dc"},
|
||||
{file = "lxml-4.9.1-pp38-pypy38_pp73-macosx_10_15_x86_64.whl", hash = "sha256:603a464c2e67d8a546ddaa206d98e3246e5db05594b97db844c2f0a1af37cf5b"},
|
||||
{file = "lxml-4.9.1-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:c4b2e0559b68455c085fb0f6178e9752c4be3bba104d6e881eb5573b399d1eb2"},
|
||||
{file = "lxml-4.9.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0f3f0059891d3254c7b5fb935330d6db38d6519ecd238ca4fce93c234b4a0f73"},
|
||||
{file = "lxml-4.9.1-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:c852b1530083a620cb0de5f3cd6826f19862bafeaf77586f1aef326e49d95f0c"},
|
||||
{file = "lxml-4.9.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:287605bede6bd36e930577c5925fcea17cb30453d96a7b4c63c14a257118dbb9"},
|
||||
{file = "lxml-4.9.1.tar.gz", hash = "sha256:fe749b052bb7233fe5d072fcb549221a8cb1a16725c47c37e42b0b9cb3ff2c3f"},
|
||||
]
|
||||
mypy = [
|
||||
{file = "mypy-0.982-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5085e6f442003fa915aeb0a46d4da58128da69325d8213b4b35cc7054090aed5"},
|
||||
{file = "mypy-0.982-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:41fd1cf9bc0e1c19b9af13a6580ccb66c381a5ee2cf63ee5ebab747a4badeba3"},
|
||||
{file = "mypy-0.982-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f793e3dd95e166b66d50e7b63e69e58e88643d80a3dcc3bcd81368e0478b089c"},
|
||||
{file = "mypy-0.982-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86ebe67adf4d021b28c3f547da6aa2cce660b57f0432617af2cca932d4d378a6"},
|
||||
{file = "mypy-0.982-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:175f292f649a3af7082fe36620369ffc4661a71005aa9f8297ea473df5772046"},
|
||||
{file = "mypy-0.982-cp310-cp310-win_amd64.whl", hash = "sha256:8ee8c2472e96beb1045e9081de8e92f295b89ac10c4109afdf3a23ad6e644f3e"},
|
||||
{file = "mypy-0.982-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58f27ebafe726a8e5ccb58d896451dd9a662a511a3188ff6a8a6a919142ecc20"},
|
||||
{file = "mypy-0.982-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6af646bd46f10d53834a8e8983e130e47d8ab2d4b7a97363e35b24e1d588947"},
|
||||
{file = "mypy-0.982-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7aeaa763c7ab86d5b66ff27f68493d672e44c8099af636d433a7f3fa5596d40"},
|
||||
{file = "mypy-0.982-cp37-cp37m-win_amd64.whl", hash = "sha256:724d36be56444f569c20a629d1d4ee0cb0ad666078d59bb84f8f887952511ca1"},
|
||||
{file = "mypy-0.982-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:14d53cdd4cf93765aa747a7399f0961a365bcddf7855d9cef6306fa41de01c24"},
|
||||
{file = "mypy-0.982-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:26ae64555d480ad4b32a267d10cab7aec92ff44de35a7cd95b2b7cb8e64ebe3e"},
|
||||
{file = "mypy-0.982-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6389af3e204975d6658de4fb8ac16f58c14e1bacc6142fee86d1b5b26aa52bda"},
|
||||
{file = "mypy-0.982-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b35ce03a289480d6544aac85fa3674f493f323d80ea7226410ed065cd46f206"},
|
||||
{file = "mypy-0.982-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c6e564f035d25c99fd2b863e13049744d96bd1947e3d3d2f16f5828864506763"},
|
||||
{file = "mypy-0.982-cp38-cp38-win_amd64.whl", hash = "sha256:cebca7fd333f90b61b3ef7f217ff75ce2e287482206ef4a8b18f32b49927b1a2"},
|
||||
{file = "mypy-0.982-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a705a93670c8b74769496280d2fe6cd59961506c64f329bb179970ff1d24f9f8"},
|
||||
{file = "mypy-0.982-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:75838c649290d83a2b83a88288c1eb60fe7a05b36d46cbea9d22efc790002146"},
|
||||
{file = "mypy-0.982-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:91781eff1f3f2607519c8b0e8518aad8498af1419e8442d5d0afb108059881fc"},
|
||||
{file = "mypy-0.982-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaa97b9ddd1dd9901a22a879491dbb951b5dec75c3b90032e2baa7336777363b"},
|
||||
{file = "mypy-0.982-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a692a8e7d07abe5f4b2dd32d731812a0175626a90a223d4b58f10f458747dd8a"},
|
||||
{file = "mypy-0.982-cp39-cp39-win_amd64.whl", hash = "sha256:eb7a068e503be3543c4bd329c994103874fa543c1727ba5288393c21d912d795"},
|
||||
{file = "mypy-0.982-py3-none-any.whl", hash = "sha256:1021c241e8b6e1ca5a47e4d52601274ac078a89845cfde66c6d5f769819ffa1d"},
|
||||
{file = "mypy-0.982.tar.gz", hash = "sha256:85f7a343542dc8b1ed0a888cdd34dca56462654ef23aa673907305b260b3d746"},
|
||||
]
|
||||
mypy-extensions = [
|
||||
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
|
||||
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
|
||||
]
|
||||
nodeenv = [
|
||||
{file = "nodeenv-1.7.0-py2.py3-none-any.whl", hash = "sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e"},
|
||||
{file = "nodeenv-1.7.0.tar.gz", hash = "sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b"},
|
||||
]
|
||||
platformdirs = [
|
||||
{file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"},
|
||||
{file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"},
|
||||
]
|
||||
pre-commit = [
|
||||
{file = "pre_commit-2.20.0-py2.py3-none-any.whl", hash = "sha256:51a5ba7c480ae8072ecdb6933df22d2f812dc897d5fe848778116129a681aac7"},
|
||||
{file = "pre_commit-2.20.0.tar.gz", hash = "sha256:a978dac7bc9ec0bcee55c18a277d553b0f419d259dadb4b9418ff2d00eb43959"},
|
||||
]
|
||||
pyyaml = [
|
||||
{file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"},
|
||||
{file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"},
|
||||
{file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"},
|
||||
{file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"},
|
||||
{file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"},
|
||||
{file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"},
|
||||
{file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"},
|
||||
{file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"},
|
||||
{file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"},
|
||||
{file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"},
|
||||
{file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"},
|
||||
{file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"},
|
||||
{file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"},
|
||||
{file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"},
|
||||
{file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"},
|
||||
{file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"},
|
||||
{file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"},
|
||||
{file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"},
|
||||
{file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"},
|
||||
{file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"},
|
||||
{file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"},
|
||||
{file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"},
|
||||
{file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"},
|
||||
{file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"},
|
||||
{file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"},
|
||||
{file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"},
|
||||
{file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"},
|
||||
{file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"},
|
||||
{file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"},
|
||||
{file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"},
|
||||
{file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"},
|
||||
{file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"},
|
||||
{file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"},
|
||||
]
|
||||
setuptools = [
|
||||
{file = "setuptools-65.5.1-py3-none-any.whl", hash = "sha256:d0b9a8433464d5800cbe05094acf5c6d52a91bfac9b52bcfc4d41382be5d5d31"},
|
||||
{file = "setuptools-65.5.1.tar.gz", hash = "sha256:e197a19aa8ec9722928f2206f8de752def0e4c9fc6953527360d1c36d94ddb2f"},
|
||||
]
|
||||
toml = [
|
||||
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
|
||||
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
|
||||
]
|
||||
tomli = [
|
||||
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
|
||||
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
|
||||
]
|
||||
typed-ast = [
|
||||
{file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"},
|
||||
{file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"},
|
||||
{file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"},
|
||||
{file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"},
|
||||
{file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"},
|
||||
{file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"},
|
||||
{file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"},
|
||||
{file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"},
|
||||
{file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"},
|
||||
{file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"},
|
||||
{file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"},
|
||||
{file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"},
|
||||
{file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"},
|
||||
{file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"},
|
||||
{file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"},
|
||||
{file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"},
|
||||
{file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"},
|
||||
{file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"},
|
||||
{file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"},
|
||||
{file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"},
|
||||
{file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"},
|
||||
{file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"},
|
||||
{file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"},
|
||||
{file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"},
|
||||
]
|
||||
typing-extensions = [
|
||||
{file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"},
|
||||
{file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"},
|
||||
]
|
||||
virtualenv = [
|
||||
{file = "virtualenv-20.16.6-py3-none-any.whl", hash = "sha256:186ca84254abcbde98180fd17092f9628c5fe742273c02724972a1d8a2035108"},
|
||||
{file = "virtualenv-20.16.6.tar.gz", hash = "sha256:530b850b523c6449406dfba859d6345e48ef19b8439606c5d74d7d3c9e14d76e"},
|
||||
]
|
||||
zipp = [
|
||||
{file = "zipp-3.10.0-py3-none-any.whl", hash = "sha256:4fcb6f278987a6605757302a6e40e896257570d11c51628968ccb2a47e80c6c1"},
|
||||
{file = "zipp-3.10.0.tar.gz", hash = "sha256:7a7262fd930bd3e36c50b9a64897aec3fafff3dfdeec9623ae22b40e93f99bb8"},
|
||||
]
|
4
poetry.toml
Normal file
4
poetry.toml
Normal file
|
@ -0,0 +1,4 @@
|
|||
cache-dir = "build/cache"
|
||||
|
||||
[virtualenvs]
|
||||
path = "{cache-dir}/virtualenvs"
|
35
pyproject.toml
Normal file
35
pyproject.toml
Normal file
|
@ -0,0 +1,35 @@
|
|||
[tool.poetry]
|
||||
name = "homebank"
|
||||
version = "0.0.1"
|
||||
description = "Read Homebank XML files"
|
||||
license = "MIT"
|
||||
authors = [
|
||||
"Jonny007-MKD <me@jonny007-mkd.de>"
|
||||
]
|
||||
readme = "README.md"
|
||||
repository = "https://git.nordlichter-brv.de/Jonny007-MKD/homebank"
|
||||
keywords = [ "homebank", "xhb" ]
|
||||
classifiers = [
|
||||
"Development Status :: 3 - Alpha",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Programming Language :: Python :: 3"
|
||||
]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.7"
|
||||
lxml = "^4.6"
|
||||
|
||||
[tool.poetry.group.test.dependencies]
|
||||
mypy = "*"
|
||||
pre-commit = "^2.20.0"
|
||||
|
||||
[tool.mypy]
|
||||
warn_return_any = true
|
||||
warn_unused_configs = true
|
||||
ignore_missing_imports = true
|
||||
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
161
src/homebank/Homebank.py
Normal file
161
src/homebank/Homebank.py
Normal file
|
@ -0,0 +1,161 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
from dataclasses import dataclass
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
from lxml import etree
|
||||
|
||||
|
||||
# XML functions
|
||||
def get_attribute(node: etree.Element, name: str) -> str:
|
||||
if not name in node.attrib:
|
||||
raise KeyError(f"Node '{node.tag}' in line {node.sourceline} is missing attribute '{name}'")
|
||||
|
||||
return node.attrib[name]
|
||||
|
||||
def get_attribute_optional(node: etree.Element, name: str) -> Optional[str]:
|
||||
return node.attrib.get(name, None)
|
||||
|
||||
def get_attribute_optional_int(node: etree.Element, name: str) -> Optional[int]:
|
||||
if not name in node.attrib: return None
|
||||
val = node.attrib[name]
|
||||
try:
|
||||
return int(val)
|
||||
except ValueError as ex:
|
||||
raise type(ex)(f"Could not convert attribute '{name}' of node '{node.tag}' in line {node.sourceline} to integer") from ex
|
||||
|
||||
def get_attribute_int(node: etree.Element, name: str) -> int:
|
||||
val = get_attribute_optional_int(node, name)
|
||||
if val is None:
|
||||
raise KeyError(f"Node '{node.tag}' in line {node.sourceline} is missing attribute '{name}'")
|
||||
return val
|
||||
|
||||
def get_attribute_optional_float(node: etree.Element, name: str) -> Optional[float]:
|
||||
if not name in node.attrib: return None
|
||||
val = node.attrib[name]
|
||||
try:
|
||||
return float(val)
|
||||
except ValueError as ex:
|
||||
raise type(ex)(f"Could not convert attribute '{name}' of node '{node.tag}' in line {node.sourceline} to float") from ex
|
||||
|
||||
def get_attribute_float(node: etree.Element, name: str) -> float:
|
||||
val = get_attribute_optional_float(node, name)
|
||||
if val is None:
|
||||
raise KeyError(f"Node '{node.tag}' in line {node.sourceline} is missing attribute '{name}'")
|
||||
return val
|
||||
|
||||
|
||||
# Homebank Data classes
|
||||
|
||||
@dataclass
|
||||
class Payee:
|
||||
name: str
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"Payee(\"{self.name}\")"
|
||||
|
||||
@staticmethod
|
||||
def _from_node(node: etree.Element) -> Tuple[int, "Payee"]:
|
||||
key = get_attribute_int(node, "key")
|
||||
name = get_attribute(node, "name")
|
||||
return key, Payee(name)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Account:
|
||||
name: str
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"Account(\"{self.name}\")"
|
||||
|
||||
@staticmethod
|
||||
def _from_node(node: etree.Element) -> Tuple[int, "Account"]:
|
||||
key = get_attribute_int(node, "key")
|
||||
name = get_attribute(node, "name")
|
||||
return key, Account(name)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Category:
|
||||
name: str
|
||||
parent: Optional[Category] = None
|
||||
|
||||
def __repr__(self) -> str:
|
||||
if self.parent is not None:
|
||||
return f"Category(\"{self.name}\", {repr(self.parent)})"
|
||||
else:
|
||||
return f"Category(\"{self.name}\", None)"
|
||||
|
||||
@staticmethod
|
||||
def _from_node(node: etree.Element, categories: Dict[int, "Category"]) -> Tuple[int, "Category"]:
|
||||
key: int = get_attribute_int(node, "key")
|
||||
name: str = get_attribute(node, "name")
|
||||
parent: Optional[int] = get_attribute_optional_int(node, "parent")
|
||||
parent_class: Optional["Category"] = None
|
||||
if parent is not None:
|
||||
if parent not in categories:
|
||||
raise KeyError(f"Parent category {parent} for category '{name}' not found")
|
||||
parent_class = categories[parent]
|
||||
return key, Category(name, parent_class)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Operation:
|
||||
date: datetime.date
|
||||
amount: float
|
||||
account: Account
|
||||
dst_account: Optional[Account]
|
||||
payee: Optional[Payee]
|
||||
category: Optional[Category]
|
||||
wording: Optional[str]
|
||||
|
||||
@staticmethod
|
||||
def _from_node(node: etree.Element, accounts: Dict[int, Account], payees: Dict[int, Payee], categories: Dict[int, Category]) -> "Operation":
|
||||
date_i = get_attribute_int(node, "date")
|
||||
date = datetime.date(1,1,1) + datetime.timedelta(days=date_i-1)
|
||||
amount = get_attribute_float(node, "amount")
|
||||
def find_account(account_i: int):
|
||||
if not account_i in accounts:
|
||||
raise KeyError(f"Account {account} for operation ({date}, {amount}) not found")
|
||||
return accounts[account_i]
|
||||
account_i = get_attribute_int(node, "account")
|
||||
account = find_account(account_i)
|
||||
dst_account_i = get_attribute_optional_int(node, "dst_account")
|
||||
dst_account: Optional[Account] = None
|
||||
if dst_account_i is not None:
|
||||
dst_account = find_account(dst_account_i)
|
||||
payee_i = get_attribute_optional_int(node, "payee")
|
||||
payee: Optional[Payee] = None
|
||||
if payee_i is not None:
|
||||
payee = payees[payee_i]
|
||||
category_i = get_attribute_optional_int(node, "category")
|
||||
category: Optional[Category] = None
|
||||
if category_i is not None:
|
||||
category = categories[category_i]
|
||||
wording = get_attribute_optional(node, "wording")
|
||||
return Operation(date, amount, account, dst_account, payee, category, wording)
|
||||
|
||||
|
||||
class Homebank:
|
||||
def __init__(self, path: str):
|
||||
self.payees: Dict[int, Payee] = {}
|
||||
self.accounts: Dict[int, Account] = {}
|
||||
self.categories: Dict[int, Category] = {}
|
||||
self.operations: List[Operation] = []
|
||||
|
||||
root = etree.parse(path).getroot()
|
||||
|
||||
for node in root:
|
||||
if node.tag == "account":
|
||||
key, account = Account._from_node(node)
|
||||
self.accounts[key] = account
|
||||
elif node.tag == "pay":
|
||||
key, payee = Payee._from_node(node)
|
||||
self.payees[key] = payee
|
||||
elif node.tag == "cat":
|
||||
key, category = Category._from_node(node, self.categories)
|
||||
self.categories[key] = category
|
||||
elif node.tag == "ope":
|
||||
operation = Operation._from_node(node, self.accounts, self.payees, self.categories)
|
||||
self.operations.append(operation)
|
1
src/homebank/__init__.py
Normal file
1
src/homebank/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
from .Homebank import Account, Category, Homebank, Operation, Payee
|
150
test/test.py
Normal file
150
test/test.py
Normal file
|
@ -0,0 +1,150 @@
|
|||
import unittest
|
||||
from datetime import date
|
||||
|
||||
from lxml import etree
|
||||
|
||||
import homebank
|
||||
|
||||
|
||||
class TestReadXml_InvalidInput(unittest.TestCase):
|
||||
def test_invalid_path(self):
|
||||
with self.assertRaises(TypeError):
|
||||
homebank.Homebank(None)
|
||||
|
||||
def test_nonexistent_path(self):
|
||||
with self.assertRaises(OSError):
|
||||
homebank.Homebank("nonexistent.xhb")
|
||||
|
||||
def test_not_an_xml(self):
|
||||
with self.assertRaises(etree.XMLSyntaxError):
|
||||
homebank.Homebank("test/test.py")
|
||||
|
||||
|
||||
class TestReadXml_Test1(unittest.TestCase):
|
||||
def test_payees(self):
|
||||
hb = homebank.Homebank("test/test1.xhb")
|
||||
self.assertEqual(hb.payees, {
|
||||
1: homebank.Payee("Payee1"),
|
||||
2: homebank.Payee("Payee2"),
|
||||
})
|
||||
|
||||
def test_accounts(self):
|
||||
hb = homebank.Homebank("test/test1.xhb")
|
||||
self.assertEqual(hb.accounts, {
|
||||
1: homebank.Account("MyBankAccount"),
|
||||
2: homebank.Account("MyCashAccount"),
|
||||
3: homebank.Account("MyAssetAccount"),
|
||||
4: homebank.Account("MyCreditCardAccount"),
|
||||
})
|
||||
|
||||
def test_categories(self):
|
||||
hb = homebank.Homebank("test/test1.xhb")
|
||||
cat1 = homebank.Category("Category1")
|
||||
cat2 = homebank.Category("Subcategory1", cat1)
|
||||
cat3 = homebank.Category("Category2")
|
||||
self.assertEqual(hb.categories, {
|
||||
1: cat1,
|
||||
2: cat2,
|
||||
3: cat3,
|
||||
})
|
||||
|
||||
def test_operations(self):
|
||||
hb = homebank.Homebank("test/test1.xhb")
|
||||
self.assertCountEqual(hb.operations, [
|
||||
homebank.Operation(date(2022,11,1), -0.01, hb.accounts[2], None, hb.payees[1], hb.categories[2], "MyMemo"),
|
||||
homebank.Operation(date(2022,11,1), -0.02, hb.accounts[4], None, hb.payees[2], hb.categories[3], "MyMemo2"),
|
||||
])
|
||||
|
||||
|
||||
class TestReadXml_Payees(unittest.TestCase):
|
||||
def test_missing_key(self):
|
||||
with self.assertRaisesRegex(KeyError, "Node 'pay'.*is missing attribute 'key'"):
|
||||
homebank.Homebank("test/test_error_payee_key.xhb")
|
||||
|
||||
def test_missing_name(self):
|
||||
with self.assertRaisesRegex(KeyError, "Node 'pay'.*is missing attribute 'name'"):
|
||||
homebank.Homebank("test/test_error_payee_name.xhb")
|
||||
|
||||
def test_invalid_key(self):
|
||||
with self.assertRaisesRegex(ValueError, "Could not convert attribute 'key' of node 'pay'.*to integer"):
|
||||
homebank.Homebank("test/test_error_payee_key_invalid.xhb")
|
||||
|
||||
|
||||
class TestReadXml_Accounts(unittest.TestCase):
|
||||
def test_missing_key(self):
|
||||
with self.assertRaisesRegex(KeyError, "Node 'account'.*is missing attribute 'key'"):
|
||||
homebank.Homebank("test/test_error_account_key.xhb")
|
||||
|
||||
def test_missing_name(self):
|
||||
with self.assertRaisesRegex(KeyError, "Node 'account'.*is missing attribute 'name'"):
|
||||
homebank.Homebank("test/test_error_account_name.xhb")
|
||||
|
||||
def test_invalid_key(self):
|
||||
with self.assertRaisesRegex(ValueError, "Could not convert attribute 'key' of node 'account'.*to integer"):
|
||||
homebank.Homebank("test/test_error_account_key_invalid.xhb")
|
||||
|
||||
|
||||
class TestReadXml_Categories(unittest.TestCase):
|
||||
def test_missing_key(self):
|
||||
with self.assertRaisesRegex(KeyError, "Node 'cat'.*is missing attribute 'key'"):
|
||||
homebank.Homebank("test/test_error_category_key.xhb")
|
||||
|
||||
def test_missing_name(self):
|
||||
with self.assertRaisesRegex(KeyError, "Node 'cat'.*is missing attribute 'name'"):
|
||||
homebank.Homebank("test/test_error_category_name.xhb")
|
||||
|
||||
def test_invalid_key(self):
|
||||
with self.assertRaisesRegex(ValueError, "Could not convert attribute 'key' of node 'cat'.*to integer"):
|
||||
homebank.Homebank("test/test_error_category_key_invalid.xhb")
|
||||
|
||||
def test_invalid_parent(self):
|
||||
with self.assertRaisesRegex(ValueError, "Could not convert attribute 'parent' of node 'cat'.*to integer"):
|
||||
homebank.Homebank("test/test_error_category_parent_invalid.xhb")
|
||||
|
||||
def test_unknown_parent(self):
|
||||
with self.assertRaisesRegex(KeyError, "Parent category 123 for category 'Category1' not found"):
|
||||
homebank.Homebank("test/test_error_category_parent_unknown.xhb")
|
||||
|
||||
|
||||
class TestReadXml_Operations(unittest.TestCase):
|
||||
def test_missing_date(self):
|
||||
with self.assertRaisesRegex(KeyError, "Node 'ope'.*is missing attribute 'date'"):
|
||||
homebank.Homebank("test/test_error_operation_date.xhb")
|
||||
|
||||
def test_invalid_date(self):
|
||||
with self.assertRaisesRegex(ValueError, "Could not convert attribute 'date' of node 'ope'.*to integer"):
|
||||
homebank.Homebank("test/test_error_operation_date_invalid.xhb")
|
||||
|
||||
def test_missing_amount(self):
|
||||
with self.assertRaisesRegex(KeyError, "Node 'ope'.*is missing attribute 'amount'"):
|
||||
homebank.Homebank("test/test_error_operation_amount.xhb")
|
||||
|
||||
def test_invalid_amount(self):
|
||||
with self.assertRaisesRegex(ValueError, "Could not convert attribute 'amount' of node 'ope'.*to float"):
|
||||
homebank.Homebank("test/test_error_operation_amount_invalid.xhb")
|
||||
|
||||
def test_missing_account(self):
|
||||
with self.assertRaisesRegex(KeyError, "Node 'ope'.*is missing attribute 'account'"):
|
||||
homebank.Homebank("test/test_error_operation_account.xhb")
|
||||
|
||||
def test_invalid_account(self):
|
||||
with self.assertRaisesRegex(ValueError, "Could not convert attribute 'account' of node 'ope'.*to integer"):
|
||||
homebank.Homebank("test/test_error_operation_account_invalid.xhb")
|
||||
|
||||
def test_invalid_dst_account(self):
|
||||
with self.assertRaisesRegex(ValueError, "Could not convert attribute 'dst_account' of node 'ope'.*to integer"):
|
||||
homebank.Homebank("test/test_error_operation_dst_account_invalid.xhb")
|
||||
|
||||
def test_invalid_payee(self):
|
||||
with self.assertRaisesRegex(ValueError, "Could not convert attribute 'payee' of node 'ope'.*to integer"):
|
||||
homebank.Homebank("test/test_error_operation_payee_invalid.xhb")
|
||||
|
||||
def test_invalid_category(self):
|
||||
with self.assertRaisesRegex(ValueError, "Could not convert attribute 'category' of node 'ope'.*to integer"):
|
||||
homebank.Homebank("test/test_error_operation_category_invalid.xhb")
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
16
test/test1.xhb
Normal file
16
test/test1.xhb
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<account key="1" pos="1" type="1" curr="1" name="MyBankAccount" initial="0" minimum="0" maximum="0"/>
|
||||
<account key="2" pos="2" type="2" curr="1" name="MyCashAccount" initial="0" minimum="0" maximum="0" rdate="738460"/>
|
||||
<account key="3" pos="3" type="3" curr="1" name="MyAssetAccount" initial="0" minimum="0" maximum="0"/>
|
||||
<account key="4" pos="4" type="4" curr="1" name="MyCreditCardAccount" initial="0" minimum="0" maximum="0"/>
|
||||
<pay key="1" name="Payee1"/>
|
||||
<pay key="2" name="Payee2"/>
|
||||
<cat key="1" name="Category1"/>
|
||||
<cat key="2" parent="1" flags="1" name="Subcategory1"/>
|
||||
<cat key="3" name="Category2"/>
|
||||
<ope date="738460" amount="-0.01" account="2" paymode="3" payee="1" category="2" wording="MyMemo" info="info" tags="Tag1 Tag2"/>
|
||||
<ope date="738460" amount="-0.02" account="4" paymode="6" st="2" payee="2" category="3" wording="MyMemo2"/>
|
||||
</homebank>
|
6
test/test_error_account_key.xhb
Normal file
6
test/test_error_account_key.xhb
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<account pos="2" type="2" curr="1" name="MyCashAccount" initial="0" minimum="0" maximum="0" rdate="738460"/>
|
||||
</homebank>
|
6
test/test_error_account_key_invalid.xhb
Normal file
6
test/test_error_account_key_invalid.xhb
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<account key="bla" pos="2" type="2" curr="1" name="MyCashAccount" initial="0" minimum="0" maximum="0" rdate="738460"/>
|
||||
</homebank>
|
6
test/test_error_account_name.xhb
Normal file
6
test/test_error_account_name.xhb
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<account key="3" pos="2" type="2" curr="1" initial="0" minimum="0" maximum="0" rdate="738460"/>
|
||||
</homebank>
|
6
test/test_error_category_key.xhb
Normal file
6
test/test_error_category_key.xhb
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<cat name="Category1"/>
|
||||
</homebank>
|
6
test/test_error_category_key_invalid.xhb
Normal file
6
test/test_error_category_key_invalid.xhb
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<cat key="bla" name="Category1"/>
|
||||
</homebank>
|
6
test/test_error_category_name.xhb
Normal file
6
test/test_error_category_name.xhb
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<cat key="1"/>
|
||||
</homebank>
|
6
test/test_error_category_parent_invalid.xhb
Normal file
6
test/test_error_category_parent_invalid.xhb
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<cat key="1" name="Category1" parent="bla"/>
|
||||
</homebank>
|
6
test/test_error_category_parent_unknown.xhb
Normal file
6
test/test_error_category_parent_unknown.xhb
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<cat key="1" name="Category1" parent="123"/>
|
||||
</homebank>
|
9
test/test_error_operation_account.xhb
Normal file
9
test/test_error_operation_account.xhb
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<account key="1" pos="1" type="1" curr="1" name="MyBankAccount" initial="0" minimum="0" maximum="0"/>
|
||||
<pay key="1" name="Payee1"/>
|
||||
<cat key="1" name="Category1"/>
|
||||
<ope date="738460" amount="-0.01" paymode="3" payee="1" category="1" wording="MyMemo" info="info" tags="Tag1 Tag2"/>
|
||||
</homebank>
|
9
test/test_error_operation_account_invalid.xhb
Normal file
9
test/test_error_operation_account_invalid.xhb
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<account key="1" pos="1" type="1" curr="1" name="MyBankAccount" initial="0" minimum="0" maximum="0"/>
|
||||
<pay key="1" name="Payee1"/>
|
||||
<cat key="1" name="Category1"/>
|
||||
<ope date="738460" amount="-0.01" account="bla" paymode="3" payee="1" category="1" wording="MyMemo" info="info" tags="Tag1 Tag2"/>
|
||||
</homebank>
|
9
test/test_error_operation_amount.xhb
Normal file
9
test/test_error_operation_amount.xhb
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<account key="1" pos="1" type="1" curr="1" name="MyBankAccount" initial="0" minimum="0" maximum="0"/>
|
||||
<pay key="1" name="Payee1"/>
|
||||
<cat key="1" name="Category1"/>
|
||||
<ope date="738460" account="1" paymode="3" payee="1" category="1" wording="MyMemo" info="info" tags="Tag1 Tag2"/>
|
||||
</homebank>
|
9
test/test_error_operation_amount_invalid.xhb
Normal file
9
test/test_error_operation_amount_invalid.xhb
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<account key="1" pos="1" type="1" curr="1" name="MyBankAccount" initial="0" minimum="0" maximum="0"/>
|
||||
<pay key="1" name="Payee1"/>
|
||||
<cat key="1" name="Category1"/>
|
||||
<ope date="738460" amount="bla" account="1" paymode="3" payee="1" category="1" wording="MyMemo" info="info" tags="Tag1 Tag2"/>
|
||||
</homebank>
|
9
test/test_error_operation_category_invalid.xhb
Normal file
9
test/test_error_operation_category_invalid.xhb
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<account key="1" pos="1" type="1" curr="1" name="MyBankAccount" initial="0" minimum="0" maximum="0"/>
|
||||
<pay key="1" name="Payee1"/>
|
||||
<cat key="1" name="Category1"/>
|
||||
<ope date="738460" amount="-0.01" account="1" paymode="3" payee="1" category="bla" wording="MyMemo" info="info" tags="Tag1 Tag2"/>
|
||||
</homebank>
|
9
test/test_error_operation_date.xhb
Normal file
9
test/test_error_operation_date.xhb
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<account key="1" pos="1" type="1" curr="1" name="MyBankAccount" initial="0" minimum="0" maximum="0"/>
|
||||
<pay key="1" name="Payee1"/>
|
||||
<cat key="1" name="Category1"/>
|
||||
<ope amount="-0.01" account="1" paymode="3" payee="1" category="1" wording="MyMemo" info="info" tags="Tag1 Tag2"/>
|
||||
</homebank>
|
9
test/test_error_operation_date_invalid.xhb
Normal file
9
test/test_error_operation_date_invalid.xhb
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<account key="1" pos="1" type="1" curr="1" name="MyBankAccount" initial="0" minimum="0" maximum="0"/>
|
||||
<pay key="1" name="Payee1"/>
|
||||
<cat key="1" name="Category1"/>
|
||||
<ope date="bla" amount="-0.01" account="1" paymode="3" payee="1" category="1" wording="MyMemo" info="info" tags="Tag1 Tag2"/>
|
||||
</homebank>
|
9
test/test_error_operation_dst_account_invalid.xhb
Normal file
9
test/test_error_operation_dst_account_invalid.xhb
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<account key="1" pos="1" type="1" curr="1" name="MyBankAccount" initial="0" minimum="0" maximum="0"/>
|
||||
<pay key="1" name="Payee1"/>
|
||||
<cat key="1" name="Category1"/>
|
||||
<ope date="738460" amount="-0.01" account="1" dst_account="bla" paymode="3" payee="1" category="1" wording="MyMemo" info="info" tags="Tag1 Tag2"/>
|
||||
</homebank>
|
9
test/test_error_operation_payee_invalid.xhb
Normal file
9
test/test_error_operation_payee_invalid.xhb
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<account key="1" pos="1" type="1" curr="1" name="MyBankAccount" initial="0" minimum="0" maximum="0"/>
|
||||
<pay key="1" name="Payee1"/>
|
||||
<cat key="1" name="Category1"/>
|
||||
<ope date="738460" amount="-0.01" account="1" paymode="3" payee="bla" category="1" wording="MyMemo" info="info" tags="Tag1 Tag2"/>
|
||||
</homebank>
|
6
test/test_error_payee_key.xhb
Normal file
6
test/test_error_payee_key.xhb
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<pay name="bla"/>
|
||||
</homebank>
|
6
test/test_error_payee_key_invalid.xhb
Normal file
6
test/test_error_payee_key_invalid.xhb
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<pay key="bla" name="bla"/>
|
||||
</homebank>
|
6
test/test_error_payee_name.xhb
Normal file
6
test/test_error_payee_name.xhb
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0"?>
|
||||
<homebank v="1.3999999999999999" d="050502">
|
||||
<properties title="MyTitle" curr="1" auto_smode="1" auto_weekday="1"/>
|
||||
<cur key="1" flags="0" iso="EUR" name="Euro" symb="€" syprf="0" dchar="," gchar="." frac="2" rate="0" mdate="0"/>
|
||||
<pay key="1"/>
|
||||
</homebank>
|
Loading…
Reference in a new issue