diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f2f5e6324..a184a51e0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,6 +26,9 @@ jobs: run: | python -m pip install --upgrade pip poetry poetry install + - name: "Run pyupgrade" + run: | + poetry run pre-commit run pyupgrade --all-files - name: "Code formating (black)" run: | poetry run pre-commit run black --all-files diff --git a/.github_changelog_generator b/.github_changelog_generator new file mode 100644 index 000000000..db89ad20c --- /dev/null +++ b/.github_changelog_generator @@ -0,0 +1 @@ +usernames-as-github-logins=true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cf8dd7867..0a05343d9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.0.1 + rev: v4.1.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -10,13 +10,13 @@ repos: - id: check-ast - repo: https://github.com/asottile/pyupgrade - rev: v2.29.1 + rev: v2.31.0 hooks: - id: pyupgrade args: ['--py37-plus'] - repo: https://github.com/python/black - rev: 21.12b0 + rev: 22.1.0 hooks: - id: black @@ -27,13 +27,13 @@ repos: additional_dependencies: [flake8-docstrings] - repo: https://github.com/pre-commit/mirrors-isort - rev: v5.9.3 + rev: v5.10.1 hooks: - id: isort additional_dependencies: [toml] - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.920 + rev: v0.931 hooks: - id: mypy additional_dependencies: [types-click] diff --git a/CHANGELOG.md b/CHANGELOG.md index 84aa4e942..c94510725 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,32 +1,73 @@ # Changelog +## [0.4.2](https://github.com/python-kasa/python-kasa/tree/0.4.2) (2022-03-21) + +This is the last release prior restructuring the code to enable easier extendability by moving towards more modular architecture. +The most prominent change in this release is the support for effects on light strips. + +[Full Changelog](https://github.com/python-kasa/python-kasa/compare/0.4.1...0.4.2) + +**Implemented enhancements:** + +- Allow environment variables for discovery target, device type and debug [\#313](https://github.com/python-kasa/python-kasa/pull/313) (@rytilahti) +- Add 'internal\_state' to return the results from the last update query [\#306](https://github.com/python-kasa/python-kasa/pull/306) (@rytilahti) +- Drop microsecond precision for on\_since [\#296](https://github.com/python-kasa/python-kasa/pull/296) (@rytilahti) +- Add effect support for light strips [\#293](https://github.com/python-kasa/python-kasa/pull/293) (@bdraco) + +**Fixed bugs:** + +- TypeError: \_\_init\_\_\(\) got an unexpected keyword argument 'package\_name' [\#311](https://github.com/python-kasa/python-kasa/issues/311) +- RuntimeError: Event loop is closed on WSL [\#294](https://github.com/python-kasa/python-kasa/issues/294) +- Don't crash on devices not reporting features [\#317](https://github.com/python-kasa/python-kasa/pull/317) (@rytilahti) + +**Closed issues:** + +- SmartDeviceException: Communication error on system:set\_relay\_state [\#309](https://github.com/python-kasa/python-kasa/issues/309) +- Add Support: ES20M and KS200M motion/light switches [\#308](https://github.com/python-kasa/python-kasa/issues/308) +- New problem with installing on Ubuntu 20.04.3 LTS [\#305](https://github.com/python-kasa/python-kasa/issues/305) +- KeyError: 'emeter' when discovering [\#302](https://github.com/python-kasa/python-kasa/issues/302) +- RuntimeError: Event loop is closed [\#291](https://github.com/python-kasa/python-kasa/issues/291) +- provisioning format [\#290](https://github.com/python-kasa/python-kasa/issues/290) +- Fix CI publishing on pypi [\#222](https://github.com/python-kasa/python-kasa/issues/222) +- LED strips effects are not supported \(was LEDs is not turning on after switching on\) [\#191](https://github.com/python-kasa/python-kasa/issues/191) + +**Merged pull requests:** + +- Add pyupgrade to CI runs [\#314](https://github.com/python-kasa/python-kasa/pull/314) (@rytilahti) +- Depend on asyncclick \>= 8 [\#312](https://github.com/python-kasa/python-kasa/pull/312) (@rytilahti) +- Guard emeter accesses to avoid keyerrors [\#304](https://github.com/python-kasa/python-kasa/pull/304) (@rytilahti) +- cli: cleanup discover, fetch update prior device access [\#303](https://github.com/python-kasa/python-kasa/pull/303) (@rytilahti) +- Fix unsafe \_\_del\_\_ in TPLinkSmartHomeProtocol [\#300](https://github.com/python-kasa/python-kasa/pull/300) (@bdraco) +- Improve typing for protocol class [\#289](https://github.com/python-kasa/python-kasa/pull/289) (@rytilahti) +- Added a fixture file for KS220M [\#273](https://github.com/python-kasa/python-kasa/pull/273) (@mrbetta) + ## [0.4.1](https://github.com/python-kasa/python-kasa/tree/0.4.1) (2022-01-14) [Full Changelog](https://github.com/python-kasa/python-kasa/compare/0.4.0...0.4.1) **Implemented enhancements:** -- Add --type option to cli [\#269](https://github.com/python-kasa/python-kasa/pull/269) ([rytilahti](https://github.com/rytilahti)) -- Minor improvements to onboarding doc [\#264](https://github.com/python-kasa/python-kasa/pull/264) ([rytilahti](https://github.com/rytilahti)) -- Add fixture file for KL135 [\#263](https://github.com/python-kasa/python-kasa/pull/263) ([ErikSGross](https://github.com/ErikSGross)) -- Add KL135 color temperature range [\#256](https://github.com/python-kasa/python-kasa/pull/256) ([rytilahti](https://github.com/rytilahti)) -- Add py.typed to flag that the package is typed [\#251](https://github.com/python-kasa/python-kasa/pull/251) ([rytilahti](https://github.com/rytilahti)) -- Add script to check supported devices, update README [\#242](https://github.com/python-kasa/python-kasa/pull/242) ([rytilahti](https://github.com/rytilahti)) -- Add perftest to devtools [\#236](https://github.com/python-kasa/python-kasa/pull/236) ([rytilahti](https://github.com/rytilahti)) -- Add KP401 US fixture [\#234](https://github.com/python-kasa/python-kasa/pull/234) ([bdraco](https://github.com/bdraco)) -- Add KL60 US KP105 UK fixture [\#233](https://github.com/python-kasa/python-kasa/pull/233) ([bdraco](https://github.com/bdraco)) -- Make cli interface more consistent [\#232](https://github.com/python-kasa/python-kasa/pull/232) ([rytilahti](https://github.com/rytilahti)) -- Add KL400, KL50 fixtures [\#231](https://github.com/python-kasa/python-kasa/pull/231) ([bdraco](https://github.com/bdraco)) -- Add fixture for newer KP400 firmware [\#227](https://github.com/python-kasa/python-kasa/pull/227) ([bdraco](https://github.com/bdraco)) -- Switch to poetry-core [\#226](https://github.com/python-kasa/python-kasa/pull/226) ([fabaff](https://github.com/fabaff)) -- Add fixtures for LB110, KL110, EP40, KL430, KP115 [\#224](https://github.com/python-kasa/python-kasa/pull/224) ([bdraco](https://github.com/bdraco)) +- Add --type option to cli [\#269](https://github.com/python-kasa/python-kasa/pull/269) (@rytilahti) +- Minor improvements to onboarding doc [\#264](https://github.com/python-kasa/python-kasa/pull/264) (@rytilahti) +- Add fixture file for KL135 [\#263](https://github.com/python-kasa/python-kasa/pull/263) (@ErikSGross) +- Add KL135 color temperature range [\#256](https://github.com/python-kasa/python-kasa/pull/256) (@rytilahti) +- Add py.typed to flag that the package is typed [\#251](https://github.com/python-kasa/python-kasa/pull/251) (@rytilahti) +- Add script to check supported devices, update README [\#242](https://github.com/python-kasa/python-kasa/pull/242) (@rytilahti) +- Add perftest to devtools [\#236](https://github.com/python-kasa/python-kasa/pull/236) (@rytilahti) +- Add KP401 US fixture [\#234](https://github.com/python-kasa/python-kasa/pull/234) (@bdraco) +- Add KL60 US KP105 UK fixture [\#233](https://github.com/python-kasa/python-kasa/pull/233) (@bdraco) +- Make cli interface more consistent [\#232](https://github.com/python-kasa/python-kasa/pull/232) (@rytilahti) +- Add KL400, KL50 fixtures [\#231](https://github.com/python-kasa/python-kasa/pull/231) (@bdraco) +- Add fixture for newer KP400 firmware [\#227](https://github.com/python-kasa/python-kasa/pull/227) (@bdraco) +- Switch to poetry-core [\#226](https://github.com/python-kasa/python-kasa/pull/226) (@fabaff) +- Add fixtures for LB110, KL110, EP40, KL430, KP115 [\#224](https://github.com/python-kasa/python-kasa/pull/224) (@bdraco) **Fixed bugs:** - Discovery on WSL results in OSError: \[Errno 22\] Invalid argument [\#246](https://github.com/python-kasa/python-kasa/issues/246) - New firmware for HS103 blocking local access? [\#42](https://github.com/python-kasa/python-kasa/issues/42) -- Pin mistune to \<2.0.0 to fix doc builds [\#270](https://github.com/python-kasa/python-kasa/pull/270) ([rytilahti](https://github.com/rytilahti)) -- Catch exceptions raised on unknown devices during discovery [\#240](https://github.com/python-kasa/python-kasa/pull/240) ([rytilahti](https://github.com/rytilahti)) +- Pin mistune to \<2.0.0 to fix doc builds [\#270](https://github.com/python-kasa/python-kasa/pull/270) (@rytilahti) +- Catch exceptions raised on unknown devices during discovery [\#240](https://github.com/python-kasa/python-kasa/pull/240) (@rytilahti) **Closed issues:** @@ -47,13 +88,14 @@ **Merged pull requests:** -- Publish to pypi on github release published [\#287](https://github.com/python-kasa/python-kasa/pull/287) ([rytilahti](https://github.com/rytilahti)) -- Relax asyncclick version requirement [\#286](https://github.com/python-kasa/python-kasa/pull/286) ([rytilahti](https://github.com/rytilahti)) -- Do not crash on discovery on WSL [\#283](https://github.com/python-kasa/python-kasa/pull/283) ([rytilahti](https://github.com/rytilahti)) -- Add python 3.10 to CI [\#279](https://github.com/python-kasa/python-kasa/pull/279) ([rytilahti](https://github.com/rytilahti)) -- Use codecov-action@v2 for CI [\#277](https://github.com/python-kasa/python-kasa/pull/277) ([rytilahti](https://github.com/rytilahti)) -- Add coverage\[toml\] dependency to fix coverage on CI [\#271](https://github.com/python-kasa/python-kasa/pull/271) ([rytilahti](https://github.com/rytilahti)) -- Allow publish on test pypi workflow to fail [\#248](https://github.com/python-kasa/python-kasa/pull/248) ([rytilahti](https://github.com/rytilahti)) +- Prepare 0.4.1 [\#288](https://github.com/python-kasa/python-kasa/pull/288) (@rytilahti) +- Publish to pypi on github release published [\#287](https://github.com/python-kasa/python-kasa/pull/287) (@rytilahti) +- Relax asyncclick version requirement [\#286](https://github.com/python-kasa/python-kasa/pull/286) (@rytilahti) +- Do not crash on discovery on WSL [\#283](https://github.com/python-kasa/python-kasa/pull/283) (@rytilahti) +- Add python 3.10 to CI [\#279](https://github.com/python-kasa/python-kasa/pull/279) (@rytilahti) +- Use codecov-action@v2 for CI [\#277](https://github.com/python-kasa/python-kasa/pull/277) (@rytilahti) +- Add coverage\[toml\] dependency to fix coverage on CI [\#271](https://github.com/python-kasa/python-kasa/pull/271) (@rytilahti) +- Allow publish on test pypi workflow to fail [\#248](https://github.com/python-kasa/python-kasa/pull/248) (@rytilahti) ## [0.4.0](https://github.com/python-kasa/python-kasa/tree/0.4.0) (2021-09-27) @@ -61,8 +103,8 @@ **Implemented enhancements:** -- Fix lock being unexpectedly reset on close [\#218](https://github.com/python-kasa/python-kasa/pull/218) ([bdraco](https://github.com/bdraco)) -- Avoid calling pformat unless debug logging is enabled [\#217](https://github.com/python-kasa/python-kasa/pull/217) ([bdraco](https://github.com/bdraco)) +- Fix lock being unexpectedly reset on close [\#218](https://github.com/python-kasa/python-kasa/pull/218) (@bdraco) +- Avoid calling pformat unless debug logging is enabled [\#217](https://github.com/python-kasa/python-kasa/pull/217) (@bdraco) **Closed issues:** @@ -70,9 +112,9 @@ **Merged pull requests:** -- Release 0.4.0 [\#221](https://github.com/python-kasa/python-kasa/pull/221) ([rytilahti](https://github.com/rytilahti)) -- Add github workflow for pypi publishing [\#220](https://github.com/python-kasa/python-kasa/pull/220) ([rytilahti](https://github.com/rytilahti)) -- Add host information to protocol debug logs [\#219](https://github.com/python-kasa/python-kasa/pull/219) ([rytilahti](https://github.com/rytilahti)) +- Release 0.4.0 [\#221](https://github.com/python-kasa/python-kasa/pull/221) (@rytilahti) +- Add github workflow for pypi publishing [\#220](https://github.com/python-kasa/python-kasa/pull/220) (@rytilahti) +- Add host information to protocol debug logs [\#219](https://github.com/python-kasa/python-kasa/pull/219) (@rytilahti) ## [0.4.0.dev5](https://github.com/python-kasa/python-kasa/tree/0.4.0.dev5) (2021-09-24) @@ -80,13 +122,13 @@ **Implemented enhancements:** -- Keep connection open and lock to prevent duplicate requests [\#213](https://github.com/python-kasa/python-kasa/pull/213) ([bdraco](https://github.com/bdraco)) +- Keep connection open and lock to prevent duplicate requests [\#213](https://github.com/python-kasa/python-kasa/pull/213) (@bdraco) **Merged pull requests:** -- Release 0.4.0.dev5 [\#215](https://github.com/python-kasa/python-kasa/pull/215) ([rytilahti](https://github.com/rytilahti)) -- Add KL130 fixture, initial lightstrip tests [\#214](https://github.com/python-kasa/python-kasa/pull/214) ([rytilahti](https://github.com/rytilahti)) -- Cleanup discovery & add tests [\#212](https://github.com/python-kasa/python-kasa/pull/212) ([rytilahti](https://github.com/rytilahti)) +- Release 0.4.0.dev5 [\#215](https://github.com/python-kasa/python-kasa/pull/215) (@rytilahti) +- Add KL130 fixture, initial lightstrip tests [\#214](https://github.com/python-kasa/python-kasa/pull/214) (@rytilahti) +- Cleanup discovery & add tests [\#212](https://github.com/python-kasa/python-kasa/pull/212) (@rytilahti) ## [0.4.0.dev4](https://github.com/python-kasa/python-kasa/tree/0.4.0.dev4) (2021-09-23) @@ -94,20 +136,20 @@ **Implemented enhancements:** -- Improve emeterstatus API, move into own module [\#205](https://github.com/python-kasa/python-kasa/pull/205) ([rytilahti](https://github.com/rytilahti)) -- Avoid temp array during encrypt and decrypt [\#204](https://github.com/python-kasa/python-kasa/pull/204) ([bdraco](https://github.com/bdraco)) -- Add emeter support for strip sockets [\#203](https://github.com/python-kasa/python-kasa/pull/203) ([bdraco](https://github.com/bdraco)) -- Add own device type for smartstrip children [\#201](https://github.com/python-kasa/python-kasa/pull/201) ([rytilahti](https://github.com/rytilahti)) -- bulb: allow set\_hsv without v, add fallback ct range [\#200](https://github.com/python-kasa/python-kasa/pull/200) ([rytilahti](https://github.com/rytilahti)) -- Improve bulb support \(alias, time settings\) [\#198](https://github.com/python-kasa/python-kasa/pull/198) ([rytilahti](https://github.com/rytilahti)) -- Improve testing harness to allow tests on real devices [\#197](https://github.com/python-kasa/python-kasa/pull/197) ([rytilahti](https://github.com/rytilahti)) -- cli: add human-friendly printout when calling temperature on non-supported devices [\#196](https://github.com/python-kasa/python-kasa/pull/196) ([JaydenRA](https://github.com/JaydenRA)) +- Improve emeterstatus API, move into own module [\#205](https://github.com/python-kasa/python-kasa/pull/205) (@rytilahti) +- Avoid temp array during encrypt and decrypt [\#204](https://github.com/python-kasa/python-kasa/pull/204) (@bdraco) +- Add emeter support for strip sockets [\#203](https://github.com/python-kasa/python-kasa/pull/203) (@bdraco) +- Add own device type for smartstrip children [\#201](https://github.com/python-kasa/python-kasa/pull/201) (@rytilahti) +- bulb: allow set\_hsv without v, add fallback ct range [\#200](https://github.com/python-kasa/python-kasa/pull/200) (@rytilahti) +- Improve bulb support \(alias, time settings\) [\#198](https://github.com/python-kasa/python-kasa/pull/198) (@rytilahti) +- Improve testing harness to allow tests on real devices [\#197](https://github.com/python-kasa/python-kasa/pull/197) (@rytilahti) +- cli: add human-friendly printout when calling temperature on non-supported devices [\#196](https://github.com/python-kasa/python-kasa/pull/196) (@JaydenRA) **Fixed bugs:** - KL430: Throw error for Device specific information [\#189](https://github.com/python-kasa/python-kasa/issues/189) - HS300 Children plugs have emeter [\#64](https://github.com/python-kasa/python-kasa/issues/64) -- dump\_devinfo: handle latitude/longitude keys properly [\#175](https://github.com/python-kasa/python-kasa/pull/175) ([rytilahti](https://github.com/rytilahti)) +- dump\_devinfo: handle latitude/longitude keys properly [\#175](https://github.com/python-kasa/python-kasa/pull/175) (@rytilahti) **Closed issues:** @@ -122,16 +164,16 @@ **Merged pull requests:** -- Release 0.4.0.dev4 [\#210](https://github.com/python-kasa/python-kasa/pull/210) ([rytilahti](https://github.com/rytilahti)) -- More CI fixes [\#208](https://github.com/python-kasa/python-kasa/pull/208) ([rytilahti](https://github.com/rytilahti)) -- Fix CI dep installation [\#207](https://github.com/python-kasa/python-kasa/pull/207) ([rytilahti](https://github.com/rytilahti)) -- Use github actions instead of azure pipelines [\#206](https://github.com/python-kasa/python-kasa/pull/206) ([rytilahti](https://github.com/rytilahti)) -- Add KP115 fixture [\#202](https://github.com/python-kasa/python-kasa/pull/202) ([rytilahti](https://github.com/rytilahti)) -- Perform initial update only using the sysinfo query [\#199](https://github.com/python-kasa/python-kasa/pull/199) ([rytilahti](https://github.com/rytilahti)) -- Add real kasa KL430\(UN\) device dump [\#192](https://github.com/python-kasa/python-kasa/pull/192) ([iprodanovbg](https://github.com/iprodanovbg)) -- Use less strict matcher for kl430 color temperature [\#190](https://github.com/python-kasa/python-kasa/pull/190) ([rytilahti](https://github.com/rytilahti)) -- Add EP10\(US\) 1.0 1.0.2 fixture [\#174](https://github.com/python-kasa/python-kasa/pull/174) ([nbrew](https://github.com/nbrew)) -- Add a note about using the discovery target parameter [\#168](https://github.com/python-kasa/python-kasa/pull/168) ([leandroreox](https://github.com/leandroreox)) +- Release 0.4.0.dev4 [\#210](https://github.com/python-kasa/python-kasa/pull/210) (@rytilahti) +- More CI fixes [\#208](https://github.com/python-kasa/python-kasa/pull/208) (@rytilahti) +- Fix CI dep installation [\#207](https://github.com/python-kasa/python-kasa/pull/207) (@rytilahti) +- Use github actions instead of azure pipelines [\#206](https://github.com/python-kasa/python-kasa/pull/206) (@rytilahti) +- Add KP115 fixture [\#202](https://github.com/python-kasa/python-kasa/pull/202) (@rytilahti) +- Perform initial update only using the sysinfo query [\#199](https://github.com/python-kasa/python-kasa/pull/199) (@rytilahti) +- Add real kasa KL430\(UN\) device dump [\#192](https://github.com/python-kasa/python-kasa/pull/192) (@iprodanovbg) +- Use less strict matcher for kl430 color temperature [\#190](https://github.com/python-kasa/python-kasa/pull/190) (@rytilahti) +- Add EP10\(US\) 1.0 1.0.2 fixture [\#174](https://github.com/python-kasa/python-kasa/pull/174) (@nbrew) +- Add a note about using the discovery target parameter [\#168](https://github.com/python-kasa/python-kasa/pull/168) (@leandroreox) ## [0.4.0.dev3](https://github.com/python-kasa/python-kasa/tree/0.4.0.dev3) (2021-06-16) @@ -141,8 +183,8 @@ - `Unable to find a value for 'current'` error when attempting to query KL125 bulb emeter [\#142](https://github.com/python-kasa/python-kasa/issues/142) - `Unknown color temperature range` error when attempting to query KL125 bulb state [\#141](https://github.com/python-kasa/python-kasa/issues/141) -- Simplify discovery query, refactor dump-devinfo [\#147](https://github.com/python-kasa/python-kasa/pull/147) ([rytilahti](https://github.com/rytilahti)) -- Return None instead of raising an exception on missing, valid emeter keys [\#146](https://github.com/python-kasa/python-kasa/pull/146) ([rytilahti](https://github.com/rytilahti)) +- Simplify discovery query, refactor dump-devinfo [\#147](https://github.com/python-kasa/python-kasa/pull/147) (@rytilahti) +- Return None instead of raising an exception on missing, valid emeter keys [\#146](https://github.com/python-kasa/python-kasa/pull/146) (@rytilahti) **Closed issues:** @@ -162,16 +204,16 @@ **Merged pull requests:** -- Prepare 0.4.0.dev3 [\#172](https://github.com/python-kasa/python-kasa/pull/172) ([rytilahti](https://github.com/rytilahti)) -- Simplify mac address handling [\#162](https://github.com/python-kasa/python-kasa/pull/162) ([rytilahti](https://github.com/rytilahti)) -- Added KL125 and HS200 fixture dumps and updated tests to run on new format [\#160](https://github.com/python-kasa/python-kasa/pull/160) ([brianthedavis](https://github.com/brianthedavis)) -- Add KL125 bulb definition [\#143](https://github.com/python-kasa/python-kasa/pull/143) ([mdarnol](https://github.com/mdarnol)) -- README.md: Add link to MQTT interface for python-kasa [\#140](https://github.com/python-kasa/python-kasa/pull/140) ([flavio-fernandes](https://github.com/flavio-fernandes)) -- Fix documentation on Smart strips [\#136](https://github.com/python-kasa/python-kasa/pull/136) ([flavio-fernandes](https://github.com/flavio-fernandes)) -- add tapo link, fix tplink-smarthome-simulator link [\#133](https://github.com/python-kasa/python-kasa/pull/133) ([rytilahti](https://github.com/rytilahti)) -- Leverage data from UDP discovery to initialize device structure [\#132](https://github.com/python-kasa/python-kasa/pull/132) ([dlee1j1](https://github.com/dlee1j1)) -- Improve cli documentation for bulbs and power strips [\#123](https://github.com/python-kasa/python-kasa/pull/123) ([rytilahti](https://github.com/rytilahti)) -- Add HS220 hw 2.0 fixture [\#107](https://github.com/python-kasa/python-kasa/pull/107) ([appleguru](https://github.com/appleguru)) +- Prepare 0.4.0.dev3 [\#172](https://github.com/python-kasa/python-kasa/pull/172) (@rytilahti) +- Simplify mac address handling [\#162](https://github.com/python-kasa/python-kasa/pull/162) (@rytilahti) +- Added KL125 and HS200 fixture dumps and updated tests to run on new format [\#160](https://github.com/python-kasa/python-kasa/pull/160) (@brianthedavis) +- Add KL125 bulb definition [\#143](https://github.com/python-kasa/python-kasa/pull/143) (@mdarnol) +- README.md: Add link to MQTT interface for python-kasa [\#140](https://github.com/python-kasa/python-kasa/pull/140) (@flavio-fernandes) +- Fix documentation on Smart strips [\#136](https://github.com/python-kasa/python-kasa/pull/136) (@flavio-fernandes) +- add tapo link, fix tplink-smarthome-simulator link [\#133](https://github.com/python-kasa/python-kasa/pull/133) (@rytilahti) +- Leverage data from UDP discovery to initialize device structure [\#132](https://github.com/python-kasa/python-kasa/pull/132) (@dlee1j1) +- Improve cli documentation for bulbs and power strips [\#123](https://github.com/python-kasa/python-kasa/pull/123) (@rytilahti) +- Add HS220 hw 2.0 fixture [\#107](https://github.com/python-kasa/python-kasa/pull/107) (@appleguru) ## [0.4.0.dev2](https://github.com/python-kasa/python-kasa/tree/0.4.0.dev2) (2020-11-21) @@ -179,12 +221,12 @@ **Implemented enhancements:** -- 'Interface' parameter added to discovery process [\#79](https://github.com/python-kasa/python-kasa/pull/79) ([dmitryelj](https://github.com/dmitryelj)) +- 'Interface' parameter added to discovery process [\#79](https://github.com/python-kasa/python-kasa/pull/79) (@dmitryelj) **Fixed bugs:** -- Simplify device class detection for discovery, fix hardcoded timeout [\#112](https://github.com/python-kasa/python-kasa/pull/112) ([rytilahti](https://github.com/rytilahti)) -- Update cli.py to addresss crash on year/month calls and improve output formatting [\#103](https://github.com/python-kasa/python-kasa/pull/103) ([BuongiornoTexas](https://github.com/BuongiornoTexas)) +- Simplify device class detection for discovery, fix hardcoded timeout [\#112](https://github.com/python-kasa/python-kasa/pull/112) (@rytilahti) +- Update cli.py to addresss crash on year/month calls and improve output formatting [\#103](https://github.com/python-kasa/python-kasa/pull/103) (@BuongiornoTexas) **Closed issues:** @@ -201,8 +243,8 @@ **Merged pull requests:** -- Release 0.4.0.dev2 [\#118](https://github.com/python-kasa/python-kasa/pull/118) ([rytilahti](https://github.com/rytilahti)) -- Pin dependencies on major versions, add poetry.lock [\#94](https://github.com/python-kasa/python-kasa/pull/94) ([rytilahti](https://github.com/rytilahti)) +- Release 0.4.0.dev2 [\#118](https://github.com/python-kasa/python-kasa/pull/118) (@rytilahti) +- Pin dependencies on major versions, add poetry.lock [\#94](https://github.com/python-kasa/python-kasa/pull/94) (@rytilahti) ## [0.4.0.dev1](https://github.com/python-kasa/python-kasa/tree/0.4.0.dev1) (2020-07-28) @@ -212,7 +254,7 @@ - KL430 support [\#67](https://github.com/python-kasa/python-kasa/issues/67) - Improve retry logic for discovery, messaging \(was: Handle empty responses\) [\#38](https://github.com/python-kasa/python-kasa/issues/38) -- Add support for lightstrips \(KL430\) [\#74](https://github.com/python-kasa/python-kasa/pull/74) ([rytilahti](https://github.com/rytilahti)) +- Add support for lightstrips \(KL430\) [\#74](https://github.com/python-kasa/python-kasa/pull/74) (@rytilahti) **Closed issues:** @@ -227,25 +269,29 @@ **Merged pull requests:** -- Release 0.4.0.dev1 [\#93](https://github.com/python-kasa/python-kasa/pull/93) ([rytilahti](https://github.com/rytilahti)) -- add a small example script to show library usage [\#90](https://github.com/python-kasa/python-kasa/pull/90) ([rytilahti](https://github.com/rytilahti)) -- add .readthedocs.yml required for poetry builds [\#89](https://github.com/python-kasa/python-kasa/pull/89) ([rytilahti](https://github.com/rytilahti)) -- Improve installation instructions [\#86](https://github.com/python-kasa/python-kasa/pull/86) ([rytilahti](https://github.com/rytilahti)) -- cli: Fix incorrect use of asyncio.run for temperature command [\#85](https://github.com/python-kasa/python-kasa/pull/85) ([rytilahti](https://github.com/rytilahti)) -- Add parse\_pcap to devtools, improve readme on contributing [\#84](https://github.com/python-kasa/python-kasa/pull/84) ([rytilahti](https://github.com/rytilahti)) -- Add --transition to bulb-specific cli commands, fix turn\_{on,off} signatures [\#81](https://github.com/python-kasa/python-kasa/pull/81) ([rytilahti](https://github.com/rytilahti)) -- Improve bulb API, force turn on for all light changes as offline changes are not supported [\#76](https://github.com/python-kasa/python-kasa/pull/76) ([rytilahti](https://github.com/rytilahti)) -- Simplify API documentation by using doctests [\#73](https://github.com/python-kasa/python-kasa/pull/73) ([rytilahti](https://github.com/rytilahti)) -- Bulbs: allow specifying transition for state changes [\#70](https://github.com/python-kasa/python-kasa/pull/70) ([rytilahti](https://github.com/rytilahti)) -- Add transition support for SmartDimmer [\#69](https://github.com/python-kasa/python-kasa/pull/69) ([connorproctor](https://github.com/connorproctor)) +- Release 0.4.0.dev1 [\#93](https://github.com/python-kasa/python-kasa/pull/93) (@rytilahti) +- add a small example script to show library usage [\#90](https://github.com/python-kasa/python-kasa/pull/90) (@rytilahti) +- add .readthedocs.yml required for poetry builds [\#89](https://github.com/python-kasa/python-kasa/pull/89) (@rytilahti) +- Improve installation instructions [\#86](https://github.com/python-kasa/python-kasa/pull/86) (@rytilahti) +- cli: Fix incorrect use of asyncio.run for temperature command [\#85](https://github.com/python-kasa/python-kasa/pull/85) (@rytilahti) +- Add parse\_pcap to devtools, improve readme on contributing [\#84](https://github.com/python-kasa/python-kasa/pull/84) (@rytilahti) +- Add --transition to bulb-specific cli commands, fix turn\_{on,off} signatures [\#81](https://github.com/python-kasa/python-kasa/pull/81) (@rytilahti) +- Improve bulb API, force turn on for all light changes as offline changes are not supported [\#76](https://github.com/python-kasa/python-kasa/pull/76) (@rytilahti) +- Simplify API documentation by using doctests [\#73](https://github.com/python-kasa/python-kasa/pull/73) (@rytilahti) +- Bulbs: allow specifying transition for state changes [\#70](https://github.com/python-kasa/python-kasa/pull/70) (@rytilahti) +- Add transition support for SmartDimmer [\#69](https://github.com/python-kasa/python-kasa/pull/69) (@connorproctor) ## [0.4.0.dev0](https://github.com/python-kasa/python-kasa/tree/0.4.0.dev0) (2020-05-27) -[Full Changelog](https://github.com/python-kasa/python-kasa/compare/0.3.5...0.4.0.dev0) +[Full Changelog](https://github.com/python-kasa/python-kasa/compare/0.4.0.pre0...0.4.0.dev0) + +## [0.4.0.pre0](https://github.com/python-kasa/python-kasa/tree/0.4.0.pre0) (2020-05-27) + +[Full Changelog](https://github.com/python-kasa/python-kasa/compare/0.3.5...0.4.0.pre0) **Implemented enhancements:** -- Add commands to control the wifi settings [\#45](https://github.com/python-kasa/python-kasa/pull/45) ([rytilahti](https://github.com/rytilahti)) +- Add commands to control the wifi settings [\#45](https://github.com/python-kasa/python-kasa/pull/45) (@rytilahti) **Fixed bugs:** @@ -271,43 +317,43 @@ **Merged pull requests:** -- Add retries to protocol queries [\#65](https://github.com/python-kasa/python-kasa/pull/65) ([rytilahti](https://github.com/rytilahti)) -- General cleanups all around \(janitoring\) [\#63](https://github.com/python-kasa/python-kasa/pull/63) ([rytilahti](https://github.com/rytilahti)) -- Improve dimmer support [\#62](https://github.com/python-kasa/python-kasa/pull/62) ([rytilahti](https://github.com/rytilahti)) -- Optimize I/O access [\#59](https://github.com/python-kasa/python-kasa/pull/59) ([rytilahti](https://github.com/rytilahti)) -- Remove unnecessary f-string definition to make tests pass [\#58](https://github.com/python-kasa/python-kasa/pull/58) ([rytilahti](https://github.com/rytilahti)) -- Convert to use poetry & pyproject.toml for dep & build management [\#54](https://github.com/python-kasa/python-kasa/pull/54) ([rytilahti](https://github.com/rytilahti)) -- Add fixture for KL60 [\#52](https://github.com/python-kasa/python-kasa/pull/52) ([rytilahti](https://github.com/rytilahti)) -- Ignore D202 where necessary [\#50](https://github.com/python-kasa/python-kasa/pull/50) ([rytilahti](https://github.com/rytilahti)) -- Support wifi scan & join for bulbs using a different interface [\#49](https://github.com/python-kasa/python-kasa/pull/49) ([rytilahti](https://github.com/rytilahti)) -- Return on\_since only when its available and the device is on [\#48](https://github.com/python-kasa/python-kasa/pull/48) ([rytilahti](https://github.com/rytilahti)) -- Allow 0 brightness for smartdimmer [\#47](https://github.com/python-kasa/python-kasa/pull/47) ([rytilahti](https://github.com/rytilahti)) -- async++, small powerstrip improvements [\#46](https://github.com/python-kasa/python-kasa/pull/46) ([rytilahti](https://github.com/rytilahti)) -- Check for emeter support on power strips/multiple plug outlets [\#41](https://github.com/python-kasa/python-kasa/pull/41) ([acmay](https://github.com/acmay)) -- Remove unnecessary cache [\#40](https://github.com/python-kasa/python-kasa/pull/40) ([rytilahti](https://github.com/rytilahti)) -- Add in some new device types [\#39](https://github.com/python-kasa/python-kasa/pull/39) ([acmay](https://github.com/acmay)) -- Add test fixture for KL130 [\#35](https://github.com/python-kasa/python-kasa/pull/35) ([bdraco](https://github.com/bdraco)) -- Move dimmer support to its own class [\#34](https://github.com/python-kasa/python-kasa/pull/34) ([rytilahti](https://github.com/rytilahti)) -- Fix azure pipeline badge [\#32](https://github.com/python-kasa/python-kasa/pull/32) ([rytilahti](https://github.com/rytilahti)) -- Enable Windows & OSX builds [\#31](https://github.com/python-kasa/python-kasa/pull/31) ([rytilahti](https://github.com/rytilahti)) -- Depend on py3.7+ for tox, add python 3.8 to azure pipeline targets [\#29](https://github.com/python-kasa/python-kasa/pull/29) ([rytilahti](https://github.com/rytilahti)) -- Add KP303 to the list of powerstrips [\#28](https://github.com/python-kasa/python-kasa/pull/28) ([rytilahti](https://github.com/rytilahti)) -- Move child socket handling to its own SmartStripPlug class [\#26](https://github.com/python-kasa/python-kasa/pull/26) ([rytilahti](https://github.com/rytilahti)) -- Adding KP303 to supported devices [\#25](https://github.com/python-kasa/python-kasa/pull/25) ([epicalex](https://github.com/epicalex)) -- use pytestmark to avoid repeating asyncio mark [\#24](https://github.com/python-kasa/python-kasa/pull/24) ([rytilahti](https://github.com/rytilahti)) -- Cleanup constructors by removing ioloop and protocol arguments [\#23](https://github.com/python-kasa/python-kasa/pull/23) ([rytilahti](https://github.com/rytilahti)) -- Add \(some\) tests to the cli tool [\#22](https://github.com/python-kasa/python-kasa/pull/22) ([rytilahti](https://github.com/rytilahti)) -- Test against the newly added device fixtures [\#21](https://github.com/python-kasa/python-kasa/pull/21) ([rytilahti](https://github.com/rytilahti)) -- move testing reqs to requirements\_test.txt, add pytest-asyncio for pipelines [\#20](https://github.com/python-kasa/python-kasa/pull/20) ([rytilahti](https://github.com/rytilahti)) -- Remove unused save option and add scrubbing [\#19](https://github.com/python-kasa/python-kasa/pull/19) ([TheGardenMonkey](https://github.com/TheGardenMonkey)) -- Add real kasa device dumps [\#18](https://github.com/python-kasa/python-kasa/pull/18) ([TheGardenMonkey](https://github.com/TheGardenMonkey)) -- Fix dump-discover to use asyncio.run [\#16](https://github.com/python-kasa/python-kasa/pull/16) ([rytilahti](https://github.com/rytilahti)) -- Add device\_id property, rename context to child\_id [\#15](https://github.com/python-kasa/python-kasa/pull/15) ([rytilahti](https://github.com/rytilahti)) -- Remove sync interface, add asyncio discovery [\#14](https://github.com/python-kasa/python-kasa/pull/14) ([rytilahti](https://github.com/rytilahti)) -- Remove --ip which was just an alias to --host [\#6](https://github.com/python-kasa/python-kasa/pull/6) ([rytilahti](https://github.com/rytilahti)) -- Set minimum requirement to python 3.7 [\#5](https://github.com/python-kasa/python-kasa/pull/5) ([rytilahti](https://github.com/rytilahti)) -- change ID of Azure Pipeline [\#3](https://github.com/python-kasa/python-kasa/pull/3) ([basnijholt](https://github.com/basnijholt)) -- Mass rename to \(python-\)kasa [\#1](https://github.com/python-kasa/python-kasa/pull/1) ([rytilahti](https://github.com/rytilahti)) +- Add retries to protocol queries [\#65](https://github.com/python-kasa/python-kasa/pull/65) (@rytilahti) +- General cleanups all around \(janitoring\) [\#63](https://github.com/python-kasa/python-kasa/pull/63) (@rytilahti) +- Improve dimmer support [\#62](https://github.com/python-kasa/python-kasa/pull/62) (@rytilahti) +- Optimize I/O access [\#59](https://github.com/python-kasa/python-kasa/pull/59) (@rytilahti) +- Remove unnecessary f-string definition to make tests pass [\#58](https://github.com/python-kasa/python-kasa/pull/58) (@rytilahti) +- Convert to use poetry & pyproject.toml for dep & build management [\#54](https://github.com/python-kasa/python-kasa/pull/54) (@rytilahti) +- Add fixture for KL60 [\#52](https://github.com/python-kasa/python-kasa/pull/52) (@rytilahti) +- Ignore D202 where necessary [\#50](https://github.com/python-kasa/python-kasa/pull/50) (@rytilahti) +- Support wifi scan & join for bulbs using a different interface [\#49](https://github.com/python-kasa/python-kasa/pull/49) (@rytilahti) +- Return on\_since only when its available and the device is on [\#48](https://github.com/python-kasa/python-kasa/pull/48) (@rytilahti) +- Allow 0 brightness for smartdimmer [\#47](https://github.com/python-kasa/python-kasa/pull/47) (@rytilahti) +- async++, small powerstrip improvements [\#46](https://github.com/python-kasa/python-kasa/pull/46) (@rytilahti) +- Check for emeter support on power strips/multiple plug outlets [\#41](https://github.com/python-kasa/python-kasa/pull/41) (@acmay) +- Remove unnecessary cache [\#40](https://github.com/python-kasa/python-kasa/pull/40) (@rytilahti) +- Add in some new device types [\#39](https://github.com/python-kasa/python-kasa/pull/39) (@acmay) +- Add test fixture for KL130 [\#35](https://github.com/python-kasa/python-kasa/pull/35) (@bdraco) +- Move dimmer support to its own class [\#34](https://github.com/python-kasa/python-kasa/pull/34) (@rytilahti) +- Fix azure pipeline badge [\#32](https://github.com/python-kasa/python-kasa/pull/32) (@rytilahti) +- Enable Windows & OSX builds [\#31](https://github.com/python-kasa/python-kasa/pull/31) (@rytilahti) +- Depend on py3.7+ for tox, add python 3.8 to azure pipeline targets [\#29](https://github.com/python-kasa/python-kasa/pull/29) (@rytilahti) +- Add KP303 to the list of powerstrips [\#28](https://github.com/python-kasa/python-kasa/pull/28) (@rytilahti) +- Move child socket handling to its own SmartStripPlug class [\#26](https://github.com/python-kasa/python-kasa/pull/26) (@rytilahti) +- Adding KP303 to supported devices [\#25](https://github.com/python-kasa/python-kasa/pull/25) (@epicalex) +- use pytestmark to avoid repeating asyncio mark [\#24](https://github.com/python-kasa/python-kasa/pull/24) (@rytilahti) +- Cleanup constructors by removing ioloop and protocol arguments [\#23](https://github.com/python-kasa/python-kasa/pull/23) (@rytilahti) +- Add \(some\) tests to the cli tool [\#22](https://github.com/python-kasa/python-kasa/pull/22) (@rytilahti) +- Test against the newly added device fixtures [\#21](https://github.com/python-kasa/python-kasa/pull/21) (@rytilahti) +- move testing reqs to requirements\_test.txt, add pytest-asyncio for pipelines [\#20](https://github.com/python-kasa/python-kasa/pull/20) (@rytilahti) +- Remove unused save option and add scrubbing [\#19](https://github.com/python-kasa/python-kasa/pull/19) (@TheGardenMonkey) +- Add real kasa device dumps [\#18](https://github.com/python-kasa/python-kasa/pull/18) (@TheGardenMonkey) +- Fix dump-discover to use asyncio.run [\#16](https://github.com/python-kasa/python-kasa/pull/16) (@rytilahti) +- Add device\_id property, rename context to child\_id [\#15](https://github.com/python-kasa/python-kasa/pull/15) (@rytilahti) +- Remove sync interface, add asyncio discovery [\#14](https://github.com/python-kasa/python-kasa/pull/14) (@rytilahti) +- Remove --ip which was just an alias to --host [\#6](https://github.com/python-kasa/python-kasa/pull/6) (@rytilahti) +- Set minimum requirement to python 3.7 [\#5](https://github.com/python-kasa/python-kasa/pull/5) (@rytilahti) +- change ID of Azure Pipeline [\#3](https://github.com/python-kasa/python-kasa/pull/3) (@basnijholt) +- Mass rename to \(python-\)kasa [\#1](https://github.com/python-kasa/python-kasa/pull/1) (@rytilahti) Historical pyHS100 changelog ============================ diff --git a/devtools/dump_devinfo.py b/devtools/dump_devinfo.py index 1108e7fb4..2f3c20e01 100644 --- a/devtools/dump_devinfo.py +++ b/devtools/dump_devinfo.py @@ -76,6 +76,8 @@ def cli(host, debug): Call( module="smartlife.iot.smartbulb.lightingservice", method="get_light_state" ), + Call(module="smartlife.iot.LAS", method="get_config"), + Call(module="smartlife.iot.PIR", method="get_config"), ] successes = [] diff --git a/kasa/cli.py b/kasa/cli.py index 9c0b50a2e..696dd9aab 100755 --- a/kasa/cli.py +++ b/kasa/cli.py @@ -1,4 +1,5 @@ """python-kasa cli tool.""" +import asyncio import logging from pprint import pformat as pf from typing import cast @@ -44,17 +45,22 @@ ) @click.option( "--target", + envvar="KASA_TARGET", default="255.255.255.255", required=False, + show_default=True, help="The broadcast address to be used for discovery.", ) -@click.option("-d", "--debug", default=False, is_flag=True) +@click.option("-d", "--debug", envvar="KASA_DEBUG", default=False, is_flag=True) @click.option("--bulb", default=False, is_flag=True) @click.option("--plug", default=False, is_flag=True) @click.option("--lightstrip", default=False, is_flag=True) @click.option("--strip", default=False, is_flag=True) @click.option( - "--type", default=None, type=click.Choice(TYPE_TO_CLASS, case_sensitive=False) + "--type", + envvar="KASA_TYPE", + default=None, + type=click.Choice(TYPE_TO_CLASS, case_sensitive=False), ) @click.version_option(package_name="python-kasa") @click.pass_context @@ -145,24 +151,24 @@ async def join(dev: SmartDevice, ssid, password, keytype): @cli.command() @click.option("--timeout", default=3, required=False) -@click.option("--discover-only", default=False) @click.option("--dump-raw", is_flag=True) @click.pass_context -async def discover(ctx, timeout, discover_only, dump_raw): +async def discover(ctx, timeout, dump_raw): """Discover devices in the network.""" target = ctx.parent.params["target"] click.echo(f"Discovering devices on {target} for {timeout} seconds") - found_devs = await Discover.discover(target=target, timeout=timeout) - if not discover_only: - for ip, dev in found_devs.items(): - if dump_raw: - click.echo(dev.sys_info) - continue + sem = asyncio.Semaphore() + + async def print_discovered(dev: SmartDevice): + await dev.update() + async with sem: ctx.obj = dev await ctx.invoke(state) click.echo() - return found_devs + await Discover.discover( + target=target, timeout=timeout, on_discovered=print_discovered + ) async def find_host_from_alias(alias, target="255.255.255.255", timeout=1, attempts=3): @@ -224,7 +230,6 @@ async def state(ctx, dev: SmartDevice): click.echo(click.style("\n\t== Device specific information ==", bold=True)) for k, v in dev.state_information.items(): click.echo(f"\t{k}: {v}") - click.echo() if dev.has_emeter: click.echo(click.style("\n\t== Current State ==", bold=True)) @@ -366,6 +371,27 @@ async def temperature(dev: SmartBulb, temperature: int, transition: int): return await dev.set_color_temp(temperature, transition=transition) +@cli.command() +@click.argument("effect", type=click.STRING, default=None, required=False) +@click.pass_context +@pass_dev +async def effect(dev, ctx, effect): + """Set an effect.""" + if not dev.has_effects: + click.echo("Device does not support effects") + return + if effect is None: + raise click.BadArgumentUsage( + f"Setting an effect requires a named built-in effect: {dev.effect_list}", + ctx, + ) + if effect not in dev.effect_list: + raise click.BadArgumentUsage(f"Effect must be one of: {dev.effect_list}", ctx) + + click.echo(f"Setting Effect: {effect}") + return await dev.set_effect(effect) + + @cli.command() @click.argument("h", type=click.IntRange(0, 360), default=None, required=False) @click.argument("s", type=click.IntRange(0, 100), default=None, required=False) diff --git a/kasa/effects.py b/kasa/effects.py new file mode 100644 index 000000000..cf72bb8d8 --- /dev/null +++ b/kasa/effects.py @@ -0,0 +1,296 @@ +"""Module for light strip effects (LB*, KL*, KB*).""" + +from typing import List, cast + +EFFECT_AURORA = { + "custom": 0, + "id": "xqUxDhbAhNLqulcuRMyPBmVGyTOyEMEu", + "brightness": 100, + "name": "Aurora", + "segments": [0], + "expansion_strategy": 1, + "enable": 1, + "type": "sequence", + "duration": 0, + "transition": 1500, + "direction": 4, + "spread": 7, + "repeat_times": 0, + "sequence": [[120, 100, 100], [240, 100, 100], [260, 100, 100], [280, 100, 100]], +} +EFFECT_BUBBLING_CAULDRON = { + "custom": 0, + "id": "tIwTRQBqJpeNKbrtBMFCgkdPTbAQGfRP", + "brightness": 100, + "name": "Bubbling Cauldron", + "segments": [0], + "expansion_strategy": 1, + "enable": 1, + "type": "random", + "hue_range": [100, 270], + "saturation_range": [80, 100], + "brightness_range": [50, 100], + "duration": 0, + "transition": 200, + "init_states": [[270, 100, 100]], + "fadeoff": 1000, + "random_seed": 24, + "backgrounds": [[270, 40, 50]], +} +EFFECT_CANDY_CANE = { + "custom": 0, + "id": "HCOttllMkNffeHjEOLEgrFJjbzQHoxEJ", + "brightness": 100, + "name": "Candy Cane", + "segments": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], + "expansion_strategy": 1, + "enable": 1, + "type": "sequence", + "duration": 700, + "transition": 500, + "direction": 1, + "spread": 1, + "repeat_times": 0, + "sequence": [ + [0, 0, 100], + [0, 0, 100], + [360, 81, 100], + [0, 0, 100], + [0, 0, 100], + [360, 81, 100], + [360, 81, 100], + [0, 0, 100], + [0, 0, 100], + [360, 81, 100], + [360, 81, 100], + [360, 81, 100], + [360, 81, 100], + [0, 0, 100], + [0, 0, 100], + [360, 81, 100], + ], +} +EFFECT_CHRISTMAS = { + "custom": 0, + "id": "bwTatyinOUajKrDwzMmqxxJdnInQUgvM", + "brightness": 100, + "name": "Christmas", + "segments": [0], + "expansion_strategy": 1, + "enable": 1, + "type": "random", + "hue_range": [136, 146], + "saturation_range": [90, 100], + "brightness_range": [50, 100], + "duration": 5000, + "transition": 0, + "init_states": [[136, 0, 100]], + "fadeoff": 2000, + "random_seed": 100, + "backgrounds": [[136, 98, 75], [136, 0, 0], [350, 0, 100], [350, 97, 94]], +} +EFFECT_FLICKER = { + "custom": 0, + "id": "bCTItKETDFfrKANolgldxfgOakaarARs", + "brightness": 100, + "name": "Flicker", + "segments": [1], + "expansion_strategy": 1, + "enable": 1, + "type": "random", + "hue_range": [30, 40], + "saturation_range": [100, 100], + "brightness_range": [50, 100], + "duration": 0, + "transition": 0, + "transition_range": [375, 500], + "init_states": [[30, 81, 80]], +} +EFFECT_HANUKKAH = { + "custom": 0, + "id": "CdLeIgiKcQrLKMINRPTMbylATulQewLD", + "brightness": 100, + "name": "Hanukkah", + "segments": [1], + "expansion_strategy": 1, + "enable": 1, + "type": "random", + "hue_range": [200, 210], + "saturation_range": [0, 100], + "brightness_range": [50, 100], + "duration": 1500, + "transition": 0, + "transition_range": [400, 500], + "init_states": [[35, 81, 80]], +} +EFFECT_HAUNTED_MANSION = { + "custom": 0, + "id": "oJnFHsVQzFUTeIOBAhMRfVeujmSauhjJ", + "brightness": 80, + "name": "Haunted Mansion", + "segments": [80], + "expansion_strategy": 2, + "enable": 1, + "type": "random", + "hue_range": [45, 45], + "saturation_range": [10, 10], + "brightness_range": [0, 80], + "duration": 0, + "transition": 0, + "transition_range": [50, 1500], + "init_states": [[45, 10, 100]], + "fadeoff": 200, + "random_seed": 1, + "backgrounds": [[45, 10, 100]], +} +EFFECT_ICICLE = { + "custom": 0, + "id": "joqVjlaTsgzmuQQBAlHRkkPAqkBUiqeb", + "brightness": 70, + "name": "Icicle", + "segments": [0], + "expansion_strategy": 1, + "enable": 1, + "type": "sequence", + "duration": 0, + "transition": 400, + "direction": 4, + "spread": 3, + "repeat_times": 0, + "sequence": [ + [190, 100, 70], + [190, 100, 70], + [190, 30, 50], + [190, 100, 70], + [190, 100, 70], + ], +} +EFFECT_LIGHTNING = { + "custom": 0, + "id": "ojqpUUxdGHoIugGPknrUcRoyJiItsjuE", + "brightness": 100, + "name": "Lightning", + "segments": [7, 20, 23, 32, 34, 35, 49, 65, 66, 74, 80], + "expansion_strategy": 1, + "enable": 1, + "type": "random", + "hue_range": [240, 240], + "saturation_range": [10, 11], + "brightness_range": [90, 100], + "duration": 0, + "transition": 50, + "init_states": [[240, 30, 100]], + "fadeoff": 150, + "random_seed": 600, + "backgrounds": [[200, 100, 100], [200, 50, 10], [210, 10, 50], [240, 10, 0]], +} +EFFECT_OCEAN = { + "custom": 0, + "id": "oJjUMosgEMrdumfPANKbkFmBcAdEQsPy", + "brightness": 30, + "name": "Ocean", + "segments": [0], + "expansion_strategy": 1, + "enable": 1, + "type": "sequence", + "duration": 0, + "transition": 2000, + "direction": 3, + "spread": 16, + "repeat_times": 0, + "sequence": [[198, 84, 30], [198, 70, 30], [198, 10, 30]], +} +EFFECT_RAINBOW = { + "custom": 0, + "id": "izRhLCQNcDzIKdpMPqSTtBMuAIoreAuT", + "brightness": 100, + "name": "Rainbow", + "segments": [0], + "expansion_strategy": 1, + "enable": 1, + "type": "sequence", + "duration": 0, + "transition": 1500, + "direction": 1, + "spread": 12, + "repeat_times": 0, + "sequence": [[0, 100, 100], [100, 100, 100], [200, 100, 100], [300, 100, 100]], +} +EFFECT_RAINDROP = { + "custom": 0, + "id": "QbDFwiSFmLzQenUOPnJrsGqyIVrJrRsl", + "brightness": 30, + "name": "Raindrop", + "segments": [0], + "expansion_strategy": 1, + "enable": 1, + "type": "random", + "hue_range": [200, 200], + "saturation_range": [10, 20], + "brightness_range": [10, 30], + "duration": 0, + "transition": 1000, + "init_states": [[200, 40, 100]], + "fadeoff": 1000, + "random_seed": 24, + "backgrounds": [[200, 40, 0]], +} +EFFECT_SPRING = { + "custom": 0, + "id": "URdUpEdQbnOOechDBPMkKrwhSupLyvAg", + "brightness": 100, + "name": "Spring", + "segments": [0], + "expansion_strategy": 1, + "enable": 1, + "type": "random", + "hue_range": [0, 90], + "saturation_range": [30, 100], + "brightness_range": [90, 100], + "duration": 600, + "transition": 0, + "transition_range": [2000, 6000], + "init_states": [[80, 30, 100]], + "fadeoff": 1000, + "random_seed": 20, + "backgrounds": [[130, 100, 40]], +} +EFFECT_VALENTINES = { + "custom": 0, + "id": "QglBhMShPHUAuxLqzNEefFrGiJwahOmz", + "brightness": 100, + "name": "Valentines", + "segments": [0], + "expansion_strategy": 1, + "enable": 1, + "type": "random", + "hue_range": [340, 340], + "saturation_range": [30, 40], + "brightness_range": [90, 100], + "duration": 600, + "transition": 2000, + "init_states": [[340, 30, 100]], + "fadeoff": 3000, + "random_seed": 100, + "backgrounds": [[340, 20, 50], [20, 50, 50], [0, 100, 50]], +} + +EFFECTS_LIST_V1 = [ + EFFECT_AURORA, + EFFECT_BUBBLING_CAULDRON, + EFFECT_CANDY_CANE, + EFFECT_CHRISTMAS, + EFFECT_FLICKER, + EFFECT_HANUKKAH, + EFFECT_HAUNTED_MANSION, + EFFECT_ICICLE, + EFFECT_LIGHTNING, + EFFECT_OCEAN, + EFFECT_RAINBOW, + EFFECT_RAINDROP, + EFFECT_SPRING, + EFFECT_VALENTINES, +] + +EFFECT_NAMES_V1: List[str] = [cast(str, effect["name"]) for effect in EFFECTS_LIST_V1] +EFFECT_MAPPING_V1 = {effect["name"]: effect for effect in EFFECTS_LIST_V1} diff --git a/kasa/protocol.py b/kasa/protocol.py index 54fea0803..e2f946269 100755 --- a/kasa/protocol.py +++ b/kasa/protocol.py @@ -15,7 +15,7 @@ import logging import struct from pprint import pformat as pf -from typing import Dict, Optional, Union +from typing import Dict, Generator, Optional, Union from .exceptions import SmartDeviceException @@ -107,7 +107,7 @@ async def _execute_query(self, request: str) -> Dict: return json_payload - async def close(self): + async def close(self) -> None: """Close the connection.""" writer = self.writer self.reader = self.writer = None @@ -116,7 +116,7 @@ async def close(self): with contextlib.suppress(Exception): await writer.wait_closed() - def _reset(self): + def _reset(self) -> None: """Clear any varibles that should not survive between loops.""" self.reader = self.writer = self.loop = self.query_lock = None @@ -154,13 +154,17 @@ async def _query(self, request: str, retry_count: int, timeout: int) -> Dict: await self.close() raise SmartDeviceException("Query reached somehow to unreachable") - def __del__(self): + def __del__(self) -> None: if self.writer and self.loop and self.loop.is_running(): - self.writer.close() + # Since __del__ will be called when python does + # garbage collection is can happen in the event loop thread + # or in another thread so we need to make sure the call to + # close is called safely with call_soon_threadsafe + self.loop.call_soon_threadsafe(self.writer.close) self._reset() @staticmethod - def _xor_payload(unencrypted): + def _xor_payload(unencrypted: bytes) -> Generator[int, None, None]: key = TPLinkSmartHomeProtocol.INITIALIZATION_VECTOR for unencryptedbyte in unencrypted: key = key ^ unencryptedbyte @@ -179,7 +183,7 @@ def encrypt(request: str) -> bytes: ) @staticmethod - def _xor_encrypted_payload(ciphertext): + def _xor_encrypted_payload(ciphertext: bytes) -> Generator[int, None, None]: key = TPLinkSmartHomeProtocol.INITIALIZATION_VECTOR for cipherbyte in ciphertext: plainbyte = key ^ cipherbyte diff --git a/kasa/smartbulb.py b/kasa/smartbulb.py index 8ccce15a8..e5dcfbe90 100644 --- a/kasa/smartbulb.py +++ b/kasa/smartbulb.py @@ -172,6 +172,12 @@ def light_state(self) -> Dict[str, str]: return light_state + @property # type: ignore + @requires_update + def has_effects(self) -> bool: + """Return True if the device supports effects.""" + return "lighting_effect_state" in self.sys_info + async def get_light_details(self) -> Dict[str, int]: """Return light details. diff --git a/kasa/smartdevice.py b/kasa/smartdevice.py index fabf26b32..7a66a864d 100755 --- a/kasa/smartdevice.py +++ b/kasa/smartdevice.py @@ -219,6 +219,8 @@ def _verify_emeter(self) -> None: """Raise an exception if there is no emeter.""" if not self.has_emeter: raise SmartDeviceException("Device has no emeter") + if self.emeter_type not in self._last_update: + raise SmartDeviceException("update() required prior accessing emeter") async def _query_helper( self, target: str, cmd: str, arg: Optional[Dict] = None, child_ids=None @@ -260,7 +262,11 @@ async def _query_helper( @requires_update def features(self) -> Set[str]: """Return a set of features that the device supports.""" - return set(self.sys_info["feature"].split(":")) + try: + return set(self.sys_info["feature"].split(":")) + except KeyError: + _LOGGER.debug("Device does not have feature information") + return set() @property # type: ignore @requires_update @@ -598,7 +604,7 @@ def on_since(self) -> Optional[datetime]: on_time = self.sys_info["on_time"] - return datetime.now() - timedelta(seconds=on_time) + return datetime.now().replace(microsecond=0) - timedelta(seconds=on_time) @property # type: ignore @requires_update @@ -719,6 +725,15 @@ def is_color(self) -> bool: """Return True if the device supports color changes.""" return False + @property + def internal_state(self) -> Any: + """Return the internal state of the instance. + + The returned object contains the raw results from the last update call. + This should only be used for debugging purposes. + """ + return self._last_update + def __repr__(self): if self._last_update is None: return f"<{self._device_type} at {self.host} - update() needed>" diff --git a/kasa/smartlightstrip.py b/kasa/smartlightstrip.py index c579fec20..087234538 100644 --- a/kasa/smartlightstrip.py +++ b/kasa/smartlightstrip.py @@ -1,8 +1,9 @@ """Module for light strips (KL430).""" -from typing import Any, Dict +from typing import Any, Dict, List, Optional +from .effects import EFFECT_MAPPING_V1, EFFECT_NAMES_V1 from .smartbulb import SmartBulb -from .smartdevice import DeviceType, requires_update +from .smartdevice import DeviceType, SmartDeviceException, requires_update class SmartLightStrip(SmartBulb): @@ -64,6 +65,16 @@ def effect(self) -> Dict: """ return self.sys_info["lighting_effect_state"] + @property # type: ignore + @requires_update + def effect_list(self) -> Optional[List[str]]: + """Return built-in effects list. + + Example: + ['Aurora', 'Bubbling Cauldron', ...] + """ + return EFFECT_NAMES_V1 if self.has_effects else None + @property # type: ignore @requires_update def state_information(self) -> Dict[str, Any]: @@ -71,5 +82,37 @@ def state_information(self) -> Dict[str, Any]: info = super().state_information info["Length"] = self.length + if self.has_effects: + info["Effect"] = self.effect["name"] return info + + @requires_update + async def set_effect( + self, + effect: str, + ) -> None: + """Set an effect on the device. + + :param str effect: The effect to set + """ + if effect not in EFFECT_MAPPING_V1: + raise SmartDeviceException(f"The effect {effect} is not a built in effect.") + await self.set_custom_effect(EFFECT_MAPPING_V1[effect]) + + @requires_update + async def set_custom_effect( + self, + effect_dict: Dict, + ) -> None: + """Set a custom effect on the device. + + :param str effect_dict: The custom effect dict to set + """ + if not self.has_effects: + raise SmartDeviceException("Bulb does not support effects.") + await self._query_helper( + "smartlife.iot.lighting_effect", + "set_lighting_effect", + effect_dict, + ) diff --git a/kasa/tests/conftest.py b/kasa/tests/conftest.py index 2c1d1e49c..f9fc917f6 100644 --- a/kasa/tests/conftest.py +++ b/kasa/tests/conftest.py @@ -53,7 +53,7 @@ "KP401", } STRIPS = {"HS107", "HS300", "KP303", "KP400", "EP40"} -DIMMERS = {"HS220"} +DIMMERS = {"HS220", "KS220M"} DIMMABLE = {*BULBS, *DIMMERS} WITH_EMETER = {"HS110", "HS300", "KP115", *BULBS} diff --git a/kasa/tests/fixtures/KL400L5(US)_1.0_1.0.8.json b/kasa/tests/fixtures/KL400L5(US)_1.0_1.0.8.json new file mode 100644 index 000000000..a737cd2a1 --- /dev/null +++ b/kasa/tests/fixtures/KL400L5(US)_1.0_1.0.8.json @@ -0,0 +1,57 @@ +{ + "smartlife.iot.common.emeter": { + "get_realtime": { + "err_code": 0, + "power_mw": 10800, + "total_wh": 1 + } + }, + "system": { + "get_sysinfo": { + "LEF": 0, + "active_mode": "none", + "alias": "Kl400", + "ctrl_protocols": { + "name": "Linkie", + "version": "1.0" + }, + "description": "Kasa Smart Light Strip, Multicolor", + "dev_state": "normal", + "deviceId": "0000000000000000000000000000000000000000", + "disco_ver": "1.0", + "err_code": 0, + "hwId": "00000000000000000000000000000000", + "hw_ver": "1.0", + "is_color": 1, + "is_dimmable": 1, + "is_factory": false, + "is_variable_color_temp": 0, + "latitude_i": 0, + "length": 1, + "light_state": { + "brightness": 100, + "color_temp": 6500, + "hue": 0, + "mode": "normal", + "on_off": 1, + "saturation": 0 + }, + "lighting_effect_state": { + "brightness": 100, + "custom": 0, + "enable": 1, + "id": "CdLeIgiKcQrLKMINRPTMbylATulQewLD", + "name": "Hanukkah" + }, + "longitude_i": 0, + "mic_mac": "00:00:00:00:00:00", + "mic_type": "IOT.SMARTBULB", + "model": "KL400L5(US)", + "oemId": "00000000000000000000000000000000", + "preferred_state": [], + "rssi": -44, + "status": "new", + "sw_ver": "1.0.8 Build 211018 Rel.162056" + } + } +} diff --git a/kasa/tests/fixtures/KL430(US)_2.0_1.0.9.json b/kasa/tests/fixtures/KL430(US)_2.0_1.0.9.json new file mode 100644 index 000000000..d5f2eafbc --- /dev/null +++ b/kasa/tests/fixtures/KL430(US)_2.0_1.0.9.json @@ -0,0 +1,57 @@ +{ + "smartlife.iot.common.emeter": { + "get_realtime": { + "err_code": 0, + "power_mw": 11150, + "total_wh": 18 + } + }, + "system": { + "get_sysinfo": { + "LEF": 1, + "active_mode": "none", + "alias": "kl430 updated", + "ctrl_protocols": { + "name": "Linkie", + "version": "1.0" + }, + "description": "Kasa Smart Light Strip, Multicolor", + "dev_state": "normal", + "deviceId": "0000000000000000000000000000000000000000", + "disco_ver": "1.0", + "err_code": 0, + "hwId": "00000000000000000000000000000000", + "hw_ver": "2.0", + "is_color": 1, + "is_dimmable": 1, + "is_factory": false, + "is_variable_color_temp": 1, + "latitude_i": 0, + "length": 16, + "light_state": { + "brightness": 100, + "color_temp": 0, + "hue": 194, + "mode": "normal", + "on_off": 1, + "saturation": 50 + }, + "lighting_effect_state": { + "brightness": 100, + "custom": 0, + "enable": 1, + "id": "izRhLCQNcDzIKdpMPqSTtBMuAIoreAuT", + "name": "Rainbow" + }, + "longitude_i": 0, + "mic_mac": "00:00:00:00:00:00", + "mic_type": "IOT.SMARTBULB", + "model": "KL430(US)", + "oemId": "00000000000000000000000000000000", + "preferred_state": [], + "rssi": -58, + "status": "new", + "sw_ver": "1.0.9 Build 210915 Rel.170534" + } + } +} diff --git a/kasa/tests/fixtures/KS220M(US)_1.0_1.0.4.json b/kasa/tests/fixtures/KS220M(US)_1.0_1.0.4.json new file mode 100644 index 000000000..40da46fdd --- /dev/null +++ b/kasa/tests/fixtures/KS220M(US)_1.0_1.0.4.json @@ -0,0 +1,126 @@ +{ + "smartlife.iot.LAS": { + "get_config": { + "devs": [ + { + "dark_index": 0, + "enable": 1, + "hw_id": 0, + "level_array": [ + { + "adc": 490, + "name": "cloudy", + "value": 20 + }, + { + "adc": 294, + "name": "overcast", + "value": 12 + }, + { + "adc": 222, + "name": "dawn", + "value": 9 + }, + { + "adc": 222, + "name": "twilight", + "value": 9 + }, + { + "adc": 111, + "name": "total darkness", + "value": 4 + }, + { + "adc": 2400, + "name": "custom", + "value": 97 + } + ], + "max_adc": 2450, + "min_adc": 0 + } + ], + "err_code": 0, + "ver": "1.0" + } + }, + "smartlife.iot.PIR": { + "get_config": { + "array": [ + 80, + 50, + 20, + 61 + ], + "cold_time": 60000, + "enable": 1, + "err_code": 0, + "max_adc": 4095, + "min_adc": 0, + "trigger_index": 2, + "version": "1.0" + } + }, + "smartlife.iot.dimmer": { + "get_dimmer_parameters": { + "bulb_type": 1, + "err_code": 0, + "fadeOffTime": 0, + "fadeOnTime": 0, + "gentleOffTime": 10000, + "gentleOnTime": 3000, + "minThreshold": 1, + "rampRate": 30 + } + }, + "system": { + "get_sysinfo": { + "active_mode": "none", + "alias": "Garage Entryway Lights", + "brightness": 100, + "dev_name": "Wi-Fi Smart Dimmer with sensor", + "deviceId": "0000000000000000000000000000000000000000", + "err_code": 0, + "feature": "TIM", + "hwId": "00000000000000000000000000000000", + "hw_ver": "1.0", + "icon_hash": "", + "latitude_i": 0, + "led_off": 0, + "longitude_i": 0, + "mac": "00:00:00:00:00:00", + "mic_type": "IOT.SMARTPLUGSWITCH", + "model": "KS220M(US)", + "next_action": { + "type": -1 + }, + "oemId": "00000000000000000000000000000000", + "on_time": 0, + "preferred_state": [ + { + "brightness": 100, + "index": 0 + }, + { + "brightness": 75, + "index": 1 + }, + { + "brightness": 50, + "index": 2 + }, + { + "brightness": 25, + "index": 3 + } + ], + "relay_state": 0, + "rssi": -42, + "status": "new", + "sw_ver": "1.0.4 Build 210616 Rel.193517", + "updating": 0 + } + } +} diff --git a/kasa/tests/newfakes.py b/kasa/tests/newfakes.py index 2afae2aa3..904d45c79 100644 --- a/kasa/tests/newfakes.py +++ b/kasa/tests/newfakes.py @@ -359,6 +359,10 @@ def set_hs220_dimmer_transition(self, x, *args): self.proto["system"]["get_sysinfo"]["relay_state"] = 1 self.proto["system"]["get_sysinfo"]["brightness"] = x["brightness"] + def set_lighting_effect(self, effect, *args): + _LOGGER.debug("Setting light effect to %s", effect) + self.proto["system"]["get_sysinfo"]["lighting_effect_state"] = dict(effect) + def transition_light_state(self, state_changes, *args): _LOGGER.debug("Setting light state to %s", state_changes) light_state = self.proto["system"]["get_sysinfo"]["light_state"] @@ -422,6 +426,9 @@ def light_state(self, x, *args): "get_light_state": light_state, "transition_light_state": transition_light_state, }, + "smartlife.iot.lighting_effect": { + "set_lighting_effect": set_lighting_effect, + }, # lightstrip follows the same payloads but uses different module & method "smartlife.iot.lightStrip": { "set_light_state": transition_light_state, @@ -437,6 +444,8 @@ def light_state(self, x, *args): "set_brightness": set_hs220_brightness, "set_dimmer_transition": set_hs220_dimmer_transition, }, + "smartlife.iot.LAS": {}, + "smartlife.iot.PIR": {}, } async def query(self, request, port=9999): diff --git a/kasa/tests/test_lightstrip.py b/kasa/tests/test_lightstrip.py index 7a8d8726a..e53bb1f76 100644 --- a/kasa/tests/test_lightstrip.py +++ b/kasa/tests/test_lightstrip.py @@ -1,4 +1,7 @@ +import pytest + from kasa import DeviceType, SmartLightStrip +from kasa.exceptions import SmartDeviceException from .conftest import lightstrip, pytestmark @@ -15,3 +18,19 @@ async def test_lightstrip_effect(dev: SmartLightStrip): assert isinstance(dev.effect, dict) for k in ["brightness", "custom", "enable", "id", "name"]: assert k in dev.effect + + +@lightstrip +async def test_effects_lightstrip_set_effect(dev: SmartLightStrip): + with pytest.raises(SmartDeviceException): + await dev.set_effect("Not real") + + await dev.set_effect("Candy Cane") + assert dev.effect["name"] == "Candy Cane" + assert dev.state_information["Effect"] == "Candy Cane" + + +@lightstrip +async def test_effects_lightstrip_has_effects(dev: SmartLightStrip): + assert dev.has_effects is True + assert dev.effect_list diff --git a/kasa/tests/test_smartdevice.py b/kasa/tests/test_smartdevice.py index 380cdd1fb..d977daeb3 100644 --- a/kasa/tests/test_smartdevice.py +++ b/kasa/tests/test_smartdevice.py @@ -134,3 +134,17 @@ async def test_childrens(dev): assert len(dev.children) > 0 else: assert len(dev.children) == 0 + + +async def test_internal_state(dev): + """Make sure the internal state returns the last update results.""" + assert dev.internal_state == dev._last_update + + +async def test_features(dev): + """Make sure features is always accessible.""" + sysinfo = dev._last_update["system"]["get_sysinfo"] + if "feature" in sysinfo: + assert dev.features == set(sysinfo["feature"].split(":")) + else: + assert dev.features == set() diff --git a/poetry.lock b/poetry.lock index 88d46723e..d3af30c3f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -26,7 +26,7 @@ trio = ["trio (>=0.16)"] [[package]] name = "asyncclick" -version = "8.0.3.1" +version = "8.0.3.2" description = "Composable command line interface toolkit, async version" category = "main" optional = false @@ -87,7 +87,7 @@ python-versions = ">=3.6.1" [[package]] name = "charset-normalizer" -version = "2.0.10" +version = "2.0.12" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "main" optional = false @@ -118,11 +118,11 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "coverage" -version = "6.2" +version = "6.3.2" description = "Code coverage measurement for Python" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] tomli = {version = "*", optional = true, markers = "extra == \"toml\""} @@ -148,7 +148,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "filelock" -version = "3.4.2" +version = "3.6.0" description = "A platform independent file lock." category = "dev" optional = false @@ -160,11 +160,11 @@ testing = ["covdefaults (>=1.2.0)", "coverage (>=4)", "pytest (>=4)", "pytest-co [[package]] name = "identify" -version = "2.4.4" +version = "2.4.12" description = "File identification library for Python" category = "dev" optional = false -python-versions = ">=3.6.1" +python-versions = ">=3.7" [package.extras] license = ["ukkonen"] @@ -187,7 +187,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "importlib-metadata" -version = "4.10.0" +version = "4.11.3" description = "Read metadata from Python packages" category = "main" optional = false @@ -198,9 +198,9 @@ typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"] perf = ["ipython"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"] [[package]] name = "iniconfig" @@ -238,11 +238,11 @@ mistune = "*" [[package]] name = "markupsafe" -version = "2.0.1" +version = "2.1.1" description = "Safely add untrusted strings to HTML/XML markup." category = "main" optional = true -python-versions = ">=3.6" +python-versions = ">=3.7" [[package]] name = "mistune" @@ -273,7 +273,7 @@ pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" [[package]] name = "platformdirs" -version = "2.4.1" +version = "2.5.1" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false @@ -300,7 +300,7 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pre-commit" -version = "2.16.0" +version = "2.17.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." category = "dev" optional = false @@ -333,7 +333,7 @@ python-versions = ">=3.5" [[package]] name = "pyparsing" -version = "3.0.6" +version = "3.0.7" description = "Python parsing module" category = "main" optional = false @@ -344,11 +344,11 @@ diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pytest" -version = "6.2.5" +version = "7.1.1" description = "pytest: simple powerful testing with Python" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} @@ -359,24 +359,25 @@ iniconfig = "*" packaging = "*" pluggy = ">=0.12,<2.0" py = ">=1.8.2" -toml = "*" +tomli = ">=1.0.0" [package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] [[package]] name = "pytest-asyncio" -version = "0.17.0" +version = "0.18.2" description = "Pytest support for asyncio" category = "dev" optional = false python-versions = ">=3.7" [package.dependencies] -pytest = ">=5.4.0" +pytest = ">=6.1.0" +typing-extensions = {version = ">=3.7.2", markers = "python_version < \"3.8\""} [package.extras] -testing = ["coverage (==6.2)", "hypothesis (>=5.7.1)", "flaky (>=3.5.0)"] +testing = ["coverage (==6.2)", "hypothesis (>=5.7.1)", "flaky (>=3.5.0)", "mypy (==0.931)"] [[package]] name = "pytest-cov" @@ -396,11 +397,11 @@ testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtuale [[package]] name = "pytest-mock" -version = "3.6.1" +version = "3.7.0" description = "Thin-wrapper around the mock package for easier use with pytest" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] pytest = ">=5.0" @@ -423,7 +424,7 @@ termcolor = ">=1.1.0" [[package]] name = "pytz" -version = "2021.3" +version = "2022.1" description = "World timezone definitions, modern and historical" category = "main" optional = true @@ -625,7 +626,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "tomli" -version = "2.0.0" +version = "2.0.1" description = "A lil' TOML parser" category = "dev" optional = false @@ -656,7 +657,7 @@ testing = ["flaky (>=3.4.0)", "freezegun (>=0.3.11)", "pytest (>=4.0.0)", "pytes [[package]] name = "typing-extensions" -version = "4.0.1" +version = "4.1.1" description = "Backported and Experimental Type Hints for Python 3.6+" category = "main" optional = false @@ -664,20 +665,20 @@ python-versions = ">=3.6" [[package]] name = "urllib3" -version = "1.26.8" +version = "1.26.9" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" [package.extras] -brotli = ["brotlipy (>=0.6.0)"] +brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "virtualenv" -version = "20.13.0" +version = "20.13.4" description = "Virtual Python Environment builder" category = "dev" optional = false @@ -738,7 +739,7 @@ docs = ["sphinx", "sphinx_rtd_theme", "m2r", "mistune", "sphinxcontrib-programou [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "e4ae6318d9d43109a5f6f0c8f3e6f233bb353f8945665a7cca2a1ddea6a705bf" +content-hash = "9c4aaea750c8c2cb4ed6d37c53ec3884a10d698ceb77716c33b04eed12a08506" [metadata.files] alabaster = [ @@ -750,7 +751,7 @@ anyio = [ {file = "anyio-3.5.0.tar.gz", hash = "sha256:a0aeffe2fb1fdf374a8e4b471444f0f3ac4fb9f5a5b542b48824475e0042a5a6"}, ] asyncclick = [ - {file = "asyncclick-8.0.3.1.tar.gz", hash = "sha256:564bdb9e90c8ec06e535db10068624644b4ad76ff723ead1b7e1755d6b4a6c32"}, + {file = "asyncclick-8.0.3.2.tar.gz", hash = "sha256:251030d8497c139a09d51f8c4b9b8c261a2be0b7d5722f1b7916cc6770368684"}, ] atomicwrites = [ {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, @@ -773,8 +774,8 @@ cfgv = [ {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, ] charset-normalizer = [ - {file = "charset-normalizer-2.0.10.tar.gz", hash = "sha256:876d180e9d7432c5d1dfd4c5d26b72f099d503e8fcc0feb7532c9289be60fcbd"}, - {file = "charset_normalizer-2.0.10-py3-none-any.whl", hash = "sha256:cb957888737fc0bbcd78e3df769addb41fd1ff8cf950dc9e7ad7793f1bf44455"}, + {file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"}, + {file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"}, ] codecov = [ {file = "codecov-2.1.12-py2.py3-none-any.whl", hash = "sha256:585dc217dc3d8185198ceb402f85d5cb5dbfa0c5f350a5abcdf9e347776a5b47"}, @@ -786,53 +787,47 @@ colorama = [ {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] coverage = [ - {file = "coverage-6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6dbc1536e105adda7a6312c778f15aaabe583b0e9a0b0a324990334fd458c94b"}, - {file = "coverage-6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:174cf9b4bef0db2e8244f82059a5a72bd47e1d40e71c68ab055425172b16b7d0"}, - {file = "coverage-6.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:92b8c845527eae547a2a6617d336adc56394050c3ed8a6918683646328fbb6da"}, - {file = "coverage-6.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c7912d1526299cb04c88288e148c6c87c0df600eca76efd99d84396cfe00ef1d"}, - {file = "coverage-6.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5d2033d5db1d58ae2d62f095e1aefb6988af65b4b12cb8987af409587cc0739"}, - {file = "coverage-6.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3feac4084291642165c3a0d9eaebedf19ffa505016c4d3db15bfe235718d4971"}, - {file = "coverage-6.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:276651978c94a8c5672ea60a2656e95a3cce2a3f31e9fb2d5ebd4c215d095840"}, - {file = "coverage-6.2-cp310-cp310-win32.whl", hash = "sha256:f506af4f27def639ba45789fa6fde45f9a217da0be05f8910458e4557eed020c"}, - {file = "coverage-6.2-cp310-cp310-win_amd64.whl", hash = "sha256:3f7c17209eef285c86f819ff04a6d4cbee9b33ef05cbcaae4c0b4e8e06b3ec8f"}, - {file = "coverage-6.2-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:13362889b2d46e8d9f97c421539c97c963e34031ab0cb89e8ca83a10cc71ac76"}, - {file = "coverage-6.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:22e60a3ca5acba37d1d4a2ee66e051f5b0e1b9ac950b5b0cf4aa5366eda41d47"}, - {file = "coverage-6.2-cp311-cp311-win_amd64.whl", hash = "sha256:b637c57fdb8be84e91fac60d9325a66a5981f8086c954ea2772efe28425eaf64"}, - {file = "coverage-6.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f467bbb837691ab5a8ca359199d3429a11a01e6dfb3d9dcc676dc035ca93c0a9"}, - {file = "coverage-6.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2641f803ee9f95b1f387f3e8f3bf28d83d9b69a39e9911e5bfee832bea75240d"}, - {file = "coverage-6.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1219d760ccfafc03c0822ae2e06e3b1248a8e6d1a70928966bafc6838d3c9e48"}, - {file = "coverage-6.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9a2b5b52be0a8626fcbffd7e689781bf8c2ac01613e77feda93d96184949a98e"}, - {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8e2c35a4c1f269704e90888e56f794e2d9c0262fb0c1b1c8c4ee44d9b9e77b5d"}, - {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:5d6b09c972ce9200264c35a1d53d43ca55ef61836d9ec60f0d44273a31aa9f17"}, - {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e3db840a4dee542e37e09f30859f1612da90e1c5239a6a2498c473183a50e781"}, - {file = "coverage-6.2-cp36-cp36m-win32.whl", hash = "sha256:4e547122ca2d244f7c090fe3f4b5a5861255ff66b7ab6d98f44a0222aaf8671a"}, - {file = "coverage-6.2-cp36-cp36m-win_amd64.whl", hash = "sha256:01774a2c2c729619760320270e42cd9e797427ecfddd32c2a7b639cdc481f3c0"}, - {file = "coverage-6.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fb8b8ee99b3fffe4fd86f4c81b35a6bf7e4462cba019997af2fe679365db0c49"}, - {file = "coverage-6.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:619346d57c7126ae49ac95b11b0dc8e36c1dd49d148477461bb66c8cf13bb521"}, - {file = "coverage-6.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0a7726f74ff63f41e95ed3a89fef002916c828bb5fcae83b505b49d81a066884"}, - {file = "coverage-6.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cfd9386c1d6f13b37e05a91a8583e802f8059bebfccde61a418c5808dea6bbfa"}, - {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:17e6c11038d4ed6e8af1407d9e89a2904d573be29d51515f14262d7f10ef0a64"}, - {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c254b03032d5a06de049ce8bca8338a5185f07fb76600afff3c161e053d88617"}, - {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:dca38a21e4423f3edb821292e97cec7ad38086f84313462098568baedf4331f8"}, - {file = "coverage-6.2-cp37-cp37m-win32.whl", hash = "sha256:600617008aa82032ddeace2535626d1bc212dfff32b43989539deda63b3f36e4"}, - {file = "coverage-6.2-cp37-cp37m-win_amd64.whl", hash = "sha256:bf154ba7ee2fd613eb541c2bc03d3d9ac667080a737449d1a3fb342740eb1a74"}, - {file = "coverage-6.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f9afb5b746781fc2abce26193d1c817b7eb0e11459510fba65d2bd77fe161d9e"}, - {file = "coverage-6.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edcada2e24ed68f019175c2b2af2a8b481d3d084798b8c20d15d34f5c733fa58"}, - {file = "coverage-6.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a9c8c4283e17690ff1a7427123ffb428ad6a52ed720d550e299e8291e33184dc"}, - {file = "coverage-6.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f614fc9956d76d8a88a88bb41ddc12709caa755666f580af3a688899721efecd"}, - {file = "coverage-6.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9365ed5cce5d0cf2c10afc6add145c5037d3148585b8ae0e77cc1efdd6aa2953"}, - {file = "coverage-6.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8bdfe9ff3a4ea37d17f172ac0dff1e1c383aec17a636b9b35906babc9f0f5475"}, - {file = "coverage-6.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:63c424e6f5b4ab1cf1e23a43b12f542b0ec2e54f99ec9f11b75382152981df57"}, - {file = "coverage-6.2-cp38-cp38-win32.whl", hash = "sha256:49dbff64961bc9bdd2289a2bda6a3a5a331964ba5497f694e2cbd540d656dc1c"}, - {file = "coverage-6.2-cp38-cp38-win_amd64.whl", hash = "sha256:9a29311bd6429be317c1f3fe4bc06c4c5ee45e2fa61b2a19d4d1d6111cb94af2"}, - {file = "coverage-6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03b20e52b7d31be571c9c06b74746746d4eb82fc260e594dc662ed48145e9efd"}, - {file = "coverage-6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:215f8afcc02a24c2d9a10d3790b21054b58d71f4b3c6f055d4bb1b15cecce685"}, - {file = "coverage-6.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a4bdeb0a52d1d04123b41d90a4390b096f3ef38eee35e11f0b22c2d031222c6c"}, - {file = "coverage-6.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c332d8f8d448ded473b97fefe4a0983265af21917d8b0cdcb8bb06b2afe632c3"}, - {file = "coverage-6.2-cp39-cp39-win32.whl", hash = "sha256:6e1394d24d5938e561fbeaa0cd3d356207579c28bd1792f25a068743f2d5b282"}, - {file = "coverage-6.2-cp39-cp39-win_amd64.whl", hash = "sha256:86f2e78b1eff847609b1ca8050c9e1fa3bd44ce755b2ec30e70f2d3ba3844644"}, - {file = "coverage-6.2-pp36.pp37.pp38-none-any.whl", hash = "sha256:5829192582c0ec8ca4a2532407bc14c2f338d9878a10442f5d03804a95fac9de"}, - {file = "coverage-6.2.tar.gz", hash = "sha256:e2cad8093172b7d1595b4ad66f24270808658e11acf43a8f95b41276162eb5b8"}, + {file = "coverage-6.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9b27d894748475fa858f9597c0ee1d4829f44683f3813633aaf94b19cb5453cf"}, + {file = "coverage-6.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37d1141ad6b2466a7b53a22e08fe76994c2d35a5b6b469590424a9953155afac"}, + {file = "coverage-6.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9987b0354b06d4df0f4d3e0ec1ae76d7ce7cbca9a2f98c25041eb79eec766f1"}, + {file = "coverage-6.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:26e2deacd414fc2f97dd9f7676ee3eaecd299ca751412d89f40bc01557a6b1b4"}, + {file = "coverage-6.3.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4dd8bafa458b5c7d061540f1ee9f18025a68e2d8471b3e858a9dad47c8d41903"}, + {file = "coverage-6.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:46191097ebc381fbf89bdce207a6c107ac4ec0890d8d20f3360345ff5976155c"}, + {file = "coverage-6.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6f89d05e028d274ce4fa1a86887b071ae1755082ef94a6740238cd7a8178804f"}, + {file = "coverage-6.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:58303469e9a272b4abdb9e302a780072c0633cdcc0165db7eec0f9e32f901e05"}, + {file = "coverage-6.3.2-cp310-cp310-win32.whl", hash = "sha256:2fea046bfb455510e05be95e879f0e768d45c10c11509e20e06d8fcaa31d9e39"}, + {file = "coverage-6.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:a2a8b8bcc399edb4347a5ca8b9b87e7524c0967b335fbb08a83c8421489ddee1"}, + {file = "coverage-6.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f1555ea6d6da108e1999b2463ea1003fe03f29213e459145e70edbaf3e004aaa"}, + {file = "coverage-6.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5f4e1edcf57ce94e5475fe09e5afa3e3145081318e5fd1a43a6b4539a97e518"}, + {file = "coverage-6.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a15dc0a14008f1da3d1ebd44bdda3e357dbabdf5a0b5034d38fcde0b5c234b7"}, + {file = "coverage-6.3.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21b7745788866028adeb1e0eca3bf1101109e2dc58456cb49d2d9b99a8c516e6"}, + {file = "coverage-6.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8ce257cac556cb03be4a248d92ed36904a59a4a5ff55a994e92214cde15c5bad"}, + {file = "coverage-6.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b0be84e5a6209858a1d3e8d1806c46214e867ce1b0fd32e4ea03f4bd8b2e3359"}, + {file = "coverage-6.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:acf53bc2cf7282ab9b8ba346746afe703474004d9e566ad164c91a7a59f188a4"}, + {file = "coverage-6.3.2-cp37-cp37m-win32.whl", hash = "sha256:8bdde1177f2311ee552f47ae6e5aa7750c0e3291ca6b75f71f7ffe1f1dab3dca"}, + {file = "coverage-6.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:b31651d018b23ec463e95cf10070d0b2c548aa950a03d0b559eaa11c7e5a6fa3"}, + {file = "coverage-6.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:07e6db90cd9686c767dcc593dff16c8c09f9814f5e9c51034066cad3373b914d"}, + {file = "coverage-6.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2c6dbb42f3ad25760010c45191e9757e7dce981cbfb90e42feef301d71540059"}, + {file = "coverage-6.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c76aeef1b95aff3905fb2ae2d96e319caca5b76fa41d3470b19d4e4a3a313512"}, + {file = "coverage-6.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cf5cfcb1521dc3255d845d9dca3ff204b3229401994ef8d1984b32746bb45ca"}, + {file = "coverage-6.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fbbdc8d55990eac1b0919ca69eb5a988a802b854488c34b8f37f3e2025fa90d"}, + {file = "coverage-6.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ec6bc7fe73a938933d4178c9b23c4e0568e43e220aef9472c4f6044bfc6dd0f0"}, + {file = "coverage-6.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9baff2a45ae1f17c8078452e9e5962e518eab705e50a0aa8083733ea7d45f3a6"}, + {file = "coverage-6.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd9e830e9d8d89b20ab1e5af09b32d33e1a08ef4c4e14411e559556fd788e6b2"}, + {file = "coverage-6.3.2-cp38-cp38-win32.whl", hash = "sha256:f7331dbf301b7289013175087636bbaf5b2405e57259dd2c42fdcc9fcc47325e"}, + {file = "coverage-6.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:68353fe7cdf91f109fc7d474461b46e7f1f14e533e911a2a2cbb8b0fc8613cf1"}, + {file = "coverage-6.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b78e5afb39941572209f71866aa0b206c12f0109835aa0d601e41552f9b3e620"}, + {file = "coverage-6.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4e21876082ed887baed0146fe222f861b5815455ada3b33b890f4105d806128d"}, + {file = "coverage-6.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34626a7eee2a3da12af0507780bb51eb52dca0e1751fd1471d0810539cefb536"}, + {file = "coverage-6.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1ebf730d2381158ecf3dfd4453fbca0613e16eaa547b4170e2450c9707665ce7"}, + {file = "coverage-6.3.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd6fe30bd519694b356cbfcaca9bd5c1737cddd20778c6a581ae20dc8c04def2"}, + {file = "coverage-6.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:96f8a1cb43ca1422f36492bebe63312d396491a9165ed3b9231e778d43a7fca4"}, + {file = "coverage-6.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:dd035edafefee4d573140a76fdc785dc38829fe5a455c4bb12bac8c20cfc3d69"}, + {file = "coverage-6.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ca5aeb4344b30d0bec47481536b8ba1181d50dbe783b0e4ad03c95dc1296684"}, + {file = "coverage-6.3.2-cp39-cp39-win32.whl", hash = "sha256:f5fa5803f47e095d7ad8443d28b01d48c0359484fec1b9d8606d0e3282084bc4"}, + {file = "coverage-6.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:9548f10d8be799551eb3a9c74bbf2b4934ddb330e08a73320123c07f95cc2d92"}, + {file = "coverage-6.3.2-pp36.pp37.pp38-none-any.whl", hash = "sha256:18d520c6860515a771708937d2f78f63cc47ab3b80cb78e86573b0a760161faf"}, + {file = "coverage-6.3.2.tar.gz", hash = "sha256:03e2a7826086b91ef345ff18742ee9fc47a6839ccd517061ef8fa1976e652ce9"}, ] distlib = [ {file = "distlib-0.3.4-py2.py3-none-any.whl", hash = "sha256:6564fe0a8f51e734df6333d08b8b94d4ea8ee6b99b5ed50613f731fd4089f34b"}, @@ -843,12 +838,12 @@ docutils = [ {file = "docutils-0.16.tar.gz", hash = "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"}, ] filelock = [ - {file = "filelock-3.4.2-py3-none-any.whl", hash = "sha256:cf0fc6a2f8d26bd900f19bf33915ca70ba4dd8c56903eeb14e1e7a2fd7590146"}, - {file = "filelock-3.4.2.tar.gz", hash = "sha256:38b4f4c989f9d06d44524df1b24bd19e167d851f19b50bf3e3559952dddc5b80"}, + {file = "filelock-3.6.0-py3-none-any.whl", hash = "sha256:f8314284bfffbdcfa0ff3d7992b023d4c628ced6feb957351d4c48d059f56bc0"}, + {file = "filelock-3.6.0.tar.gz", hash = "sha256:9cd540a9352e432c7246a48fe4e8712b10acb1df2ad1f30e8c070b82ae1fed85"}, ] identify = [ - {file = "identify-2.4.4-py2.py3-none-any.whl", hash = "sha256:aa68609c7454dbcaae60a01ff6b8df1de9b39fe6e50b1f6107ec81dcda624aa6"}, - {file = "identify-2.4.4.tar.gz", hash = "sha256:6b4b5031f69c48bf93a646b90de9b381c6b5f560df4cbe0ed3cf7650ae741e4d"}, + {file = "identify-2.4.12-py2.py3-none-any.whl", hash = "sha256:5f06b14366bd1facb88b00540a1de05b69b310cbc2654db3c7e07fa3a4339323"}, + {file = "identify-2.4.12.tar.gz", hash = "sha256:3f3244a559290e7d3deb9e9adc7b33594c1bc85a9dd82e0f1be519bf12a1ec17"}, ] idna = [ {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, @@ -859,8 +854,8 @@ imagesize = [ {file = "imagesize-1.3.0.tar.gz", hash = "sha256:cd1750d452385ca327479d45b64d9c7729ecf0b3969a58148298c77092261f9d"}, ] importlib-metadata = [ - {file = "importlib_metadata-4.10.0-py3-none-any.whl", hash = "sha256:b7cf7d3fef75f1e4c80a96ca660efbd51473d7e8f39b5ab9210febc7809012a4"}, - {file = "importlib_metadata-4.10.0.tar.gz", hash = "sha256:92a8b58ce734b2a4494878e0ecf7d79ccd7a128b5fc6014c401e0b61f006f0f6"}, + {file = "importlib_metadata-4.11.3-py3-none-any.whl", hash = "sha256:1208431ca90a8cca1a6b8af391bb53c1a2db74e5d1cef6ddced95d4b2062edc6"}, + {file = "importlib_metadata-4.11.3.tar.gz", hash = "sha256:ea4c597ebf37142f827b8f39299579e31685c31d3a438b59f469406afd0f2539"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, @@ -874,40 +869,46 @@ m2r = [ {file = "m2r-0.2.1.tar.gz", hash = "sha256:bf90bad66cda1164b17e5ba4a037806d2443f2a4d5ddc9f6a5554a0322aaed99"}, ] markupsafe = [ - {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, - {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, + {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, ] mistune = [ {file = "mistune-0.8.4-py2.py3-none-any.whl", hash = "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4"}, @@ -922,16 +923,16 @@ packaging = [ {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, ] platformdirs = [ - {file = "platformdirs-2.4.1-py3-none-any.whl", hash = "sha256:1d7385c7db91728b83efd0ca99a5afb296cab9d0ed8313a45ed8ba17967ecfca"}, - {file = "platformdirs-2.4.1.tar.gz", hash = "sha256:440633ddfebcc36264232365d7840a970e75e1018d15b4327d11f91909045fda"}, + {file = "platformdirs-2.5.1-py3-none-any.whl", hash = "sha256:bcae7cab893c2d310a711b70b24efb93334febe65f8de776ee320b517471e227"}, + {file = "platformdirs-2.5.1.tar.gz", hash = "sha256:7535e70dfa32e84d4b34996ea99c5e432fa29a708d0f4e394bbcb2a8faa4f16d"}, ] pluggy = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] pre-commit = [ - {file = "pre_commit-2.16.0-py2.py3-none-any.whl", hash = "sha256:758d1dc9b62c2ed8881585c254976d66eae0889919ab9b859064fc2fe3c7743e"}, - {file = "pre_commit-2.16.0.tar.gz", hash = "sha256:fe9897cac830aa7164dbd02a4e7b90cae49630451ce88464bca73db486ba9f65"}, + {file = "pre_commit-2.17.0-py2.py3-none-any.whl", hash = "sha256:725fa7459782d7bec5ead072810e47351de01709be838c2ce1726b9591dad616"}, + {file = "pre_commit-2.17.0.tar.gz", hash = "sha256:c1a8040ff15ad3d648c70cc3e55b93e4d2d5b687320955505587fd79bbaed06a"}, ] py = [ {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, @@ -942,31 +943,31 @@ pygments = [ {file = "Pygments-2.11.2.tar.gz", hash = "sha256:4e426f72023d88d03b2fa258de560726ce890ff3b630f88c21cbb8b2503b8c6a"}, ] pyparsing = [ - {file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"}, - {file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"}, + {file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"}, + {file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"}, ] pytest = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, + {file = "pytest-7.1.1-py3-none-any.whl", hash = "sha256:92f723789a8fdd7180b6b06483874feca4c48a5c76968e03bb3e7f806a1869ea"}, + {file = "pytest-7.1.1.tar.gz", hash = "sha256:841132caef6b1ad17a9afde46dc4f6cfa59a05f9555aae5151f73bdf2820ca63"}, ] pytest-asyncio = [ - {file = "pytest-asyncio-0.17.0.tar.gz", hash = "sha256:c98e0e04ae5910bbcc219f52bdf871bd1d392f624ef77c49c236613c0b6d8ee1"}, - {file = "pytest_asyncio-0.17.0-py3-none-any.whl", hash = "sha256:b41c3ff0ec5b5b144459aa1c53a866f67278177f6d4f3ef6874bd864fc82834d"}, + {file = "pytest-asyncio-0.18.2.tar.gz", hash = "sha256:fc8e4190f33fee7797cc7f1829f46a82c213f088af5d1bb5d4e454fe87e6cdc2"}, + {file = "pytest_asyncio-0.18.2-py3-none-any.whl", hash = "sha256:20db0bdd3d7581b2e11f5858a5d9541f2db9cd8c5853786f94ad273d466c8c6d"}, ] pytest-cov = [ {file = "pytest-cov-2.12.1.tar.gz", hash = "sha256:261ceeb8c227b726249b376b8526b600f38667ee314f910353fa318caa01f4d7"}, {file = "pytest_cov-2.12.1-py2.py3-none-any.whl", hash = "sha256:261bb9e47e65bd099c89c3edf92972865210c36813f80ede5277dceb77a4a62a"}, ] pytest-mock = [ - {file = "pytest-mock-3.6.1.tar.gz", hash = "sha256:40217a058c52a63f1042f0784f62009e976ba824c418cced42e88d5f40ab0e62"}, - {file = "pytest_mock-3.6.1-py3-none-any.whl", hash = "sha256:30c2f2cc9759e76eee674b81ea28c9f0b94f8f0445a1b87762cadf774f0df7e3"}, + {file = "pytest-mock-3.7.0.tar.gz", hash = "sha256:5112bd92cc9f186ee96e1a92efc84969ea494939c3aead39c50f421c4cc69534"}, + {file = "pytest_mock-3.7.0-py3-none-any.whl", hash = "sha256:6cff27cec936bf81dc5ee87f07132b807bcda51106b5ec4b90a04331cba76231"}, ] pytest-sugar = [ {file = "pytest-sugar-0.9.4.tar.gz", hash = "sha256:b1b2186b0a72aada6859bea2a5764145e3aaa2c1cfbb23c3a19b5f7b697563d3"}, ] pytz = [ - {file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"}, - {file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"}, + {file = "pytz-2022.1-py2.py3-none-any.whl", hash = "sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c"}, + {file = "pytz-2022.1.tar.gz", hash = "sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7"}, ] pyyaml = [ {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, @@ -1063,24 +1064,24 @@ toml = [ {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] tomli = [ - {file = "tomli-2.0.0-py3-none-any.whl", hash = "sha256:b5bde28da1fed24b9bd1d4d2b8cba62300bfb4ec9a6187a957e8ddb9434c5224"}, - {file = "tomli-2.0.0.tar.gz", hash = "sha256:c292c34f58502a1eb2bbb9f5bbc9a5ebc37bee10ffb8c2d6bbdfa8eb13cc14e1"}, + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] tox = [ {file = "tox-3.24.5-py2.py3-none-any.whl", hash = "sha256:be3362472a33094bce26727f5f771ca0facf6dafa217f65875314e9a6600c95c"}, {file = "tox-3.24.5.tar.gz", hash = "sha256:67e0e32c90e278251fea45b696d0fef3879089ccbe979b0c556d35d5a70e2993"}, ] typing-extensions = [ - {file = "typing_extensions-4.0.1-py3-none-any.whl", hash = "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"}, - {file = "typing_extensions-4.0.1.tar.gz", hash = "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e"}, + {file = "typing_extensions-4.1.1-py3-none-any.whl", hash = "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2"}, + {file = "typing_extensions-4.1.1.tar.gz", hash = "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42"}, ] urllib3 = [ - {file = "urllib3-1.26.8-py2.py3-none-any.whl", hash = "sha256:000ca7f471a233c2251c6c7023ee85305721bfdf18621ebff4fd17a8653427ed"}, - {file = "urllib3-1.26.8.tar.gz", hash = "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"}, + {file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"}, + {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"}, ] virtualenv = [ - {file = "virtualenv-20.13.0-py2.py3-none-any.whl", hash = "sha256:339f16c4a86b44240ba7223d0f93a7887c3ca04b5f9c8129da7958447d079b09"}, - {file = "virtualenv-20.13.0.tar.gz", hash = "sha256:d8458cf8d59d0ea495ad9b34c2599487f8a7772d796f9910858376d1600dd2dd"}, + {file = "virtualenv-20.13.4-py2.py3-none-any.whl", hash = "sha256:c3e01300fb8495bc00ed70741f5271fc95fed067eb7106297be73d30879af60c"}, + {file = "virtualenv-20.13.4.tar.gz", hash = "sha256:ce8901d3bbf3b90393498187f2d56797a8a452fb2d0d7efc6fd837554d6f679c"}, ] voluptuous = [ {file = "voluptuous-0.12.2.tar.gz", hash = "sha256:4db1ac5079db9249820d49c891cb4660a6f8cae350491210abce741fabf56513"}, diff --git a/pyproject.toml b/pyproject.toml index 618375f26..04adb76f8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "python-kasa" -version = "0.4.1" +version = "0.4.2" description = "Python API for TP-Link Kasa Smarthome devices" license = "GPL-3.0-or-later" authors = ["Your Name "] @@ -18,7 +18,7 @@ kasa = "kasa.cli:cli" python = "^3.7" anyio = "*" # see https://github.com/python-trio/asyncclick/issues/18 importlib-metadata = "*" -asyncclick = ">=7" +asyncclick = ">=8" # required only for docs sphinx = { version = "^3", optional = true }