diff --git a/CHANGELOG.md b/CHANGELOG.md index 25e61fe7c..0b6d5a54d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,28 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed +- Bumped the minimum Alluka version to `v0.3.0`. + +### Deprecated +- Providing the following classes as global type-dependencies: + * [hikari.impl.RESTClientImpl][] + * [hikari.impl.CacheImpl][] + * [hikari.impl.EventManagerImpl][] + * [hikari.impl.InteractionServer][] + * [hikari.impl.GatewayShardImpl][] + * [hikari.impl.VoiceComponentImpl][] + + The relevant ABCs should be used instead. +- Setting subclasses of [tanjun.Client][] as global type-dependencies. +- Providing the following classes as context-specific type-dependencies: + * [tanjun.AutocompleteContext][tanjun.context.AutocompleteContext] + * [tanjun.MessageContext][tanjun.context.MessageContext] + * [tanjun.MenuContext][tanjun.context.MenuContext] + * [tanjun.SlashContext][tanjun.context.SlashContext] + + The relevant ABCs should be used instead. + ## [2.17.5] - 2024-05-11 ### Fixed - Now compatible with Alluka `v0.3.0`. diff --git a/dev-requirements/constraints.in b/dev-requirements/constraints.in index 18fd03175..f1f3dea79 100644 --- a/dev-requirements/constraints.in +++ b/dev-requirements/constraints.in @@ -1,3 +1,3 @@ -alluka>=0.2.0, <1 +alluka>=0.3.0, <1 hikari>=2.0.0.dev115, <3 typing-extensions>=4.5, <5 diff --git a/dev-requirements/constraints.txt b/dev-requirements/constraints.txt index 80795ec78..64b7d7632 100644 --- a/dev-requirements/constraints.txt +++ b/dev-requirements/constraints.txt @@ -84,9 +84,9 @@ aiohttp==3.9.5 ; python_full_version >= "3.9.0" and python_version < "3.13" \ aiosignal==1.3.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc \ --hash=sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17 -alluka==0.3.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:1b56fbfb1ba80e2d2e7ef5f69dd0852aeea0a65f65e9d4d688da1b93188ef4ec \ - --hash=sha256:41585a274a27edbbf71472912c4cb13675fe360e356642bf93dc1e974a3598e3 +alluka==0.3.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:40563bbc7d55a366901b3939d047d1e08195219e4c62b7a1b63be0f20e394ff2 \ + --hash=sha256:b7100a9dcced87fb3bf0bc8755b3b35fe3308b9275cb6c03db9cb09ae12db6db async-timeout==4.0.3 ; python_full_version >= "3.9.0" and python_version < "3.11" \ --hash=sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f \ --hash=sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028 @@ -177,9 +177,9 @@ frozenlist==1.4.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887 \ --hash=sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced \ --hash=sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74 -hikari==2.0.0.dev125 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:4c139e7f81089dc234e21d81177ca7d0d97bba974ac0de5a03b3e7e0ac0c6541 \ - --hash=sha256:f9677386b77f58fcb04d1b91cd6f4f5b306014fb952b11615ef0ca3430296953 +hikari==2.0.0.dev126 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:1ace1bc6d3a634a97d6d6aa3a8bc56f1cf3ad02caae4a9860699247b52e650a5 \ + --hash=sha256:cdbe0916dcfdc8e2dee16f89731a20f66e27e01914a549e06b06c74261141d31 idna==3.7 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc \ --hash=sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0 @@ -274,9 +274,9 @@ multidict==6.0.5 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24 \ --hash=sha256:fce28b3c8a81b6b36dfac9feb1de115bab619b3c13905b419ec71d03a3fc1423 \ --hash=sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef -typing-extensions==4.11.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0 \ - --hash=sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a +typing-extensions==4.12.2 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d \ + --hash=sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8 yarl==1.9.4 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51 \ --hash=sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce \ diff --git a/dev-requirements/tests.txt b/dev-requirements/tests.txt index 2a1ca9983..565cbb82b 100644 --- a/dev-requirements/tests.txt +++ b/dev-requirements/tests.txt @@ -84,9 +84,9 @@ aiohttp==3.9.5 ; python_full_version >= "3.9.0" and python_version < "3.13" \ aiosignal==1.3.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc \ --hash=sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17 -alluka==0.3.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:1b56fbfb1ba80e2d2e7ef5f69dd0852aeea0a65f65e9d4d688da1b93188ef4ec \ - --hash=sha256:41585a274a27edbbf71472912c4cb13675fe360e356642bf93dc1e974a3598e3 +alluka==0.3.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:40563bbc7d55a366901b3939d047d1e08195219e4c62b7a1b63be0f20e394ff2 \ + --hash=sha256:b7100a9dcced87fb3bf0bc8755b3b35fe3308b9275cb6c03db9cb09ae12db6db async-timeout==4.0.3 ; python_full_version >= "3.9.0" and python_version < "3.11" \ --hash=sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f \ --hash=sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028 @@ -99,59 +99,59 @@ colorama==0.4.6 ; python_full_version >= "3.9.0" and python_version < "3.13" and colorlog==6.8.2 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:3e3e079a41feb5a1b64f978b5ea4f46040a94f11f0e8bbb8261e3dbbeca64d44 \ --hash=sha256:4dcbb62368e2800cb3c5abd348da7e53f6c362dda502ec27c560b2e58a66bd33 -coverage[toml]==7.5.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:0646599e9b139988b63704d704af8e8df7fa4cbc4a1f33df69d97f36cb0a38de \ - --hash=sha256:0cdcbc320b14c3e5877ee79e649677cb7d89ef588852e9583e6b24c2e5072661 \ - --hash=sha256:0d0a0f5e06881ecedfe6f3dd2f56dcb057b6dbeb3327fd32d4b12854df36bf26 \ - --hash=sha256:1434e088b41594baa71188a17533083eabf5609e8e72f16ce8c186001e6b8c41 \ - --hash=sha256:16db7f26000a07efcf6aea00316f6ac57e7d9a96501e990a36f40c965ec7a95d \ - --hash=sha256:1cc0fe9b0b3a8364093c53b0b4c0c2dd4bb23acbec4c9240b5f284095ccf7981 \ - --hash=sha256:1fc81d5878cd6274ce971e0a3a18a8803c3fe25457165314271cf78e3aae3aa2 \ - --hash=sha256:2ec92012fefebee89a6b9c79bc39051a6cb3891d562b9270ab10ecfdadbc0c34 \ - --hash=sha256:39afcd3d4339329c5f58de48a52f6e4e50f6578dd6099961cf22228feb25f38f \ - --hash=sha256:4a7b0ceee8147444347da6a66be737c9d78f3353b0681715b668b72e79203e4a \ - --hash=sha256:4a9ca3f2fae0088c3c71d743d85404cec8df9be818a005ea065495bedc33da35 \ - --hash=sha256:4bf0655ab60d754491004a5efd7f9cccefcc1081a74c9ef2da4735d6ee4a6223 \ - --hash=sha256:4cc37def103a2725bc672f84bd939a6fe4522310503207aae4d56351644682f1 \ - --hash=sha256:4fc84a37bfd98db31beae3c2748811a3fa72bf2007ff7902f68746d9757f3746 \ - --hash=sha256:5037f8fcc2a95b1f0e80585bd9d1ec31068a9bcb157d9750a172836e98bc7a90 \ - --hash=sha256:54de9ef3a9da981f7af93eafde4ede199e0846cd819eb27c88e2b712aae9708c \ - --hash=sha256:556cf1a7cbc8028cb60e1ff0be806be2eded2daf8129b8811c63e2b9a6c43bca \ - --hash=sha256:57e0204b5b745594e5bc14b9b50006da722827f0b8c776949f1135677e88d0b8 \ - --hash=sha256:5a5740d1fb60ddf268a3811bcd353de34eb56dc24e8f52a7f05ee513b2d4f596 \ - --hash=sha256:5c3721c2c9e4c4953a41a26c14f4cef64330392a6d2d675c8b1db3b645e31f0e \ - --hash=sha256:5fa567e99765fe98f4e7d7394ce623e794d7cabb170f2ca2ac5a4174437e90dd \ - --hash=sha256:5fd215c0c7d7aab005221608a3c2b46f58c0285a819565887ee0b718c052aa4e \ - --hash=sha256:6175d1a0559986c6ee3f7fccfc4a90ecd12ba0a383dcc2da30c2b9918d67d8a3 \ - --hash=sha256:61c4bf1ba021817de12b813338c9be9f0ad5b1e781b9b340a6d29fc13e7c1b5e \ - --hash=sha256:6537e7c10cc47c595828b8a8be04c72144725c383c4702703ff4e42e44577312 \ - --hash=sha256:68f962d9b72ce69ea8621f57551b2fa9c70509af757ee3b8105d4f51b92b41a7 \ - --hash=sha256:7352b9161b33fd0b643ccd1f21f3a3908daaddf414f1c6cb9d3a2fd618bf2572 \ - --hash=sha256:796a79f63eca8814ca3317a1ea443645c9ff0d18b188de470ed7ccd45ae79428 \ - --hash=sha256:79afb6197e2f7f60c4824dd4b2d4c2ec5801ceb6ba9ce5d2c3080e5660d51a4f \ - --hash=sha256:7a588d39e0925f6a2bff87154752481273cdb1736270642aeb3635cb9b4cad07 \ - --hash=sha256:8748731ad392d736cc9ccac03c9845b13bb07d020a33423fa5b3a36521ac6e4e \ - --hash=sha256:8fe7502616b67b234482c3ce276ff26f39ffe88adca2acf0261df4b8454668b4 \ - --hash=sha256:9314d5678dcc665330df5b69c1e726a0e49b27df0461c08ca12674bcc19ef136 \ - --hash=sha256:9735317685ba6ec7e3754798c8871c2f49aa5e687cc794a0b1d284b2389d1bd5 \ - --hash=sha256:9981706d300c18d8b220995ad22627647be11a4276721c10911e0e9fa44c83e8 \ - --hash=sha256:9e78295f4144f9dacfed4f92935fbe1780021247c2fabf73a819b17f0ccfff8d \ - --hash=sha256:b016ea6b959d3b9556cb401c55a37547135a587db0115635a443b2ce8f1c7228 \ - --hash=sha256:b6cf3764c030e5338e7f61f95bd21147963cf6aa16e09d2f74f1fa52013c1206 \ - --hash=sha256:beccf7b8a10b09c4ae543582c1319c6df47d78fd732f854ac68d518ee1fb97fa \ - --hash=sha256:c0884920835a033b78d1c73b6d3bbcda8161a900f38a488829a83982925f6c2e \ - --hash=sha256:c3e757949f268364b96ca894b4c342b41dc6f8f8b66c37878aacef5930db61be \ - --hash=sha256:ca498687ca46a62ae590253fba634a1fe9836bc56f626852fb2720f334c9e4e5 \ - --hash=sha256:d1d0d98d95dd18fe29dc66808e1accf59f037d5716f86a501fc0256455219668 \ - --hash=sha256:d21918e9ef11edf36764b93101e2ae8cc82aa5efdc7c5a4e9c6c35a48496d601 \ - --hash=sha256:d7fed867ee50edf1a0b4a11e8e5d0895150e572af1cd6d315d557758bfa9c057 \ - --hash=sha256:db66fc317a046556a96b453a58eced5024af4582a8dbdc0c23ca4dbc0d5b3146 \ - --hash=sha256:dde0070c40ea8bb3641e811c1cfbf18e265d024deff6de52c5950677a8fb1e0f \ - --hash=sha256:df4e745a81c110e7446b1cc8131bf986157770fa405fe90e15e850aaf7619bc8 \ - --hash=sha256:e2213def81a50519d7cc56ed643c9e93e0247f5bbe0d1247d15fa520814a7cd7 \ - --hash=sha256:ef48e2707fb320c8f139424a596f5b69955a85b178f15af261bab871873bb987 \ - --hash=sha256:f152cbf5b88aaeb836127d920dd0f5e7edff5a66f10c079157306c4343d86c19 \ - --hash=sha256:fc0b4d8bfeabd25ea75e94632f5b6e047eef8adaed0c2161ada1e922e7f7cece +coverage[toml]==7.5.4 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f \ + --hash=sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d \ + --hash=sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747 \ + --hash=sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f \ + --hash=sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d \ + --hash=sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f \ + --hash=sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47 \ + --hash=sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e \ + --hash=sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba \ + --hash=sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c \ + --hash=sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b \ + --hash=sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4 \ + --hash=sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7 \ + --hash=sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555 \ + --hash=sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233 \ + --hash=sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace \ + --hash=sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805 \ + --hash=sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136 \ + --hash=sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4 \ + --hash=sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d \ + --hash=sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806 \ + --hash=sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99 \ + --hash=sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8 \ + --hash=sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b \ + --hash=sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5 \ + --hash=sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da \ + --hash=sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0 \ + --hash=sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078 \ + --hash=sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f \ + --hash=sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029 \ + --hash=sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353 \ + --hash=sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638 \ + --hash=sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9 \ + --hash=sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f \ + --hash=sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7 \ + --hash=sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3 \ + --hash=sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e \ + --hash=sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016 \ + --hash=sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088 \ + --hash=sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4 \ + --hash=sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882 \ + --hash=sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7 \ + --hash=sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53 \ + --hash=sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d \ + --hash=sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080 \ + --hash=sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5 \ + --hash=sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d \ + --hash=sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c \ + --hash=sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8 \ + --hash=sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633 \ + --hash=sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9 \ + --hash=sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c exceptiongroup==1.2.1 ; python_full_version >= "3.9.0" and python_version < "3.11" \ --hash=sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad \ --hash=sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16 @@ -239,9 +239,9 @@ frozenlist==1.4.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887 \ --hash=sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced \ --hash=sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74 -hikari==2.0.0.dev125 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:4c139e7f81089dc234e21d81177ca7d0d97bba974ac0de5a03b3e7e0ac0c6541 \ - --hash=sha256:f9677386b77f58fcb04d1b91cd6f4f5b306014fb952b11615ef0ca3430296953 +hikari==2.0.0.dev126 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:1ace1bc6d3a634a97d6d6aa3a8bc56f1cf3ad02caae4a9860699247b52e650a5 \ + --hash=sha256:cdbe0916dcfdc8e2dee16f89731a20f66e27e01914a549e06b06c74261141d31 idna==3.7 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc \ --hash=sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0 @@ -342,15 +342,15 @@ multidict==6.0.5 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24 \ --hash=sha256:fce28b3c8a81b6b36dfac9feb1de115bab619b3c13905b419ec71d03a3fc1423 \ --hash=sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef -packaging==24.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5 \ - --hash=sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9 +packaging==24.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002 \ + --hash=sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124 pluggy==1.5.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1 \ --hash=sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669 -pytest-asyncio==0.23.6 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:68516fdd1018ac57b846c9846b954f0393b26f094764a28c955eabb0536a4e8a \ - --hash=sha256:ffe523a89c1c222598c76856e76852b787504ddb72dd5d9b6617ffa8aa2cde5f +pytest-asyncio==0.23.7 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:009b48127fbe44518a547bddd25611551b0e43ccdbf1e67d12479f569832c20b \ + --hash=sha256:5f5c72948f4c49e7db4f29f2521d4031f1c27f86e57b046126654083d4770268 pytest-cov==5.0.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652 \ --hash=sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857 @@ -378,9 +378,9 @@ termcolor==2.4.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ tomli==2.0.1 ; python_full_version >= "3.9.0" and python_full_version <= "3.11.0a6" \ --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \ --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f -typing-extensions==4.11.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0 \ - --hash=sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a +typing-extensions==4.12.2 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d \ + --hash=sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8 yarl==1.9.4 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51 \ --hash=sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce \ diff --git a/dev-requirements/type-checking.txt b/dev-requirements/type-checking.txt index f38f60233..dd71a216e 100644 --- a/dev-requirements/type-checking.txt +++ b/dev-requirements/type-checking.txt @@ -84,15 +84,15 @@ aiohttp==3.9.5 ; python_full_version >= "3.9.0" and python_version < "3.13" \ aiosignal==1.3.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc \ --hash=sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17 -alluka==0.3.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:1b56fbfb1ba80e2d2e7ef5f69dd0852aeea0a65f65e9d4d688da1b93188ef4ec \ - --hash=sha256:41585a274a27edbbf71472912c4cb13675fe360e356642bf93dc1e974a3598e3 -annotated-types==0.6.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43 \ - --hash=sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d -argcomplete==3.3.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:c168c3723482c031df3c207d4ba8fa702717ccb9fc0bfe4117166c1f537b4a54 \ - --hash=sha256:fd03ff4a5b9e6580569d34b273f741e85cd9e072f3feeeee3eba4891c70eda62 +alluka==0.3.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:40563bbc7d55a366901b3939d047d1e08195219e4c62b7a1b63be0f20e394ff2 \ + --hash=sha256:b7100a9dcced87fb3bf0bc8755b3b35fe3308b9275cb6c03db9cb09ae12db6db +annotated-types==0.7.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ + --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 +argcomplete==3.4.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:69a79e083a716173e5532e0fa3bef45f793f4e61096cf52b5a42c0211c8b8aa5 \ + --hash=sha256:c2abcdfe1be8ace47ba777d4fce319eb13bf8ad9dace8d085dcad6eded88057f async-timeout==4.0.3 ; python_full_version >= "3.9.0" and python_version < "3.11" \ --hash=sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f \ --hash=sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028 @@ -105,59 +105,59 @@ colorama==0.4.6 ; python_full_version >= "3.9.0" and python_version < "3.13" and colorlog==6.8.2 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:3e3e079a41feb5a1b64f978b5ea4f46040a94f11f0e8bbb8261e3dbbeca64d44 \ --hash=sha256:4dcbb62368e2800cb3c5abd348da7e53f6c362dda502ec27c560b2e58a66bd33 -coverage[toml]==7.5.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:0646599e9b139988b63704d704af8e8df7fa4cbc4a1f33df69d97f36cb0a38de \ - --hash=sha256:0cdcbc320b14c3e5877ee79e649677cb7d89ef588852e9583e6b24c2e5072661 \ - --hash=sha256:0d0a0f5e06881ecedfe6f3dd2f56dcb057b6dbeb3327fd32d4b12854df36bf26 \ - --hash=sha256:1434e088b41594baa71188a17533083eabf5609e8e72f16ce8c186001e6b8c41 \ - --hash=sha256:16db7f26000a07efcf6aea00316f6ac57e7d9a96501e990a36f40c965ec7a95d \ - --hash=sha256:1cc0fe9b0b3a8364093c53b0b4c0c2dd4bb23acbec4c9240b5f284095ccf7981 \ - --hash=sha256:1fc81d5878cd6274ce971e0a3a18a8803c3fe25457165314271cf78e3aae3aa2 \ - --hash=sha256:2ec92012fefebee89a6b9c79bc39051a6cb3891d562b9270ab10ecfdadbc0c34 \ - --hash=sha256:39afcd3d4339329c5f58de48a52f6e4e50f6578dd6099961cf22228feb25f38f \ - --hash=sha256:4a7b0ceee8147444347da6a66be737c9d78f3353b0681715b668b72e79203e4a \ - --hash=sha256:4a9ca3f2fae0088c3c71d743d85404cec8df9be818a005ea065495bedc33da35 \ - --hash=sha256:4bf0655ab60d754491004a5efd7f9cccefcc1081a74c9ef2da4735d6ee4a6223 \ - --hash=sha256:4cc37def103a2725bc672f84bd939a6fe4522310503207aae4d56351644682f1 \ - --hash=sha256:4fc84a37bfd98db31beae3c2748811a3fa72bf2007ff7902f68746d9757f3746 \ - --hash=sha256:5037f8fcc2a95b1f0e80585bd9d1ec31068a9bcb157d9750a172836e98bc7a90 \ - --hash=sha256:54de9ef3a9da981f7af93eafde4ede199e0846cd819eb27c88e2b712aae9708c \ - --hash=sha256:556cf1a7cbc8028cb60e1ff0be806be2eded2daf8129b8811c63e2b9a6c43bca \ - --hash=sha256:57e0204b5b745594e5bc14b9b50006da722827f0b8c776949f1135677e88d0b8 \ - --hash=sha256:5a5740d1fb60ddf268a3811bcd353de34eb56dc24e8f52a7f05ee513b2d4f596 \ - --hash=sha256:5c3721c2c9e4c4953a41a26c14f4cef64330392a6d2d675c8b1db3b645e31f0e \ - --hash=sha256:5fa567e99765fe98f4e7d7394ce623e794d7cabb170f2ca2ac5a4174437e90dd \ - --hash=sha256:5fd215c0c7d7aab005221608a3c2b46f58c0285a819565887ee0b718c052aa4e \ - --hash=sha256:6175d1a0559986c6ee3f7fccfc4a90ecd12ba0a383dcc2da30c2b9918d67d8a3 \ - --hash=sha256:61c4bf1ba021817de12b813338c9be9f0ad5b1e781b9b340a6d29fc13e7c1b5e \ - --hash=sha256:6537e7c10cc47c595828b8a8be04c72144725c383c4702703ff4e42e44577312 \ - --hash=sha256:68f962d9b72ce69ea8621f57551b2fa9c70509af757ee3b8105d4f51b92b41a7 \ - --hash=sha256:7352b9161b33fd0b643ccd1f21f3a3908daaddf414f1c6cb9d3a2fd618bf2572 \ - --hash=sha256:796a79f63eca8814ca3317a1ea443645c9ff0d18b188de470ed7ccd45ae79428 \ - --hash=sha256:79afb6197e2f7f60c4824dd4b2d4c2ec5801ceb6ba9ce5d2c3080e5660d51a4f \ - --hash=sha256:7a588d39e0925f6a2bff87154752481273cdb1736270642aeb3635cb9b4cad07 \ - --hash=sha256:8748731ad392d736cc9ccac03c9845b13bb07d020a33423fa5b3a36521ac6e4e \ - --hash=sha256:8fe7502616b67b234482c3ce276ff26f39ffe88adca2acf0261df4b8454668b4 \ - --hash=sha256:9314d5678dcc665330df5b69c1e726a0e49b27df0461c08ca12674bcc19ef136 \ - --hash=sha256:9735317685ba6ec7e3754798c8871c2f49aa5e687cc794a0b1d284b2389d1bd5 \ - --hash=sha256:9981706d300c18d8b220995ad22627647be11a4276721c10911e0e9fa44c83e8 \ - --hash=sha256:9e78295f4144f9dacfed4f92935fbe1780021247c2fabf73a819b17f0ccfff8d \ - --hash=sha256:b016ea6b959d3b9556cb401c55a37547135a587db0115635a443b2ce8f1c7228 \ - --hash=sha256:b6cf3764c030e5338e7f61f95bd21147963cf6aa16e09d2f74f1fa52013c1206 \ - --hash=sha256:beccf7b8a10b09c4ae543582c1319c6df47d78fd732f854ac68d518ee1fb97fa \ - --hash=sha256:c0884920835a033b78d1c73b6d3bbcda8161a900f38a488829a83982925f6c2e \ - --hash=sha256:c3e757949f268364b96ca894b4c342b41dc6f8f8b66c37878aacef5930db61be \ - --hash=sha256:ca498687ca46a62ae590253fba634a1fe9836bc56f626852fb2720f334c9e4e5 \ - --hash=sha256:d1d0d98d95dd18fe29dc66808e1accf59f037d5716f86a501fc0256455219668 \ - --hash=sha256:d21918e9ef11edf36764b93101e2ae8cc82aa5efdc7c5a4e9c6c35a48496d601 \ - --hash=sha256:d7fed867ee50edf1a0b4a11e8e5d0895150e572af1cd6d315d557758bfa9c057 \ - --hash=sha256:db66fc317a046556a96b453a58eced5024af4582a8dbdc0c23ca4dbc0d5b3146 \ - --hash=sha256:dde0070c40ea8bb3641e811c1cfbf18e265d024deff6de52c5950677a8fb1e0f \ - --hash=sha256:df4e745a81c110e7446b1cc8131bf986157770fa405fe90e15e850aaf7619bc8 \ - --hash=sha256:e2213def81a50519d7cc56ed643c9e93e0247f5bbe0d1247d15fa520814a7cd7 \ - --hash=sha256:ef48e2707fb320c8f139424a596f5b69955a85b178f15af261bab871873bb987 \ - --hash=sha256:f152cbf5b88aaeb836127d920dd0f5e7edff5a66f10c079157306c4343d86c19 \ - --hash=sha256:fc0b4d8bfeabd25ea75e94632f5b6e047eef8adaed0c2161ada1e922e7f7cece +coverage[toml]==7.5.4 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f \ + --hash=sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d \ + --hash=sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747 \ + --hash=sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f \ + --hash=sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d \ + --hash=sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f \ + --hash=sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47 \ + --hash=sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e \ + --hash=sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba \ + --hash=sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c \ + --hash=sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b \ + --hash=sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4 \ + --hash=sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7 \ + --hash=sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555 \ + --hash=sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233 \ + --hash=sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace \ + --hash=sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805 \ + --hash=sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136 \ + --hash=sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4 \ + --hash=sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d \ + --hash=sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806 \ + --hash=sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99 \ + --hash=sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8 \ + --hash=sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b \ + --hash=sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5 \ + --hash=sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da \ + --hash=sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0 \ + --hash=sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078 \ + --hash=sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f \ + --hash=sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029 \ + --hash=sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353 \ + --hash=sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638 \ + --hash=sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9 \ + --hash=sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f \ + --hash=sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7 \ + --hash=sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3 \ + --hash=sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e \ + --hash=sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016 \ + --hash=sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088 \ + --hash=sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4 \ + --hash=sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882 \ + --hash=sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7 \ + --hash=sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53 \ + --hash=sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d \ + --hash=sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080 \ + --hash=sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5 \ + --hash=sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d \ + --hash=sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c \ + --hash=sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8 \ + --hash=sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633 \ + --hash=sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9 \ + --hash=sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c distlib==0.3.8 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784 \ --hash=sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64 @@ -167,9 +167,9 @@ exceptiongroup==1.2.1 ; python_full_version >= "3.9.0" and python_version < "3.1 execnet==2.1.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc \ --hash=sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3 -filelock==3.14.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:43339835842f110ca7ae60f1e1c160714c5a6afd15a2873419ab185334975c0f \ - --hash=sha256:6ea72da3be9b8c82afd3edcf99f2fffbb5076335a5ae4d03248bb5b6c3eae78a +filelock==3.15.4 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb \ + --hash=sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7 freezegun==1.5.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:b29dedfcda6d5e8e083ce71b2b542753ad48cfec44037b3fc79702e2980a89e9 \ --hash=sha256:bf111d7138a8abe55ab48a71755673dbaa4ab87f4cff5634a4442dfec34c15f1 @@ -251,9 +251,9 @@ frozenlist==1.4.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887 \ --hash=sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced \ --hash=sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74 -hikari==2.0.0.dev125 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:4c139e7f81089dc234e21d81177ca7d0d97bba974ac0de5a03b3e7e0ac0c6541 \ - --hash=sha256:f9677386b77f58fcb04d1b91cd6f4f5b306014fb952b11615ef0ca3430296953 +hikari==2.0.0.dev126 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:1ace1bc6d3a634a97d6d6aa3a8bc56f1cf3ad02caae4a9860699247b52e650a5 \ + --hash=sha256:cdbe0916dcfdc8e2dee16f89731a20f66e27e01914a549e06b06c74261141d31 idna==3.7 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc \ --hash=sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0 @@ -449,110 +449,110 @@ mypy==1.10.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727 \ --hash=sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976 \ --hash=sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4 -nodeenv==1.8.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2 \ - --hash=sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec +nodeenv==1.9.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f \ + --hash=sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9 nox==2024.4.15 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:6492236efa15a460ecb98e7b67562a28b70da006ab0be164e8821177577c0565 \ --hash=sha256:ecf6700199cdfa9e5ea0a41ff5e6ef4641d09508eda6edb89d9987864115817f -packaging==24.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5 \ - --hash=sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9 -platformdirs==4.2.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:031cd18d4ec63ec53e82dceaac0417d218a6863f7745dfcc9efe7793b7039bdf \ - --hash=sha256:17d5a1161b3fd67b390023cb2d3b026bbd40abde6fdb052dfbd3a29c3ba22ee1 +packaging==24.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002 \ + --hash=sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124 +platformdirs==4.2.2 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee \ + --hash=sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3 pluggy==1.5.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1 \ --hash=sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669 -pydantic-core==2.18.2 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:0098300eebb1c837271d3d1a2cd2911e7c11b396eac9661655ee524a7f10587b \ - --hash=sha256:042473b6280246b1dbf530559246f6842b56119c2926d1e52b631bdc46075f2a \ - --hash=sha256:05b7133a6e6aeb8df37d6f413f7705a37ab4031597f64ab56384c94d98fa0e90 \ - --hash=sha256:0680b1f1f11fda801397de52c36ce38ef1c1dc841a0927a94f226dea29c3ae3d \ - --hash=sha256:0d69b4c2f6bb3e130dba60d34c0845ba31b69babdd3f78f7c0c8fae5021a253e \ - --hash=sha256:1404c69d6a676245199767ba4f633cce5f4ad4181f9d0ccb0577e1f66cf4c46d \ - --hash=sha256:182245ff6b0039e82b6bb585ed55a64d7c81c560715d1bad0cbad6dfa07b4027 \ - --hash=sha256:1a388a77e629b9ec814c1b1e6b3b595fe521d2cdc625fcca26fbc2d44c816804 \ - --hash=sha256:1d90c3265ae107f91a4f279f4d6f6f1d4907ac76c6868b27dc7fb33688cfb347 \ - --hash=sha256:20aca1e2298c56ececfd8ed159ae4dde2df0781988c97ef77d5c16ff4bd5b400 \ - --hash=sha256:219da3f096d50a157f33645a1cf31c0ad1fe829a92181dd1311022f986e5fbe3 \ - --hash=sha256:22057013c8c1e272eb8d0eebc796701167d8377441ec894a8fed1af64a0bf399 \ - --hash=sha256:223ee893d77a310a0391dca6df00f70bbc2f36a71a895cecd9a0e762dc37b349 \ - --hash=sha256:224c421235f6102e8737032483f43c1a8cfb1d2f45740c44166219599358c2cd \ - --hash=sha256:2334ce8c673ee93a1d6a65bd90327588387ba073c17e61bf19b4fd97d688d63c \ - --hash=sha256:269322dcc3d8bdb69f054681edff86276b2ff972447863cf34c8b860f5188e2e \ - --hash=sha256:2728b01246a3bba6de144f9e3115b532ee44bd6cf39795194fb75491824a1413 \ - --hash=sha256:2b8ed04b3582771764538f7ee7001b02e1170223cf9b75dff0bc698fadb00cf3 \ - --hash=sha256:2e29d20810dfc3043ee13ac7d9e25105799817683348823f305ab3f349b9386e \ - --hash=sha256:36789b70d613fbac0a25bb07ab3d9dba4d2e38af609c020cf4d888d165ee0bf3 \ - --hash=sha256:390193c770399861d8df9670fb0d1874f330c79caaca4642332df7c682bf6b91 \ - --hash=sha256:3a6515ebc6e69d85502b4951d89131ca4e036078ea35533bb76327f8424531ce \ - --hash=sha256:3f9a801e7c8f1ef8718da265bba008fa121243dfe37c1cea17840b0944dfd72c \ - --hash=sha256:43f0f463cf89ace478de71a318b1b4f05ebc456a9b9300d027b4b57c1a2064fb \ - --hash=sha256:4456f2dca97c425231d7315737d45239b2b51a50dc2b6f0c2bb181fce6207664 \ - --hash=sha256:470b94480bb5ee929f5acba6995251ada5e059a5ef3e0dfc63cca287283ebfa6 \ - --hash=sha256:4774f3184d2ef3e14e8693194f661dea5a4d6ca4e3dc8e39786d33a94865cefd \ - --hash=sha256:4b4356d3538c3649337df4074e81b85f0616b79731fe22dd11b99499b2ebbdf3 \ - --hash=sha256:553ef617b6836fc7e4df130bb851e32fe357ce36336d897fd6646d6058d980af \ - --hash=sha256:6132dd3bd52838acddca05a72aafb6eab6536aa145e923bb50f45e78b7251043 \ - --hash=sha256:6a46e22a707e7ad4484ac9ee9f290f9d501df45954184e23fc29408dfad61350 \ - --hash=sha256:6e5c584d357c4e2baf0ff7baf44f4994be121e16a2c88918a5817331fc7599d7 \ - --hash=sha256:75250dbc5290e3f1a0f4618db35e51a165186f9034eff158f3d490b3fed9f8a0 \ - --hash=sha256:75f7e9488238e920ab6204399ded280dc4c307d034f3924cd7f90a38b1829563 \ - --hash=sha256:78363590ef93d5d226ba21a90a03ea89a20738ee5b7da83d771d283fd8a56761 \ - --hash=sha256:7ca4ae5a27ad7a4ee5170aebce1574b375de390bc01284f87b18d43a3984df72 \ - --hash=sha256:800d60565aec896f25bc3cfa56d2277d52d5182af08162f7954f938c06dc4ee3 \ - --hash=sha256:82d5d4d78e4448683cb467897fe24e2b74bb7b973a541ea1dcfec1d3cbce39fb \ - --hash=sha256:852e966fbd035a6468fc0a3496589b45e2208ec7ca95c26470a54daed82a0788 \ - --hash=sha256:868649da93e5a3d5eacc2b5b3b9235c98ccdbfd443832f31e075f54419e1b96b \ - --hash=sha256:886eec03591b7cf058467a70a87733b35f44707bd86cf64a615584fd72488b7c \ - --hash=sha256:8b172601454f2d7701121bbec3425dd71efcb787a027edf49724c9cefc14c038 \ - --hash=sha256:95b9d5e72481d3780ba3442eac863eae92ae43a5f3adb5b4d0a1de89d42bb250 \ - --hash=sha256:98758d627ff397e752bc339272c14c98199c613f922d4a384ddc07526c86a2ec \ - --hash=sha256:997abc4df705d1295a42f95b4eec4950a37ad8ae46d913caeee117b6b198811c \ - --hash=sha256:9b5155ff768083cb1d62f3e143b49a8a3432e6789a3abee8acd005c3c7af1c74 \ - --hash=sha256:9e08e867b306f525802df7cd16c44ff5ebbe747ff0ca6cf3fde7f36c05a59a81 \ - --hash=sha256:9fdad8e35f278b2c3eb77cbdc5c0a49dada440657bf738d6905ce106dc1de439 \ - --hash=sha256:a1874c6dd4113308bd0eb568418e6114b252afe44319ead2b4081e9b9521fe75 \ - --hash=sha256:a8309f67285bdfe65c372ea3722b7a5642680f3dba538566340a9d36e920b5f0 \ - --hash=sha256:ae0a8a797a5e56c053610fa7be147993fe50960fa43609ff2a9552b0e07013e8 \ - --hash=sha256:b14d82cdb934e99dda6d9d60dc84a24379820176cc4a0d123f88df319ae9c150 \ - --hash=sha256:b1bd7e47b1558ea872bd16c8502c414f9e90dcf12f1395129d7bb42a09a95438 \ - --hash=sha256:b3ef08e20ec49e02d5c6717a91bb5af9b20f1805583cb0adfe9ba2c6b505b5ae \ - --hash=sha256:b89ed9eb7d616ef5714e5590e6cf7f23b02d0d539767d33561e3675d6f9e3857 \ - --hash=sha256:c4fcf5cd9c4b655ad666ca332b9a081112cd7a58a8b5a6ca7a3104bc950f2038 \ - --hash=sha256:c6fdc8627910eed0c01aed6a390a252fe3ea6d472ee70fdde56273f198938374 \ - --hash=sha256:c9bd70772c720142be1020eac55f8143a34ec9f82d75a8e7a07852023e46617f \ - --hash=sha256:ca7b0c1f1c983e064caa85f3792dd2fe3526b3505378874afa84baf662e12241 \ - --hash=sha256:cbca948f2d14b09d20268cda7b0367723d79063f26c4ffc523af9042cad95592 \ - --hash=sha256:cc1cfd88a64e012b74e94cd00bbe0f9c6df57049c97f02bb07d39e9c852e19a4 \ - --hash=sha256:ccdd111c03bfd3666bd2472b674c6899550e09e9f298954cfc896ab92b5b0e6d \ - --hash=sha256:cfeecd1ac6cc1fb2692c3d5110781c965aabd4ec5d32799773ca7b1456ac636b \ - --hash=sha256:d4d938ec0adf5167cb335acb25a4ee69a8107e4984f8fbd2e897021d9e4ca21b \ - --hash=sha256:d7d904828195733c183d20a54230c0df0eb46ec746ea1a666730787353e87182 \ - --hash=sha256:d91cb5ea8b11607cc757675051f61b3d93f15eca3cefb3e6c704a5d6e8440f4e \ - --hash=sha256:d9319e499827271b09b4e411905b24a426b8fb69464dfa1696258f53a3334641 \ - --hash=sha256:e0e8b1be28239fc64a88a8189d1df7fad8be8c1ae47fcc33e43d4be15f99cc70 \ - --hash=sha256:e18609ceaa6eed63753037fc06ebb16041d17d28199ae5aba0052c51449650a9 \ - --hash=sha256:e1b395e58b10b73b07b7cf740d728dd4ff9365ac46c18751bf8b3d8cca8f625a \ - --hash=sha256:e23ec367a948b6d812301afc1b13f8094ab7b2c280af66ef450efc357d2ae543 \ - --hash=sha256:e25add29b8f3b233ae90ccef2d902d0ae0432eb0d45370fe315d1a5cf231004b \ - --hash=sha256:e6dac87ddb34aaec85f873d737e9d06a3555a1cc1a8e0c44b7f8d5daeb89d86f \ - --hash=sha256:ef26c9e94a8c04a1b2924149a9cb081836913818e55681722d7f29af88fe7b38 \ - --hash=sha256:eff2de745698eb46eeb51193a9f41d67d834d50e424aef27df2fcdee1b153845 \ - --hash=sha256:f0a21cbaa69900cbe1a2e7cad2aa74ac3cf21b10c3efb0fa0b80305274c0e8a2 \ - --hash=sha256:f459a5ce8434614dfd39bbebf1041952ae01da6bed9855008cb33b875cb024c0 \ - --hash=sha256:f93a8a2e3938ff656a7c1bc57193b1319960ac015b6e87d76c76bf14fe0244b4 \ - --hash=sha256:fb2bd7be70c0fe4dfd32c951bc813d9fe6ebcbfdd15a07527796c8204bd36242 -pydantic==2.7.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:e029badca45266732a9a79898a15ae2e8b14840b1eabbb25844be28f0b33f3d5 \ - --hash=sha256:e9dbb5eada8abe4d9ae5f46b9939aead650cd2b68f249bb3a8139dbe125803cc -pyright==1.1.362 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:6a477e448d4a07a6a0eab58b2a15a1bbed031eb3169fa809edee79cca168d83a \ - --hash=sha256:969957cff45154d8a45a4ab1dae5bdc8223d8bd3c64654fa608ab3194dfff319 -pytest-asyncio==0.23.6 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:68516fdd1018ac57b846c9846b954f0393b26f094764a28c955eabb0536a4e8a \ - --hash=sha256:ffe523a89c1c222598c76856e76852b787504ddb72dd5d9b6617ffa8aa2cde5f +pydantic-core==2.18.4 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:01dd777215e2aa86dfd664daed5957704b769e726626393438f9c87690ce78c3 \ + --hash=sha256:0eb2a4f660fcd8e2b1c90ad566db2b98d7f3f4717c64fe0a83e0adb39766d5b8 \ + --hash=sha256:0fbbdc827fe5e42e4d196c746b890b3d72876bdbf160b0eafe9f0334525119c8 \ + --hash=sha256:123c3cec203e3f5ac7b000bd82235f1a3eced8665b63d18be751f115588fea30 \ + --hash=sha256:14601cdb733d741b8958224030e2bfe21a4a881fb3dd6fbb21f071cabd48fa0a \ + --hash=sha256:18f469a3d2a2fdafe99296a87e8a4c37748b5080a26b806a707f25a902c040a8 \ + --hash=sha256:19894b95aacfa98e7cb093cd7881a0c76f55731efad31073db4521e2b6ff5b7d \ + --hash=sha256:1b4de2e51bbcb61fdebd0ab86ef28062704f62c82bbf4addc4e37fa4b00b7cbc \ + --hash=sha256:1d886dc848e60cb7666f771e406acae54ab279b9f1e4143babc9c2258213daa2 \ + --hash=sha256:1f4d26ceb5eb9eed4af91bebeae4b06c3fb28966ca3a8fb765208cf6b51102ab \ + --hash=sha256:21a5e440dbe315ab9825fcd459b8814bb92b27c974cbc23c3e8baa2b76890077 \ + --hash=sha256:293afe532740370aba8c060882f7d26cfd00c94cae32fd2e212a3a6e3b7bc15e \ + --hash=sha256:2f5966897e5461f818e136b8451d0551a2e77259eb0f73a837027b47dc95dab9 \ + --hash=sha256:2fd41f6eff4c20778d717af1cc50eca52f5afe7805ee530a4fbd0bae284f16e9 \ + --hash=sha256:2fdf2156aa3d017fddf8aea5adfba9f777db1d6022d392b682d2a8329e087cef \ + --hash=sha256:3c40d4eaad41f78e3bbda31b89edc46a3f3dc6e171bf0ecf097ff7a0ffff7cb1 \ + --hash=sha256:43d447dd2ae072a0065389092a231283f62d960030ecd27565672bd40746c507 \ + --hash=sha256:44a688331d4a4e2129140a8118479443bd6f1905231138971372fcde37e43528 \ + --hash=sha256:44c7486a4228413c317952e9d89598bcdfb06399735e49e0f8df643e1ccd0558 \ + --hash=sha256:44cd83ab6a51da80fb5adbd9560e26018e2ac7826f9626bc06ca3dc074cd198b \ + --hash=sha256:46387e38bd641b3ee5ce247563b60c5ca098da9c56c75c157a05eaa0933ed154 \ + --hash=sha256:4701b19f7e3a06ea655513f7938de6f108123bf7c86bbebb1196eb9bd35cf724 \ + --hash=sha256:4748321b5078216070b151d5271ef3e7cc905ab170bbfd27d5c83ee3ec436695 \ + --hash=sha256:4b06beb3b3f1479d32befd1f3079cc47b34fa2da62457cdf6c963393340b56e9 \ + --hash=sha256:4d0dcc59664fcb8974b356fe0a18a672d6d7cf9f54746c05f43275fc48636851 \ + --hash=sha256:4e99bc050fe65c450344421017f98298a97cefc18c53bb2f7b3531eb39bc7805 \ + --hash=sha256:509daade3b8649f80d4e5ff21aa5673e4ebe58590b25fe42fac5f0f52c6f034a \ + --hash=sha256:51991a89639a912c17bef4b45c87bd83593aee0437d8102556af4885811d59f5 \ + --hash=sha256:53db086f9f6ab2b4061958d9c276d1dbe3690e8dd727d6abf2321d6cce37fa94 \ + --hash=sha256:564d7922e4b13a16b98772441879fcdcbe82ff50daa622d681dd682175ea918c \ + --hash=sha256:574d92eac874f7f4db0ca653514d823a0d22e2354359d0759e3f6a406db5d55d \ + --hash=sha256:578e24f761f3b425834f297b9935e1ce2e30f51400964ce4801002435a1b41ef \ + --hash=sha256:59ff3e89f4eaf14050c8022011862df275b552caef8082e37b542b066ce1ff26 \ + --hash=sha256:5f09baa656c904807e832cf9cce799c6460c450c4ad80803517032da0cd062e2 \ + --hash=sha256:6891a2ae0e8692679c07728819b6e2b822fb30ca7445f67bbf6509b25a96332c \ + --hash=sha256:6a750aec7bf431517a9fd78cb93c97b9b0c496090fee84a47a0d23668976b4b0 \ + --hash=sha256:6f5c4d41b2771c730ea1c34e458e781b18cc668d194958e0112455fff4e402b2 \ + --hash=sha256:77450e6d20016ec41f43ca4a6c63e9fdde03f0ae3fe90e7c27bdbeaece8b1ed4 \ + --hash=sha256:81b5efb2f126454586d0f40c4d834010979cb80785173d1586df845a632e4e6d \ + --hash=sha256:823be1deb01793da05ecb0484d6c9e20baebb39bd42b5d72636ae9cf8350dbd2 \ + --hash=sha256:834b5230b5dfc0c1ec37b2fda433b271cbbc0e507560b5d1588e2cc1148cf1ce \ + --hash=sha256:847a35c4d58721c5dc3dba599878ebbdfd96784f3fb8bb2c356e123bdcd73f34 \ + --hash=sha256:86110d7e1907ab36691f80b33eb2da87d780f4739ae773e5fc83fb272f88825f \ + --hash=sha256:8951eee36c57cd128f779e641e21eb40bc5073eb28b2d23f33eb0ef14ffb3f5d \ + --hash=sha256:8a7164fe2005d03c64fd3b85649891cd4953a8de53107940bf272500ba8a788b \ + --hash=sha256:8b8bab4c97248095ae0c4455b5a1cd1cdd96e4e4769306ab19dda135ea4cdb07 \ + --hash=sha256:90afc12421df2b1b4dcc975f814e21bc1754640d502a2fbcc6d41e77af5ec312 \ + --hash=sha256:938cb21650855054dc54dfd9120a851c974f95450f00683399006aa6e8abb057 \ + --hash=sha256:942ba11e7dfb66dc70f9ae66b33452f51ac7bb90676da39a7345e99ffb55402d \ + --hash=sha256:972658f4a72d02b8abfa2581d92d59f59897d2e9f7e708fdabe922f9087773af \ + --hash=sha256:97736815b9cc893b2b7f663628e63f436018b75f44854c8027040e05230eeddb \ + --hash=sha256:98906207f29bc2c459ff64fa007afd10a8c8ac080f7e4d5beff4c97086a3dabd \ + --hash=sha256:99457f184ad90235cfe8461c4d70ab7dd2680e28821c29eca00252ba90308c78 \ + --hash=sha256:a0d829524aaefdebccb869eed855e2d04c21d2d7479b6cada7ace5448416597b \ + --hash=sha256:a2fdd81edd64342c85ac7cf2753ccae0b79bf2dfa063785503cb85a7d3593223 \ + --hash=sha256:a55b5b16c839df1070bc113c1f7f94a0af4433fcfa1b41799ce7606e5c79ce0a \ + --hash=sha256:a642295cd0c8df1b86fc3dced1d067874c353a188dc8e0f744626d49e9aa51c4 \ + --hash=sha256:ab86ce7c8f9bea87b9d12c7f0af71102acbf5ecbc66c17796cff45dae54ef9a5 \ + --hash=sha256:abc267fa9837245cc28ea6929f19fa335f3dc330a35d2e45509b6566dc18be23 \ + --hash=sha256:ae1d6df168efb88d7d522664693607b80b4080be6750c913eefb77e34c12c71a \ + --hash=sha256:b2ebef0e0b4454320274f5e83a41844c63438fdc874ea40a8b5b4ecb7693f1c4 \ + --hash=sha256:b48ece5bde2e768197a2d0f6e925f9d7e3e826f0ad2271120f8144a9db18d5c8 \ + --hash=sha256:b7cdf28938ac6b8b49ae5e92f2735056a7ba99c9b110a474473fd71185c1af5d \ + --hash=sha256:bb4462bd43c2460774914b8525f79b00f8f407c945d50881568f294c1d9b4443 \ + --hash=sha256:bc4ff9805858bd54d1a20efff925ccd89c9d2e7cf4986144b30802bf78091c3e \ + --hash=sha256:c1322d7dd74713dcc157a2b7898a564ab091ca6c58302d5c7b4c07296e3fd00f \ + --hash=sha256:c67598100338d5d985db1b3d21f3619ef392e185e71b8d52bceacc4a7771ea7e \ + --hash=sha256:ca26a1e73c48cfc54c4a76ff78df3727b9d9f4ccc8dbee4ae3f73306a591676d \ + --hash=sha256:d323a01da91851a4f17bf592faf46149c9169d68430b3146dcba2bb5e5719abc \ + --hash=sha256:dc1803ac5c32ec324c5261c7209e8f8ce88e83254c4e1aebdc8b0a39f9ddb443 \ + --hash=sha256:e00a3f196329e08e43d99b79b286d60ce46bed10f2280d25a1718399457e06be \ + --hash=sha256:e85637bc8fe81ddb73fda9e56bab24560bdddfa98aa64f87aaa4e4b6730c23d2 \ + --hash=sha256:e858ac0a25074ba4bce653f9b5d0a85b7456eaddadc0ce82d3878c22489fa4ee \ + --hash=sha256:eae237477a873ab46e8dd748e515c72c0c804fb380fbe6c85533c7de51f23a8f \ + --hash=sha256:ebef0dd9bf9b812bf75bda96743f2a6c5734a02092ae7f721c048d156d5fabae \ + --hash=sha256:ec3beeada09ff865c344ff3bc2f427f5e6c26401cc6113d77e372c3fdac73864 \ + --hash=sha256:f76d0ad001edd426b92233d45c746fd08f467d56100fd8f30e9ace4b005266e4 \ + --hash=sha256:f85d05aa0918283cf29a30b547b4df2fbb56b45b135f9e35b6807cb28bc47951 \ + --hash=sha256:f9899c94762343f2cc2fc64c13e7cae4c3cc65cdfc87dd810a31654c9b7358cc +pydantic==2.7.4 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:0c84efd9548d545f63ac0060c1e4d39bb9b14db8b3c0652338aecc07b5adec52 \ + --hash=sha256:ee8538d41ccb9c0a9ad3e0e5f07bf15ed8015b481ced539a1759d8cc89ae90d0 +pyright==1.1.368 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:4a86e34b61c755b43b367af7fbf927fc6466fff6b81a9dcea07d42416c640af3 \ + --hash=sha256:9b2aa48142d9d9fc9a6aedff743c76873cc4e615f3297cdbf893d5793f75b306 +pytest-asyncio==0.23.7 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:009b48127fbe44518a547bddd25611551b0e43ccdbf1e67d12479f569832c20b \ + --hash=sha256:5f5c72948f4c49e7db4f29f2521d4031f1c27f86e57b046126654083d4770268 pytest-cov==5.0.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652 \ --hash=sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857 @@ -571,9 +571,6 @@ pytest==7.4.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ python-dateutil==2.9.0.post0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 -setuptools==69.5.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:6c1fccdac05a97e598fb0ae3bbed5904ccb317337a51139dcd51453611bbb987 \ - --hash=sha256:c636ac361bc47580504644275c9ad802c50415c7522212252c033bd15f301f32 six==1.16.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 @@ -583,12 +580,12 @@ termcolor==2.4.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ tomli==2.0.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \ --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f -typing-extensions==4.11.0 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0 \ - --hash=sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a -virtualenv==20.26.1 ; python_full_version >= "3.9.0" and python_version < "3.13" \ - --hash=sha256:604bfdceaeece392802e6ae48e69cec49168b9c5f4a44e483963f9242eb0e78b \ - --hash=sha256:7aa9982a728ae5892558bff6a2839c00b9ed145523ece2274fad6f414690ae75 +typing-extensions==4.12.2 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d \ + --hash=sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8 +virtualenv==20.26.3 ; python_full_version >= "3.9.0" and python_version < "3.13" \ + --hash=sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a \ + --hash=sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589 yarl==1.9.4 ; python_full_version >= "3.9.0" and python_version < "3.13" \ --hash=sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51 \ --hash=sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce \ diff --git a/docs/usage.md b/docs/usage.md index f126785c9..7381e2df1 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -385,13 +385,14 @@ The following types are registered globally as type dependencies: The following type dependencies are available in specific contexts: * [tanjun.abc.AutocompleteContext][]: slash command autocomplete execution -* [tanjun.abc.AppCommandContext][]: both slash and menu command execution (excluding any checks) +* [tanjun.abc.Context][] for all command execution (not autocomplete) +* [tanjun.abc.AppCommandContext][]: both slash and menu command execution * [tanjun.abc.MenuContext][]: menu command execution * [tanjun.abc.MessageContext][]: message command execution * [tanjun.abc.SlashContext][]: slash command execution - * [tanjun.abc.Component][]: Command execution (excluding client checks) diff --git a/pyproject.toml b/pyproject.toml index cf3446cdf..b1f7b952c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,7 @@ classifiers = [ "Topic :: Utilities", "Typing :: Typed", ] -dependencies = ["alluka>=0.2.0, <1", "hikari>=2.0.0.dev115, <3", "typing-extensions>=4.5, <5"] +dependencies = ["alluka>=0.3.0, <1", "hikari>=2.0.0.dev115, <3", "typing-extensions>=4.5, <5"] dynamic = ["description"] [project.urls] diff --git a/tanjun/_internal/__init__.py b/tanjun/_internal/__init__.py index a8e7da8cf..0f4a7d31d 100644 --- a/tanjun/_internal/__init__.py +++ b/tanjun/_internal/__init__.py @@ -52,6 +52,7 @@ if typing.TYPE_CHECKING: import typing_extensions + from alluka import abc as alluka from .. import abc as tanjun @@ -89,18 +90,25 @@ class _DefaultEnum(enum.Enum): """The type of `DEFAULT`.""" -async def _execute_check(ctx: _ContextT, callback: tanjun.CheckSig[_ContextT], /) -> bool: - if result := await ctx.call_with_async_di(callback, ctx): +async def _execute_check(alluka_ctx: alluka.Context, ctx: _ContextT, callback: tanjun.CheckSig[_ContextT], /) -> bool: + if result := await alluka_ctx.call_with_async_di(callback, ctx): return result raise errors.FailedCheck -async def gather_checks(ctx: _ContextT, checks: collections.Iterable[tanjun.CheckSig[_ContextT]], /) -> bool: +async def gather_checks( + alluka_ctx: typing.Optional[alluka.Context], + ctx: _ContextT, + checks: collections.Iterable[tanjun.CheckSig[_ContextT]], + /, +) -> bool: """Gather a collection of checks. Parameters ---------- + alluka_ctx + The Alluka context to use for dependency injection. ctx : tanjun.abc.Context The context to check. checks : collections.abc.Iterable[tanjun.abc.CheckSig] @@ -111,8 +119,9 @@ async def gather_checks(ctx: _ContextT, checks: collections.Iterable[tanjun.Chec bool Whether all the checks passed or not. """ + alluka_ctx = alluka_ctx or ctx.client.injector.make_context() try: - await asyncio.gather(*(_execute_check(ctx, check) for check in checks)) + await asyncio.gather(*(_execute_check(alluka_ctx, ctx, check) for check in checks)) except errors.FailedCheck: return False diff --git a/tanjun/abc.py b/tanjun/abc.py index 61bc3183a..567a70289 100644 --- a/tanjun/abc.py +++ b/tanjun/abc.py @@ -76,6 +76,7 @@ from collections import abc as collections import hikari +import typing_extensions from alluka import abc as alluka if typing.TYPE_CHECKING: @@ -136,8 +137,6 @@ # 3.9 and 3.10 just can't handle ending Concatenate with ... so we lie about this at runtime. if typing.TYPE_CHECKING: - import typing_extensions - _MaybeAwaitable = typing.Union[_CoroT[_T], _T] AutocompleteSig = collections.Callable[ @@ -288,7 +287,12 @@ class _DefaultFlag(enum.Enum): class Context(alluka.Context): - """Interface for the context of a command execution.""" + """Interface for the context of a command execution. + + !!! warning "deprecated" + Using Tanjun contexts as an Alluka context is + deprecated behaviour and may not behave as expected. + """ __slots__ = () @@ -938,9 +942,77 @@ async def respond( If an internal error occurs on Discord while handling the request. """ + @property + @abc.abstractmethod + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def injection_client(self) -> alluka.Client: ... + + @abc.abstractmethod + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def cache_result(self, callback: alluka.CallbackSig[_T], value: _T, /) -> None: ... + + @typing.overload + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + @abc.abstractmethod + def call_with_di( + self, callback: collections.Callable[..., _CoroT[typing.Any]], *args: typing.Any, **kwargs: typing.Any + ) -> typing.NoReturn: ... + + @typing.overload + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + @abc.abstractmethod + def call_with_di(self, callback: collections.Callable[..., _T], *args: typing.Any, **kwargs: typing.Any) -> _T: ... + + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + @abc.abstractmethod + def call_with_di(self, callback: collections.Callable[..., _T], *args: typing.Any, **kwargs: typing.Any) -> _T: ... + + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + @abc.abstractmethod + async def call_with_async_di( + self, callback: alluka.CallbackSig[_T], *args: typing.Any, **kwargs: typing.Any + ) -> _T: ... + + @typing.overload + @abc.abstractmethod + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_cached_result(self, callback: alluka.CallbackSig[_T], /) -> _T: ... + + @typing.overload + @abc.abstractmethod + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_cached_result( + self, callback: alluka.CallbackSig[_T], /, *, default: _DefaultT + ) -> typing.Union[_T, _DefaultT]: ... + + @abc.abstractmethod + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_cached_result( + self, callback: alluka.CallbackSig[_T], /, *, default: _DefaultT = ... + ) -> typing.Union[_T, _DefaultT]: ... + + @typing.overload + @abc.abstractmethod + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_type_dependency(self, type_: type[_T], /) -> _T: ... + + @typing.overload + @abc.abstractmethod + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_type_dependency(self, type_: type[_T], /, *, default: _DefaultT) -> typing.Union[_T, _DefaultT]: ... + + @abc.abstractmethod + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_type_dependency(self, type_: type[_T], /, *, default: _DefaultT = ...) -> typing.Union[_T, _DefaultT]: ... + class MessageContext(Context, abc.ABC): - """Interface of a message command specific context.""" + """Interface of a message command specific context. + + !!! warning "deprecated" + Using Tanjun contexts as an Alluka context is + deprecated behaviour and may not behave as expected. + """ __slots__ = () @@ -1350,7 +1422,12 @@ def resolve_to_user(self) -> typing.Union[hikari.User, hikari.Member]: class AppCommandContext(Context, abc.ABC): - """Base class for application command contexts.""" + """Base class for application command contexts. + + !!! warning "deprecated" + Using Tanjun contexts as an Alluka context is + deprecated behaviour and may not behave as expected. + """ __slots__ = () @@ -1741,7 +1818,12 @@ async def create_modal_response( class MenuContext(AppCommandContext, abc.ABC): - """Interface of a menu command context.""" + """Interface of a menu command context. + + !!! warning "deprecated" + Using Tanjun contexts as an Alluka context is + deprecated behaviour and may not behave as expected. + """ __slots__ = () @@ -1841,7 +1923,12 @@ def resolve_to_user(self) -> typing.Union[hikari.User, hikari.Member]: class SlashContext(AppCommandContext, abc.ABC): - """Interface of a slash command specific context.""" + """Interface of a slash command specific context. + + !!! warning "deprecated" + Using Tanjun contexts as an Alluka context is + deprecated behaviour and may not behave as expected. + """ __slots__ = () @@ -1878,7 +1965,12 @@ def set_command(self, command: typing.Optional[BaseSlashCommand], /) -> Self: class AutocompleteContext(alluka.Context): - """Interface of an autocomplete context.""" + """Interface of an autocomplete context. + + !!! warning "deprecated" + Using Tanjun contexts as an Alluka context is + deprecated behaviour and may not behave as expected. + """ __slots__ = () @@ -2119,6 +2211,69 @@ async def set_choices( If more than 25 choices are passed. """ + @property + @abc.abstractmethod + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def injection_client(self) -> alluka.Client: ... + + @abc.abstractmethod + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def cache_result(self, callback: alluka.CallbackSig[_T], value: _T, /) -> None: ... + + @typing.overload + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + @abc.abstractmethod + def call_with_di( + self, callback: collections.Callable[..., _CoroT[typing.Any]], *args: typing.Any, **kwargs: typing.Any + ) -> typing.NoReturn: ... + + @typing.overload + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + @abc.abstractmethod + def call_with_di(self, callback: collections.Callable[..., _T], *args: typing.Any, **kwargs: typing.Any) -> _T: ... + + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + @abc.abstractmethod + def call_with_di(self, callback: collections.Callable[..., _T], *args: typing.Any, **kwargs: typing.Any) -> _T: ... + + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + @abc.abstractmethod + async def call_with_async_di( + self, callback: alluka.CallbackSig[_T], *args: typing.Any, **kwargs: typing.Any + ) -> _T: ... + + @typing.overload + @abc.abstractmethod + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_cached_result(self, callback: alluka.CallbackSig[_T], /) -> _T: ... + + @typing.overload + @abc.abstractmethod + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_cached_result( + self, callback: alluka.CallbackSig[_T], /, *, default: _DefaultT + ) -> typing.Union[_T, _DefaultT]: ... + + @abc.abstractmethod + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_cached_result( + self, callback: alluka.CallbackSig[_T], /, *, default: _DefaultT = ... + ) -> typing.Union[_T, _DefaultT]: ... + + @typing.overload + @abc.abstractmethod + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_type_dependency(self, type_: type[_T], /) -> _T: ... + + @typing.overload + @abc.abstractmethod + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_type_dependency(self, type_: type[_T], /, *, default: _DefaultT) -> typing.Union[_T, _DefaultT]: ... + + @abc.abstractmethod + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_type_dependency(self, type_: type[_T], /, *, default: _DefaultT = ...) -> typing.Union[_T, _DefaultT]: ... + class Hooks(abc.ABC, typing.Generic[_ContextT_contra]): """Interface of a collection of callbacks called during set stage of command execution.""" @@ -2480,25 +2635,41 @@ async def trigger_error( exception: Exception, /, *, + alluka_ctx: typing.Optional[alluka.Context] = None, hooks: typing.Optional[collections.Set[Hooks[_ContextT_contra]]] = None, ) -> int: raise NotImplementedError @abc.abstractmethod async def trigger_post_execution( - self, ctx: _ContextT_contra, /, *, hooks: typing.Optional[collections.Set[Hooks[_ContextT_contra]]] = None + self, + ctx: _ContextT_contra, + /, + *, + alluka_ctx: typing.Optional[alluka.Context] = None, + hooks: typing.Optional[collections.Set[Hooks[_ContextT_contra]]] = None, ) -> None: raise NotImplementedError @abc.abstractmethod async def trigger_pre_execution( - self, ctx: _ContextT_contra, /, *, hooks: typing.Optional[collections.Set[Hooks[_ContextT_contra]]] = None + self, + ctx: _ContextT_contra, + /, + *, + alluka_ctx: typing.Optional[alluka.Context] = None, + hooks: typing.Optional[collections.Set[Hooks[_ContextT_contra]]] = None, ) -> None: raise NotImplementedError @abc.abstractmethod async def trigger_success( - self, ctx: _ContextT_contra, /, *, hooks: typing.Optional[collections.Set[Hooks[_ContextT_contra]]] = None + self, + ctx: _ContextT_contra, + /, + *, + alluka_ctx: typing.Optional[alluka.Context] = None, + hooks: typing.Optional[collections.Set[Hooks[_ContextT_contra]]] = None, ) -> None: raise NotImplementedError @@ -2735,7 +2906,9 @@ def build(self, *, component: typing.Optional[Component] = None) -> hikari.api.C """ @abc.abstractmethod - async def check_context(self, ctx: _AppCommandContextT, /) -> bool: + async def check_context( + self, ctx: _AppCommandContextT, /, *, alluka_ctx: typing.Optional[alluka.Context] = None + ) -> bool: raise NotImplementedError @abc.abstractmethod @@ -2744,6 +2917,7 @@ async def execute( ctx: _AppCommandContextT, /, *, + alluka_ctx: typing.Optional[alluka.Context] = None, hooks: typing.Optional[collections.MutableSet[Hooks[_AppCommandContextT]]] = None, ) -> None: raise NotImplementedError @@ -2828,15 +3002,21 @@ async def execute( ctx: SlashContext, /, *, - option: typing.Optional[hikari.CommandInteractionOption] = None, + alluka_ctx: typing.Optional[alluka.Context] = None, hooks: typing.Optional[collections.MutableSet[SlashHooks]] = None, + option: typing.Optional[hikari.CommandInteractionOption] = None, ) -> None: raise NotImplementedError ... @abc.abstractmethod async def execute_autocomplete( - self, ctx: AutocompleteContext, /, *, option: typing.Optional[hikari.AutocompleteInteractionOption] = None + self, + ctx: AutocompleteContext, + /, + *, + alluka_ctx: typing.Optional[alluka.Context] = None, + option: typing.Optional[hikari.AutocompleteInteractionOption] = None, ) -> None: ... @@ -3119,12 +3299,19 @@ def copy(self, *, parent: typing.Optional[MessageCommandGroup[typing.Any]] = Non """ @abc.abstractmethod - async def check_context(self, ctx: MessageContext, /) -> bool: + async def check_context( + self, ctx: MessageContext, /, *, alluka_ctx: typing.Optional[alluka.Context] = None + ) -> bool: raise NotImplementedError @abc.abstractmethod async def execute( - self, ctx: MessageContext, /, *, hooks: typing.Optional[collections.MutableSet[Hooks[MessageContext]]] = None + self, + ctx: MessageContext, + /, + *, + alluka_ctx: typing.Optional[alluka.Context] = None, + hooks: typing.Optional[collections.MutableSet[Hooks[MessageContext]]] = None, ) -> None: raise NotImplementedError @@ -3632,7 +3819,9 @@ def check_slash_name(self, name: str, /) -> collections.Iterator[BaseSlashComman """ @abc.abstractmethod - def execute_autocomplete(self, ctx: AutocompleteContext, /) -> typing.Optional[_CoroT[None]]: + def execute_autocomplete( + self, ctx: AutocompleteContext, /, *, alluka_ctx: typing.Optional[alluka.Context] = None + ) -> typing.Optional[_CoroT[None]]: """Execute an autocomplete context. !!! note @@ -3657,7 +3846,12 @@ def execute_autocomplete(self, ctx: AutocompleteContext, /) -> typing.Optional[_ @abc.abstractmethod async def execute_menu( - self, ctx: MenuContext, /, *, hooks: typing.Optional[collections.MutableSet[MenuHooks]] = None + self, + ctx: MenuContext, + /, + *, + alluka_ctx: typing.Optional[alluka.Context] = None, + hooks: typing.Optional[collections.MutableSet[MenuHooks]] = None, ) -> typing.Optional[_CoroT[None]]: """Execute a menu context. @@ -3689,7 +3883,12 @@ async def execute_menu( @abc.abstractmethod async def execute_slash( - self, ctx: SlashContext, /, *, hooks: typing.Optional[collections.MutableSet[SlashHooks]] = None + self, + ctx: SlashContext, + /, + *, + alluka_ctx: typing.Optional[alluka.Context] = None, + hooks: typing.Optional[collections.MutableSet[SlashHooks]] = None, ) -> typing.Optional[_CoroT[None]]: """Execute a slash context. @@ -3721,7 +3920,12 @@ async def execute_slash( @abc.abstractmethod async def execute_message( - self, ctx: MessageContext, /, *, hooks: typing.Optional[collections.MutableSet[MessageHooks]] = None + self, + ctx: MessageContext, + /, + *, + alluka_ctx: typing.Optional[alluka.Context] = None, + hooks: typing.Optional[collections.MutableSet[MessageHooks]] = None, ) -> bool: """Execute a message context. diff --git a/tanjun/checks.py b/tanjun/checks.py index a18961bb8..43528263e 100644 --- a/tanjun/checks.py +++ b/tanjun/checks.py @@ -72,12 +72,20 @@ _ContextT_contra = typing.TypeVar("_ContextT_contra", bound=tanjun.Context, contravariant=True) - class _AnyCallback(typing.Protocol[_ContextT_contra]): + class _AnyCallbackProto(typing.Protocol[_ContextT_contra]): async def __call__( - self, ctx: _ContextT_contra, /, *, localiser: typing.Optional[dependencies.AbstractLocaliser] = None + self, + ctx: _ContextT_contra, + /, + *, + alluka_ctx: alluka.Injected[alluka.abc.Context], + localiser: typing.Optional[dependencies.AbstractLocaliser] = None, ) -> bool: raise NotImplementedError + class _AllChecksProto(typing.Protocol[_ContextT_contra]): + async def __call__(self, ctx: _ContextT_contra, /, *, alluka_ctx: alluka.abc.Context) -> bool: ... + _CommandT = typing.TypeVar("_CommandT", bound=tanjun.ExecutableCommand[typing.Any]) _CallbackReturnT = typing.Union[_CommandT, collections.Callable[[_CommandT], _CommandT]] _MenuCommandT = typing.TypeVar("_MenuCommandT", bound=tanjun.MenuCommand[typing.Any, typing.Any]) @@ -1037,17 +1045,15 @@ class _AllChecks(typing.Generic[_ContextT]): def __init__(self, checks: list[tanjun.CheckSig[_ContextT]]) -> None: self._checks = checks - async def __call__(self, ctx: _ContextT, /) -> bool: + async def __call__(self, ctx: _ContextT, /, *, alluka_ctx: alluka.Injected[alluka.abc.Context]) -> bool: for check in self._checks: # noqa: SIM111 - if not await ctx.call_with_async_di(check, ctx): + if not await alluka_ctx.call_with_async_di(check, ctx): return False return True -def all_checks( - check: tanjun.CheckSig[_ContextT], /, *checks: tanjun.CheckSig[_ContextT] -) -> collections.Callable[[_ContextT], collections.Coroutine[typing.Any, typing.Any, bool]]: +def all_checks(check: tanjun.CheckSig[_ContextT], /, *checks: tanjun.CheckSig[_ContextT]) -> _AllChecksProto[_ContextT]: """Combine multiple check callbacks into a check which will only pass if all the callbacks pass. This ensures that the callbacks are run in the order they were supplied in @@ -1148,11 +1154,16 @@ def __init__( self._suppress = suppress async def __call__( - self, ctx: _ContextT, /, *, localiser: alluka.Injected[typing.Optional[dependencies.AbstractLocaliser]] = None + self, + ctx: _ContextT, + /, + *, + alluka_ctx: alluka.Injected[alluka.abc.Context], + localiser: alluka.Injected[typing.Optional[dependencies.AbstractLocaliser]] = None, ) -> bool: for check in self._checks: try: - if await ctx.call_with_async_di(check, ctx): + if await alluka_ctx.call_with_async_di(check, ctx): return True except errors.FailedCheck: @@ -1172,7 +1183,7 @@ def any_checks( error_message: typing.Union[str, collections.Mapping[str, str], None], halt_execution: bool = False, suppress: tuple[type[Exception], ...] = (errors.CommandError, errors.HaltExecution), -) -> _AnyCallback[_ContextT]: +) -> _AnyCallbackProto[_ContextT]: """Combine multiple checks into a check which'll pass if any of the callbacks pass. This ensures that the callbacks are run in the order they were supplied in diff --git a/tanjun/clients.py b/tanjun/clients.py index 012ad274e..9337f74f2 100644 --- a/tanjun/clients.py +++ b/tanjun/clients.py @@ -792,19 +792,19 @@ def __init__( ( self.set_type_dependency(tanjun.Client, self) .set_type_dependency(Client, self) - .set_type_dependency(type(self), self) + .set_type_dependency(type(self), self) # Deprecated behaviour .set_type_dependency(hikari.api.RESTClient, rest) - .set_type_dependency(type(rest), rest) + .set_type_dependency(type(rest), rest) # Deprecated behaviour ._maybe_set_type_dep(hikari.api.Cache, cache) - ._maybe_set_type_dep(type(cache), cache) + ._maybe_set_type_dep(type(cache), cache) # Deprecated behaviour ._maybe_set_type_dep(hikari.api.EventManager, events) - ._maybe_set_type_dep(type(events), events) + ._maybe_set_type_dep(type(events), events) # Deprecated behaviour ._maybe_set_type_dep(hikari.api.InteractionServer, server) - ._maybe_set_type_dep(type(server), server) + ._maybe_set_type_dep(type(server), server) # Deprecated behaviour ._maybe_set_type_dep(hikari.ShardAware, shards) - ._maybe_set_type_dep(type(shards), shards) + ._maybe_set_type_dep(type(shards), shards) # Deprecated behaviour ._maybe_set_type_dep(hikari.api.VoiceComponent, voice) - ._maybe_set_type_dep(type(voice), voice) + ._maybe_set_type_dep(type(voice), voice) # Deprecated behaviour ) dependencies.set_standard_dependencies(self) @@ -1951,8 +1951,8 @@ def with_check(self, check: _CheckSigT, /) -> _CheckSigT: self.add_check(check) return check - async def check(self, ctx: tanjun.Context, /) -> bool: - return await _internal.gather_checks(ctx, self._checks) + async def check(self, ctx: tanjun.Context, /, *, alluka_ctx: typing.Optional[alluka.abc.Context] = None) -> bool: + return await _internal.gather_checks(alluka_ctx, ctx, self._checks) def add_component(self, component: tanjun.Component, /) -> Self: """Add a component to this client. @@ -2285,10 +2285,12 @@ def check_slash_name(self, name: str, /) -> collections.Iterator[tanjun.BaseSlas component.check_slash_name(name) for component in self._components.values() ) - async def _check_prefix(self, ctx: tanjun.MessageContext, /) -> typing.Optional[str]: + async def _check_prefix( + self, alluka_ctx: alluka.abc.Context, ctx: tanjun.MessageContext, / + ) -> typing.Optional[str]: prefix: str # MyPy fubs up its introspection here so we explicitly annotate. if self._prefix_getter: - for prefix in await ctx.call_with_async_di(self._prefix_getter, ctx): + for prefix in await alluka_ctx.call_with_async_di(self._prefix_getter, ctx): if ctx.content.startswith(prefix): return prefix @@ -2807,7 +2809,13 @@ async def on_message_create_event(self, event: hikari.MessageCreateEvent, /) -> ctx = self._make_message_context( client=self, register_task=self._add_task, content=event.message.content, message=event.message ) - if (prefix := await self._check_prefix(ctx)) is None: + alluka_ctx = ( + alluka.OverridingContext.from_client(self._injector) + .set_type_dependency(tanjun.Context, ctx) + .set_type_dependency(tanjun.MessageContext, ctx) + .set_type_dependency(type(ctx), ctx) # Deprecated behaviour + ) + if (prefix := await self._check_prefix(alluka_ctx, ctx)) is None: return ctx.set_content(ctx.content.lstrip()[len(prefix) :].lstrip()).set_triggering_prefix(prefix) @@ -2822,9 +2830,10 @@ async def on_message_create_event(self, event: hikari.MessageCreateEvent, /) -> hooks = {self._message_hooks} try: - if await self.check(ctx): + if await self.check(ctx, alluka_ctx=alluka_ctx): for component in self._components.values(): - if await component.execute_message(ctx, hooks=hooks): + alluka_ctx.set_type_dependency(tanjun.Component, component) + if await component.execute_message(ctx, alluka_ctx=alluka_ctx, hooks=hooks): return except errors.HaltExecution: @@ -2881,8 +2890,14 @@ async def on_gateway_autocomplete_create(self, interaction: hikari.AutocompleteI The interaction to execute a command based on. """ ctx = self._make_autocomplete_context(self, interaction) + alluka_ctx = ( + alluka.OverridingContext.from_client(self._injector) + .set_type_dependency(tanjun.AutocompleteContext, ctx) + .set_type_dependency(type(ctx), ctx) # Deprecated behaviour + ) for component in self._components.values(): - if coro := component.execute_autocomplete(ctx): # pyright: ignore[reportUnnecessaryComparison] + coro = component.execute_autocomplete(ctx, alluka_ctx=alluka_ctx) + if coro: # pyright: ignore[reportUnnecessaryComparison] await coro return @@ -2894,8 +2909,11 @@ async def on_gateway_command_create(self, interaction: hikari.CommandInteraction interaction The interaction to execute a command based on. """ + alluka_ctx = alluka.OverridingContext.from_client(self._injector) + + ctx: typing.Union[context.MenuContext, context.SlashContext] if interaction.command_type is hikari.CommandType.SLASH: - ctx: typing.Union[context.MenuContext, context.SlashContext] = self._make_slash_context( + ctx = self._make_slash_context( client=self, interaction=interaction, register_task=self._add_task, @@ -2903,6 +2921,7 @@ async def on_gateway_command_create(self, interaction: hikari.CommandInteraction default_to_ephemeral=self._defaults_to_ephemeral, ) hooks: typing.Union[set[tanjun.MenuHooks], set[tanjun.SlashHooks], None] = self._get_slash_hooks() + alluka_ctx.set_type_dependency(tanjun.SlashContext, ctx) elif interaction.command_type in _MENU_TYPES: ctx = self._make_menu_context( @@ -2913,6 +2932,7 @@ async def on_gateway_command_create(self, interaction: hikari.CommandInteraction default_to_ephemeral=self._defaults_to_ephemeral, ) hooks = self._get_menu_hooks() + alluka_ctx.set_type_dependency(tanjun.MenuContext, ctx) else: raise RuntimeError(f"Unknown command type {interaction.command_type}") @@ -2920,12 +2940,19 @@ async def on_gateway_command_create(self, interaction: hikari.CommandInteraction if self._auto_defer_after is not None: ctx.start_defer_timer(self._auto_defer_after) + ( + alluka_ctx.set_type_dependency(tanjun.Context, ctx) + .set_type_dependency(tanjun.AppCommandContext, ctx) + .set_type_dependency(type(ctx), ctx) # Deprecated behaviour + ) + try: - if not await self.check(ctx): + if not await self.check(ctx, alluka_ctx=alluka_ctx): await _mark_not_found_event(ctx) return for component in self._components.values(): + alluka_ctx.set_type_dependency(tanjun.Component, component) # This is set on each iteration to ensure that any component # state which was set to this isn't propagated to other components. ctx.set_ephemeral_default(self._defaults_to_ephemeral) @@ -2996,8 +3023,15 @@ async def on_autocomplete_interaction_request( future: asyncio.Future[hikari.api.InteractionAutocompleteBuilder] = loop.create_future() ctx = self._make_autocomplete_context(self, interaction, future=future) + alluka_ctx = ( + alluka.OverridingContext.from_client(self._injector) + .set_type_dependency(tanjun.AutocompleteContext, ctx) + .set_type_dependency(type(ctx), ctx) # Deprecated behaviour + ) + for component in self._components.values(): - if coro := component.execute_autocomplete(ctx): # pyright: ignore[reportUnnecessaryComparison] + coro = component.execute_autocomplete(ctx, alluka_ctx=alluka_ctx) + if coro: # pyright: ignore[reportUnnecessaryComparison] task = loop.create_task(coro) task.add_done_callback(lambda _: future.cancel()) self._add_task(task) @@ -3024,9 +3058,11 @@ async def on_command_interaction_request( """ # noqa: E501 loop = asyncio.get_running_loop() future: asyncio.Future[_AppCmdResponse] = loop.create_future() + alluka_ctx = alluka.OverridingContext.from_client(self._injector) + ctx: typing.Union[context.MenuContext, context.SlashContext] if interaction.command_type is hikari.CommandType.SLASH: - ctx: typing.Union[context.MenuContext, context.SlashContext] = self._make_slash_context( + ctx = self._make_slash_context( client=self, interaction=interaction, register_task=self._add_task, @@ -3035,6 +3071,7 @@ async def on_command_interaction_request( future=future, ) hooks: typing.Union[set[tanjun.MenuHooks], set[tanjun.SlashHooks], None] = self._get_slash_hooks() + alluka_ctx.set_type_dependency(tanjun.SlashContext, ctx) elif interaction.command_type in _MENU_TYPES: ctx = self._make_menu_context( @@ -3046,6 +3083,7 @@ async def on_command_interaction_request( future=future, ) hooks = self._get_menu_hooks() + alluka_ctx.set_type_dependency(tanjun.MenuContext, ctx) else: raise RuntimeError(f"Unknown command type {interaction.command_type}") @@ -3053,9 +3091,15 @@ async def on_command_interaction_request( if self._auto_defer_after is not None: ctx.start_defer_timer(self._auto_defer_after) + ( + alluka_ctx.set_type_dependency(tanjun.Context, ctx) + .set_type_dependency(tanjun.AppCommandContext, ctx) + .set_type_dependency(type(ctx), ctx) # Deprecated behaviour + ) + task: asyncio.Task[typing.Any] # MyPy compat try: - if not await self.check(ctx): + if not await self.check(ctx, alluka_ctx=alluka_ctx): return await self._mark_not_found_request(ctx, loop, future) for component in self._components.values(): diff --git a/tanjun/commands/menu.py b/tanjun/commands/menu.py index 2173f9497..eca3ec1e1 100644 --- a/tanjun/commands/menu.py +++ b/tanjun/commands/menu.py @@ -48,6 +48,7 @@ if typing.TYPE_CHECKING: from collections import abc as collections + from alluka import abc as alluka from typing_extensions import Self _AnyCallbackSigT = typing.TypeVar( @@ -651,10 +652,12 @@ def set_ephemeral_default(self, state: typing.Optional[bool], /) -> Self: self._defaults_to_ephemeral = state return self - async def check_context(self, ctx: tanjun.MenuContext, /) -> bool: + async def check_context( + self, ctx: tanjun.MenuContext, /, *, alluka_ctx: typing.Optional[alluka.Context] = None + ) -> bool: # <>. ctx.set_command(self) - result = await _internal.gather_checks(ctx, self._checks) + result = await _internal.gather_checks(alluka_ctx, ctx, self._checks) ctx.set_command(None) return result @@ -665,16 +668,22 @@ def copy(self, *, parent: typing.Optional[tanjun.SlashCommandGroup] = None) -> S return inst async def execute( - self, ctx: tanjun.MenuContext, /, *, hooks: typing.Optional[collections.MutableSet[tanjun.MenuHooks]] = None + self, + ctx: tanjun.MenuContext, + /, + *, + alluka_ctx: typing.Optional[alluka.Context] = None, + hooks: typing.Optional[collections.MutableSet[tanjun.MenuHooks]] = None, ) -> None: # <>. if self._always_defer and not ctx.has_been_deferred and not ctx.has_responded: await ctx.defer() ctx = ctx.set_command(self) + alluka_ctx = alluka_ctx or ctx.client.injector.make_context() own_hooks = self._hooks or _EMPTY_HOOKS try: - await own_hooks.trigger_pre_execution(ctx, hooks=hooks) + await own_hooks.trigger_pre_execution(ctx, alluka_ctx=alluka_ctx, hooks=hooks) if self._type is hikari.CommandType.USER: value: typing.Union[hikari.Message, hikari.User] = ctx.resolve_to_user() @@ -682,7 +691,7 @@ async def execute( else: value = ctx.resolve_to_message() - await ctx.call_with_async_di(self._callback, ctx, value) + await alluka_ctx.call_with_async_di(self._callback, ctx, value) except errors.CommandError as exc: await exc.send(ctx) @@ -693,13 +702,13 @@ async def execute( await ctx.mark_not_found() except Exception as exc: - if await own_hooks.trigger_error(ctx, exc, hooks=hooks) <= 0: + if await own_hooks.trigger_error(ctx, exc, alluka_ctx=alluka_ctx, hooks=hooks) <= 0: raise else: - await own_hooks.trigger_success(ctx, hooks=hooks) + await own_hooks.trigger_success(ctx, alluka_ctx=alluka_ctx, hooks=hooks) - await own_hooks.trigger_post_execution(ctx, hooks=hooks) + await own_hooks.trigger_post_execution(ctx, alluka_ctx=alluka_ctx, hooks=hooks) def load_into_component(self, component: tanjun.Component, /) -> None: # <>. diff --git a/tanjun/commands/message.py b/tanjun/commands/message.py index 328b7a720..a981be791 100644 --- a/tanjun/commands/message.py +++ b/tanjun/commands/message.py @@ -46,6 +46,7 @@ if typing.TYPE_CHECKING: from collections import abc as collections + import alluka from typing_extensions import Self _AnyMessageCommandT = typing.TypeVar("_AnyMessageCommandT", bound=tanjun.MessageCommand[typing.Any]) @@ -317,10 +318,12 @@ def set_parser(self, parser: typing.Optional[tanjun.MessageParser], /) -> Self: self._parser = parser return self - async def check_context(self, ctx: tanjun.MessageContext, /) -> bool: + async def check_context( + self, ctx: tanjun.MessageContext, /, *, alluka_ctx: typing.Optional[alluka.abc.Context] = None + ) -> bool: # <>. ctx.set_command(self) - result = await _internal.gather_checks(ctx, self._checks) + result = await _internal.gather_checks(alluka_ctx, ctx, self._checks) ctx.set_command(None) return result @@ -329,13 +332,15 @@ async def execute( ctx: tanjun.MessageContext, /, *, + alluka_ctx: typing.Optional[alluka.abc.Context] = None, hooks: typing.Optional[collections.MutableSet[tanjun.MessageHooks]] = None, ) -> None: # <>. + alluka_ctx = alluka_ctx or ctx.client.injector.make_context() ctx = ctx.set_command(self) own_hooks = self._hooks or _EMPTY_HOOKS try: - await own_hooks.trigger_pre_execution(ctx, hooks=hooks) + await own_hooks.trigger_pre_execution(ctx, alluka_ctx=alluka_ctx, hooks=hooks) if self._parser is not None: kwargs = await self._parser.parse(ctx) @@ -343,7 +348,7 @@ async def execute( else: kwargs = _EMPTY_DICT - await ctx.call_with_async_di(self._callback, ctx, **kwargs) + await alluka_ctx.call_with_async_di(self._callback, ctx, **kwargs) except errors.CommandError as exc: await exc.send(ctx) @@ -352,14 +357,14 @@ async def execute( raise except Exception as exc: - if await own_hooks.trigger_error(ctx, exc, hooks=hooks) <= 0: + if await own_hooks.trigger_error(ctx, exc, alluka_ctx=alluka_ctx, hooks=hooks) <= 0: raise else: # TODO: how should this be handled around CommandError? - await own_hooks.trigger_success(ctx, hooks=hooks) + await own_hooks.trigger_success(ctx, alluka_ctx=alluka_ctx, hooks=hooks) - await own_hooks.trigger_post_execution(ctx, hooks=hooks) + await own_hooks.trigger_post_execution(ctx, alluka_ctx=alluka_ctx, hooks=hooks) def load_into_component(self, component: tanjun.Component, /) -> None: # <>. @@ -583,6 +588,7 @@ async def execute( ctx: tanjun.MessageContext, /, *, + alluka_ctx: typing.Optional[alluka.abc.Context] = None, hooks: typing.Optional[collections.MutableSet[tanjun.MessageHooks]] = None, ) -> None: # <>. @@ -600,11 +606,11 @@ async def execute( case_sensitive = ctx.component.is_case_sensitive for name, command in self._commands.find(ctx.content, case_sensitive): - if await command.check_context(ctx): + if await command.check_context(ctx, alluka_ctx=alluka_ctx): content = ctx.content[len(name) :] ctx.set_triggering_name(ctx.triggering_name + " " + name) ctx.set_content(content.lstrip()) - await command.execute(ctx, hooks=hooks) + await command.execute(ctx, alluka_ctx=alluka_ctx, hooks=hooks) return - await super().execute(ctx, hooks=hooks) + await super().execute(ctx, alluka_ctx=alluka_ctx, hooks=hooks) diff --git a/tanjun/commands/slash.py b/tanjun/commands/slash.py index 1f3b3c3ad..84d219ba3 100644 --- a/tanjun/commands/slash.py +++ b/tanjun/commands/slash.py @@ -56,6 +56,7 @@ import warnings from collections import abc as collections +import alluka import hikari import typing_extensions @@ -815,14 +816,14 @@ def check_client(self, client: tanjun.Client, /) -> None: if isinstance(converter, conversion.BaseConverter): converter.check_client(client, f"{self.name} slash command option") - async def convert(self, ctx: tanjun.SlashContext, value: typing.Any, /) -> typing.Any: + async def convert(self, alluka_ctx: alluka.abc.Context, value: typing.Any, /) -> typing.Any: if not self.converters: return value exceptions: list[ValueError] = [] for converter in self.converters: try: - return await ctx.call_with_async_di(converter, value) + return await alluka_ctx.call_with_async_di(converter, value) except ValueError as exc: exceptions.append(exc) @@ -1045,10 +1046,12 @@ def set_parent(self, parent: typing.Optional[tanjun.SlashCommandGroup], /) -> Se self._parent = parent return self - async def check_context(self, ctx: tanjun.SlashContext, /) -> bool: + async def check_context( + self, ctx: tanjun.SlashContext, /, *, alluka_ctx: typing.Optional[alluka.abc.Context] = None + ) -> bool: # <>. ctx.set_command(self) - result = await _internal.gather_checks(ctx, self._checks) + result = await _internal.gather_checks(alluka_ctx, ctx, self._checks) ctx.set_command(None) return result @@ -1417,8 +1420,9 @@ async def execute( ctx: tanjun.SlashContext, /, *, - option: typing.Optional[hikari.CommandInteractionOption] = None, + alluka_ctx: typing.Optional[alluka.abc.Context] = None, hooks: typing.Optional[collections.MutableSet[tanjun.SlashHooks]] = None, + option: typing.Optional[hikari.CommandInteractionOption] = None, ) -> None: # <>. if not option and ctx.interaction.options: @@ -1434,8 +1438,8 @@ async def execute( if command.defaults_to_ephemeral is not None: ctx.set_ephemeral_default(command.defaults_to_ephemeral) - if await command.check_context(ctx): - await command.execute(ctx, option=option, hooks=hooks) + if await command.check_context(ctx, alluka_ctx=alluka_ctx): + await command.execute(ctx, alluka_ctx=alluka_ctx, option=option, hooks=hooks) return await ctx.mark_not_found() @@ -1445,6 +1449,7 @@ async def execute_autocomplete( ctx: tanjun.AutocompleteContext, /, *, + alluka_ctx: typing.Optional[alluka.abc.Context] = None, option: typing.Optional[hikari.AutocompleteInteractionOption] = None, ) -> None: if not option and ctx.interaction.options: @@ -1460,7 +1465,7 @@ async def execute_autocomplete( if not command: raise RuntimeError(f"Sub-command '{option.name}' no found") - await command.execute_autocomplete(ctx, option=option) + await command.execute_autocomplete(ctx, alluka_ctx=alluka_ctx, option=option) def _assert_in_range(name: str, value: typing.Optional[int], min_value: int, max_value: int, /) -> None: @@ -3095,7 +3100,9 @@ def decorator(callback: _StrAutocompleteSigT, /) -> _StrAutocompleteSigT: return decorator - async def _process_args(self, ctx: tanjun.SlashContext, /) -> collections.Mapping[str, typing.Any]: + async def _process_args( + self, alluka_ctx: alluka.abc.Context, ctx: tanjun.SlashContext, / + ) -> collections.Mapping[str, typing.Any]: keyword_args: dict[ str, typing.Union[int, float, str, hikari.Attachment, hikari.User, hikari.Role, hikari.InteractionChannel] ] = {} @@ -3139,7 +3146,7 @@ async def _process_args(self, ctx: tanjun.SlashContext, /) -> collections.Mappin value = float(value) if tracked_option.converters: - value = await tracked_option.convert(ctx, option.value) + value = await tracked_option.convert(alluka_ctx, option.value) keyword_args[tracked_option.key] = value @@ -3150,25 +3157,27 @@ async def execute( ctx: tanjun.SlashContext, /, *, - option: typing.Optional[hikari.CommandInteractionOption] = None, + alluka_ctx: typing.Optional[alluka.abc.Context] = None, hooks: typing.Optional[collections.MutableSet[tanjun.SlashHooks]] = None, + option: typing.Optional[hikari.CommandInteractionOption] = None, ) -> None: # <>. if self._always_defer and not ctx.has_been_deferred and not ctx.has_responded: await ctx.defer() + alluka_ctx = alluka.OverridingContext(alluka_ctx or ctx.client.injector.make_context()) ctx = ctx.set_command(self) own_hooks = self._hooks or _EMPTY_HOOKS try: - await own_hooks.trigger_pre_execution(ctx, hooks=hooks) + await own_hooks.trigger_pre_execution(ctx, alluka_ctx=alluka_ctx, hooks=hooks) if self._tracked_options: - kwargs = await self._process_args(ctx) + kwargs = await self._process_args(alluka_ctx, ctx) else: kwargs = _EMPTY_DICT - await ctx.call_with_async_di(self._callback, ctx, **kwargs) + await alluka_ctx.call_with_async_di(self._callback, ctx, **kwargs) except errors.CommandError as exc: await exc.send(ctx) @@ -3179,19 +3188,20 @@ async def execute( await ctx.mark_not_found() except Exception as exc: - if await own_hooks.trigger_error(ctx, exc, hooks=hooks) <= 0: + if await own_hooks.trigger_error(ctx, exc, alluka_ctx=alluka_ctx, hooks=hooks) <= 0: raise else: - await own_hooks.trigger_success(ctx, hooks=hooks) + await own_hooks.trigger_success(ctx, alluka_ctx=alluka_ctx, hooks=hooks) - await own_hooks.trigger_post_execution(ctx, hooks=hooks) + await own_hooks.trigger_post_execution(ctx, alluka_ctx=alluka_ctx, hooks=hooks) async def execute_autocomplete( self, ctx: tanjun.AutocompleteContext, /, *, + alluka_ctx: typing.Optional[alluka.abc.Context] = None, option: typing.Optional[hikari.AutocompleteInteractionOption] = None, ) -> None: # <>. @@ -3210,7 +3220,8 @@ async def execute_autocomplete( if not callback: raise RuntimeError(f"No autocomplete callback found for '{ctx.focused.name}' option") - await ctx.call_with_async_di(callback, ctx, ctx.focused.value) + alluka_ctx = alluka_ctx or ctx.client.injector.make_context() + await alluka_ctx.call_with_async_di(callback, ctx, ctx.focused.value) def copy(self, *, parent: typing.Optional[tanjun.SlashCommandGroup] = None) -> Self: # <>. diff --git a/tanjun/components.py b/tanjun/components.py index e79545778..a6123b960 100644 --- a/tanjun/components.py +++ b/tanjun/components.py @@ -49,6 +49,7 @@ from . import abc as tanjun if typing.TYPE_CHECKING: + from alluka import abc as alluka from typing_extensions import Self from . import schedules as schedules_ @@ -1160,11 +1161,11 @@ def unbind_client(self, client: tanjun.Client, /) -> Self: return self - async def _check_context(self, ctx: tanjun.Context, /) -> bool: - return await _internal.gather_checks(ctx, self._checks) + async def _check_context(self, alluka_ctx: typing.Optional[alluka.Context], ctx: tanjun.Context, /) -> bool: + return await _internal.gather_checks(alluka_ctx, ctx, self._checks) async def _check_message_context( # noqa: ASYNC900 # Async generator without `@asynccontextmanager` not allowed. - self, ctx: tanjun.MessageContext, / + self, alluka_ctx: typing.Optional[alluka.Context], ctx: tanjun.MessageContext, / ) -> collections.AsyncIterator[tuple[str, tanjun.MessageCommand[typing.Any]]]: ctx.set_component(self) checks_run = False @@ -1174,12 +1175,12 @@ async def _check_message_context( # noqa: ASYNC900 # Async generator without ` for name, command in self.check_message_name(ctx.content, case_sensitive=case_sensitive): if not checks_run: - if not await self._check_context(ctx): + if not await self._check_context(alluka_ctx, ctx): return checks_run = True - if await command.check_context(ctx): + if await command.check_context(ctx, alluka_ctx=alluka_ctx): yield name, command ctx.set_component(None) @@ -1196,24 +1197,29 @@ def check_slash_name(self, name: str, /) -> collections.Iterator[tanjun.BaseSlas yield command def execute_autocomplete( - self, ctx: tanjun.AutocompleteContext, / + self, ctx: tanjun.AutocompleteContext, /, *, alluka_ctx: typing.Optional[alluka.Context] = None ) -> typing.Optional[collections.Coroutine[typing.Any, typing.Any, None]]: # <>. if command := self._slash_commands.get(ctx.interaction.command_name): - return command.execute_autocomplete(ctx) + return command.execute_autocomplete(ctx, alluka_ctx=alluka_ctx) return None # MyPy compat async def _execute_app( self, ctx: _AppCommandContextT, + alluka_ctx: typing.Optional[alluka.Context], command: typing.Optional[tanjun.AppCommand[_AppCommandContextT]], /, *, hooks: typing.Optional[collections.MutableSet[tanjun.Hooks[_AppCommandContextT]]] = None, other_hooks: typing.Optional[tanjun.Hooks[_AppCommandContextT]] = None, ) -> typing.Optional[collections.Coroutine[typing.Any, typing.Any, None]]: - if not command or not await self._check_context(ctx) or not await command.check_context(ctx): + if ( + not command + or not await self._check_context(alluka_ctx, ctx) + or not await command.check_context(ctx, alluka_ctx=alluka_ctx) + ): return None if self._hooks: @@ -1228,13 +1234,18 @@ async def _execute_app( hooks.add(other_hooks) - return command.execute(ctx, hooks=hooks) + return command.execute(ctx, alluka_ctx=alluka_ctx, hooks=hooks) # To ensure that ctx.set_ephemeral_default is called as soon as possible if # a match is found the public function is kept sync to avoid yielding # to the event loop until after this is set. def execute_menu( - self, ctx: tanjun.MenuContext, /, *, hooks: typing.Optional[collections.MutableSet[tanjun.MenuHooks]] = None + self, + ctx: tanjun.MenuContext, + /, + *, + alluka_ctx: typing.Optional[alluka.Context] = None, + hooks: typing.Optional[collections.MutableSet[tanjun.MenuHooks]] = None, ) -> collections.Coroutine[ typing.Any, typing.Any, typing.Optional[collections.Coroutine[typing.Any, typing.Any, None]] ]: @@ -1247,13 +1258,18 @@ def execute_menu( elif self._defaults_to_ephemeral is not None: ctx.set_ephemeral_default(self._defaults_to_ephemeral) - return self._execute_app(ctx, command, hooks=hooks, other_hooks=self._menu_hooks) + return self._execute_app(ctx, alluka_ctx, command, hooks=hooks, other_hooks=self._menu_hooks) # To ensure that ctx.set_ephemeral_default is called as soon as possible if # a match is found the public function is kept sync to avoid yielding # to the event loop until after this is set. def execute_slash( - self, ctx: tanjun.SlashContext, /, *, hooks: typing.Optional[collections.MutableSet[tanjun.SlashHooks]] = None + self, + ctx: tanjun.SlashContext, + /, + *, + alluka_ctx: typing.Optional[alluka.Context] = None, + hooks: typing.Optional[collections.MutableSet[tanjun.SlashHooks]] = None, ) -> collections.Coroutine[ typing.Any, typing.Any, typing.Optional[collections.Coroutine[typing.Any, typing.Any, None]] ]: @@ -1266,17 +1282,18 @@ def execute_slash( elif self._defaults_to_ephemeral is not None: ctx.set_ephemeral_default(self._defaults_to_ephemeral) - return self._execute_app(ctx, command, hooks=hooks, other_hooks=self._slash_hooks) + return self._execute_app(ctx, alluka_ctx, command, hooks=hooks, other_hooks=self._slash_hooks) async def execute_message( self, ctx: tanjun.MessageContext, /, *, + alluka_ctx: typing.Optional[alluka.Context] = None, hooks: typing.Optional[collections.MutableSet[tanjun.MessageHooks]] = None, ) -> bool: # <>. - async for name, command in self._check_message_context(ctx): + async for name, command in self._check_message_context(alluka_ctx, ctx): ctx.set_triggering_name(name) ctx.set_content(ctx.content[len(name) :].lstrip()) ctx.set_component(self) @@ -1294,7 +1311,7 @@ async def execute_message( hooks.add(self._hooks) - await command.execute(ctx, hooks=hooks) + await command.execute(ctx, alluka_ctx=alluka_ctx, hooks=hooks) return True ctx.set_component(None) diff --git a/tanjun/context/autocomplete.py b/tanjun/context/autocomplete.py index b5d8b13cc..1b3cfef70 100644 --- a/tanjun/context/autocomplete.py +++ b/tanjun/context/autocomplete.py @@ -36,8 +36,8 @@ import typing -import alluka import hikari +import typing_extensions from hikari import snowflakes from .. import _internal @@ -48,13 +48,22 @@ import datetime from collections import abc as collections + from alluka import abc as alluka + _ValueT = typing.TypeVar("_ValueT", int, float, str) + _T = typing.TypeVar("_T") + _DefaultT = typing.TypeVar("_DefaultT") + +class AutocompleteContext(tanjun.AutocompleteContext): + """Standard implementation of an autocomplete context. -class AutocompleteContext(alluka.BasicContext, tanjun.AutocompleteContext): - """Standard implementation of an autocomplete context.""" + !!! warning "deprecated" + Using Tanjun contexts as an Alluka context is + deprecated behaviour and may not behave as expected. + """ - __slots__ = ("_tanjun_client", "_command_name", "_focused", "_future", "_has_responded", "_interaction", "_options") + __slots__ = ("_client", "_command_name", "_focused", "_future", "_has_responded", "_interaction", "_options") def __init__( self, @@ -75,8 +84,7 @@ def __init__( A future used to set the initial response if this is being called through the REST webhook flow. """ - super().__init__(client.injector) - self._tanjun_client = client + self._client = client self._future = future self._has_responded = False self._interaction = interaction @@ -92,7 +100,6 @@ def __init__( assert focused is not None self._command_name = command_name self._focused = focused - self._set_type_special_case(AutocompleteContext, self)._set_type_special_case(tanjun.AutocompleteContext, self) @property def author(self) -> hikari.User: @@ -107,12 +114,12 @@ def channel_id(self) -> hikari.Snowflake: @property def cache(self) -> typing.Optional[hikari.api.Cache]: # <>. - return self._tanjun_client.cache + return self._client.cache @property def client(self) -> tanjun.Client: # <>. - return self._tanjun_client + return self._client @property def triggering_name(self) -> str: @@ -127,7 +134,7 @@ def created_at(self) -> datetime.datetime: @property def events(self) -> typing.Optional[hikari.api.EventManager]: # <>. - return self._tanjun_client.events + return self._client.events @property def focused(self) -> hikari.AutocompleteInteractionOption: @@ -147,36 +154,36 @@ def member(self) -> typing.Optional[hikari.Member]: @property def server(self) -> typing.Optional[hikari.api.InteractionServer]: # <>. - return self._tanjun_client.server + return self._client.server @property def rest(self) -> hikari.api.RESTClient: # <>. - return self._tanjun_client.rest + return self._client.rest @property def shard(self) -> typing.Optional[hikari.api.GatewayShard]: # <>. - if not self._tanjun_client.shards: + if not self._client.shards: return None if self.guild_id is not None: - shard_id = snowflakes.calculate_shard_id(self._tanjun_client.shards, self.guild_id) + shard_id = snowflakes.calculate_shard_id(self._client.shards, self.guild_id) else: shard_id = 0 - return self._tanjun_client.shards.shards[shard_id] + return self._client.shards.shards[shard_id] @property def shards(self) -> typing.Optional[hikari.ShardAware]: # <>. - return self._tanjun_client.shards + return self._client.shards @property def voice(self) -> typing.Optional[hikari.api.VoiceComponent]: # <>. - return self._tanjun_client.voice + return self._client.voice @property def has_responded(self) -> bool: @@ -233,3 +240,77 @@ async def set_choices( else: await self._interaction.create_response(choice_objects) + + @property + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def injection_client(self) -> alluka.Client: + return self._client.injector + + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def cache_result(self, callback: alluka.CallbackSig[_T], value: _T, /) -> None: + return None + + @typing.overload + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def call_with_di( + self, + callback: collections.Callable[..., collections.Coroutine[typing.Any, typing.Any, typing.Any]], + *args: typing.Any, + **kwargs: typing.Any, + ) -> typing.NoReturn: ... + + @typing.overload + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def call_with_di(self, callback: collections.Callable[..., _T], *args: typing.Any, **kwargs: typing.Any) -> _T: ... + + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def call_with_di(self, callback: collections.Callable[..., _T], *args: typing.Any, **kwargs: typing.Any) -> _T: + return self._client.injector.call_with_di(callback, *args, **kwargs) + + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + async def call_with_async_di(self, callback: alluka.CallbackSig[_T], *args: typing.Any, **kwargs: typing.Any) -> _T: + return await self._client.injector.call_with_async_di(callback, *args, **kwargs) + + @typing.overload + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_cached_result(self, callback: alluka.CallbackSig[_T], /) -> _T: ... + + @typing.overload + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_cached_result( + self, callback: alluka.CallbackSig[_T], /, *, default: _DefaultT + ) -> typing.Union[_T, _DefaultT]: ... + + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_cached_result( + self, + callback: alluka.CallbackSig[_T], + /, + *, + default: typing.Union[_DefaultT, tanjun.NoDefault] = tanjun.NO_DEFAULT, + ) -> typing.Union[_T, _DefaultT]: + if default is tanjun.NO_DEFAULT: + raise KeyError + + return default + + @typing.overload + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_type_dependency(self, type_: type[_T], /) -> _T: ... + + @typing.overload + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_type_dependency(self, type_: type[_T], /, *, default: _DefaultT) -> typing.Union[_T, _DefaultT]: ... + + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_type_dependency( + self, type_: type[_T], /, *, default: typing.Union[_DefaultT, tanjun.NoDefault] = tanjun.NO_DEFAULT + ) -> typing.Union[_T, _DefaultT]: + result: typing.Union[_DefaultT, tanjun.NoDefault, _T] = self._client.injector.get_type_dependency( + type_, default=default + ) + + if result is tanjun.NO_DEFAULT: + raise KeyError + + return result diff --git a/tanjun/context/base.py b/tanjun/context/base.py index a4d96dfa7..75a233810 100644 --- a/tanjun/context/base.py +++ b/tanjun/context/base.py @@ -35,37 +35,46 @@ import typing -import alluka import hikari +import typing_extensions from hikari import snowflakes from .. import abc as tanjun if typing.TYPE_CHECKING: + from collections import abc as collections + + from alluka import abc as alluka from typing_extensions import Self + _T = typing.TypeVar("_T") + _DefaultT = typing.TypeVar("_DefaultT") + -class BaseContext(alluka.BasicContext, tanjun.Context): - """Base class for the standard command context implementations.""" +class BaseContext(tanjun.Context): + """Base class for the standard command context implementations. - __slots__ = ("_tanjun_client", "_component", "_final") + !!! warning "deprecated" + Using Tanjun contexts as an Alluka context is + deprecated behaviour and may not behave as expected. + """ + + __slots__ = ("_client", "_component", "_final") def __init__(self, client: tanjun.Client, /) -> None: - super().__init__(client.injector) - self._tanjun_client = client + self._client = client self._component: typing.Optional[tanjun.Component] = None self._final = False - self._set_type_special_case(tanjun.Context, self) @property def cache(self) -> typing.Optional[hikari.api.Cache]: # <>. - return self._tanjun_client.cache + return self._client.cache @property def client(self) -> tanjun.Client: # <>. - return self._tanjun_client + return self._client @property def component(self) -> typing.Optional[tanjun.Component]: @@ -75,41 +84,41 @@ def component(self) -> typing.Optional[tanjun.Component]: @property def events(self) -> typing.Optional[hikari.api.EventManager]: # <>. - return self._tanjun_client.events + return self._client.events @property def server(self) -> typing.Optional[hikari.api.InteractionServer]: # <>. - return self._tanjun_client.server + return self._client.server @property def rest(self) -> hikari.api.RESTClient: # <>. - return self._tanjun_client.rest + return self._client.rest @property def shard(self) -> typing.Optional[hikari.api.GatewayShard]: # <>. - if not self._tanjun_client.shards: + if not self._client.shards: return None if self.guild_id is not None: - shard_id = snowflakes.calculate_shard_id(self._tanjun_client.shards, self.guild_id) + shard_id = snowflakes.calculate_shard_id(self._client.shards, self.guild_id) else: shard_id = 0 - return self._tanjun_client.shards.shards[shard_id] + return self._client.shards.shards[shard_id] @property def shards(self) -> typing.Optional[hikari.ShardAware]: # <>. - return self._tanjun_client.shards + return self._client.shards @property def voice(self) -> typing.Optional[hikari.api.VoiceComponent]: # <>. - return self._tanjun_client.voice + return self._client.voice def _assert_not_final(self) -> None: if self._final: @@ -129,19 +138,13 @@ def finalise(self) -> Self: def set_component(self, component: typing.Optional[tanjun.Component], /) -> Self: # <>. self._assert_not_final() - if component: - self._set_type_special_case(tanjun.Component, component) - - elif self._component: - self._remove_type_special_case(tanjun.Component) - self._component = component return self def get_channel(self) -> typing.Optional[hikari.TextableGuildChannel]: # <>. - if self._tanjun_client.cache: - channel = self._tanjun_client.cache.get_guild_channel(self.channel_id) + if self._client.cache: + channel = self._client.cache.get_guild_channel(self.channel_id) assert channel is None or isinstance(channel, hikari.TextableGuildChannel) return channel @@ -149,20 +152,94 @@ def get_channel(self) -> typing.Optional[hikari.TextableGuildChannel]: def get_guild(self) -> typing.Optional[hikari.Guild]: # <>. - if self.guild_id is not None and self._tanjun_client.cache: - return self._tanjun_client.cache.get_guild(self.guild_id) + if self.guild_id is not None and self._client.cache: + return self._client.cache.get_guild(self.guild_id) return None # MyPy compat async def fetch_channel(self) -> hikari.TextableChannel: # <>. - channel = await self._tanjun_client.rest.fetch_channel(self.channel_id) + channel = await self._client.rest.fetch_channel(self.channel_id) assert isinstance(channel, hikari.TextableChannel) return channel async def fetch_guild(self) -> typing.Optional[hikari.Guild]: # TODO: or raise? # <>. if self.guild_id is not None: - return await self._tanjun_client.rest.fetch_guild(self.guild_id) + return await self._client.rest.fetch_guild(self.guild_id) return None # MyPy compat + + @property + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def injection_client(self) -> alluka.Client: + return self._client.injector + + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def cache_result(self, callback: alluka.CallbackSig[_T], value: _T, /) -> None: + return None + + @typing.overload + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def call_with_di( + self, + callback: collections.Callable[..., collections.Coroutine[typing.Any, typing.Any, typing.Any]], + *args: typing.Any, + **kwargs: typing.Any, + ) -> typing.NoReturn: ... + + @typing.overload + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def call_with_di(self, callback: collections.Callable[..., _T], *args: typing.Any, **kwargs: typing.Any) -> _T: ... + + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def call_with_di(self, callback: collections.Callable[..., _T], *args: typing.Any, **kwargs: typing.Any) -> _T: + return self._client.injector.call_with_di(callback, *args, **kwargs) + + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + async def call_with_async_di(self, callback: alluka.CallbackSig[_T], *args: typing.Any, **kwargs: typing.Any) -> _T: + return await self._client.injector.call_with_async_di(callback, *args, **kwargs) + + @typing.overload + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_cached_result(self, callback: alluka.CallbackSig[_T], /) -> _T: ... + + @typing.overload + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_cached_result( + self, callback: alluka.CallbackSig[_T], /, *, default: _DefaultT + ) -> typing.Union[_T, _DefaultT]: ... + + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_cached_result( + self, + callback: alluka.CallbackSig[_T], + /, + *, + default: typing.Union[tanjun.NoDefault, _DefaultT] = tanjun.NO_DEFAULT, + ) -> typing.Union[_T, _DefaultT]: + if default is tanjun.NO_DEFAULT: + raise KeyError + + return default + + @typing.overload + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_type_dependency(self, type_: type[_T], /) -> _T: ... + + @typing.overload + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_type_dependency(self, type_: type[_T], /, *, default: _DefaultT) -> typing.Union[_T, _DefaultT]: ... + + @typing_extensions.deprecated("Using a Tanjun context as an Alluka context is deprecated") + def get_type_dependency( + self, type_: type[_T], /, *, default: typing.Union[tanjun.NoDefault, _DefaultT] = tanjun.NO_DEFAULT + ) -> typing.Union[_T, _DefaultT]: + result: typing.Union[_T, _DefaultT, tanjun.NoDefault] = self._client.injector.get_type_dependency( + type_, default=default + ) + + if result is tanjun.NO_DEFAULT: + raise KeyError + + return result diff --git a/tanjun/context/menu.py b/tanjun/context/menu.py index 6e94cb650..3996e2659 100644 --- a/tanjun/context/menu.py +++ b/tanjun/context/menu.py @@ -59,7 +59,12 @@ class MenuContext(slash.AppCommandContext, tanjun.MenuContext): - """Standard menu command execution context.""" + """Standard menu command execution context. + + !!! warning "deprecated" + Using Tanjun contexts as an Alluka context is + deprecated behaviour and may not behave as expected. + """ __slots__ = ("_command", "_marked_not_found", "_on_not_found") @@ -95,7 +100,6 @@ def __init__( self._command: typing.Optional[tanjun.MenuCommand[typing.Any, typing.Any]] = None self._marked_not_found = False self._on_not_found = on_not_found - self._set_type_special_case(tanjun.MenuContext, self)._set_type_special_case(MenuContext, self) @property def command(self) -> typing.Optional[tanjun.MenuCommand[typing.Any, typing.Any]]: @@ -149,12 +153,6 @@ async def mark_not_found(self) -> None: def set_command(self, command: typing.Optional[tanjun.MenuCommand[typing.Any, typing.Any]], /) -> Self: # <>. - if command: - self._set_type_special_case(tanjun.MenuCommand, command) - - elif self._command: - self._remove_type_special_case(tanjun.MenuContext) - self._command = command return self diff --git a/tanjun/context/message.py b/tanjun/context/message.py index ccd9e5918..378862312 100644 --- a/tanjun/context/message.py +++ b/tanjun/context/message.py @@ -57,7 +57,12 @@ def _delete_after_to_float(delete_after: typing.Union[datetime.timedelta, float, class MessageContext(base.BaseContext, tanjun.MessageContext): - """Standard implementation of a command context as used within Tanjun.""" + """Standard implementation of a command context as used within Tanjun. + + !!! warning "deprecated" + Using Tanjun contexts as an Alluka context is + deprecated behaviour and may not behave as expected. + """ __slots__ = ( "_command", @@ -111,7 +116,6 @@ def __init__( self._message = message self._triggering_name = triggering_name self._triggering_prefix = triggering_prefix - self._set_type_special_case(tanjun.MessageContext, self)._set_type_special_case(MessageContext, self) def __repr__(self) -> str: return f"MessageContext <{self._message!r}, {self._command!r}>" @@ -179,15 +183,6 @@ def triggering_prefix(self) -> str: def set_command(self, command: typing.Optional[tanjun.MessageCommand[typing.Any]], /) -> Self: # <>. self._assert_not_final() - if command: - # TODO: command group? - self._set_type_special_case(tanjun.ExecutableCommand, command)._set_type_special_case( - tanjun.MessageCommand, command - ) - - elif self._command: - self._remove_type_special_case(tanjun.ExecutableCommand)._remove_type_special_case(tanjun.MessageCommand) - self._command = command return self @@ -225,14 +220,14 @@ async def delete_initial_response(self) -> None: if self._initial_response_id is None: raise LookupError("Context has no initial response") - await self._tanjun_client.rest.delete_message(self._message.channel_id, self._initial_response_id) + await self._client.rest.delete_message(self._message.channel_id, self._initial_response_id) async def delete_last_response(self) -> None: # <>. if self._last_response_id is None: raise LookupError("Context has no previous responses") - await self._tanjun_client.rest.delete_message(self._message.channel_id, self._last_response_id) + await self._client.rest.delete_message(self._message.channel_id, self._last_response_id) async def edit_initial_response( self, diff --git a/tanjun/context/slash.py b/tanjun/context/slash.py index 9335162d7..032baf0d7 100644 --- a/tanjun/context/slash.py +++ b/tanjun/context/slash.py @@ -285,7 +285,12 @@ def resolve_to_user(self) -> typing.Union[hikari.User, hikari.Member]: class AppCommandContext(base.BaseContext, tanjun.AppCommandContext): - """Base class for interaction-based command contexts.""" + """Base class for interaction-based command contexts. + + !!! warning "deprecated" + Using Tanjun contexts as an Alluka context is + deprecated behaviour and may not behave as expected. + """ __slots__ = ( "_defaults_to_ephemeral", @@ -318,7 +323,6 @@ def __init__( self._register_task = register_task self._response_future = future self._response_lock = asyncio.Lock() - self._set_type_special_case(tanjun.AppCommandContext, self) @property def author(self) -> hikari.User: @@ -333,7 +337,7 @@ def channel_id(self) -> hikari.Snowflake: @property def client(self) -> tanjun.Client: # <>. - return self._tanjun_client + return self._client @property def created_at(self) -> datetime.datetime: @@ -1039,7 +1043,6 @@ def __init__( command_name, options = _internal.flatten_options(interaction.command_name, interaction.options) self._command_name = command_name self._options = {option.name: SlashOption(interaction.resolved, option) for option in options} - (self._set_type_special_case(tanjun.SlashContext, self)._set_type_special_case(SlashContext, self)) @property def command(self) -> typing.Optional[tanjun.BaseSlashCommand]: @@ -1071,22 +1074,5 @@ async def mark_not_found(self) -> None: def set_command(self, command: typing.Optional[tanjun.BaseSlashCommand], /) -> Self: # <>. self._assert_not_final() - if command: - # TODO: command group? - ( - self._set_type_special_case(tanjun.ExecutableCommand, command) - ._set_type_special_case(tanjun.AppCommand, command) - ._set_type_special_case(tanjun.BaseSlashCommand, command) - ._set_type_special_case(tanjun.SlashCommand, command) - ) - - elif self._command: - ( - self._remove_type_special_case(tanjun.ExecutableCommand) - ._remove_type_special_case(tanjun.AppCommand) - ._remove_type_special_case(tanjun.BaseSlashCommand) - ._remove_type_special_case(tanjun.SlashCommand) - ) - self._command = command return self diff --git a/tanjun/dependencies/limiters.py b/tanjun/dependencies/limiters.py index fe7f013ab..e6abe66f3 100644 --- a/tanjun/dependencies/limiters.py +++ b/tanjun/dependencies/limiters.py @@ -447,13 +447,17 @@ async def _get_ctx_target(ctx: tanjun.Context, type_: BucketResource, /) -> hika if cached_channel := ctx.get_channel(): return cached_channel.parent_id or ctx.guild_id - channel_cache = ctx.get_type_dependency(async_cache.SfCache[hikari.PermissibleGuildChannel], default=None) + channel_cache = ctx.client.injector.get_type_dependency( + async_cache.SfCache[hikari.PermissibleGuildChannel], default=None + ) if channel_cache: # noqa: SIM102 # Has to be nested cause of pyright bug: if channel := await channel_cache.get(ctx.channel_id, default=None): return channel.parent_id or ctx.guild_id - thread_cache = ctx.get_type_dependency(async_cache.SfCache[hikari.GuildThreadChannel], default=None) + thread_cache = ctx.client.injector.get_type_dependency( + async_cache.SfCache[hikari.GuildThreadChannel], default=None + ) if thread_cache: # noqa: SIM102 # Has to be nested cause of pyright bug if channel := await thread_cache.get(ctx.channel_id, default=None): @@ -476,7 +480,7 @@ async def _get_ctx_target(ctx: tanjun.Context, type_: BucketResource, /) -> hika try_rest = not roles if try_rest: # noqa: SIM102 # Has to be nested cause of pyright bug - if role_cache := ctx.get_type_dependency(async_cache.SfCache[hikari.Role], default=None): + if role_cache := ctx.client.injector.get_type_dependency(async_cache.SfCache[hikari.Role], default=None): try: roles = filter(None, [await _try_get_role(role_cache, role_id) for role_id in ctx.member.role_ids]) try_rest = False diff --git a/tanjun/hooks.py b/tanjun/hooks.py index 24f4802b3..ec4d00f87 100644 --- a/tanjun/hooks.py +++ b/tanjun/hooks.py @@ -43,6 +43,7 @@ if typing.TYPE_CHECKING: from collections import abc as collections + from alluka import abc as alluka from typing_extensions import Self _AnyCommandT = typing.TypeVar("_AnyCommandT", bound=tanjun.ExecutableCommand[typing.Any]) @@ -378,21 +379,29 @@ async def trigger_error( exception: Exception, /, *, + alluka_ctx: typing.Optional[alluka.Context] = None, hooks: typing.Optional[collections.Set[tanjun.Hooks[_ContextT_contra]]] = None, ) -> int: # <>. + alluka_ctx = alluka_ctx or ctx.client.injector.make_context() level = 0 if isinstance(exception, errors.ParserError): if self._parser_error_callbacks: - await asyncio.gather(*(ctx.call_with_async_di(c, ctx, exception) for c in self._parser_error_callbacks)) + await asyncio.gather( + *(alluka_ctx.call_with_async_di(c, ctx, exception) for c in self._parser_error_callbacks) + ) level = 100 # We don't want to re-raise a parser error if it was caught elif self._error_callbacks: - results = await asyncio.gather(*(ctx.call_with_async_di(c, ctx, exception) for c in self._error_callbacks)) + results = await asyncio.gather( + *(alluka_ctx.call_with_async_di(c, ctx, exception) for c in self._error_callbacks) + ) level = results.count(True) - results.count(False) if hooks: - level += sum(await asyncio.gather(*(hook.trigger_error(ctx, exception) for hook in hooks))) + level += sum( + await asyncio.gather(*(hook.trigger_error(ctx, exception, alluka_ctx=alluka_ctx) for hook in hooks)) + ) return level @@ -401,42 +410,48 @@ async def trigger_post_execution( ctx: _ContextT_contra, /, *, + alluka_ctx: typing.Optional[alluka.Context] = None, hooks: typing.Optional[collections.Set[tanjun.Hooks[_ContextT_contra]]] = None, ) -> None: # <>. if self._post_execution_callbacks: - await asyncio.gather(*(ctx.call_with_async_di(c, ctx) for c in self._post_execution_callbacks)) + alluka_ctx = alluka_ctx or ctx.client.injector.make_context() + await asyncio.gather(*(alluka_ctx.call_with_async_di(c, ctx) for c in self._post_execution_callbacks)) if hooks: - await asyncio.gather(*(hook.trigger_post_execution(ctx) for hook in hooks)) + await asyncio.gather(*(hook.trigger_post_execution(ctx, alluka_ctx=alluka_ctx) for hook in hooks)) async def trigger_pre_execution( self, ctx: _ContextT_contra, /, *, + alluka_ctx: typing.Optional[alluka.Context] = None, hooks: typing.Optional[collections.Set[tanjun.Hooks[_ContextT_contra]]] = None, ) -> None: # <>. if self._pre_execution_callbacks: - await asyncio.gather(*(ctx.call_with_async_di(c, ctx) for c in self._pre_execution_callbacks)) + alluka_ctx = alluka_ctx or ctx.client.injector.make_context() + await asyncio.gather(*(alluka_ctx.call_with_async_di(c, ctx) for c in self._pre_execution_callbacks)) if hooks: - await asyncio.gather(*(hook.trigger_pre_execution(ctx) for hook in hooks)) + await asyncio.gather(*(hook.trigger_pre_execution(ctx, alluka_ctx=alluka_ctx) for hook in hooks)) async def trigger_success( self, ctx: _ContextT_contra, /, *, + alluka_ctx: typing.Optional[alluka.Context] = None, hooks: typing.Optional[collections.Set[tanjun.Hooks[_ContextT_contra]]] = None, ) -> None: # <>. if self._success_callbacks: - await asyncio.gather(*(ctx.call_with_async_di(c, ctx) for c in self._success_callbacks)) + alluka_ctx = alluka_ctx or ctx.client.injector.make_context() + await asyncio.gather(*(alluka_ctx.call_with_async_di(c, ctx) for c in self._success_callbacks)) if hooks: - await asyncio.gather(*(hook.trigger_success(ctx) for hook in hooks)) + await asyncio.gather(*(hook.trigger_success(ctx, alluka_ctx=alluka_ctx) for hook in hooks)) AnyHooks = Hooks[tanjun.Context] diff --git a/tanjun/injecting.py b/tanjun/injecting.py index c4bfb018c..6ea1500dd 100644 --- a/tanjun/injecting.py +++ b/tanjun/injecting.py @@ -54,7 +54,7 @@ import alluka from alluka import AsyncSelfInjecting as SelfInjectingCallback # pyright: ignore[reportDeprecated] -from alluka import BasicContext as BasicInjectionContext +from alluka import BasicContext as BasicInjectionContext # pyright: ignore[reportDeprecated] from alluka import Client as InjectorClient from alluka import Injected from alluka import inject diff --git a/tests/context/test_autocomplete.py b/tests/context/test_autocomplete.py index 921f04187..ae3e763ac 100644 --- a/tests/context/test_autocomplete.py +++ b/tests/context/test_autocomplete.py @@ -128,7 +128,7 @@ def test_shard_property_when_dm( assert context.shard is mock_shard def test_shard_property_when_no_shards(self, context: tanjun.context.AutocompleteContext): - context._tanjun_client = mock.Mock(shards=None) + context._client = mock.Mock(shards=None) assert context.shard is None diff --git a/tests/context/test_base.py b/tests/context/test_base.py index 3cba50530..af5cbad95 100644 --- a/tests/context/test_base.py +++ b/tests/context/test_base.py @@ -115,7 +115,7 @@ def test_shard_property_when_dm(self, mock_client: mock.Mock): assert context.shard is mock_shard def test_shard_property_when_no_shards(self, context: tanjun.context.MessageContext): - context._tanjun_client = mock.Mock(shards=None) + context._client = mock.Mock(shards=None) assert context.shard is None @@ -135,7 +135,6 @@ def test_set_component(self, context: base_context.BaseContext): assert context.set_component(component) is context assert context.component is component - assert context.get_type_dependency(tanjun.abc.Component) is component def test_set_component_when_none_and_previously_set(self, context: base_context.BaseContext): mock_component = mock.Mock() @@ -144,18 +143,12 @@ def test_set_component_when_none_and_previously_set(self, context: base_context. assert context.component is None - with pytest.raises(KeyError): - context.get_type_dependency(tanjun.abc.Component) - def test_set_component_when_none(self, context: base_context.BaseContext): context.set_component(None) context.set_component(None) assert context.component is None - with pytest.raises(KeyError): - context.get_type_dependency(tanjun.abc.Component) - def test_set_component_when_final(self, context: base_context.BaseContext): component = mock.Mock() context.finalise() diff --git a/tests/context/test_message.py b/tests/context/test_message.py index 59584e11a..be15a9ece 100644 --- a/tests/context/test_message.py +++ b/tests/context/test_message.py @@ -142,8 +142,6 @@ def test_set_command(self, context: tanjun.context.MessageContext): assert context.set_command(mock_command) is context assert context.command is mock_command - assert context.get_type_dependency(tanjun.abc.ExecutableCommand) is mock_command - assert context.get_type_dependency(tanjun.abc.MessageCommand) is mock_command def test_set_command_when_none(self, context: tanjun.context.MessageContext): context.set_command(None) @@ -151,12 +149,6 @@ def test_set_command_when_none(self, context: tanjun.context.MessageContext): assert context.command is None - with pytest.raises(KeyError): - assert context.get_type_dependency(tanjun.abc.ExecutableCommand) - - with pytest.raises(KeyError): - assert context.get_type_dependency(tanjun.abc.MessageCommand) - def test_set_command_when_none_and_previously_set(self, context: tanjun.context.MessageContext): mock_command = mock.Mock() context.set_command(mock_command) @@ -164,12 +156,6 @@ def test_set_command_when_none_and_previously_set(self, context: tanjun.context. assert context.command is None - with pytest.raises(KeyError): - assert context.get_type_dependency(tanjun.abc.ExecutableCommand) - - with pytest.raises(KeyError): - assert context.get_type_dependency(tanjun.abc.MessageCommand) - def test_set_command_when_finalised(self, context: tanjun.context.MessageContext): context.finalise() mock_command = mock.Mock() diff --git a/tests/context/test_slash.py b/tests/context/test_slash.py index e7fb4afbd..0621cb177 100644 --- a/tests/context/test_slash.py +++ b/tests/context/test_slash.py @@ -1131,10 +1131,6 @@ def test_set_command(self, context: tanjun.context.SlashContext): assert context.set_command(mock_command) is context assert context.command is mock_command - assert context.get_type_dependency(tanjun.abc.ExecutableCommand) is mock_command - assert context.get_type_dependency(tanjun.abc.AppCommand) is mock_command - assert context.get_type_dependency(tanjun.abc.BaseSlashCommand) is mock_command - assert context.get_type_dependency(tanjun.abc.SlashCommand) is mock_command def test_set_command_when_none(self, context: tanjun.context.SlashContext): context.set_command(None) @@ -1142,18 +1138,6 @@ def test_set_command_when_none(self, context: tanjun.context.SlashContext): assert context.command is None - with pytest.raises(KeyError): - assert context.get_type_dependency(tanjun.abc.ExecutableCommand) - - with pytest.raises(KeyError): - assert context.get_type_dependency(tanjun.abc.AppCommand) - - with pytest.raises(KeyError): - assert context.get_type_dependency(tanjun.abc.BaseSlashCommand) - - with pytest.raises(KeyError): - assert context.get_type_dependency(tanjun.abc.SlashCommand) - def test_set_command_when_none_and_previously_set(self, context: tanjun.context.SlashContext): mock_command = mock.Mock() context.set_command(mock_command) @@ -1161,18 +1145,6 @@ def test_set_command_when_none_and_previously_set(self, context: tanjun.context. assert context.command is None - with pytest.raises(KeyError): - assert context.get_type_dependency(tanjun.abc.ExecutableCommand) - - with pytest.raises(KeyError): - assert context.get_type_dependency(tanjun.abc.AppCommand) - - with pytest.raises(KeyError): - assert context.get_type_dependency(tanjun.abc.BaseSlashCommand) - - with pytest.raises(KeyError): - assert context.get_type_dependency(tanjun.abc.SlashCommand) - def test_set_command_when_finalised(self, context: tanjun.context.SlashContext): context.finalise() mock_command = mock.Mock() diff --git a/tests/test_injecting.py b/tests/test_injecting.py index c04c9c150..71bbd6ae5 100644 --- a/tests/test_injecting.py +++ b/tests/test_injecting.py @@ -62,7 +62,7 @@ def test_aliases(): "injected", } assert tanjun.injecting.SelfInjectingCallback is alluka.AsyncSelfInjecting # pyright: ignore[reportDeprecated] - assert tanjun.injecting.BasicInjectionContext is alluka.BasicContext + assert tanjun.injecting.BasicInjectionContext is alluka.BasicContext # pyright: ignore[reportDeprecated] assert tanjun.injecting.InjectorClient is alluka.Client assert tanjun.injecting.Injected is alluka.Injected assert tanjun.injecting.inject is alluka.inject