diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d929f05..f588aa2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ default_stages: [commit, manual] fail_fast: true repos: - repo: "https://github.com/commitizen-tools/commitizen" - rev: v3.18.3 + rev: v3.20.0 hooks: - id: commitizen - id: commitizen-branch @@ -59,7 +59,7 @@ repos: entry: yamllint --strict --config-file .yamllint.yml - repo: "https://github.com/charliermarsh/ruff-pre-commit" - rev: "v0.3.2" + rev: "v0.3.4" hooks: - id: ruff args: ["--extend-ignore", "I001,D401"] diff --git a/poetry.lock b/poetry.lock index bcd4833..8e9dbd8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "annotated-types" @@ -173,13 +173,13 @@ files = [ [[package]] name = "commitizen" -version = "3.18.3" +version = "3.20.0" description = "Python commitizen client tool" optional = false python-versions = ">=3.8" files = [ - {file = "commitizen-3.18.3-py3-none-any.whl", hash = "sha256:864abe3a68328ba16cac5bc2bc9f8225b973bd14957d12716641c5da8dc36d18"}, - {file = "commitizen-3.18.3.tar.gz", hash = "sha256:980eb09abfb27d0d16960a6ca9e40c78b8608205987d8b012e3c09347bc4d35d"}, + {file = "commitizen-3.20.0-py3-none-any.whl", hash = "sha256:f079d9642347d314afae75664d289b0de80cf0343c99c3dcfa85782f164333f3"}, + {file = "commitizen-3.20.0.tar.gz", hash = "sha256:17aebc8f36326fa3e65dcc08195303579e356be84b0d65c3c4bfed85b8822411"}, ] [package.dependencies] @@ -214,63 +214,63 @@ toml = ">=0.10.2,<0.11.0" [[package]] name = "coverage" -version = "7.4.3" +version = "7.4.4" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.4.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8580b827d4746d47294c0e0b92854c85a92c2227927433998f0d3320ae8a71b6"}, - {file = "coverage-7.4.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:718187eeb9849fc6cc23e0d9b092bc2348821c5e1a901c9f8975df0bc785bfd4"}, - {file = "coverage-7.4.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:767b35c3a246bcb55b8044fd3a43b8cd553dd1f9f2c1eeb87a302b1f8daa0524"}, - {file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae7f19afe0cce50039e2c782bff379c7e347cba335429678450b8fe81c4ef96d"}, - {file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba3a8aaed13770e970b3df46980cb068d1c24af1a1968b7818b69af8c4347efb"}, - {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ee866acc0861caebb4f2ab79f0b94dbfbdbfadc19f82e6e9c93930f74e11d7a0"}, - {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:506edb1dd49e13a2d4cac6a5173317b82a23c9d6e8df63efb4f0380de0fbccbc"}, - {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd6545d97c98a192c5ac995d21c894b581f1fd14cf389be90724d21808b657e2"}, - {file = "coverage-7.4.3-cp310-cp310-win32.whl", hash = "sha256:f6a09b360d67e589236a44f0c39218a8efba2593b6abdccc300a8862cffc2f94"}, - {file = "coverage-7.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:18d90523ce7553dd0b7e23cbb28865db23cddfd683a38fb224115f7826de78d0"}, - {file = "coverage-7.4.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbbe5e739d45a52f3200a771c6d2c7acf89eb2524890a4a3aa1a7fa0695d2a47"}, - {file = "coverage-7.4.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:489763b2d037b164846ebac0cbd368b8a4ca56385c4090807ff9fad817de4113"}, - {file = "coverage-7.4.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:451f433ad901b3bb00184d83fd83d135fb682d780b38af7944c9faeecb1e0bfe"}, - {file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcc66e222cf4c719fe7722a403888b1f5e1682d1679bd780e2b26c18bb648cdc"}, - {file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3ec74cfef2d985e145baae90d9b1b32f85e1741b04cd967aaf9cfa84c1334f3"}, - {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:abbbd8093c5229c72d4c2926afaee0e6e3140de69d5dcd918b2921f2f0c8baba"}, - {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:35eb581efdacf7b7422af677b92170da4ef34500467381e805944a3201df2079"}, - {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8249b1c7334be8f8c3abcaaa996e1e4927b0e5a23b65f5bf6cfe3180d8ca7840"}, - {file = "coverage-7.4.3-cp311-cp311-win32.whl", hash = "sha256:cf30900aa1ba595312ae41978b95e256e419d8a823af79ce670835409fc02ad3"}, - {file = "coverage-7.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:18c7320695c949de11a351742ee001849912fd57e62a706d83dfc1581897fa2e"}, - {file = "coverage-7.4.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b51bfc348925e92a9bd9b2e48dad13431b57011fd1038f08316e6bf1df107d10"}, - {file = "coverage-7.4.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d6cdecaedea1ea9e033d8adf6a0ab11107b49571bbb9737175444cea6eb72328"}, - {file = "coverage-7.4.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b2eccb883368f9e972e216c7b4c7c06cabda925b5f06dde0650281cb7666a30"}, - {file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c00cdc8fa4e50e1cc1f941a7f2e3e0f26cb2a1233c9696f26963ff58445bac7"}, - {file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9a4a8dd3dcf4cbd3165737358e4d7dfbd9d59902ad11e3b15eebb6393b0446e"}, - {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:062b0a75d9261e2f9c6d071753f7eef0fc9caf3a2c82d36d76667ba7b6470003"}, - {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ebe7c9e67a2d15fa97b77ea6571ce5e1e1f6b0db71d1d5e96f8d2bf134303c1d"}, - {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c0a120238dd71c68484f02562f6d446d736adcc6ca0993712289b102705a9a3a"}, - {file = "coverage-7.4.3-cp312-cp312-win32.whl", hash = "sha256:37389611ba54fd6d278fde86eb2c013c8e50232e38f5c68235d09d0a3f8aa352"}, - {file = "coverage-7.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:d25b937a5d9ffa857d41be042b4238dd61db888533b53bc76dc082cb5a15e914"}, - {file = "coverage-7.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:28ca2098939eabab044ad68850aac8f8db6bf0b29bc7f2887d05889b17346454"}, - {file = "coverage-7.4.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:280459f0a03cecbe8800786cdc23067a8fc64c0bd51dc614008d9c36e1659d7e"}, - {file = "coverage-7.4.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c0cdedd3500e0511eac1517bf560149764b7d8e65cb800d8bf1c63ebf39edd2"}, - {file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a9babb9466fe1da12417a4aed923e90124a534736de6201794a3aea9d98484e"}, - {file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dec9de46a33cf2dd87a5254af095a409ea3bf952d85ad339751e7de6d962cde6"}, - {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:16bae383a9cc5abab9bb05c10a3e5a52e0a788325dc9ba8499e821885928968c"}, - {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2c854ce44e1ee31bda4e318af1dbcfc929026d12c5ed030095ad98197eeeaed0"}, - {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ce8c50520f57ec57aa21a63ea4f325c7b657386b3f02ccaedeccf9ebe27686e1"}, - {file = "coverage-7.4.3-cp38-cp38-win32.whl", hash = "sha256:708a3369dcf055c00ddeeaa2b20f0dd1ce664eeabde6623e516c5228b753654f"}, - {file = "coverage-7.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:1bf25fbca0c8d121a3e92a2a0555c7e5bc981aee5c3fdaf4bb7809f410f696b9"}, - {file = "coverage-7.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3b253094dbe1b431d3a4ac2f053b6d7ede2664ac559705a704f621742e034f1f"}, - {file = "coverage-7.4.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:77fbfc5720cceac9c200054b9fab50cb2a7d79660609200ab83f5db96162d20c"}, - {file = "coverage-7.4.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6679060424faa9c11808598504c3ab472de4531c571ab2befa32f4971835788e"}, - {file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4af154d617c875b52651dd8dd17a31270c495082f3d55f6128e7629658d63765"}, - {file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8640f1fde5e1b8e3439fe482cdc2b0bb6c329f4bb161927c28d2e8879c6029ee"}, - {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:69b9f6f66c0af29642e73a520b6fed25ff9fd69a25975ebe6acb297234eda501"}, - {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0842571634f39016a6c03e9d4aba502be652a6e4455fadb73cd3a3a49173e38f"}, - {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a78ed23b08e8ab524551f52953a8a05d61c3a760781762aac49f8de6eede8c45"}, - {file = "coverage-7.4.3-cp39-cp39-win32.whl", hash = "sha256:c0524de3ff096e15fcbfe8f056fdb4ea0bf497d584454f344d59fce069d3e6e9"}, - {file = "coverage-7.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:0209a6369ccce576b43bb227dc8322d8ef9e323d089c6f3f26a597b09cb4d2aa"}, - {file = "coverage-7.4.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:7cbde573904625509a3f37b6fecea974e363460b556a627c60dc2f47e2fffa51"}, - {file = "coverage-7.4.3.tar.gz", hash = "sha256:276f6077a5c61447a48d133ed13e759c09e62aff0dc84274a68dc18660104d52"}, + {file = "coverage-7.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0be5efd5127542ef31f165de269f77560d6cdef525fffa446de6f7e9186cfb2"}, + {file = "coverage-7.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ccd341521be3d1b3daeb41960ae94a5e87abe2f46f17224ba5d6f2b8398016cf"}, + {file = "coverage-7.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09fa497a8ab37784fbb20ab699c246053ac294d13fc7eb40ec007a5043ec91f8"}, + {file = "coverage-7.4.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b1a93009cb80730c9bca5d6d4665494b725b6e8e157c1cb7f2db5b4b122ea562"}, + {file = "coverage-7.4.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:690db6517f09336559dc0b5f55342df62370a48f5469fabf502db2c6d1cffcd2"}, + {file = "coverage-7.4.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:09c3255458533cb76ef55da8cc49ffab9e33f083739c8bd4f58e79fecfe288f7"}, + {file = "coverage-7.4.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8ce1415194b4a6bd0cdcc3a1dfbf58b63f910dcb7330fe15bdff542c56949f87"}, + {file = "coverage-7.4.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b91cbc4b195444e7e258ba27ac33769c41b94967919f10037e6355e998af255c"}, + {file = "coverage-7.4.4-cp310-cp310-win32.whl", hash = "sha256:598825b51b81c808cb6f078dcb972f96af96b078faa47af7dfcdf282835baa8d"}, + {file = "coverage-7.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:09ef9199ed6653989ebbcaacc9b62b514bb63ea2f90256e71fea3ed74bd8ff6f"}, + {file = "coverage-7.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0f9f50e7ef2a71e2fae92774c99170eb8304e3fdf9c8c3c7ae9bab3e7229c5cf"}, + {file = "coverage-7.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:623512f8ba53c422fcfb2ce68362c97945095b864cda94a92edbaf5994201083"}, + {file = "coverage-7.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0513b9508b93da4e1716744ef6ebc507aff016ba115ffe8ecff744d1322a7b63"}, + {file = "coverage-7.4.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40209e141059b9370a2657c9b15607815359ab3ef9918f0196b6fccce8d3230f"}, + {file = "coverage-7.4.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a2b2b78c78293782fd3767d53e6474582f62443d0504b1554370bde86cc8227"}, + {file = "coverage-7.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:73bfb9c09951125d06ee473bed216e2c3742f530fc5acc1383883125de76d9cd"}, + {file = "coverage-7.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1f384c3cc76aeedce208643697fb3e8437604b512255de6d18dae3f27655a384"}, + {file = "coverage-7.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:54eb8d1bf7cacfbf2a3186019bcf01d11c666bd495ed18717162f7eb1e9dd00b"}, + {file = "coverage-7.4.4-cp311-cp311-win32.whl", hash = "sha256:cac99918c7bba15302a2d81f0312c08054a3359eaa1929c7e4b26ebe41e9b286"}, + {file = "coverage-7.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:b14706df8b2de49869ae03a5ccbc211f4041750cd4a66f698df89d44f4bd30ec"}, + {file = "coverage-7.4.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:201bef2eea65e0e9c56343115ba3814e896afe6d36ffd37bab783261db430f76"}, + {file = "coverage-7.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41c9c5f3de16b903b610d09650e5e27adbfa7f500302718c9ffd1c12cf9d6818"}, + {file = "coverage-7.4.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d898fe162d26929b5960e4e138651f7427048e72c853607f2b200909794ed978"}, + {file = "coverage-7.4.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ea79bb50e805cd6ac058dfa3b5c8f6c040cb87fe83de10845857f5535d1db70"}, + {file = "coverage-7.4.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce4b94265ca988c3f8e479e741693d143026632672e3ff924f25fab50518dd51"}, + {file = "coverage-7.4.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:00838a35b882694afda09f85e469c96367daa3f3f2b097d846a7216993d37f4c"}, + {file = "coverage-7.4.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:fdfafb32984684eb03c2d83e1e51f64f0906b11e64482df3c5db936ce3839d48"}, + {file = "coverage-7.4.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:69eb372f7e2ece89f14751fbcbe470295d73ed41ecd37ca36ed2eb47512a6ab9"}, + {file = "coverage-7.4.4-cp312-cp312-win32.whl", hash = "sha256:137eb07173141545e07403cca94ab625cc1cc6bc4c1e97b6e3846270e7e1fea0"}, + {file = "coverage-7.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:d71eec7d83298f1af3326ce0ff1d0ea83c7cb98f72b577097f9083b20bdaf05e"}, + {file = "coverage-7.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d5ae728ff3b5401cc320d792866987e7e7e880e6ebd24433b70a33b643bb0384"}, + {file = "coverage-7.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cc4f1358cb0c78edef3ed237ef2c86056206bb8d9140e73b6b89fbcfcbdd40e1"}, + {file = "coverage-7.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8130a2aa2acb8788e0b56938786c33c7c98562697bf9f4c7d6e8e5e3a0501e4a"}, + {file = "coverage-7.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf271892d13e43bc2b51e6908ec9a6a5094a4df1d8af0bfc360088ee6c684409"}, + {file = "coverage-7.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4cdc86d54b5da0df6d3d3a2f0b710949286094c3a6700c21e9015932b81447e"}, + {file = "coverage-7.4.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ae71e7ddb7a413dd60052e90528f2f65270aad4b509563af6d03d53e979feafd"}, + {file = "coverage-7.4.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:38dd60d7bf242c4ed5b38e094baf6401faa114fc09e9e6632374388a404f98e7"}, + {file = "coverage-7.4.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa5b1c1bfc28384f1f53b69a023d789f72b2e0ab1b3787aae16992a7ca21056c"}, + {file = "coverage-7.4.4-cp38-cp38-win32.whl", hash = "sha256:dfa8fe35a0bb90382837b238fff375de15f0dcdb9ae68ff85f7a63649c98527e"}, + {file = "coverage-7.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:b2991665420a803495e0b90a79233c1433d6ed77ef282e8e152a324bbbc5e0c8"}, + {file = "coverage-7.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3b799445b9f7ee8bf299cfaed6f5b226c0037b74886a4e11515e569b36fe310d"}, + {file = "coverage-7.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b4d33f418f46362995f1e9d4f3a35a1b6322cb959c31d88ae56b0298e1c22357"}, + {file = "coverage-7.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aadacf9a2f407a4688d700e4ebab33a7e2e408f2ca04dbf4aef17585389eff3e"}, + {file = "coverage-7.4.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c95949560050d04d46b919301826525597f07b33beba6187d04fa64d47ac82e"}, + {file = "coverage-7.4.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff7687ca3d7028d8a5f0ebae95a6e4827c5616b31a4ee1192bdfde697db110d4"}, + {file = "coverage-7.4.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5fc1de20b2d4a061b3df27ab9b7c7111e9a710f10dc2b84d33a4ab25065994ec"}, + {file = "coverage-7.4.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c74880fc64d4958159fbd537a091d2a585448a8f8508bf248d72112723974cbd"}, + {file = "coverage-7.4.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:742a76a12aa45b44d236815d282b03cfb1de3b4323f3e4ec933acfae08e54ade"}, + {file = "coverage-7.4.4-cp39-cp39-win32.whl", hash = "sha256:d89d7b2974cae412400e88f35d86af72208e1ede1a541954af5d944a8ba46c57"}, + {file = "coverage-7.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:9ca28a302acb19b6af89e90f33ee3e1906961f94b54ea37de6737b7ca9d8827c"}, + {file = "coverage-7.4.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:b2c5edc4ac10a7ef6605a966c58929ec6c1bd0917fb8c15cb3363f65aa40e677"}, + {file = "coverage-7.4.4.tar.gz", hash = "sha256:c901df83d097649e257e803be22592aedfd5182f07b3cc87d640bbb9afd50f49"}, ] [package.extras] @@ -394,13 +394,13 @@ files = [ [[package]] name = "importlib-metadata" -version = "7.0.2" +version = "7.1.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-7.0.2-py3-none-any.whl", hash = "sha256:f4bc4c0c070c490abf4ce96d715f68e95923320370efb66143df00199bb6c100"}, - {file = "importlib_metadata-7.0.2.tar.gz", hash = "sha256:198f568f3230878cb1b44fbd7975f87906c22336dba2e4a7f05278c281fbd792"}, + {file = "importlib_metadata-7.1.0-py3-none-any.whl", hash = "sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570"}, + {file = "importlib_metadata-7.1.0.tar.gz", hash = "sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2"}, ] [package.dependencies] @@ -409,7 +409,7 @@ zipp = ">=0.5" [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] [[package]] name = "iniconfig" @@ -665,6 +665,17 @@ files = [ {file = "pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d"}, ] +[[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 = "platformdirs" version = "4.2.0" @@ -903,13 +914,13 @@ testing = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygm [[package]] name = "pytest-asyncio" -version = "0.23.5.post1" +version = "0.23.6" description = "Pytest support for asyncio" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-asyncio-0.23.5.post1.tar.gz", hash = "sha256:b9a8806bea78c21276bc34321bbf234ba1b2ea5b30d9f0ce0f2dea45e4685813"}, - {file = "pytest_asyncio-0.23.5.post1-py3-none-any.whl", hash = "sha256:30f54d27774e79ac409778889880242b0403d09cabd65b727ce90fe92dd5d80e"}, + {file = "pytest-asyncio-0.23.6.tar.gz", hash = "sha256:ffe523a89c1c222598c76856e76852b787504ddb72dd5d9b6617ffa8aa2cde5f"}, + {file = "pytest_asyncio-0.23.6-py3-none-any.whl", hash = "sha256:68516fdd1018ac57b846c9846b954f0393b26f094764a28c955eabb0536a4e8a"}, ] [package.dependencies] @@ -953,17 +964,17 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "pytest-mock (>=3.12)"] [[package]] name = "pytest-mock" -version = "3.12.0" +version = "3.14.0" description = "Thin-wrapper around the mock package for easier use with pytest" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-mock-3.12.0.tar.gz", hash = "sha256:31a40f038c22cad32287bb43932054451ff5583ff094bca6f675df2f8bc1a6e9"}, - {file = "pytest_mock-3.12.0-py3-none-any.whl", hash = "sha256:0972719a7263072da3a21c7f4773069bcc7486027d7e8e1f81d98a47e701bc4f"}, + {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, + {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, ] [package.dependencies] -pytest = ">=5.0" +pytest = ">=6.2.5" [package.extras] dev = ["pre-commit", "pytest-asyncio", "tox"] @@ -1142,44 +1153,44 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.3.2" +version = "0.3.4" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.3.2-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:77f2612752e25f730da7421ca5e3147b213dca4f9a0f7e0b534e9562c5441f01"}, - {file = "ruff-0.3.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9966b964b2dd1107797be9ca7195002b874424d1d5472097701ae8f43eadef5d"}, - {file = "ruff-0.3.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b83d17ff166aa0659d1e1deaf9f2f14cbe387293a906de09bc4860717eb2e2da"}, - {file = "ruff-0.3.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb875c6cc87b3703aeda85f01c9aebdce3d217aeaca3c2e52e38077383f7268a"}, - {file = "ruff-0.3.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be75e468a6a86426430373d81c041b7605137a28f7014a72d2fc749e47f572aa"}, - {file = "ruff-0.3.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:967978ac2d4506255e2f52afe70dda023fc602b283e97685c8447d036863a302"}, - {file = "ruff-0.3.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1231eacd4510f73222940727ac927bc5d07667a86b0cbe822024dd00343e77e9"}, - {file = "ruff-0.3.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2c6d613b19e9a8021be2ee1d0e27710208d1603b56f47203d0abbde906929a9b"}, - {file = "ruff-0.3.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8439338a6303585d27b66b4626cbde89bb3e50fa3cae86ce52c1db7449330a7"}, - {file = "ruff-0.3.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:de8b480d8379620cbb5ea466a9e53bb467d2fb07c7eca54a4aa8576483c35d36"}, - {file = "ruff-0.3.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:b74c3de9103bd35df2bb05d8b2899bf2dbe4efda6474ea9681280648ec4d237d"}, - {file = "ruff-0.3.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f380be9fc15a99765c9cf316b40b9da1f6ad2ab9639e551703e581a5e6da6745"}, - {file = "ruff-0.3.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:0ac06a3759c3ab9ef86bbeca665d31ad3aa9a4b1c17684aadb7e61c10baa0df4"}, - {file = "ruff-0.3.2-py3-none-win32.whl", hash = "sha256:9bd640a8f7dd07a0b6901fcebccedadeb1a705a50350fb86b4003b805c81385a"}, - {file = "ruff-0.3.2-py3-none-win_amd64.whl", hash = "sha256:0c1bdd9920cab5707c26c8b3bf33a064a4ca7842d91a99ec0634fec68f9f4037"}, - {file = "ruff-0.3.2-py3-none-win_arm64.whl", hash = "sha256:5f65103b1d76e0d600cabd577b04179ff592064eaa451a70a81085930e907d0b"}, - {file = "ruff-0.3.2.tar.gz", hash = "sha256:fa78ec9418eb1ca3db392811df3376b46471ae93792a81af2d1cbb0e5dcb5142"}, + {file = "ruff-0.3.4-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:60c870a7d46efcbc8385d27ec07fe534ac32f3b251e4fc44b3cbfd9e09609ef4"}, + {file = "ruff-0.3.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6fc14fa742e1d8f24910e1fff0bd5e26d395b0e0e04cc1b15c7c5e5fe5b4af91"}, + {file = "ruff-0.3.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3ee7880f653cc03749a3bfea720cf2a192e4f884925b0cf7eecce82f0ce5854"}, + {file = "ruff-0.3.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cf133dd744f2470b347f602452a88e70dadfbe0fcfb5fd46e093d55da65f82f7"}, + {file = "ruff-0.3.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f3860057590e810c7ffea75669bdc6927bfd91e29b4baa9258fd48b540a4365"}, + {file = "ruff-0.3.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:986f2377f7cf12efac1f515fc1a5b753c000ed1e0a6de96747cdf2da20a1b369"}, + {file = "ruff-0.3.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fd98e85869603e65f554fdc5cddf0712e352fe6e61d29d5a6fe087ec82b76c"}, + {file = "ruff-0.3.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64abeed785dad51801b423fa51840b1764b35d6c461ea8caef9cf9e5e5ab34d9"}, + {file = "ruff-0.3.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df52972138318bc7546d92348a1ee58449bc3f9eaf0db278906eb511889c4b50"}, + {file = "ruff-0.3.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:98e98300056445ba2cc27d0b325fd044dc17fcc38e4e4d2c7711585bd0a958ed"}, + {file = "ruff-0.3.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:519cf6a0ebed244dce1dc8aecd3dc99add7a2ee15bb68cf19588bb5bf58e0488"}, + {file = "ruff-0.3.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:bb0acfb921030d00070539c038cd24bb1df73a2981e9f55942514af8b17be94e"}, + {file = "ruff-0.3.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cf187a7e7098233d0d0c71175375c5162f880126c4c716fa28a8ac418dcf3378"}, + {file = "ruff-0.3.4-py3-none-win32.whl", hash = "sha256:af27ac187c0a331e8ef91d84bf1c3c6a5dea97e912a7560ac0cef25c526a4102"}, + {file = "ruff-0.3.4-py3-none-win_amd64.whl", hash = "sha256:de0d5069b165e5a32b3c6ffbb81c350b1e3d3483347196ffdf86dc0ef9e37dd6"}, + {file = "ruff-0.3.4-py3-none-win_arm64.whl", hash = "sha256:6810563cc08ad0096b57c717bd78aeac888a1bfd38654d9113cb3dc4d3f74232"}, + {file = "ruff-0.3.4.tar.gz", hash = "sha256:f0f4484c6541a99862b693e13a151435a279b271cff20e37101116a21e2a1ad1"}, ] [[package]] name = "setuptools" -version = "69.1.1" +version = "69.2.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-69.1.1-py3-none-any.whl", hash = "sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56"}, - {file = "setuptools-69.1.1.tar.gz", hash = "sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8"}, + {file = "setuptools-69.2.0-py3-none-any.whl", hash = "sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c"}, + {file = "setuptools-69.2.0.tar.gz", hash = "sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e"}, ] [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] @@ -1242,13 +1253,13 @@ files = [ [[package]] name = "typer" -version = "0.9.0" +version = "0.9.1" description = "Typer, build great CLIs. Easy to code. Based on Python type hints." optional = false python-versions = ">=3.6" files = [ - {file = "typer-0.9.0-py3-none-any.whl", hash = "sha256:5d96d986a21493606a358cae4461bd8cdf83cbf33a5aa950ae629ca3b51467ee"}, - {file = "typer-0.9.0.tar.gz", hash = "sha256:50922fd79aea2f4751a8e0408ff10d2662bd0c8bbfa84755a699f3bada2978b2"}, + {file = "typer-0.9.1-py3-none-any.whl", hash = "sha256:aa06ca6c9b34631afb6ec402009b2cc67f40e8221171fd7f0b319dd62e3bb741"}, + {file = "typer-0.9.1.tar.gz", hash = "sha256:1cf0d77ad59eed73bf0e414b0258f523732afc7bd896122fd724910ddf308abc"}, ] [package.dependencies] @@ -1262,7 +1273,7 @@ typing-extensions = ">=3.7.4.3" all = ["colorama (>=0.4.3,<0.5.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"] dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2.17.0,<3.0.0)"] doc = ["cairosvg (>=2.5.2,<3.0.0)", "mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pillow (>=9.3.0,<10.0.0)"] -test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<8.0.0)", "pytest-cov (>=2.10.0,<5.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<4.0.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"] +test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.971)", "pytest (>=4.4.0,<8.0.0)", "pytest-cov (>=2.10.0,<5.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<4.0.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"] [[package]] name = "types-requests" @@ -1370,22 +1381,40 @@ files = [ [package.extras] dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"] +[[package]] +name = "yamllint" +version = "1.35.1" +description = "A linter for YAML files." +optional = false +python-versions = ">=3.8" +files = [ + {file = "yamllint-1.35.1-py3-none-any.whl", hash = "sha256:2e16e504bb129ff515b37823b472750b36b6de07963bd74b307341ef5ad8bdc3"}, + {file = "yamllint-1.35.1.tar.gz", hash = "sha256:7a003809f88324fd2c877734f2d575ee7881dd9043360657cc8049c809eba6cd"}, +] + +[package.dependencies] +pathspec = ">=0.5.3" +pyyaml = "*" + +[package.extras] +dev = ["doc8", "flake8", "flake8-import-order", "rstcheck[sphinx]", "sphinx"] + [[package]] name = "zipp" -version = "3.17.0" +version = "3.18.1" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, - {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, + {file = "zipp-3.18.1-py3-none-any.whl", hash = "sha256:206f5a15f2af3dbaee80769fb7dc6f249695e940acca08dfb2a4769fe61e538b"}, + {file = "zipp-3.18.1.tar.gz", hash = "sha256:2884ed22e7d8961de1c9a05142eb69a247f120291bc0206a00a7642f09b5b715"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "2ad0ecdc88fdc015bb07b7c0cc9b73675124262e511df13d3017ae93aaf4593c" +content-hash = "177976469fc6314235ac50ef7d47d94c3a4184c9890103e00b63c26e286aad0c" diff --git a/pyproject.toml b/pyproject.toml index a977e0c..1055561 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,6 +46,7 @@ ruff = "^0.3.2" types-requests = "^2.31.0.20240311" typos = "^1.19.0" + yamllint = "^1.35.1" [tool.commitizen] bump_message = "bump(release): v$current_version → v$new_version" diff --git a/src/vid_cleaner/cli/clean.py b/src/vid_cleaner/cli/clean.py index e7457ac..edaf153 100644 --- a/src/vid_cleaner/cli/clean.py +++ b/src/vid_cleaner/cli/clean.py @@ -28,16 +28,40 @@ def clean( dry_run: bool, verbosity: int, ) -> None: - """Clean command.""" + """Processes a list of video files with various cleaning and conversion options. + + This function performs a series of operations on video files, including reordering streams, processing audio and subtitle streams according to specified preferences, and converting the video to specified formats and resolutions. It can optionally perform these operations as a dry run, which does not apply any changes. If not a dry run, it handles output files according to specified replacement and verbosity settings. + + Args: + files: A list of VideoFile objects to process. + out: A Path object representing the output directory for processed files. + replace: If True, replace the original files with the processed ones. + downmix_stereo: If True, downmix audio to stereo. + drop_original_audio: If True, drop the original audio streams from the file. + keep_all_subtitles: If True, keep all subtitle streams. + keep_commentary: If True, keep commentary audio streams. + keep_local_subtitles: If True, keep subtitle streams in the local language. + subs_drop_local: If True, drop local language subtitle streams. + langs: A comma-separated string of language codes to keep in the processed video. None keeps default languages. + h265: If True, convert video to H.265 codec. + vp9: If True, convert video to VP9 codec. + video_1080: If True, convert video to 1080p resolution. + force: If True, force conversion even if it might result in loss of quality. + dry_run: If True, perform a trial run without making any changes. + verbosity: An integer that sets the verbosity level of the operation's output. + + Raises: + typer.BadParameter: If both h265 and vp9 flags are set to True. + """ + if h265 and vp9: + msg = "Cannot convert to both H265 and VP9" + raise typer.BadParameter(msg) + languages = langs or ",".join(VidCleanerConfig().keep_languages) for video in files: logger.info(f"⇨ {video.path.name}") - if h265 and vp9: - msg = "Cannot convert to both H265 and VP9" - raise typer.BadParameter(msg) - video.reorder_streams(dry_run=dry_run) video.process_streams( @@ -56,10 +80,10 @@ def clean( video.video_to_1080p(force=force, dry_run=dry_run) if h265: - video._convert_to_h265(force=force, dry_run=dry_run) + video.convert_to_h265(force=force, dry_run=dry_run) if vp9: - video._convert_to_vp9(force=force, dry_run=dry_run) + video.convert_to_vp9(force=force, dry_run=dry_run) if not dry_run: out_file = tmp_to_output( diff --git a/src/vid_cleaner/cli/clip.py b/src/vid_cleaner/cli/clip.py index c09c918..222a067 100644 --- a/src/vid_cleaner/cli/clip.py +++ b/src/vid_cleaner/cli/clip.py @@ -13,7 +13,9 @@ def clip( files: list[VideoFile], start: str, duration: str, out: Path, overwrite: bool, dry_run: bool ) -> None: - """Clips video files based on the specified start time and duration. + """Clips video files based on the specified start time and duration, saving the output in a given directory. + + This function processes each video in the provided list, clipping it according to the specified start time and duration. The resulting clips are saved in the specified output directory. The function supports overwriting existing files and performing a dry run, where no actual clipping occurs. Args: files: A list of VideoFile objects to be clipped. @@ -24,7 +26,7 @@ def clip( dry_run: A boolean indicating if the clip operation should be simulated (no actual clipping). Raises: - typer.BadParameter: If either 'start' or 'duration' does not match the expected time format. + typer.BadParameter: If either 'start' or 'duration' does not match the expected HH:MM:SS time format. """ time_pattern = re.compile(r"^\d{2}:\d{2}:\d{2}$") diff --git a/src/vid_cleaner/cli/inspect.py b/src/vid_cleaner/cli/inspect.py index 0fbe7c6..cc46819 100644 --- a/src/vid_cleaner/cli/inspect.py +++ b/src/vid_cleaner/cli/inspect.py @@ -7,7 +7,17 @@ def inspect(files: list[VideoFile], json_output: bool = False) -> None: - """Inspect command.""" + """Inspect a list of video files and output their metadata details. + + Iterates over a list of video files, using `ffprobe` to inspect each file. Depending on the `json_output` flag, the function either prints a JSON representation of the video file details or a formatted table of the video streams. The function exits the program after printing the details of all video files. + + Args: + files: A list of `VideoFile` objects to inspect. + json_output: A boolean flag. If True, output the details in JSON format. Defaults to False. + + Raises: + typer.Exit: Exits the program after printing the details of all video files. + """ for video in files: if json_output: console.print(video.ffprobe_json()) diff --git a/src/vid_cleaner/config/config.py b/src/vid_cleaner/config/config.py index af8ddb5..1809849 100644 --- a/src/vid_cleaner/config/config.py +++ b/src/vid_cleaner/config/config.py @@ -13,10 +13,7 @@ def pass_opt_without_value(value: str) -> bool: """Confz does not work well with Typer options. Confz requires a value for each CLI option, but Typer does not. To workaround this, for example, if --log-to-file is passed, we set the value to "True" regardless of what follows the CLI option.""" - if value: - return True - - return False + return bool(value) OPT_BOOLEAN = Annotated[ diff --git a/src/vid_cleaner/constants.py b/src/vid_cleaner/constants.py index f07747f..9143f24 100644 --- a/src/vid_cleaner/constants.py +++ b/src/vid_cleaner/constants.py @@ -6,6 +6,18 @@ import typer +class VideoContainerTypes(str, Enum): + """Video container types for vid-cleaner.""" + + MKV = ".mkv" + MP4 = ".mp4" + AVI = ".avi" + WEBM = ".webm" + MOV = ".mov" + WMV = ".wmv" + M4V = ".m4v" + + class CodecTypes(str, Enum): """Codec types for vid-cleaner.""" diff --git a/src/vid_cleaner/models/video_file.py b/src/vid_cleaner/models/video_file.py index 10f82d7..49bb19f 100644 --- a/src/vid_cleaner/models/video_file.py +++ b/src/vid_cleaner/models/video_file.py @@ -170,157 +170,6 @@ def __init__(self, path: Path): # Register cleanup on exit atexit.register(cleanup_on_exit, self) - def _convert_to_h265( - self, - force: bool = False, - dry_run: bool = False, - ) -> Path: - """Convert the video to H.265 codec format. - - Check if conversion is necessary and perform it if so. This involves calculating the - bitrate, building the ffmpeg command, and running it. Return the path to the converted - video or the original video if conversion isn't needed. - - Args: - force (bool, optional): Flag to force conversion even if the video is already H.265. Defaults to False. - dry_run (bool, optional): Run in dry run mode. Defaults to False. - - Returns: - Path: Path to the converted or original video file. - """ - input_path, _ = self._get_input_and_output() - - # Get ffprobe probe - probe = self._get_probe() - video_stream = [ # noqa: RUF015 - stream - for stream in probe.streams - if stream.codec_type == CodecTypes.VIDEO - and stream.codec_name.lower() not in EXCLUDED_VIDEO_CODECS - ][0] - - # Fail if no video stream is found - if not video_stream: - logger.error("No video stream found") - return input_path - - # Return if video is already H.265 - if not force and video_stream.codec_name.lower() in H265_CODECS: - logger.warning( - "H265 ENCODE: Video already H.265 or VP9. Run with `--force` to re-encode. Skipping" - ) - return input_path - - # Calculate Bitrate - # ############################ - # Check if duration info is filled, if so times it by 0.0166667 to get time in minutes. - # If not filled then get duration of stream 0 and do the same. - stream_duration = float(probe.duration) or float(video_stream.duration) - if not stream_duration: - logger.error("Could not calculate video duration") - return input_path - - duration = stream_duration * 0.0166667 - - # Work out currentBitrate using "Bitrate = file size / (number of minutes * .0075)" - # Used from here https://blog.frame.io/2017/03/06/calculate-video-bitrates/ - - stat = input_path.stat() - logger.trace(f"File size: {stat}") - file_size_megabytes = stat.st_size / 1000000 - - current_bitrate = int(file_size_megabytes / (duration * 0.0075)) - target_bitrate = int(file_size_megabytes / (duration * 0.0075) / 2) - min_bitrate = int(current_bitrate * 0.7) - max_bitrate = int(current_bitrate * 1.3) - - # Build FFMPEG Command - command: list[str] = ["-map", "0", "-c:v", "libx265"] - # Create bitrate command - command.extend( - [ - "-b:v", - f"{target_bitrate}k", - "-minrate", - f"{min_bitrate}k", - "-maxrate", - f"{max_bitrate}k", - "-bufsize", - f"{current_bitrate}k", - ] - ) - - # Copy audio and subtitles - command.extend(["-c:a", "copy", "-c:s", "copy"]) - # Run ffmpeg - return self._run_ffmpeg(command, title="Convert to H.265", step="h265", dry_run=dry_run) - - def _convert_to_vp9( - self, - force: bool = False, - dry_run: bool = False, - ) -> Path: - """Convert the video to the VP9 codec format. - - Verify if conversion is required and proceed with it using ffmpeg. This method specifically - targets the VP9 video codec. Return the path to the converted video or the original video - if conversion is not necessary. - - Args: - dry_run (bool, optional): Run in dry run mode. Defaults to False. - force (bool, optional): Flag to force conversion even if the video is already VP9. Defaults to False. - - Returns: - Path: Path to the converted or original video file. - """ - input_path, _ = self._get_input_and_output() - - # Get ffprobe probe - probe = self._get_probe() - video_stream = [ # noqa: RUF015 - stream - for stream in probe.streams - if stream.codec_type == CodecTypes.VIDEO - and stream.codec_name.lower() not in EXCLUDED_VIDEO_CODECS - ][0] - - # Fail if no video stream is found - if not video_stream: - logger.error("No video stream found") - return input_path - - # Return if video is already H.265 - if not force and video_stream.codec_name.lower() in H265_CODECS: - logger.warning( - "VP9 ENCODE: Video already H.265 or VP9. Run with `--force` to re-encode. Skipping" - ) - return input_path - - # Build ffmpeg command - command: list[str] = [ - "-map", - "0", - "-c:v", - "libvpx-vp9", - "-b:v", - "0", - "-crf", - "30", - "-c:a", - "libvorbis", - "-dn", - "-map_chapters", - "-1", - ] - - # Copy subtitles - command.extend(["-c:s", "copy"]) - - # Run ffmpeg - return self._run_ffmpeg( - command, title="Convert to vp9", suffix=".webm", step="vp9", dry_run=dry_run - ) - @staticmethod def _downmix_to_stereo(streams: list[VideoStream]) -> list[str]: """Generate a partial ffmpeg command to downmix audio streams to stereo if needed. @@ -452,7 +301,6 @@ def _get_probe(self) -> VideoProbe: # pragma: no cover Fetch detailed information about the video file using ffprobe. Optionally filter the information by a specific key. - Returns: VideoProbe: The ffprobe probe information. """ @@ -520,43 +368,6 @@ def _process_video(streams: list[VideoStream]) -> list[str]: logger.trace(f"PROCESS VIDEO: {command}") return command - def video_to_1080p(self, force: bool = False, dry_run: bool = False) -> Path: - """Convert the video to 1080p resolution.""" - input_path, _ = self._get_input_and_output() - - # Get ffprobe probe - probe = self._get_probe() - - video_stream = [ # noqa: RUF015 - stream - for stream in probe.streams - if stream.codec_type == CodecTypes.VIDEO - and stream.codec_type.value not in EXCLUDED_VIDEO_CODECS - ][0] - - # Fail if no video stream is found - if not video_stream: - logger.error("No video stream found") - return input_path - - # Return if video is not 4K - if not force and getattr(video_stream, "width", 0) <= 1920: # noqa: PLR2004 - logger.info(f"{SYMBOL_CHECK} No convert to 1080p needed") - return input_path - - # Build ffmpeg command - command: list[str] = [ - "-filter:v", - "scale=width=1920:height=-2", - "-c:a", - "copy", - "-c:s", - "copy", - ] - - # Run ffmpeg - return self._run_ffmpeg(command, title="Convert to 1080p", step="1080p", dry_run=dry_run) - def _process_subtitles( self, streams: list[VideoStream], @@ -817,6 +628,157 @@ def clip( # Run ffmpeg return self._run_ffmpeg(ffmpeg_command, title="Clip video", step="clip", dry_run=dry_run) + def convert_to_h265( + self, + force: bool = False, + dry_run: bool = False, + ) -> Path: + """Convert the video to H.265 codec format. + + Check if conversion is necessary and perform it if so. This involves calculating the + bitrate, building the ffmpeg command, and running it. Return the path to the converted + video or the original video if conversion isn't needed. + + Args: + force (bool, optional): Flag to force conversion even if the video is already H.265. Defaults to False. + dry_run (bool, optional): Run in dry run mode. Defaults to False. + + Returns: + Path: Path to the converted or original video file. + """ + input_path, _ = self._get_input_and_output() + + # Get ffprobe probe + probe = self._get_probe() + video_stream = [ # noqa: RUF015 + stream + for stream in probe.streams + if stream.codec_type == CodecTypes.VIDEO + and stream.codec_name.lower() not in EXCLUDED_VIDEO_CODECS + ][0] + + # Fail if no video stream is found + if not video_stream: + logger.error("No video stream found") + return input_path + + # Return if video is already H.265 + if not force and video_stream.codec_name.lower() in H265_CODECS: + logger.warning( + "H265 ENCODE: Video already H.265 or VP9. Run with `--force` to re-encode. Skipping" + ) + return input_path + + # Calculate Bitrate + # ############################ + # Check if duration info is filled, if so times it by 0.0166667 to get time in minutes. + # If not filled then get duration of stream 0 and do the same. + stream_duration = float(probe.duration) or float(video_stream.duration) + if not stream_duration: + logger.error("Could not calculate video duration") + return input_path + + duration = stream_duration * 0.0166667 + + # Work out currentBitrate using "Bitrate = file size / (number of minutes * .0075)" + # Used from here https://blog.frame.io/2017/03/06/calculate-video-bitrates/ + + stat = input_path.stat() + logger.trace(f"File size: {stat}") + file_size_megabytes = stat.st_size / 1000000 + + current_bitrate = int(file_size_megabytes / (duration * 0.0075)) + target_bitrate = int(file_size_megabytes / (duration * 0.0075) / 2) + min_bitrate = int(current_bitrate * 0.7) + max_bitrate = int(current_bitrate * 1.3) + + # Build FFMPEG Command + command: list[str] = ["-map", "0", "-c:v", "libx265"] + # Create bitrate command + command.extend( + [ + "-b:v", + f"{target_bitrate}k", + "-minrate", + f"{min_bitrate}k", + "-maxrate", + f"{max_bitrate}k", + "-bufsize", + f"{current_bitrate}k", + ] + ) + + # Copy audio and subtitles + command.extend(["-c:a", "copy", "-c:s", "copy"]) + # Run ffmpeg + return self._run_ffmpeg(command, title="Convert to H.265", step="h265", dry_run=dry_run) + + def convert_to_vp9( + self, + force: bool = False, + dry_run: bool = False, + ) -> Path: + """Convert the video to the VP9 codec format. + + Verify if conversion is required and proceed with it using ffmpeg. This method specifically + targets the VP9 video codec. Return the path to the converted video or the original video + if conversion is not necessary. + + Args: + dry_run (bool, optional): Run in dry run mode. Defaults to False. + force (bool, optional): Flag to force conversion even if the video is already VP9. Defaults to False. + + Returns: + Path: Path to the converted or original video file. + """ + input_path, _ = self._get_input_and_output() + + # Get ffprobe probe + probe = self._get_probe() + video_stream = [ # noqa: RUF015 + stream + for stream in probe.streams + if stream.codec_type == CodecTypes.VIDEO + and stream.codec_name.lower() not in EXCLUDED_VIDEO_CODECS + ][0] + + # Fail if no video stream is found + if not video_stream: + logger.error("No video stream found") + return input_path + + # Return if video is already H.265 + if not force and video_stream.codec_name.lower() in H265_CODECS: + logger.warning( + "VP9 ENCODE: Video already H.265 or VP9. Run with `--force` to re-encode. Skipping" + ) + return input_path + + # Build ffmpeg command + command: list[str] = [ + "-map", + "0", + "-c:v", + "libvpx-vp9", + "-b:v", + "0", + "-crf", + "30", + "-c:a", + "libvorbis", + "-dn", + "-map_chapters", + "-1", + ] + + # Copy subtitles + command.extend(["-c:s", "copy"]) + + # Run ffmpeg + return self._run_ffmpeg( + command, title="Convert to vp9", suffix=".webm", step="vp9", dry_run=dry_run + ) + def process_streams( self, langs_to_keep: list[str], @@ -939,6 +901,43 @@ def reorder_streams( # Run ffmpeg return self._run_ffmpeg(command, title="Reorder streams", step="reorder", dry_run=dry_run) + def video_to_1080p(self, force: bool = False, dry_run: bool = False) -> Path: + """Convert the video to 1080p resolution.""" + input_path, _ = self._get_input_and_output() + + # Get ffprobe probe + probe = self._get_probe() + + video_stream = [ # noqa: RUF015 + stream + for stream in probe.streams + if stream.codec_type == CodecTypes.VIDEO + and stream.codec_type.value not in EXCLUDED_VIDEO_CODECS + ][0] + + # Fail if no video stream is found + if not video_stream: + logger.error("No video stream found") + return input_path + + # Return if video is not 4K + if not force and getattr(video_stream, "width", 0) <= 1920: # noqa: PLR2004 + logger.info(f"{SYMBOL_CHECK} No convert to 1080p needed") + return input_path + + # Build ffmpeg command + command: list[str] = [ + "-filter:v", + "scale=width=1920:height=-2", + "-c:a", + "copy", + "-c:s", + "copy", + ] + + # Run ffmpeg + return self._run_ffmpeg(command, title="Convert to 1080p", step="1080p", dry_run=dry_run) + def as_stream_table(self) -> Table: """Return the video probe as a rich table.""" probe = self._get_probe() diff --git a/src/vid_cleaner/utils/helpers.py b/src/vid_cleaner/utils/helpers.py index e6798cd..760d695 100644 --- a/src/vid_cleaner/utils/helpers.py +++ b/src/vid_cleaner/utils/helpers.py @@ -183,15 +183,18 @@ def _copyfileobj( callback: Callable, length: int, ) -> None: - """Copy from src_bytes to dest_bytes. + """Copy bytes from a source file to a destination file, with callback support. - Args: - src_bytes (io.BufferedReader): Source file - dest_bytes (io.BufferedWriter): Destination file - callback (Callable): Callback to call after every length bytes copied - total (int): Total number of bytes to copy - length (int): How many bytes to copy at once + This function reads bytes from a source file and writes them to a destination file in chunks, + calling a specified callback function after each chunk is written. It continues this process + until all bytes are copied or the end of the source file is reached. + Args: + src_bytes: The source file from which to read bytes. Must support the buffer protocol. + dest_bytes: The destination file to which bytes are written. Must support the buffer protocol. + callback: A callable that is invoked after each chunk of bytes is copied. The callable + should accept a single argument, which is the total number of bytes copied so far. + length: The size of each chunk of bytes to be read and written at a time. """ copied = 0 while True: @@ -210,24 +213,33 @@ def copy_with_callback( callback: Callable | None = None, buffer_size: int = BUFFER_SIZE, ) -> Path: - """Copy file with a callback. + """Copy a file from a source to a destination, with optional progress callback. + + This function copies a file from a specified source path to a destination path. During the + copy operation, it can optionally call a provided callback function after each chunk of data + is copied, allowing for progress tracking or other notifications. The size of the chunks copied + at each step can be customized. Args: - src (Path): Path to source file - dest (Path): Path to destination file - callback (Callable, optional): Callable callback that will be called after every buffer_size bytes copied. Defaults to None. - buffer_size (int, optional): How many bytes to copy at once (between calls to callback). Defaults to BUFFER_SIZE (4mb). + src: The path of the source file to copy. + dest: The path of the destination file or directory. If a directory is provided, the source + file will be copied into this directory with the same filename. + callback: An optional callable that is invoked after each chunk of data is copied. The callback + receives one argument: the number of bytes copied so far. If not provided, no callback + is called. + buffer_size: The size of each chunk of data to copy, in bytes. This determines how often the + callback function is called, if provided. Returns: - Path: Path to destination file - + The path to the copied destination file. Raises: - FileNotFoundError: If source file does not exist - SameFileError: If source and destination are the same file - ValueError: If callback is not callable + FileNotFoundError: If the source file does not exist. + SameFileError: If the source and destination paths refer to the same file. + ValueError: If the `callback` is provided but is not callable. - Note: Does not copy extended attributes, resource forks or other metadata. + Note: + This function does not copy file metadata such as extended attributes or resource forks. """ if not src.is_file(): msg = f"src file `{src}` doesn't exist" @@ -257,18 +269,21 @@ def tmp_to_output( overwrite: bool = False, new_file: Path | None = None, ) -> Path: - """Copy a temporary file to an output file. + """Copy a temporary file to an output location with optional renaming and overwrite control. - If no output file is given, the name and directory of the source file will be used. If overwrite is False, a number will be appended to the stem if the output file already exists. + This function copies a temporary file to a specified output location. If the output file path is not provided, the function uses the current working directory and the provided stem for the file name. If the target file exists and overwrite is False, the function will append a number to the stem to create a unique filename. Args: - tmp_file (Path): Path to input file - stem (str): Stem of output file - new_file (Path, optional): Path to output file. Defaults to None. - overwrite (bool, optional): Overwrite output file if it exists. Defaults to False. + tmp_file: The path to the temporary input file to be copied. + stem: The base name (stem) to use for the output file if `new_file` is not provided. If `new_file` is provided, `stem` is ignored. + overwrite: A flag to indicate whether to overwrite the output file if it already exists. If False and the file exists, a number is appended to the file's stem to avoid overwriting. + new_file: An optional path to the output file. If provided, this path is used as the target for the copy operation, and `stem` is ignored. Returns: - Path: Path to output file + The path to the output file where the temporary file has been copied. + + Note: + This function uses a progress bar to indicate the copy progress and handles file naming conflicts by appending a number to the file stem if `overwrite` is False. """ # When a path is given, use that if new_file: diff --git a/src/vid_cleaner/utils/logging.py b/src/vid_cleaner/utils/logging.py index cb11954..703bbff 100644 --- a/src/vid_cleaner/utils/logging.py +++ b/src/vid_cleaner/utils/logging.py @@ -22,7 +22,23 @@ class LogLevel(Enum): def log_formatter(record: dict) -> str: - """Use rich to style log messages.""" + """Format log records for output with styling based on log level. + + This function takes a log record dictionary and returns a formatted string using the Rich + library's syntax for text styling. It assigns different colors and icons to log messages + based on their severity level (e.g., DEBUG, INFO, ERROR). For DEBUG and TRACE levels, it + includes additional information like the logger name, function, and line number. + + Args: + record: A dictionary containing log record information. Expected keys include 'level', + 'message', 'name', 'function', and 'line'. The 'level' key should have a 'name' + attribute indicating the log level as a string. + + Returns: + A formatted and styled string representing the log record, ready to be printed or + displayed. The string includes styling directives that are compatible with the Rich + library. + """ color_map = { "TRACE": "turquoise2", "DEBUG": "cyan", @@ -57,22 +73,22 @@ def log_formatter(record: dict) -> str: def instantiate_logger( verbosity: int, log_file: Path, log_to_file: bool ) -> None: # pragma: no cover - """Instantiate the Loguru logger for brewup. + """Initialize and configure the logging system for the application. - Configure the logger with the specified verbosity level, log file path, - and whether to log to a file. + This function sets up the Loguru logger with a specified verbosity level and optionally + directs the log output to both the console and a file. It supports different verbosity + levels for controlling the amount of log information produced and can also capture logs + from installed libraries when verbosity is high enough. Args: - verbosity (int): The verbosity level of the logger. Valid values are: - - 0: Only log messages with severity level INFO and above will be displayed. - - 1: Only log messages with severity level DEBUG and above will be displayed. - - 2: Only log messages with severity level TRACE and above will be displayed. - > 2: Include debug from installed libraries - log_file (Path): The path to the log file where the log messages will be written. - log_to_file (bool): Whether to log the messages to the file specified by `log_file`. - - Returns: - None + verbosity: Controls the amount of detail in the logs. Levels are as follows: + - 0 for INFO and above, + - 1 for DEBUG and above, + - 2 for TRACE and above, + - Greater than 2 includes DEBUG logs from installed libraries. + log_file: The file path where logs should be written if `log_to_file` is True. + log_to_file: A boolean indicating whether logs should also be saved to the file specified + by `log_file`. """ level = verbosity if verbosity < 3 else 2 # noqa: PLR2004 diff --git a/src/vid_cleaner/vid_cleaner.py b/src/vid_cleaner/vid_cleaner.py index 47fe624..a122800 100644 --- a/src/vid_cleaner/vid_cleaner.py +++ b/src/vid_cleaner/vid_cleaner.py @@ -10,7 +10,7 @@ from pydantic import ValidationError from vid_cleaner.cli import clean, clip, inspect -from vid_cleaner.constants import CONFIG_PATH, VERSION +from vid_cleaner.constants import CONFIG_PATH, VERSION, VideoContainerTypes from vid_cleaner.models import VideoFile from vid_cleaner.utils import ( console, @@ -49,8 +49,8 @@ def version_callback(value: bool) -> None: def parse_video_input(path: str) -> VideoFile: """Takes a string of a path and converts it to a VideoFile object.""" file_path = existing_file_path(path) - if file_path.suffix not in {".mkv", ".mp4", ".avi", "vp9", ".webm", ".mov", ".wmv"}: - msg = f"File type '{file_path.suffix}' is not supported" + if file_path.suffix not in VideoContainerTypes.__members__.values(): + msg = f"Vidcleaner supports {', '.join(VideoContainerTypes.__members__.values())} files. '{file_path.suffix}' is not supported." raise typer.BadParameter(msg) return VideoFile(file_path)