mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-30 03:56:23 -05:00 
			
		
		
		
	Removes support for Python 3.8 and lower from the code base
This commit is contained in:
		 Trenton Holmes
					Trenton Holmes
				
			
				
					committed by
					
						 Trenton H
						Trenton H
					
				
			
			
				
	
			
			
			 Trenton H
						Trenton H
					
				
			
						parent
						
							c8bfbb9315
						
					
				
				
					commit
					650c816a7b
				
			
							
								
								
									
										9
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @@ -17,9 +17,8 @@ env: | ||||
|   # This is the version of pipenv all the steps will use | ||||
|   # If changing this, change Dockerfile | ||||
|   DEFAULT_PIP_ENV_VERSION: "2023.9.8" | ||||
|   # This is the default version of Python to use in most steps | ||||
|   # If changing this, change Dockerfile | ||||
|   DEFAULT_PYTHON_VERSION: "3.9" | ||||
|   # This is the default version of Python to use in most steps which aren't specific | ||||
|   DEFAULT_PYTHON_VERSION: "3.10" | ||||
|  | ||||
| jobs: | ||||
|   pre-commit: | ||||
| @@ -105,7 +104,7 @@ jobs: | ||||
|       - pre-commit | ||||
|     strategy: | ||||
|       matrix: | ||||
|         python-version: ['3.8', '3.9', '3.10', '3.11'] | ||||
|         python-version: ['3.9', '3.10', '3.11'] | ||||
|       fail-fast: false | ||||
|     steps: | ||||
|       - | ||||
| @@ -283,7 +282,7 @@ jobs: | ||||
|         #  a tag | ||||
|         # Otherwise forks would require a Docker Hub account and secrets setup | ||||
|         run: | | ||||
|           if [[ ${{ github.repository_owner }} == "paperless-ngx" && ( ${{ github.ref_name }} == "main" || ${{ github.ref_name }} == "dev" || ${{ github.ref_name }} == "beta" || ${{ startsWith(github.ref, 'refs/tags/v') }} == "true" ) ]] ; then | ||||
|           if [[ ${{ github.repository_owner }} == "paperless-ngx" && ( ${{ github.ref_name }} == "dev" || ${{ github.ref_name }} == "beta" || ${{ startsWith(github.ref, 'refs/tags/v') }} == "true" ) ]] ; then | ||||
|             echo "Enabling DockerHub image push" | ||||
|             echo "enable=true" >> $GITHUB_OUTPUT | ||||
|           else | ||||
|   | ||||
| @@ -41,7 +41,7 @@ repos: | ||||
|     hooks: | ||||
|       - id: ruff | ||||
|   - repo: https://github.com/psf/black-pre-commit-mirror | ||||
|     rev: 23.7.0 | ||||
|     rev: 23.9.0 | ||||
|     hooks: | ||||
|       - id: black | ||||
|   # Dockerfile hooks | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| 3.8.17 | ||||
| 3.9.18 | ||||
|   | ||||
| @@ -7,7 +7,7 @@ fix = true | ||||
| line-length = 88 | ||||
| respect-gitignore = true | ||||
| src = ["src"] | ||||
| target-version = "py38" | ||||
| target-version = "py39" | ||||
| format = "grouped" | ||||
| show-fixes = true | ||||
|  | ||||
|   | ||||
| @@ -11,7 +11,7 @@ If you want to implement something big: | ||||
|  | ||||
| ## Python | ||||
|  | ||||
| Paperless supports python 3.8 and 3.9. We format Python code with [Black](https://github.com/psf/black). | ||||
| Paperless supports python 3.9 - 3.11. We format Python code with [Black](https://github.com/psf/black). | ||||
|  | ||||
| ## Branches | ||||
|  | ||||
|   | ||||
							
								
								
									
										1
									
								
								Pipfile
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								Pipfile
									
									
									
									
									
								
							| @@ -87,7 +87,6 @@ types-redis = "*" | ||||
| types-tqdm = "*" | ||||
| types-Markdown = "*" | ||||
| types-Pygments = "*" | ||||
| types-backports = "*" | ||||
| types-colorama = "*" | ||||
| types-psycopg2 = "*" | ||||
| types-setuptools = "*" | ||||
|   | ||||
							
								
								
									
										339
									
								
								Pipfile.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										339
									
								
								Pipfile.lock
									
									
									
										generated
									
									
									
								
							| @@ -1,7 +1,7 @@ | ||||
| { | ||||
|     "_meta": { | ||||
|         "hash": { | ||||
|             "sha256": "a3c89ceea5672a9fc97836a0dfef8e3cc0dcdab411847bc7f3bfa574b0446f1a" | ||||
|             "sha256": "ac966c7a02e216e5198e13857f2701fd5e9b1c4dbb39ad151889f8a4d8cd8711" | ||||
|         }, | ||||
|         "pipfile-spec": 6, | ||||
|         "requires": {}, | ||||
| @@ -46,28 +46,6 @@ | ||||
|             "markers": "python_full_version <= '3.11.2'", | ||||
|             "version": "==4.0.3" | ||||
|         }, | ||||
|         "backports.zoneinfo": { | ||||
|             "hashes": [ | ||||
|                 "sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf", | ||||
|                 "sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328", | ||||
|                 "sha256:1c5742112073a563c81f786e77514969acb58649bcdf6cdf0b4ed31a348d4546", | ||||
|                 "sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6", | ||||
|                 "sha256:5c144945a7752ca544b4b78c8c41544cdfaf9786f25fe5ffb10e838e19a27570", | ||||
|                 "sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9", | ||||
|                 "sha256:8439c030a11780786a2002261569bdf362264f605dfa4d65090b64b05c9f79a7", | ||||
|                 "sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987", | ||||
|                 "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722", | ||||
|                 "sha256:a76b38c52400b762e48131494ba26be363491ac4f9a04c1b7e92483d169f6582", | ||||
|                 "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc", | ||||
|                 "sha256:e55b384612d93be96506932a786bbcde5a2db7a9e6a4bb4bffe8b733f5b9036b", | ||||
|                 "sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1", | ||||
|                 "sha256:e8236383a20872c0cdf5a62b554b27538db7fa1bbec52429d8d106effbaeca08", | ||||
|                 "sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac", | ||||
|                 "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2" | ||||
|             ], | ||||
|             "markers": "python_version < '3.9'", | ||||
|             "version": "==0.2.1" | ||||
|         }, | ||||
|         "billiard": { | ||||
|             "hashes": [ | ||||
|                 "sha256:0f50d6be051c6b2b75bfbc8bfd85af195c5739c281d3f5b86a5640c65563614a", | ||||
| @@ -746,14 +724,6 @@ | ||||
|             ], | ||||
|             "version": "==0.4.4" | ||||
|         }, | ||||
|         "importlib-resources": { | ||||
|             "hashes": [ | ||||
|                 "sha256:134832a506243891221b88b4ae1213327eea96ceb4e407a00d790bb0626f45cf", | ||||
|                 "sha256:4359457e42708462b9626a04657c6208ad799ceb41e5c58c57ffa0e6a098a5d4" | ||||
|             ], | ||||
|             "markers": "python_version < '3.9'", | ||||
|             "version": "==6.0.1" | ||||
|         }, | ||||
|         "inotify-simple": { | ||||
|             "hashes": [ | ||||
|                 "sha256:8440ffe49c4ae81a8df57c1ae1eb4b6bfa7acb830099bfb3e305b383005cc128" | ||||
| @@ -1001,37 +971,34 @@ | ||||
|         }, | ||||
|         "numpy": { | ||||
|             "hashes": [ | ||||
|                 "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f", | ||||
|                 "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61", | ||||
|                 "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7", | ||||
|                 "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400", | ||||
|                 "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef", | ||||
|                 "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2", | ||||
|                 "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d", | ||||
|                 "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc", | ||||
|                 "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835", | ||||
|                 "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706", | ||||
|                 "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5", | ||||
|                 "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4", | ||||
|                 "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6", | ||||
|                 "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463", | ||||
|                 "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a", | ||||
|                 "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f", | ||||
|                 "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e", | ||||
|                 "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e", | ||||
|                 "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694", | ||||
|                 "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8", | ||||
|                 "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64", | ||||
|                 "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d", | ||||
|                 "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc", | ||||
|                 "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254", | ||||
|                 "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2", | ||||
|                 "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1", | ||||
|                 "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810", | ||||
|                 "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9" | ||||
|                 "sha256:0d60fbae8e0019865fc4784745814cff1c421df5afee233db6d88ab4f14655a2", | ||||
|                 "sha256:1a1329e26f46230bf77b02cc19e900db9b52f398d6722ca853349a782d4cff55", | ||||
|                 "sha256:1b9735c27cea5d995496f46a8b1cd7b408b3f34b6d50459d9ac8fe3a20cc17bf", | ||||
|                 "sha256:2792d23d62ec51e50ce4d4b7d73de8f67a2fd3ea710dcbc8563a51a03fb07b01", | ||||
|                 "sha256:3e0746410e73384e70d286f93abf2520035250aad8c5714240b0492a7302fdca", | ||||
|                 "sha256:4c3abc71e8b6edba80a01a52e66d83c5d14433cbcd26a40c329ec7ed09f37901", | ||||
|                 "sha256:5883c06bb92f2e6c8181df7b39971a5fb436288db58b5a1c3967702d4278691d", | ||||
|                 "sha256:5c97325a0ba6f9d041feb9390924614b60b99209a71a69c876f71052521d42a4", | ||||
|                 "sha256:60e7f0f7f6d0eee8364b9a6304c2845b9c491ac706048c7e8cf47b83123b8dbf", | ||||
|                 "sha256:76b4115d42a7dfc5d485d358728cdd8719be33cc5ec6ec08632a5d6fca2ed380", | ||||
|                 "sha256:7dc869c0c75988e1c693d0e2d5b26034644399dd929bc049db55395b1379e044", | ||||
|                 "sha256:834b386f2b8210dca38c71a6e0f4fd6922f7d3fcff935dbe3a570945acb1b545", | ||||
|                 "sha256:8b77775f4b7df768967a7c8b3567e309f617dd5e99aeb886fa14dc1a0791141f", | ||||
|                 "sha256:90319e4f002795ccfc9050110bbbaa16c944b1c37c0baeea43c5fb881693ae1f", | ||||
|                 "sha256:b79e513d7aac42ae918db3ad1341a015488530d0bb2a6abcbdd10a3a829ccfd3", | ||||
|                 "sha256:bb33d5a1cf360304754913a350edda36d5b8c5331a8237268c48f91253c3a364", | ||||
|                 "sha256:bec1e7213c7cb00d67093247f8c4db156fd03075f49876957dca4711306d39c9", | ||||
|                 "sha256:c5462d19336db4560041517dbb7759c21d181a67cb01b36ca109b2ae37d32418", | ||||
|                 "sha256:c5652ea24d33585ea39eb6a6a15dac87a1206a692719ff45d53c5282e66d4a8f", | ||||
|                 "sha256:d7806500e4f5bdd04095e849265e55de20d8cc4b661b038957354327f6d9b295", | ||||
|                 "sha256:db3ccc4e37a6873045580d413fe79b68e47a681af8db2e046f1dacfa11f86eb3", | ||||
|                 "sha256:dfe4a913e29b418d096e696ddd422d8a5d13ffba4ea91f9f60440a3b759b0187", | ||||
|                 "sha256:eb942bfb6f84df5ce05dbf4b46673ffed0d3da59f13635ea9b926af3deb76926", | ||||
|                 "sha256:f08f2e037bba04e707eebf4bc934f1972a315c883a9e0ebfa8a7756eabf9e357", | ||||
|                 "sha256:fd608e19c8d7c55021dffd43bfe5492fab8cc105cc8986f813f8c3c048b38760" | ||||
|             ], | ||||
|             "markers": "python_version >= '3.8'", | ||||
|             "version": "==1.24.4" | ||||
|             "markers": "python_version >= '3.9'", | ||||
|             "version": "==1.25.2" | ||||
|         }, | ||||
|         "ocrmypdf": { | ||||
|             "hashes": [ | ||||
| @@ -1608,30 +1575,34 @@ | ||||
|         }, | ||||
|         "scipy": { | ||||
|             "hashes": [ | ||||
|                 "sha256:049a8bbf0ad95277ffba9b3b7d23e5369cc39e66406d60422c8cfef40ccc8415", | ||||
|                 "sha256:07c3457ce0b3ad5124f98a86533106b643dd811dd61b548e78cf4c8786652f6f", | ||||
|                 "sha256:0f1564ea217e82c1bbe75ddf7285ba0709ecd503f048cb1236ae9995f64217bd", | ||||
|                 "sha256:1553b5dcddd64ba9a0d95355e63fe6c3fc303a8fd77c7bc91e77d61363f7433f", | ||||
|                 "sha256:15a35c4242ec5f292c3dd364a7c71a61be87a3d4ddcc693372813c0b73c9af1d", | ||||
|                 "sha256:1b4735d6c28aad3cdcf52117e0e91d6b39acd4272f3f5cd9907c24ee931ad601", | ||||
|                 "sha256:2cf9dfb80a7b4589ba4c40ce7588986d6d5cebc5457cad2c2880f6bc2d42f3a5", | ||||
|                 "sha256:39becb03541f9e58243f4197584286e339029e8908c46f7221abeea4b749fa88", | ||||
|                 "sha256:43b8e0bcb877faf0abfb613d51026cd5cc78918e9530e375727bf0625c82788f", | ||||
|                 "sha256:4b3f429188c66603a1a5c549fb414e4d3bdc2a24792e061ffbd607d3d75fd84e", | ||||
|                 "sha256:4c0ff64b06b10e35215abce517252b375e580a6125fd5fdf6421b98efbefb2d2", | ||||
|                 "sha256:51af417a000d2dbe1ec6c372dfe688e041a7084da4fdd350aeb139bd3fb55353", | ||||
|                 "sha256:5678f88c68ea866ed9ebe3a989091088553ba12c6090244fdae3e467b1139c35", | ||||
|                 "sha256:79c8e5a6c6ffaf3a2262ef1be1e108a035cf4f05c14df56057b64acc5bebffb6", | ||||
|                 "sha256:7ff7f37b1bf4417baca958d254e8e2875d0cc23aaadbe65b3d5b3077b0eb23ea", | ||||
|                 "sha256:aaea0a6be54462ec027de54fca511540980d1e9eea68b2d5c1dbfe084797be35", | ||||
|                 "sha256:bce5869c8d68cf383ce240e44c1d9ae7c06078a9396df68ce88a1230f93a30c1", | ||||
|                 "sha256:cd9f1027ff30d90618914a64ca9b1a77a431159df0e2a195d8a9e8a04c78abf9", | ||||
|                 "sha256:d925fa1c81b772882aa55bcc10bf88324dadb66ff85d548c71515f6689c6dac5", | ||||
|                 "sha256:e7354fd7527a4b0377ce55f286805b34e8c54b91be865bac273f527e1b839019", | ||||
|                 "sha256:fae8a7b898c42dffe3f7361c40d5952b6bf32d10c4569098d276b4c547905ee1" | ||||
|                 "sha256:0f3261f14b767b316d7137c66cc4f33a80ea05841b9c87ad83a726205b901423", | ||||
|                 "sha256:10eb6af2f751aa3424762948e5352f707b0dece77288206f227864ddf675aca0", | ||||
|                 "sha256:1342ca385c673208f32472830c10110a9dcd053cf0c4b7d4cd7026d0335a6c1d", | ||||
|                 "sha256:214cdf04bbae7a54784f8431f976704ed607c4bc69ba0d5d5d6a9df84374df76", | ||||
|                 "sha256:2b997a5369e2d30c97995dcb29d638701f8000d04df01b8e947f206e5d0ac788", | ||||
|                 "sha256:2c91cf049ffb5575917f2a01da1da082fd24ed48120d08a6e7297dfcac771dcd", | ||||
|                 "sha256:3aeb87661de987f8ec56fa6950863994cd427209158255a389fc5aea51fa7055", | ||||
|                 "sha256:4447ad057d7597476f9862ecbd9285bbf13ba9d73ce25acfa4e4b11c6801b4c9", | ||||
|                 "sha256:542a757e2a6ec409e71df3d8fd20127afbbacb1c07990cb23c5870c13953d899", | ||||
|                 "sha256:8d9886f44ef8c9e776cb7527fb01455bf4f4a46c455c4682edc2c2cc8cd78562", | ||||
|                 "sha256:90d3b1364e751d8214e325c371f0ee0dd38419268bf4888b2ae1040a6b266b2a", | ||||
|                 "sha256:95763fbda1206bec41157582bea482f50eb3702c85fffcf6d24394b071c0e87a", | ||||
|                 "sha256:ac74b1512d38718fb6a491c439aa7b3605b96b1ed3be6599c17d49d6c60fca18", | ||||
|                 "sha256:afdb0d983f6135d50770dd979df50bf1c7f58b5b33e0eb8cf5c73c70600eae1d", | ||||
|                 "sha256:b0620240ef445b5ddde52460e6bc3483b7c9c750275369379e5f609a1050911c", | ||||
|                 "sha256:b133f237bd8ba73bad51bc12eb4f2d84cbec999753bf25ba58235e9fc2096d80", | ||||
|                 "sha256:b29318a5e39bd200ca4381d80b065cdf3076c7d7281c5e36569e99273867f61d", | ||||
|                 "sha256:b8425fa963a32936c9773ee3ce44a765d8ff67eed5f4ac81dc1e4a819a238ee9", | ||||
|                 "sha256:d2b813bfbe8dec6a75164523de650bad41f4405d35b0fa24c2c28ae07fcefb20", | ||||
|                 "sha256:d690e1ca993c8f7ede6d22e5637541217fc6a4d3f78b3672a6fe454dbb7eb9a7", | ||||
|                 "sha256:e367904a0fec76433bf3fbf3e85bf60dae8e9e585ffd21898ab1085a29a04d16", | ||||
|                 "sha256:ea932570b1c2a30edafca922345854ff2cd20d43cd9123b6dacfdecebfc1a80b", | ||||
|                 "sha256:f28f1f6cfeb48339c192efc6275749b2a25a7e49c4d8369a28b6591da02fbc9a", | ||||
|                 "sha256:f73102f769ee06041a3aa26b5841359b1a93cc364ce45609657751795e8f4a4a", | ||||
|                 "sha256:fa4909c6c20c3d91480533cddbc0e7c6d849e7d9ded692918c76ce5964997898" | ||||
|             ], | ||||
|             "markers": "python_version < '3.12' and python_version >= '3.8'", | ||||
|             "version": "==1.10.1" | ||||
|             "markers": "python_version < '3.13' and python_version >= '3.9'", | ||||
|             "version": "==1.11.2" | ||||
|         }, | ||||
|         "setproctitle": { | ||||
|             "hashes": [ | ||||
| @@ -2025,14 +1996,6 @@ | ||||
|             "index": "pypi", | ||||
|             "version": "==2.7.4" | ||||
|         }, | ||||
|         "zipp": { | ||||
|             "hashes": [ | ||||
|                 "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0", | ||||
|                 "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147" | ||||
|             ], | ||||
|             "markers": "python_version < '3.10'", | ||||
|             "version": "==3.16.2" | ||||
|         }, | ||||
|         "zstandard": { | ||||
|             "hashes": [ | ||||
|                 "sha256:0aad6090ac164a9d237d096c8af241b8dcd015524ac6dbec1330092dba151657", | ||||
| @@ -2132,10 +2095,10 @@ | ||||
|         }, | ||||
|         "autobahn": { | ||||
|             "hashes": [ | ||||
|                 "sha256:c5ef8ca7422015a1af774a883b8aef73d4954c9fcd182c9b5244e08e973f7c3a" | ||||
|                 "sha256:ec9421c52a2103364d1ef0468036e6019ee84f71721e86b36fe19ad6966c1181" | ||||
|             ], | ||||
|             "markers": "python_version >= '3.7'", | ||||
|             "version": "==23.1.2" | ||||
|             "markers": "python_version >= '3.9'", | ||||
|             "version": "==23.6.2" | ||||
|         }, | ||||
|         "automat": { | ||||
|             "hashes": [ | ||||
| @@ -2154,32 +2117,12 @@ | ||||
|         }, | ||||
|         "black": { | ||||
|             "hashes": [ | ||||
|                 "sha256:01ede61aac8c154b55f35301fac3e730baf0c9cf8120f65a9cd61a81cfb4a0c3", | ||||
|                 "sha256:022a582720b0d9480ed82576c920a8c1dde97cc38ff11d8d8859b3bd6ca9eedb", | ||||
|                 "sha256:25cc308838fe71f7065df53aedd20327969d05671bac95b38fdf37ebe70ac087", | ||||
|                 "sha256:27eb7a0c71604d5de083757fbdb245b1a4fae60e9596514c6ec497eb63f95320", | ||||
|                 "sha256:327a8c2550ddc573b51e2c352adb88143464bb9d92c10416feb86b0f5aee5ff6", | ||||
|                 "sha256:47e56d83aad53ca140da0af87678fb38e44fd6bc0af71eebab2d1f59b1acf1d3", | ||||
|                 "sha256:501387a9edcb75d7ae8a4412bb8749900386eaef258f1aefab18adddea1936bc", | ||||
|                 "sha256:552513d5cd5694590d7ef6f46e1767a4df9af168d449ff767b13b084c020e63f", | ||||
|                 "sha256:5c4bc552ab52f6c1c506ccae05681fab58c3f72d59ae6e6639e8885e94fe2587", | ||||
|                 "sha256:642496b675095d423f9b8448243336f8ec71c9d4d57ec17bf795b67f08132a91", | ||||
|                 "sha256:6d1c6022b86f83b632d06f2b02774134def5d4d4f1dac8bef16d90cda18ba28a", | ||||
|                 "sha256:7f3bf2dec7d541b4619b8ce526bda74a6b0bffc480a163fed32eb8b3c9aed8ad", | ||||
|                 "sha256:831d8f54c3a8c8cf55f64d0422ee875eecac26f5f649fb6c1df65316b67c8926", | ||||
|                 "sha256:8417dbd2f57b5701492cd46edcecc4f9208dc75529bcf76c514864e48da867d9", | ||||
|                 "sha256:86cee259349b4448adb4ef9b204bb4467aae74a386bce85d56ba4f5dc0da27be", | ||||
|                 "sha256:893695a76b140881531062d48476ebe4a48f5d1e9388177e175d76234ca247cd", | ||||
|                 "sha256:9fd59d418c60c0348505f2ddf9609c1e1de8e7493eab96198fc89d9f865e7a96", | ||||
|                 "sha256:ad0014efc7acf0bd745792bd0d8857413652979200ab924fbf239062adc12491", | ||||
|                 "sha256:b5b0ee6d96b345a8b420100b7d71ebfdd19fab5e8301aff48ec270042cd40ac2", | ||||
|                 "sha256:c333286dc3ddca6fdff74670b911cccedacb4ef0a60b34e491b8a67c833b343a", | ||||
|                 "sha256:f9062af71c59c004cd519e2fb8f5d25d39e46d3af011b41ab43b9c74e27e236f", | ||||
|                 "sha256:fb074d8b213749fa1d077d630db0d5f8cc3b2ae63587ad4116e8a436e9bbe995" | ||||
|                 "sha256:3511c8a7e22ce653f89ae90dfddaf94f3bb7e2587a245246572d3b9c92adf066", | ||||
|                 "sha256:9366c1f898981f09eb8da076716c02fd021f5a0e63581c66501d68a2e4eab844" | ||||
|             ], | ||||
|             "index": "pypi", | ||||
|             "markers": "python_version >= '3.8'", | ||||
|             "version": "==23.7.0" | ||||
|             "version": "==23.9.0" | ||||
|         }, | ||||
|         "certifi": { | ||||
|             "hashes": [ | ||||
| @@ -2503,11 +2446,11 @@ | ||||
|         }, | ||||
|         "faker": { | ||||
|             "hashes": [ | ||||
|                 "sha256:0c3a7cbaa6497dcc18819bfe31ae916d2180c31a3b1ea8907c948d94eb06955d", | ||||
|                 "sha256:11f0d2a6632d212e8ab89fd9152a1b8db777816e42f3579f8c63c11e43cec873" | ||||
|                 "sha256:7cf705758f6cc5dd31f628e323f306a6d881e9a8a103f1e32e5f30a4cad0974c", | ||||
|                 "sha256:d79d5ea59f31e00fbb882546840a4adb2fd0bae99b103db1ba5869f176bc530b" | ||||
|             ], | ||||
|             "markers": "python_version >= '3.8'", | ||||
|             "version": "==19.4.0" | ||||
|             "version": "==19.6.0" | ||||
|         }, | ||||
|         "filelock": { | ||||
|             "hashes": [ | ||||
| @@ -2736,37 +2679,34 @@ | ||||
|         }, | ||||
|         "numpy": { | ||||
|             "hashes": [ | ||||
|                 "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f", | ||||
|                 "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61", | ||||
|                 "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7", | ||||
|                 "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400", | ||||
|                 "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef", | ||||
|                 "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2", | ||||
|                 "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d", | ||||
|                 "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc", | ||||
|                 "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835", | ||||
|                 "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706", | ||||
|                 "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5", | ||||
|                 "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4", | ||||
|                 "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6", | ||||
|                 "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463", | ||||
|                 "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a", | ||||
|                 "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f", | ||||
|                 "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e", | ||||
|                 "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e", | ||||
|                 "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694", | ||||
|                 "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8", | ||||
|                 "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64", | ||||
|                 "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d", | ||||
|                 "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc", | ||||
|                 "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254", | ||||
|                 "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2", | ||||
|                 "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1", | ||||
|                 "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810", | ||||
|                 "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9" | ||||
|                 "sha256:0d60fbae8e0019865fc4784745814cff1c421df5afee233db6d88ab4f14655a2", | ||||
|                 "sha256:1a1329e26f46230bf77b02cc19e900db9b52f398d6722ca853349a782d4cff55", | ||||
|                 "sha256:1b9735c27cea5d995496f46a8b1cd7b408b3f34b6d50459d9ac8fe3a20cc17bf", | ||||
|                 "sha256:2792d23d62ec51e50ce4d4b7d73de8f67a2fd3ea710dcbc8563a51a03fb07b01", | ||||
|                 "sha256:3e0746410e73384e70d286f93abf2520035250aad8c5714240b0492a7302fdca", | ||||
|                 "sha256:4c3abc71e8b6edba80a01a52e66d83c5d14433cbcd26a40c329ec7ed09f37901", | ||||
|                 "sha256:5883c06bb92f2e6c8181df7b39971a5fb436288db58b5a1c3967702d4278691d", | ||||
|                 "sha256:5c97325a0ba6f9d041feb9390924614b60b99209a71a69c876f71052521d42a4", | ||||
|                 "sha256:60e7f0f7f6d0eee8364b9a6304c2845b9c491ac706048c7e8cf47b83123b8dbf", | ||||
|                 "sha256:76b4115d42a7dfc5d485d358728cdd8719be33cc5ec6ec08632a5d6fca2ed380", | ||||
|                 "sha256:7dc869c0c75988e1c693d0e2d5b26034644399dd929bc049db55395b1379e044", | ||||
|                 "sha256:834b386f2b8210dca38c71a6e0f4fd6922f7d3fcff935dbe3a570945acb1b545", | ||||
|                 "sha256:8b77775f4b7df768967a7c8b3567e309f617dd5e99aeb886fa14dc1a0791141f", | ||||
|                 "sha256:90319e4f002795ccfc9050110bbbaa16c944b1c37c0baeea43c5fb881693ae1f", | ||||
|                 "sha256:b79e513d7aac42ae918db3ad1341a015488530d0bb2a6abcbdd10a3a829ccfd3", | ||||
|                 "sha256:bb33d5a1cf360304754913a350edda36d5b8c5331a8237268c48f91253c3a364", | ||||
|                 "sha256:bec1e7213c7cb00d67093247f8c4db156fd03075f49876957dca4711306d39c9", | ||||
|                 "sha256:c5462d19336db4560041517dbb7759c21d181a67cb01b36ca109b2ae37d32418", | ||||
|                 "sha256:c5652ea24d33585ea39eb6a6a15dac87a1206a692719ff45d53c5282e66d4a8f", | ||||
|                 "sha256:d7806500e4f5bdd04095e849265e55de20d8cc4b661b038957354327f6d9b295", | ||||
|                 "sha256:db3ccc4e37a6873045580d413fe79b68e47a681af8db2e046f1dacfa11f86eb3", | ||||
|                 "sha256:dfe4a913e29b418d096e696ddd422d8a5d13ffba4ea91f9f60440a3b759b0187", | ||||
|                 "sha256:eb942bfb6f84df5ce05dbf4b46673ffed0d3da59f13635ea9b926af3deb76926", | ||||
|                 "sha256:f08f2e037bba04e707eebf4bc934f1972a315c883a9e0ebfa8a7756eabf9e357", | ||||
|                 "sha256:fd608e19c8d7c55021dffd43bfe5492fab8cc105cc8986f813f8c3c048b38760" | ||||
|             ], | ||||
|             "markers": "python_version >= '3.8'", | ||||
|             "version": "==1.24.4" | ||||
|             "markers": "python_version >= '3.9'", | ||||
|             "version": "==1.25.2" | ||||
|         }, | ||||
|         "packaging": { | ||||
|             "hashes": [ | ||||
| @@ -2969,12 +2909,12 @@ | ||||
|         }, | ||||
|         "pytest-httpx": { | ||||
|             "hashes": [ | ||||
|                 "sha256:3a82797f3a9a14d51e8c6b7fa97524b68b847ee801109c062e696b4744f4431c", | ||||
|                 "sha256:cefb7dcf66a4cb0601b0de05e576cca423b6081f3245e7912a4d84c58fa3eae8" | ||||
|                 "sha256:193cecb57a005eb15288f68986f328d4c8d06c0b7c4ef1ce512e024cbb1d5961", | ||||
|                 "sha256:259e6266cf3e04eb8fcc18dff262657ad96f6b8668dc2171fb353eaec5571889" | ||||
|             ], | ||||
|             "index": "pypi", | ||||
|             "markers": "python_version >= '3.7'", | ||||
|             "version": "==0.22.0" | ||||
|             "markers": "python_version >= '3.9'", | ||||
|             "version": "==0.24.0" | ||||
|         }, | ||||
|         "pytest-rerunfailures": { | ||||
|             "hashes": [ | ||||
| @@ -3011,13 +2951,6 @@ | ||||
|             "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", | ||||
|             "version": "==2.8.2" | ||||
|         }, | ||||
|         "pytz": { | ||||
|             "hashes": [ | ||||
|                 "sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b", | ||||
|                 "sha256:ce42d816b81b68506614c11e8937d3aa9e41007ceb50bfdcb0749b921bf646c7" | ||||
|             ], | ||||
|             "version": "==2023.3.post1" | ||||
|         }, | ||||
|         "pywavelets": { | ||||
|             "hashes": [ | ||||
|                 "sha256:030670a213ee8fefa56f6387b0c8e7d970c7f7ad6850dc048bd7c89364771b9b", | ||||
| @@ -3240,30 +3173,34 @@ | ||||
|         }, | ||||
|         "scipy": { | ||||
|             "hashes": [ | ||||
|                 "sha256:049a8bbf0ad95277ffba9b3b7d23e5369cc39e66406d60422c8cfef40ccc8415", | ||||
|                 "sha256:07c3457ce0b3ad5124f98a86533106b643dd811dd61b548e78cf4c8786652f6f", | ||||
|                 "sha256:0f1564ea217e82c1bbe75ddf7285ba0709ecd503f048cb1236ae9995f64217bd", | ||||
|                 "sha256:1553b5dcddd64ba9a0d95355e63fe6c3fc303a8fd77c7bc91e77d61363f7433f", | ||||
|                 "sha256:15a35c4242ec5f292c3dd364a7c71a61be87a3d4ddcc693372813c0b73c9af1d", | ||||
|                 "sha256:1b4735d6c28aad3cdcf52117e0e91d6b39acd4272f3f5cd9907c24ee931ad601", | ||||
|                 "sha256:2cf9dfb80a7b4589ba4c40ce7588986d6d5cebc5457cad2c2880f6bc2d42f3a5", | ||||
|                 "sha256:39becb03541f9e58243f4197584286e339029e8908c46f7221abeea4b749fa88", | ||||
|                 "sha256:43b8e0bcb877faf0abfb613d51026cd5cc78918e9530e375727bf0625c82788f", | ||||
|                 "sha256:4b3f429188c66603a1a5c549fb414e4d3bdc2a24792e061ffbd607d3d75fd84e", | ||||
|                 "sha256:4c0ff64b06b10e35215abce517252b375e580a6125fd5fdf6421b98efbefb2d2", | ||||
|                 "sha256:51af417a000d2dbe1ec6c372dfe688e041a7084da4fdd350aeb139bd3fb55353", | ||||
|                 "sha256:5678f88c68ea866ed9ebe3a989091088553ba12c6090244fdae3e467b1139c35", | ||||
|                 "sha256:79c8e5a6c6ffaf3a2262ef1be1e108a035cf4f05c14df56057b64acc5bebffb6", | ||||
|                 "sha256:7ff7f37b1bf4417baca958d254e8e2875d0cc23aaadbe65b3d5b3077b0eb23ea", | ||||
|                 "sha256:aaea0a6be54462ec027de54fca511540980d1e9eea68b2d5c1dbfe084797be35", | ||||
|                 "sha256:bce5869c8d68cf383ce240e44c1d9ae7c06078a9396df68ce88a1230f93a30c1", | ||||
|                 "sha256:cd9f1027ff30d90618914a64ca9b1a77a431159df0e2a195d8a9e8a04c78abf9", | ||||
|                 "sha256:d925fa1c81b772882aa55bcc10bf88324dadb66ff85d548c71515f6689c6dac5", | ||||
|                 "sha256:e7354fd7527a4b0377ce55f286805b34e8c54b91be865bac273f527e1b839019", | ||||
|                 "sha256:fae8a7b898c42dffe3f7361c40d5952b6bf32d10c4569098d276b4c547905ee1" | ||||
|                 "sha256:0f3261f14b767b316d7137c66cc4f33a80ea05841b9c87ad83a726205b901423", | ||||
|                 "sha256:10eb6af2f751aa3424762948e5352f707b0dece77288206f227864ddf675aca0", | ||||
|                 "sha256:1342ca385c673208f32472830c10110a9dcd053cf0c4b7d4cd7026d0335a6c1d", | ||||
|                 "sha256:214cdf04bbae7a54784f8431f976704ed607c4bc69ba0d5d5d6a9df84374df76", | ||||
|                 "sha256:2b997a5369e2d30c97995dcb29d638701f8000d04df01b8e947f206e5d0ac788", | ||||
|                 "sha256:2c91cf049ffb5575917f2a01da1da082fd24ed48120d08a6e7297dfcac771dcd", | ||||
|                 "sha256:3aeb87661de987f8ec56fa6950863994cd427209158255a389fc5aea51fa7055", | ||||
|                 "sha256:4447ad057d7597476f9862ecbd9285bbf13ba9d73ce25acfa4e4b11c6801b4c9", | ||||
|                 "sha256:542a757e2a6ec409e71df3d8fd20127afbbacb1c07990cb23c5870c13953d899", | ||||
|                 "sha256:8d9886f44ef8c9e776cb7527fb01455bf4f4a46c455c4682edc2c2cc8cd78562", | ||||
|                 "sha256:90d3b1364e751d8214e325c371f0ee0dd38419268bf4888b2ae1040a6b266b2a", | ||||
|                 "sha256:95763fbda1206bec41157582bea482f50eb3702c85fffcf6d24394b071c0e87a", | ||||
|                 "sha256:ac74b1512d38718fb6a491c439aa7b3605b96b1ed3be6599c17d49d6c60fca18", | ||||
|                 "sha256:afdb0d983f6135d50770dd979df50bf1c7f58b5b33e0eb8cf5c73c70600eae1d", | ||||
|                 "sha256:b0620240ef445b5ddde52460e6bc3483b7c9c750275369379e5f609a1050911c", | ||||
|                 "sha256:b133f237bd8ba73bad51bc12eb4f2d84cbec999753bf25ba58235e9fc2096d80", | ||||
|                 "sha256:b29318a5e39bd200ca4381d80b065cdf3076c7d7281c5e36569e99273867f61d", | ||||
|                 "sha256:b8425fa963a32936c9773ee3ce44a765d8ff67eed5f4ac81dc1e4a819a238ee9", | ||||
|                 "sha256:d2b813bfbe8dec6a75164523de650bad41f4405d35b0fa24c2c28ae07fcefb20", | ||||
|                 "sha256:d690e1ca993c8f7ede6d22e5637541217fc6a4d3f78b3672a6fe454dbb7eb9a7", | ||||
|                 "sha256:e367904a0fec76433bf3fbf3e85bf60dae8e9e585ffd21898ab1085a29a04d16", | ||||
|                 "sha256:ea932570b1c2a30edafca922345854ff2cd20d43cd9123b6dacfdecebfc1a80b", | ||||
|                 "sha256:f28f1f6cfeb48339c192efc6275749b2a25a7e49c4d8369a28b6591da02fbc9a", | ||||
|                 "sha256:f73102f769ee06041a3aa26b5841359b1a93cc364ce45609657751795e8f4a4a", | ||||
|                 "sha256:fa4909c6c20c3d91480533cddbc0e7c6d849e7d9ded692918c76ce5964997898" | ||||
|             ], | ||||
|             "markers": "python_version < '3.12' and python_version >= '3.8'", | ||||
|             "version": "==1.10.1" | ||||
|             "markers": "python_version < '3.13' and python_version >= '3.9'", | ||||
|             "version": "==1.11.2" | ||||
|         }, | ||||
|         "service-identity": { | ||||
|             "hashes": [ | ||||
| @@ -3394,7 +3331,7 @@ | ||||
|                 "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0", | ||||
|                 "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147" | ||||
|             ], | ||||
|             "markers": "python_version < '3.10'", | ||||
|             "markers": "python_version >= '3.8'", | ||||
|             "version": "==3.16.2" | ||||
|         }, | ||||
|         "zope-interface": { | ||||
| @@ -3443,28 +3380,6 @@ | ||||
|             "markers": "python_version >= '3.7'", | ||||
|             "version": "==3.7.2" | ||||
|         }, | ||||
|         "backports.zoneinfo": { | ||||
|             "hashes": [ | ||||
|                 "sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf", | ||||
|                 "sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328", | ||||
|                 "sha256:1c5742112073a563c81f786e77514969acb58649bcdf6cdf0b4ed31a348d4546", | ||||
|                 "sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6", | ||||
|                 "sha256:5c144945a7752ca544b4b78c8c41544cdfaf9786f25fe5ffb10e838e19a27570", | ||||
|                 "sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9", | ||||
|                 "sha256:8439c030a11780786a2002261569bdf362264f605dfa4d65090b64b05c9f79a7", | ||||
|                 "sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987", | ||||
|                 "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722", | ||||
|                 "sha256:a76b38c52400b762e48131494ba26be363491ac4f9a04c1b7e92483d169f6582", | ||||
|                 "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc", | ||||
|                 "sha256:e55b384612d93be96506932a786bbcde5a2db7a9e6a4bb4bffe8b733f5b9036b", | ||||
|                 "sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1", | ||||
|                 "sha256:e8236383a20872c0cdf5a62b554b27538db7fa1bbec52429d8d106effbaeca08", | ||||
|                 "sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac", | ||||
|                 "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2" | ||||
|             ], | ||||
|             "markers": "python_version < '3.9'", | ||||
|             "version": "==0.2.1" | ||||
|         }, | ||||
|         "celery-types": { | ||||
|             "hashes": [ | ||||
|                 "sha256:4048d7c59d2ce26127d32c2799b776d1b23a3de699eb6e6e9df1b8136dfe950f", | ||||
| @@ -3788,14 +3703,6 @@ | ||||
|             "markers": "python_version < '3.11'", | ||||
|             "version": "==2.0.1" | ||||
|         }, | ||||
|         "types-backports": { | ||||
|             "hashes": [ | ||||
|                 "sha256:dafcd61848081503e738a7768872d1dd6c018401b4d2a1cfb608ea87ec9864b9", | ||||
|                 "sha256:f4b7206c073df88d6200891e3d27506185fd60cda66fb289737b2fa92c0010cf" | ||||
|             ], | ||||
|             "index": "pypi", | ||||
|             "version": "==0.1.3" | ||||
|         }, | ||||
|         "types-bleach": { | ||||
|             "hashes": [ | ||||
|                 "sha256:2b8767eb407c286b7f02803678732e522e04db8d56cbc9f1270bee49627eae92", | ||||
|   | ||||
| @@ -255,7 +255,7 @@ supported. | ||||
|  | ||||
| 1.  Install dependencies. Paperless requires the following packages. | ||||
|  | ||||
|     - `python3` - 3.8 - 3.11 are supported | ||||
|     - `python3` - 3.9 - 3.11 are supported | ||||
|     - `python3-pip` | ||||
|     - `python3-dev` | ||||
|     - `default-libmysqlclient-dev` for MariaDB | ||||
|   | ||||
| @@ -2,9 +2,7 @@ import logging | ||||
| import tempfile | ||||
| from dataclasses import dataclass | ||||
| from pathlib import Path | ||||
| from typing import Dict | ||||
| from typing import Final | ||||
| from typing import List | ||||
| from typing import Optional | ||||
|  | ||||
| from django.conf import settings | ||||
| @@ -53,7 +51,7 @@ class BarcodeReader: | ||||
|         self.file: Final[Path] = filepath | ||||
|         self.mime: Final[str] = mime_type | ||||
|         self.pdf_file: Path = self.file | ||||
|         self.barcodes: List[Barcode] = [] | ||||
|         self.barcodes: list[Barcode] = [] | ||||
|         self.temp_dir: Optional[tempfile.TemporaryDirectory] = None | ||||
|  | ||||
|         if settings.CONSUMER_BARCODE_TIFF_SUPPORT: | ||||
| @@ -111,7 +109,7 @@ class BarcodeReader: | ||||
|         return asn | ||||
|  | ||||
|     @staticmethod | ||||
|     def read_barcodes_zxing(image: Image) -> List[str]: | ||||
|     def read_barcodes_zxing(image: Image) -> list[str]: | ||||
|         barcodes = [] | ||||
|  | ||||
|         import zxingcpp | ||||
| @@ -127,7 +125,7 @@ class BarcodeReader: | ||||
|         return barcodes | ||||
|  | ||||
|     @staticmethod | ||||
|     def read_barcodes_pyzbar(image: Image) -> List[str]: | ||||
|     def read_barcodes_pyzbar(image: Image) -> list[str]: | ||||
|         barcodes = [] | ||||
|  | ||||
|         from pyzbar import pyzbar | ||||
| @@ -209,7 +207,7 @@ class BarcodeReader: | ||||
|                 f"Exception during barcode scanning: {e}", | ||||
|             ) | ||||
|  | ||||
|     def get_separation_pages(self) -> Dict[int, bool]: | ||||
|     def get_separation_pages(self) -> dict[int, bool]: | ||||
|         """ | ||||
|         Search the parsed barcodes for separators and returns a dict of page | ||||
|         numbers, which separate the file into new files, together with the | ||||
| @@ -228,7 +226,7 @@ class BarcodeReader: | ||||
|             **{bc.page: True for bc in self.barcodes if bc.is_asn and bc.page != 0}, | ||||
|         } | ||||
|  | ||||
|     def separate_pages(self, pages_to_split_on: Dict[int, bool]) -> List[Path]: | ||||
|     def separate_pages(self, pages_to_split_on: dict[int, bool]) -> list[Path]: | ||||
|         """ | ||||
|         Separate the provided pdf file on the pages_to_split_on. | ||||
|         The pages which are defined by the keys in page_numbers | ||||
| @@ -241,9 +239,9 @@ class BarcodeReader: | ||||
|         fname = self.file.with_suffix("").name | ||||
|         with Pdf.open(self.pdf_file) as input_pdf: | ||||
|             # Start with an empty document | ||||
|             current_document: List[Page] = [] | ||||
|             current_document: list[Page] = [] | ||||
|             # A list of documents, ie a list of lists of pages | ||||
|             documents: List[List[Page]] = [current_document] | ||||
|             documents: list[list[Page]] = [current_document] | ||||
|  | ||||
|             for idx, page in enumerate(input_pdf.pages): | ||||
|                 # Keep building the new PDF as long as it is not a | ||||
|   | ||||
| @@ -3,11 +3,10 @@ import os | ||||
| import pickle | ||||
| import re | ||||
| import warnings | ||||
| from collections.abc import Iterator | ||||
| from datetime import datetime | ||||
| from hashlib import sha256 | ||||
| from pathlib import Path | ||||
| from typing import Iterator | ||||
| from typing import List | ||||
| from typing import Optional | ||||
|  | ||||
| from django.conf import settings | ||||
| @@ -357,7 +356,7 @@ class DocumentClassifier: | ||||
|  | ||||
|                 # Tokenize | ||||
|                 # This splits the content into tokens, roughly words | ||||
|                 words: List[str] = word_tokenize( | ||||
|                 words: list[str] = word_tokenize( | ||||
|                     content, | ||||
|                     language=settings.NLTK_LANGUAGE, | ||||
|                 ) | ||||
| @@ -404,7 +403,7 @@ class DocumentClassifier: | ||||
|         else: | ||||
|             return None | ||||
|  | ||||
|     def predict_tags(self, content: str) -> List[int]: | ||||
|     def predict_tags(self, content: str) -> list[int]: | ||||
|         from sklearn.utils.multiclass import type_of_target | ||||
|  | ||||
|         if self.tags_classifier: | ||||
|   | ||||
| @@ -8,7 +8,6 @@ from pathlib import Path | ||||
| from subprocess import CompletedProcess | ||||
| from subprocess import run | ||||
| from typing import Optional | ||||
| from typing import Type | ||||
|  | ||||
| import magic | ||||
| from asgiref.sync import async_to_sync | ||||
| @@ -372,7 +371,7 @@ class Consumer(LoggingMixin): | ||||
|         self.log.debug(f"Detected mime type: {mime_type}") | ||||
|  | ||||
|         # Based on the mime type, get the parser for that type | ||||
|         parser_class: Optional[Type[DocumentParser]] = get_parser_class_for_mime_type( | ||||
|         parser_class: Optional[type[DocumentParser]] = get_parser_class_for_mime_type( | ||||
|             mime_type, | ||||
|         ) | ||||
|         if not parser_class: | ||||
|   | ||||
| @@ -2,7 +2,6 @@ import dataclasses | ||||
| import datetime | ||||
| import enum | ||||
| from pathlib import Path | ||||
| from typing import List | ||||
| from typing import Optional | ||||
|  | ||||
| import magic | ||||
| @@ -20,7 +19,7 @@ class DocumentMetadataOverrides: | ||||
|     title: Optional[str] = None | ||||
|     correspondent_id: Optional[int] = None | ||||
|     document_type_id: Optional[int] = None | ||||
|     tag_ids: Optional[List[int]] = None | ||||
|     tag_ids: Optional[list[int]] = None | ||||
|     created: Optional[datetime.datetime] = None | ||||
|     asn: Optional[int] = None | ||||
|     owner_id: Optional[int] = None | ||||
|   | ||||
| @@ -115,12 +115,10 @@ def collate(input_doc: ConsumableDocument) -> str: | ||||
|             staging.unlink() | ||||
|  | ||||
|     else: | ||||
|         # In Python 3.9 move supports Path objects directly, | ||||
|         # but for now we have to be compatible with 3.8 | ||||
|         shutil.move(str(pdf_file), str(staging)) | ||||
|         shutil.move(pdf_file, staging) | ||||
|         # update access to modification time so we know if the file | ||||
|         # is outdated when another file gets uploaded | ||||
|         os.utime(str(staging), (dt.datetime.now().timestamp(),) * 2) | ||||
|         os.utime(staging, (dt.datetime.now().timestamp(),) * 2) | ||||
|         logger.info( | ||||
|             "Got scan with odd numbered pages of double-sided scan, moved it to %s", | ||||
|             staging, | ||||
|   | ||||
| @@ -8,7 +8,6 @@ from threading import Event | ||||
| from time import monotonic | ||||
| from time import sleep | ||||
| from typing import Final | ||||
| from typing import Set | ||||
|  | ||||
| from django.conf import settings | ||||
| from django.core.management.base import BaseCommand | ||||
| @@ -32,7 +31,7 @@ except ImportError:  # pragma: nocover | ||||
| logger = logging.getLogger("paperless.management.consumer") | ||||
|  | ||||
|  | ||||
| def _tags_from_path(filepath) -> Set[Tag]: | ||||
| def _tags_from_path(filepath) -> set[Tag]: | ||||
|     """ | ||||
|     Walk up the directory tree from filepath to CONSUMPTION_DIR | ||||
|     and get or create Tag IDs for every directory. | ||||
|   | ||||
| @@ -5,8 +5,6 @@ import shutil | ||||
| import tempfile | ||||
| import time | ||||
| from pathlib import Path | ||||
| from typing import List | ||||
| from typing import Set | ||||
|  | ||||
| import tqdm | ||||
| from django.conf import settings | ||||
| @@ -138,8 +136,8 @@ class Command(BaseCommand): | ||||
|         BaseCommand.__init__(self, *args, **kwargs) | ||||
|         self.target: Path = None | ||||
|         self.split_manifest = False | ||||
|         self.files_in_export_dir: Set[Path] = set() | ||||
|         self.exported_files: List[Path] = [] | ||||
|         self.files_in_export_dir: set[Path] = set() | ||||
|         self.exported_files: list[Path] = [] | ||||
|         self.compare_checksums = False | ||||
|         self.use_filename_format = False | ||||
|         self.use_folder_prefix = False | ||||
|   | ||||
| @@ -6,12 +6,11 @@ import re | ||||
| import shutil | ||||
| import subprocess | ||||
| import tempfile | ||||
| from collections.abc import Iterator | ||||
| from functools import lru_cache | ||||
| from pathlib import Path | ||||
| from typing import Iterator | ||||
| from typing import Match | ||||
| from re import Match | ||||
| from typing import Optional | ||||
| from typing import Set | ||||
|  | ||||
| from django.conf import settings | ||||
| from django.utils import timezone | ||||
| @@ -90,7 +89,7 @@ def is_file_ext_supported(ext: str) -> bool: | ||||
|         return False | ||||
|  | ||||
|  | ||||
| def get_supported_file_extensions() -> Set[str]: | ||||
| def get_supported_file_extensions() -> set[str]: | ||||
|     extensions = set() | ||||
|     for response in document_consumer_declaration.send(None): | ||||
|         parser_declaration = response[1] | ||||
|   | ||||
| @@ -1,14 +1,10 @@ | ||||
| import datetime | ||||
| import math | ||||
| import re | ||||
| import zoneinfo | ||||
|  | ||||
| from celery import states | ||||
|  | ||||
| try: | ||||
|     import zoneinfo | ||||
| except ImportError: | ||||
|     from backports import zoneinfo | ||||
| import magic | ||||
| from celery import states | ||||
| from django.conf import settings | ||||
| from django.contrib.auth.models import Group | ||||
| from django.contrib.auth.models import User | ||||
|   | ||||
| @@ -3,7 +3,6 @@ import logging | ||||
| import shutil | ||||
| import uuid | ||||
| from typing import Optional | ||||
| from typing import Type | ||||
|  | ||||
| import tqdm | ||||
| from asgiref.sync import async_to_sync | ||||
| @@ -216,7 +215,7 @@ def update_document_archive_file(document_id): | ||||
|  | ||||
|     mime_type = document.mime_type | ||||
|  | ||||
|     parser_class: Type[DocumentParser] = get_parser_class_for_mime_type(mime_type) | ||||
|     parser_class: type[DocumentParser] = get_parser_class_for_mime_type(mime_type) | ||||
|  | ||||
|     if not parser_class: | ||||
|         logger.error( | ||||
|   | ||||
| @@ -7,18 +7,13 @@ import tempfile | ||||
| import urllib.request | ||||
| import uuid | ||||
| import zipfile | ||||
| import zoneinfo | ||||
| from datetime import timedelta | ||||
| from pathlib import Path | ||||
| from unittest import mock | ||||
| from unittest.mock import MagicMock | ||||
|  | ||||
| import celery | ||||
|  | ||||
| try: | ||||
|     import zoneinfo | ||||
| except ImportError: | ||||
|     from backports import zoneinfo | ||||
|  | ||||
| import pytest | ||||
| from dateutil.relativedelta import relativedelta | ||||
| from django.conf import settings | ||||
|   | ||||
| @@ -5,16 +5,11 @@ import shutil | ||||
| import stat | ||||
| import tempfile | ||||
| import uuid | ||||
| import zoneinfo | ||||
| from unittest import mock | ||||
| from unittest.mock import MagicMock | ||||
|  | ||||
| from dateutil import tz | ||||
|  | ||||
| try: | ||||
|     import zoneinfo | ||||
| except ImportError: | ||||
|     from backports import zoneinfo | ||||
|  | ||||
| from django.conf import settings | ||||
| from django.test import TestCase | ||||
| from django.test import override_settings | ||||
|   | ||||
| @@ -1,13 +1,9 @@ | ||||
| import shutil | ||||
| import tempfile | ||||
| import zoneinfo | ||||
| from pathlib import Path | ||||
| from unittest import mock | ||||
|  | ||||
| try: | ||||
|     import zoneinfo | ||||
| except ImportError: | ||||
|     from backports import zoneinfo | ||||
|  | ||||
| from django.test import TestCase | ||||
| from django.test import override_settings | ||||
| from django.utils import timezone | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import shutil | ||||
| import tempfile | ||||
| from collections.abc import Iterable | ||||
| from random import randint | ||||
| from typing import Iterable | ||||
|  | ||||
| from django.contrib.admin.models import LogEntry | ||||
| from django.contrib.auth.models import User | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| import importlib | ||||
| import shutil | ||||
| import tempfile | ||||
| from collections.abc import Iterable | ||||
| from pathlib import Path | ||||
| from typing import Callable | ||||
| from typing import Iterable | ||||
| from typing import Union | ||||
| from unittest import mock | ||||
|  | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| import importlib | ||||
| import shutil | ||||
| import tempfile | ||||
| from collections.abc import Iterable | ||||
| from pathlib import Path | ||||
| from typing import Callable | ||||
| from typing import Iterable | ||||
| from typing import Union | ||||
| from unittest import mock | ||||
|  | ||||
|   | ||||
| @@ -3,14 +3,12 @@ import tempfile | ||||
| import time | ||||
| import warnings | ||||
| from collections import namedtuple | ||||
| from collections.abc import Iterator | ||||
| from contextlib import contextmanager | ||||
| from os import PathLike | ||||
| from pathlib import Path | ||||
| from typing import Any | ||||
| from typing import Callable | ||||
| from typing import Iterator | ||||
| from typing import List | ||||
| from typing import Tuple | ||||
| from typing import Union | ||||
| from unittest import mock | ||||
|  | ||||
| @@ -88,10 +86,10 @@ def paperless_environment(): | ||||
|  | ||||
| def util_call_with_backoff( | ||||
|     method_or_callable: Callable, | ||||
|     args: Union[List, Tuple], | ||||
|     args: Union[list, tuple], | ||||
|     *, | ||||
|     skip_on_50x_err=True, | ||||
| ) -> Tuple[bool, Any]: | ||||
| ) -> tuple[bool, Any]: | ||||
|     """ | ||||
|     For whatever reason, the images started during the test pipeline like to | ||||
|     segfault sometimes, crash and otherwise fail randomly, when run with the | ||||
| @@ -219,7 +217,7 @@ class DocumentConsumeDelayMixin: | ||||
|  | ||||
|     def get_last_consume_delay_call_args( | ||||
|         self, | ||||
|     ) -> Tuple[ConsumableDocument, DocumentMetadataOverrides]: | ||||
|     ) -> tuple[ConsumableDocument, DocumentMetadataOverrides]: | ||||
|         """ | ||||
|         Returns the most recent arguments to the async task | ||||
|         """ | ||||
| @@ -233,7 +231,7 @@ class DocumentConsumeDelayMixin: | ||||
|  | ||||
|     def get_all_consume_delay_call_args( | ||||
|         self, | ||||
|     ) -> Iterator[Tuple[ConsumableDocument, DocumentMetadataOverrides]]: | ||||
|     ) -> Iterator[tuple[ConsumableDocument, DocumentMetadataOverrides]]: | ||||
|         """ | ||||
|         Iterates over all calls to the async task and returns the arguments | ||||
|         """ | ||||
| @@ -246,7 +244,7 @@ class DocumentConsumeDelayMixin: | ||||
|     def get_specific_consume_delay_call_args( | ||||
|         self, | ||||
|         index: int, | ||||
|     ) -> Iterator[Tuple[ConsumableDocument, DocumentMetadataOverrides]]: | ||||
|     ) -> Iterator[tuple[ConsumableDocument, DocumentMetadataOverrides]]: | ||||
|         """ | ||||
|         Returns the arguments of a specific call to the async task | ||||
|         """ | ||||
|   | ||||
| @@ -1,14 +1,13 @@ | ||||
| import shutil | ||||
| from os import utime | ||||
| from pathlib import Path | ||||
| from typing import Tuple | ||||
| from typing import Union | ||||
|  | ||||
|  | ||||
| def _coerce_to_path( | ||||
|     source: Union[Path, str], | ||||
|     dest: Union[Path, str], | ||||
| ) -> Tuple[Path, Path]: | ||||
| ) -> tuple[Path, Path]: | ||||
|     return Path(source).resolve(), Path(dest).resolve() | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -155,10 +155,8 @@ def settings_values_check(app_configs, **kwargs): | ||||
|         """ | ||||
|         Validates the user provided timezone is a valid timezone | ||||
|         """ | ||||
|         try: | ||||
|             import zoneinfo | ||||
|         except ImportError:  # pragma: nocover | ||||
|             from backports import zoneinfo | ||||
|         import zoneinfo | ||||
|  | ||||
|         msgs = [] | ||||
|         if settings.TIME_ZONE not in zoneinfo.available_timezones(): | ||||
|             msgs.append( | ||||
|   | ||||
| @@ -7,12 +7,8 @@ import re | ||||
| import tempfile | ||||
| from os import PathLike | ||||
| from pathlib import Path | ||||
| from typing import Dict | ||||
| from typing import Final | ||||
| from typing import List | ||||
| from typing import Optional | ||||
| from typing import Set | ||||
| from typing import Tuple | ||||
| from typing import Union | ||||
| from urllib.parse import urlparse | ||||
|  | ||||
| @@ -85,9 +81,9 @@ def __get_path( | ||||
|  | ||||
| def __get_list( | ||||
|     key: str, | ||||
|     default: Optional[List[str]] = None, | ||||
|     default: Optional[list[str]] = None, | ||||
|     sep: str = ",", | ||||
| ) -> List[str]: | ||||
| ) -> list[str]: | ||||
|     """ | ||||
|     Return a list of elements from the environment, as separated by the given | ||||
|     string, or the default if the key does not exist | ||||
| @@ -100,7 +96,7 @@ def __get_list( | ||||
|         return [] | ||||
|  | ||||
|  | ||||
| def _parse_redis_url(env_redis: Optional[str]) -> Tuple[str]: | ||||
| def _parse_redis_url(env_redis: Optional[str]) -> tuple[str]: | ||||
|     """ | ||||
|     Gets the Redis information from the environment or a default and handles | ||||
|     converting from incompatible django_channels and celery formats. | ||||
| @@ -138,7 +134,7 @@ def _parse_redis_url(env_redis: Optional[str]) -> Tuple[str]: | ||||
|     return (env_redis, env_redis) | ||||
|  | ||||
|  | ||||
| def _parse_beat_schedule() -> Dict: | ||||
| def _parse_beat_schedule() -> dict: | ||||
|     """ | ||||
|     Configures the scheduled tasks, according to default or | ||||
|     environment variables.  Task expiration is configured so the task will | ||||
| @@ -492,7 +488,7 @@ EMAIL_CERTIFICATE_FILE = __get_path("PAPERLESS_EMAIL_CERTIFICATE_FILE") | ||||
| ############################################################################### | ||||
| # Database                                                                    # | ||||
| ############################################################################### | ||||
| def _parse_db_settings() -> Dict: | ||||
| def _parse_db_settings() -> dict: | ||||
|     databases = { | ||||
|         "default": { | ||||
|             "ENGINE": "django.db.backends.sqlite3", | ||||
| @@ -928,7 +924,7 @@ if TIKA_ENABLED: | ||||
| def _parse_ignore_dates( | ||||
|     env_ignore: str, | ||||
|     date_order: str = DATE_ORDER, | ||||
| ) -> Set[datetime.datetime]: | ||||
| ) -> set[datetime.datetime]: | ||||
|     """ | ||||
|     If the PAPERLESS_IGNORE_DATES environment variable is set, parse the | ||||
|     user provided string(s) into dates | ||||
| @@ -957,7 +953,7 @@ def _parse_ignore_dates( | ||||
|  | ||||
|  | ||||
| # List dates that should be ignored when trying to parse date from document text | ||||
| IGNORE_DATES: Set[datetime.date] = set() | ||||
| IGNORE_DATES: set[datetime.date] = set() | ||||
|  | ||||
| if os.getenv("PAPERLESS_IGNORE_DATES") is not None: | ||||
|     IGNORE_DATES = _parse_ignore_dates(os.getenv("PAPERLESS_IGNORE_DATES")) | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| from typing import Final | ||||
| from typing import Tuple | ||||
|  | ||||
| __version__: Final[Tuple[int, int, int]] = (1, 17, 4) | ||||
| __version__: Final[tuple[int, int, int]] = (1, 17, 4) | ||||
| # Version string like X.Y.Z | ||||
| __full_version_str__: Final[str] = ".".join(map(str, __version__)) | ||||
| # Version string like X.Y | ||||
|   | ||||
| @@ -8,8 +8,6 @@ import traceback | ||||
| from datetime import date | ||||
| from datetime import timedelta | ||||
| from fnmatch import fnmatch | ||||
| from typing import Dict | ||||
| from typing import List | ||||
| from typing import Union | ||||
|  | ||||
| import magic | ||||
| @@ -80,7 +78,7 @@ class BaseMailAction: | ||||
|     read mails when the action is to mark mails as read). | ||||
|     """ | ||||
|  | ||||
|     def get_criteria(self) -> Union[Dict, LogicOperator]: | ||||
|     def get_criteria(self) -> Union[dict, LogicOperator]: | ||||
|         """ | ||||
|         Returns filtering criteria/query for this mail action. | ||||
|         """ | ||||
| @@ -232,7 +230,7 @@ def mailbox_login(mailbox: MailBox, account: MailAccount): | ||||
|  | ||||
| @shared_task | ||||
| def apply_mail_action( | ||||
|     result: List[str], | ||||
|     result: list[str], | ||||
|     rule_id: int, | ||||
|     message_uid: str, | ||||
|     message_subject: str, | ||||
| @@ -319,7 +317,7 @@ def error_callback( | ||||
|  | ||||
| def queue_consumption_tasks( | ||||
|     *, | ||||
|     consume_tasks: List[Signature], | ||||
|     consume_tasks: list[Signature], | ||||
|     rule: MailRule, | ||||
|     message: MailMessage, | ||||
| ): | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| import re | ||||
| from html import escape | ||||
| from pathlib import Path | ||||
| from typing import List | ||||
|  | ||||
| import httpx | ||||
| from bleach import clean | ||||
| @@ -355,7 +354,7 @@ class MailDocumentParser(DocumentParser): | ||||
|     def generate_pdf_from_html( | ||||
|         self, | ||||
|         orig_html: str, | ||||
|         attachments: List[MailAttachment], | ||||
|         attachments: list[MailAttachment], | ||||
|     ) -> Path: | ||||
|         """ | ||||
|         Generates a PDF file based on the HTML and attachments of the email | ||||
|   | ||||
| @@ -3,8 +3,7 @@ import email.contentmanager | ||||
| import random | ||||
| import uuid | ||||
| from collections import namedtuple | ||||
| from typing import ContextManager | ||||
| from typing import List | ||||
| from contextlib import AbstractContextManager | ||||
| from typing import Optional | ||||
| from typing import Union | ||||
| from unittest import mock | ||||
| @@ -53,8 +52,8 @@ class BogusFolderManager: | ||||
|  | ||||
| class BogusClient: | ||||
|     def __init__(self, messages): | ||||
|         self.messages: List[MailMessage] = messages | ||||
|         self.capabilities: List[str] = [] | ||||
|         self.messages: list[MailMessage] = messages | ||||
|         self.capabilities: list[str] = [] | ||||
|  | ||||
|     def __enter__(self): | ||||
|         return self | ||||
| @@ -78,7 +77,7 @@ class BogusClient: | ||||
|                         MailMessage.flags.fget.cache_clear() | ||||
|  | ||||
|  | ||||
| class BogusMailBox(ContextManager): | ||||
| class BogusMailBox(AbstractContextManager): | ||||
|     # Common values so tests don't need to remember an accepted login | ||||
|     USERNAME: str = "admin" | ||||
|     ASCII_PASSWORD: str = "secret" | ||||
| @@ -88,8 +87,8 @@ class BogusMailBox(ContextManager): | ||||
|     ACCESS_TOKEN = "ea7e075cd3acf2c54c48e600398d5d5a" | ||||
|  | ||||
|     def __init__(self): | ||||
|         self.messages: List[MailMessage] = [] | ||||
|         self.messages_spam: List[MailMessage] = [] | ||||
|         self.messages: list[MailMessage] = [] | ||||
|         self.messages_spam: list[MailMessage] = [] | ||||
|         self.folder = BogusFolderManager() | ||||
|         self.client = BogusClient(self.messages) | ||||
|         self._host = "" | ||||
| @@ -221,11 +220,11 @@ class TestMail( | ||||
|  | ||||
|     def create_message( | ||||
|         self, | ||||
|         attachments: Union[int, List[_AttachmentDef]] = 1, | ||||
|         attachments: Union[int, list[_AttachmentDef]] = 1, | ||||
|         body: str = "", | ||||
|         subject: str = "the subject", | ||||
|         from_: str = "noone@mail.com", | ||||
|         to: Optional[List[str]] = None, | ||||
|         to: Optional[list[str]] = None, | ||||
|         seen: bool = False, | ||||
|         flagged: bool = False, | ||||
|         processed: bool = False, | ||||
| @@ -1056,6 +1055,7 @@ class TestMail( | ||||
|             ], | ||||
|         ) | ||||
|  | ||||
|     @pytest.mark.flaky(reruns=4) | ||||
|     def test_filters(self): | ||||
|         account = MailAccount.objects.create( | ||||
|             name="test3", | ||||
| @@ -1203,7 +1203,7 @@ class TestMail( | ||||
|         self.assertEqual(len(self.bogus_mailbox.fetch("UNSEEN", False)), 0) | ||||
|         self.assertEqual(len(self.bogus_mailbox.messages), 3) | ||||
|  | ||||
|     def assert_queue_consumption_tasks_call_args(self, expected_call_args: List): | ||||
|     def assert_queue_consumption_tasks_call_args(self, expected_call_args: list): | ||||
|         """ | ||||
|         Verifies that queue_consumption_tasks has been called with the expected arguments. | ||||
|  | ||||
|   | ||||
| @@ -2,8 +2,8 @@ import os | ||||
| import shutil | ||||
| import tempfile | ||||
| import uuid | ||||
| from contextlib import AbstractContextManager | ||||
| from pathlib import Path | ||||
| from typing import ContextManager | ||||
| from unittest import mock | ||||
|  | ||||
| from django.test import TestCase | ||||
| @@ -29,7 +29,7 @@ def fake_convert(input_file, output_file, **kwargs): | ||||
|             f2.write(line.strip()) | ||||
|  | ||||
|  | ||||
| class FakeImageFile(ContextManager): | ||||
| class FakeImageFile(AbstractContextManager): | ||||
|     def __init__(self, fname): | ||||
|         self.fname = fname | ||||
|  | ||||
|   | ||||
| @@ -1,13 +1,9 @@ | ||||
| import datetime | ||||
| import os | ||||
| import zoneinfo | ||||
| from pathlib import Path | ||||
| from unittest import mock | ||||
|  | ||||
| try: | ||||
|     import zoneinfo | ||||
| except ImportError: | ||||
|     from backports import zoneinfo | ||||
|  | ||||
| from django.test import TestCase | ||||
| from django.test import override_settings | ||||
| from httpx import Request | ||||
|   | ||||
		Reference in New Issue
	
	Block a user