From ed57563e8bc8e50c4d95ae7218bd935f8a6cb61d Mon Sep 17 00:00:00 2001 From: Teemu R Date: Tue, 12 May 2020 12:11:47 +0200 Subject: [PATCH] Convert to use poetry & pyproject.toml for dep & build management (#54) * Convert to use poetry and pyproject.toml, update README * add some resources for contributors * minor adjustments * ci: separate tests from linting, run using poetry * add pytest-mock to dev requirements * combine running tests and reporting to codecov * generate both xml and html coverage reports * add codecov to dev dependencies --- .flake8 | 8 ++ .pre-commit-config.yaml | 2 +- Dockerfile | 50 ---------- README.md | 146 ++++++++++++--------------- azure-pipelines.yml | 191 ++++++++++++++++++++---------------- kasa/__init__.py | 4 + kasa/cli.py | 1 + kasa/smartbulb.py | 23 +++-- kasa/smartplug.py | 5 +- kasa/tests/conftest.py | 2 +- kasa/tests/newfakes.py | 11 ++- kasa/tests/test_cli.py | 2 +- kasa/tests/test_fixtures.py | 2 +- kasa/version.py | 2 - pyproject.toml | 57 +++++++++++ requirements.txt | 3 - requirements_test.txt | 8 -- setup.py | 19 ---- tox.ini | 72 +++++--------- 19 files changed, 296 insertions(+), 312 deletions(-) create mode 100644 .flake8 delete mode 100644 Dockerfile delete mode 100644 kasa/version.py create mode 100644 pyproject.toml delete mode 100644 requirements.txt delete mode 100644 requirements_test.txt delete mode 100644 setup.py diff --git a/.flake8 b/.flake8 new file mode 100644 index 00000000..a9d63596 --- /dev/null +++ b/.flake8 @@ -0,0 +1,8 @@ +[flake8] +exclude = .git,.tox,__pycache__,kasa/tests/newfakes.py,kasa/tests/test_fixtures.py +max-line-length = 88 +per-file-ignores = + kasa/tests/*.py:D100,D101,D102,D103,D104 + setup.py:D100 +ignore = D105, D107, E203, E501, W503 +max-complexity = 18 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0606516f..7606de0b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,11 +26,11 @@ repos: - id: flake8 additional_dependencies: [flake8-docstrings] - - repo: https://github.com/pre-commit/mirrors-isort rev: v4.3.21 hooks: - id: isort + additional_dependencies: [toml] - repo: https://github.com/pre-commit/mirrors-mypy rev: v0.740 diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index f6b70e2b..00000000 --- a/Dockerfile +++ /dev/null @@ -1,50 +0,0 @@ -#################################################### -# Use python 3.x and the latest version of alpine # -#################################################### -FROM python:3-alpine - -LABEL maintainer=peter@grainger.xyz - -################################################### -# Add all system packages relied upon by python # -################################################### -RUN apk update && \ - apk add --no-cache gcc \ - libffi-dev \ - openssl-dev \ - libxslt-dev \ - libxml2-dev \ - musl-dev \ - linux-headers - -################################################### -# Create somewhere to put the files # -################################################### -RUN mkdir -p /opt/python-kasa -WORKDIR /opt/python-kasa - -################################################### -# Requirements file first to help cache # -################################################### -COPY requirements.txt . -RUN pip install -r requirements.txt - -################################################### -# Install dev dependancies # -################################################### -RUN pip install pytest pytest-cov voluptuous typing - -################################################### -# Copy over the rest. # -################################################### -COPY ./ ./ - -################################################### -# Install everything to the path # -################################################### -RUN python setup.py install - -################################################### -# Run tests # -################################################### -CMD pytest diff --git a/README.md b/README.md index 1b16211d..d0916b4f 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,10 @@ [![PyPI version](https://badge.fury.io/py/python-kasa.svg)](https://badge.fury.io/py/python-kasa) [![Build Status](https://dev.azure.com/python-kasa/python-kasa/_apis/build/status/python-kasa.python-kasa?branchName=master)](https://dev.azure.com/python-kasa/python-kasa/_build/latest?definitionId=2&branchName=master) [![Coverage Status](https://coveralls.io/repos/github/python-kasa/python-kasa/badge.svg?branch=master)](https://coveralls.io/github/python-kasa/python-kasa?branch=master) -[![Reviewed by Hound](https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg)](https://houndci.com) -Python Library to control TPLink smart plugs/switches and smart bulbs. +python-kasa is a Python library to control TPLink smart home devices (plugs, wall switches, power strips, and bulbs) using asyncio. +This project is a maintainer-made fork of [pyHS100](https://github.com/GadgetReactor/pyHS100) project. + **Supported devices** @@ -13,6 +14,7 @@ Python Library to control TPLink smart plugs/switches and smart bulbs. * HS100 * HS103 * HS105 + * HS107 * HS110 * Power Strips * HS300 @@ -32,6 +34,9 @@ Python Library to control TPLink smart plugs/switches and smart bulbs. * KL120 * KL130 +**Contributions (be it adding missing features, fixing bugs or improving documentation) are more than welcome, feel free to submit pull requests! See below for instructions for setting up a development environment.** + + # Usage The package is shipped with a console tool named kasa, please refer to ```kasa --help``` for detailed usage. @@ -82,7 +87,7 @@ All devices support a variety of common commands, including: * `state` which returns state information * `on` and `off` for turning the device on or off * `emeter` (where applicable) to return energy consumption information - * `sysinfo` to return raw system information which is used by e.g. `state`, useful for debugging and when adding support for new device types + * `sysinfo` to return raw system information ## Energy meter @@ -96,128 +101,95 @@ $ kasa emeter Current state: {'total': 133.105, 'power': 108.223577, 'current': 0.54463, 'voltage': 225.296283} ``` -## Plug-specific commands - -At the moment only switching the state of the LED is implemented. -**Feel free to submit patches as pull requests for further features!** -### Controlling the LED - -`led` command can be used to control whether the LED light on front of the plug is on or off. - -``` -$ kasa --plug led -LED state: False -$ kasa --plug led 1 -Turning led to True -``` - ## Bulb-specific commands -At the moment setting brightness, color temperature and color (in HSV) is supported. +At the moment setting brightness, color temperature and color (in HSV) are supported depending on the device. The commands are straightforward, so feel free to check `--help` for instructions how to use them. -**Feel free to submit patches as pull requests to add more functionality (e.g. scenes)!** - # Library usage -The public API is well documented, but here are some examples to get you started. -For all available API functions run ```help(SmartPlug)``` or ```help(SmartBulb)```. +The property accesses use the data obtained before by awaiting `update()`. +The values are cached until the next update call. +Each method changing the state of the device will automatically update the cached state. + +Errors are raised as `SmartDeviceException` instances for the user to handle. ## Discovering devices -`Discover` class' `discover()` can be used to discover supported devices, -which returns a dictionary keyed with the IP address whose value hold a ready-to-use instance of the detected device type. +`Discover.discover()` can be used to discover supported devices in the local network. +The return value is a dictionary keyed with the IP address and the value holds a ready-to-use instance of the detected device type. Example: ```python +import asyncio from kasa import Discover -for dev in Discover.discover().values(): - print(dev) +devices = asyncio.run(Discover.discover()) +for addr, dev in devices.items(): + asyncio.run(dev.update()) + print(f"{addr} >> {dev}") ``` ``` -$ python3 example.py +$ python example.py ``` ## Querying basic information -*Please note that most property getters do I/O (e.g. fetching the system information) on each call. -If you want to avoid unnecessary communication with the device please use `get_sysinfo` and handle parsing of information by yourself.* - ```python -from kasa import SmartPlug, SmartBulb +import asyncio +from kasa import SmartPlug from pprint import pformat as pf plug = SmartPlug("192.168.XXX.XXX") +asyncio.run(plug.update()) print("Hardware: %s" % pf(plug.hw_info)) -print("Full sysinfo: %s" % pf(plug.get_sysinfo())) # this prints lots of information about the device +print("Full sysinfo: %s" % pf(plug.sys_info)) ``` +The rest of the examples assume that you have initialized an instance. + ## State & switching -Devices can be turned on and off by either calling appropriate methods on the device object, -or by assigning a new state to `state` property. +Devices can be turned on and off by either calling appropriate methods on the device object. ```python -print("Current state: %s" % plug.state) -plug.turn_off() -plug.turn_on() -``` - -```python -plug.state = "ON" -plug.state = "OFF" -``` - -## Time information -```python -print("Current time: %s" % plug.time) -print("Timezone: %s" % plug.timezone) -``` - -## Getting and setting the name -```python -print("Alias: %s" % plug.alias) -plug.alias = "My New Smartplug" +print("Current state: %s" % plug.is_on) +await plug.turn_off() +await plug.turn_on() ``` ## Getting emeter status (if applicable) ```python -print("Current consumption: %s" % plug.get_emeter_realtime()) -print("Per day: %s" % plug.get_emeter_daily(year=2016, month=12)) -print("Per month: %s" % plug.get_emeter_monthly(year=2016)) +print("Current consumption: %s" % await plug.get_emeter_realtime()) +print("Per day: %s" % await plug.get_emeter_daily(year=2016, month=12)) +print("Per month: %s" % await plug.get_emeter_monthly(year=2016)) ``` -## Plug-specific - -### Switching the led (plugs only) -```python -print("Current LED state: %s" % plug.led) -plug.led = False # turn off led -print("New LED state: %s" % plug.led) -``` - -## Bulb-specific API +## Bulb and dimmer-specific APIs The bulb API is likewise straightforward, so please refer to its API documentation. Information about supported features can be queried by using properties prefixed with `is_`, e.g. `is_dimmable`. ### Setting the brightness -The `brightness` property works in percentages. - ```python -print(bulb.brightness) +import asyncio +from kasa import SmartBulb + +bulb = SmartBulb("192.168.1.123") +asyncio.run(bulb.update()) + if bulb.is_dimmable: - bulb.brightness = 100 + asyncio.run(bulb.set_brightness(100)) + print(bulb.brightness) ``` ### Setting the color temperature ```python -print(bulb.color_temp) if bulb.is_variable_color_temp: - bulb.color_temp = 3000 + await bulb.set_color_temp(3000) + print(bulb.color_temp) ``` ### Setting the color @@ -225,19 +197,29 @@ if bulb.is_variable_color_temp: Hue is given in degrees (0-360) and saturation and value in percentage. ```python -print(bulb.hsv) if bulb.is_color: - bulb.hsv = (180, 100, 100) # set to cyan + await bulb.set_hsv(180, 100, 100) # set to cyan + print(bulb.hsv) ``` -## Development Setup +## Contributing -### Docker +Contributions are very welcome! To simplify the process, we are leveraging automated checks and tests for contributions. -The following assumes you have a working installation of Docker. +### Resources -Set up the environment and run the tests on demand. +* [softScheck's github contains lot of information and wireshark dissector](https://github.com/softScheck/tplink-smartplug#wireshark-dissector) +* [https://github.com/plasticrake/tplink-smarthome-simulator](tplink-smarthome-simulator) -```shell -docker build . -t kasa && docker run -v $(PWD)/kasa/tests:/opt/python-kasa/kasa/tests kasa pytest +### Setting up development environment + +```bash +poetry install +pre-commit install ``` + +### Code-style checks + +We use several tools to automatically check all contributions, which are run automatically when you commit your code. + +If you want to manually execute the checks, you can run `tox -e lint` to do the linting checks or `tox` to also execute the tests. diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 47702423..2b201ae0 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -3,93 +3,116 @@ trigger: pr: - master -strategy: - matrix: - Python 3.7 Ubuntu: - python.version: '3.7' - vmImage: 'ubuntu-latest' - Python 3.8 Ubuntu: - python.version: '3.8' - vmImage: 'ubuntu-latest' -# PyPy Ubuntu: -# python.version: pypy3 -# vmImage: 'ubuntu-latest' - Python 3.7 Windows: - python.version: '3.7' - vmImage: 'windows-latest' - Python 3.8 Windows: - python.version: '3.8' - vmImage: 'windows-latest' - Python 3.7 OSX: - python.version: '3.7' - vmImage: 'macOS-latest' - Python 3.8 OSX: - python.version: '3.8' - vmImage: 'macOS-latest' -pool: +stages: +- stage: "Linting" + jobs: + - job: "LintChecks" + pool: + vmImage: "ubuntu-latest" + strategy: + matrix: + Python 3.8: + python.version: '3.8' + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '$(python.version)' + displayName: 'Use Python $(python.version)' + + - script: | + python -m pip install --upgrade pip poetry + poetry install + displayName: 'Install dependencies' + + - script: | + poetry run pre-commit run black --all-files + displayName: 'Code formating (black)' + + - script: | + poetry run pre-commit run flake8 --all-files + displayName: 'Code formating (flake8)' + + - script: | + poetry run pre-commit run mypy --all-files + displayName: 'Typing checks (mypy)' + + - script: | + poetry run pre-commit run isort --all-files + displayName: 'Order of imports (isort)' + + - script: | + poetry run pre-commit run trailing-whitespace --all-files + displayName: 'Run trailing-whitespace' + + - script: | + poetry run pre-commit run end-of-file-fixer --all-files + displayName: 'Run end-of-file-fixer' + + - script: | + poetry run pre-commit run check-docstring-first --all-files + displayName: 'Run check-docstring-first' + + - script: | + poetry run pre-commit run check-yaml --all-files + displayName: 'Run check-yaml' + + - script: | + poetry run pre-commit run debug-statements --all-files + displayName: 'Run debug-statements' + + - script: | + poetry run pre-commit run check-ast --all-files + displayName: 'Run check-ast' + + +- stage: "Tests" + jobs: + - job: "Tests" + strategy: + matrix: + Python 3.7 Ubuntu: + python.version: '3.7' + vmImage: 'ubuntu-latest' + + Python 3.8 Ubuntu: + python.version: '3.8' + vmImage: 'ubuntu-latest' + + Python 3.7 Windows: + python.version: '3.7' + vmImage: 'windows-latest' + + Python 3.8 Windows: + python.version: '3.8' + vmImage: 'windows-latest' + + Python 3.7 OSX: + python.version: '3.7' + vmImage: 'macOS-latest' + + Python 3.8 OSX: + python.version: '3.8' + vmImage: 'macOS-latest' + + pool: vmImage: $(vmImage) -steps: -- task: UsePythonVersion@0 - inputs: - versionSpec: '$(python.version)' - displayName: 'Use Python $(python.version)' + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '$(python.version)' + displayName: 'Use Python $(python.version)' -- script: | - python -m pip install --upgrade pip - pip install -r requirements.txt - pip install -r requirements_test.txt - displayName: 'Install dependencies' + - script: | + python -m pip install --upgrade pip poetry + poetry install + displayName: 'Install dependencies' -- script: | - pre-commit run black --all-files - displayName: 'Code formating (black)' + - script: | + poetry run pytest --cov kasa --cov-report=xml --cov-report=html + displayName: 'Run tests' -- script: | - pre-commit run flake8 --all-files - displayName: 'Code formating (flake8)' - -- script: | - pre-commit run mypy --all-files - displayName: 'Typing checks (mypy)' - -- script: | - pre-commit run isort --all-files - displayName: 'Order of imports (isort)' - -- script: | - pre-commit run trailing-whitespace --all-files - displayName: 'Run trailing-whitespace' - -- script: | - pre-commit run end-of-file-fixer --all-files - displayName: 'Run end-of-file-fixer' - -- script: | - pre-commit run check-docstring-first --all-files - displayName: 'Run check-docstring-first' - -- script: | - pre-commit run check-yaml --all-files - displayName: 'Run check-yaml' - -- script: | - pre-commit run debug-statements --all-files - displayName: 'Run debug-statements' - -- script: | - pre-commit run check-ast --all-files - displayName: 'Run check-ast' - -- script: | - pre-commit run isort --all-files - displayName: 'Order of imports (isort)' - -- script: | - pytest --cov kasa --cov-report xml - displayName: 'Tests' - -- script: | - codecov -t $(codecov.token) - displayName: Report Coverage to codecov + - script: | + poetry run codecov -t $(codecov.token) + displayName: 'Report code coverage' diff --git a/kasa/__init__.py b/kasa/__init__.py index 46c3a17a..b6c42059 100755 --- a/kasa/__init__.py +++ b/kasa/__init__.py @@ -11,6 +11,7 @@ For device type specific actions `SmartBulb`, `SmartPlug`, or `SmartStrip` Module-specific errors are raised as `SmartDeviceException` and are expected to be handled by the user of the library. """ +from importlib_metadata import version # type: ignore from kasa.discover import Discover from kasa.protocol import TPLinkSmartHomeProtocol from kasa.smartbulb import SmartBulb @@ -19,6 +20,9 @@ from kasa.smartdimmer import SmartDimmer from kasa.smartplug import SmartPlug from kasa.smartstrip import SmartStrip +__version__ = version("python-kasa") + + __all__ = [ "Discover", "TPLinkSmartHomeProtocol", diff --git a/kasa/cli.py b/kasa/cli.py index 97f831ee..feb6b634 100755 --- a/kasa/cli.py +++ b/kasa/cli.py @@ -7,6 +7,7 @@ from pprint import pformat as pf from typing import cast import asyncclick as click + from kasa import Discover, SmartBulb, SmartDevice, SmartPlug, SmartStrip click.anyio_backend = "asyncio" diff --git a/kasa/smartbulb.py b/kasa/smartbulb.py index c9587be1..ab136f9a 100644 --- a/kasa/smartbulb.py +++ b/kasa/smartbulb.py @@ -23,7 +23,7 @@ TPLINK_KELVIN = { class SmartBulb(SmartDevice): """Representation of a TP-Link Smart Bulb. - Usage example when used as library: + Usage example: ```python p = SmartBulb("192.168.1.105") await p.update() @@ -33,6 +33,7 @@ class SmartBulb(SmartDevice): # change state of bulb await p.turn_on() + assert p.is_on await p.turn_off() # query and print current state of plug @@ -40,12 +41,11 @@ class SmartBulb(SmartDevice): # check whether the bulb supports color changes if p.is_color: - - # set the color to an HSV tuple - await p.set_hsv(180, 100, 100) - - # get the current HSV value - print(p.hsv) + print("we got color!") + # set the color to an HSV tuple + await p.set_hsv(180, 100, 100) + # get the current HSV value + print(p.hsv) # check whether the bulb supports setting color temperature if p.is_variable_color_temp: @@ -57,12 +57,11 @@ class SmartBulb(SmartDevice): # check whether the bulb is dimmable if p.is_dimmable: + # set the bulb to 50% brightness + await p.set_brightness(50) - # set the bulb to 50% brightness - await p.set_brightness(50) - - # check the current brightness - print(p.brightness) + # check the current brightness + print(p.brightness) ``` Errors reported by the device are raised as SmartDeviceExceptions, diff --git a/kasa/smartplug.py b/kasa/smartplug.py index a1d4c83e..d46e8b90 100644 --- a/kasa/smartplug.py +++ b/kasa/smartplug.py @@ -10,7 +10,7 @@ _LOGGER = logging.getLogger(__name__) class SmartPlug(SmartDevice): """Representation of a TP-Link Smart Switch. - Usage example when used a a synchronous library: + Usage example: ```python p = SmartPlug("192.168.1.105") @@ -19,9 +19,10 @@ class SmartPlug(SmartDevice): # change state of plug await p.turn_on() + assert p.is_on is True await p.turn_off() - # query and print current state of plug + # print current state of plug print(p.state_information) ``` diff --git a/kasa/tests/conftest.py b/kasa/tests/conftest.py index c81c19ad..9e4da9e3 100644 --- a/kasa/tests/conftest.py +++ b/kasa/tests/conftest.py @@ -4,7 +4,7 @@ import json import os from os.path import basename -import pytest +import pytest # type: ignore # see https://github.com/pytest-dev/pytest/issues/3342 from kasa import Discover, SmartBulb, SmartDimmer, SmartPlug, SmartStrip diff --git a/kasa/tests/newfakes.py b/kasa/tests/newfakes.py index d23deb0d..bd7173fc 100644 --- a/kasa/tests/newfakes.py +++ b/kasa/tests/newfakes.py @@ -1,7 +1,16 @@ import logging import re -from voluptuous import REMOVE_EXTRA, All, Any, Coerce, Invalid, Optional, Range, Schema +from voluptuous import ( # type: ignore + REMOVE_EXTRA, + All, + Any, + Coerce, + Invalid, + Optional, + Range, + Schema, +) from ..protocol import TPLinkSmartHomeProtocol diff --git a/kasa/tests/test_cli.py b/kasa/tests/test_cli.py index 632084a9..e89594e6 100644 --- a/kasa/tests/test_cli.py +++ b/kasa/tests/test_cli.py @@ -1,6 +1,6 @@ import pytest - from asyncclick.testing import CliRunner + from kasa import SmartDevice from kasa.cli import alias, brightness, emeter, raw_command, state, sysinfo diff --git a/kasa/tests/test_fixtures.py b/kasa/tests/test_fixtures.py index b2daeb73..73d31eba 100644 --- a/kasa/tests/test_fixtures.py +++ b/kasa/tests/test_fixtures.py @@ -2,7 +2,7 @@ import asyncio from datetime import datetime from unittest.mock import patch -import pytest +import pytest # type: ignore # https://github.com/pytest-dev/pytest/issues/3342 from kasa import DeviceType, SmartDeviceException, SmartStrip diff --git a/kasa/version.py b/kasa/version.py deleted file mode 100644 index 9bc7a520..00000000 --- a/kasa/version.py +++ /dev/null @@ -1,2 +0,0 @@ -# flake8: noqa -__version__ = "0.4.0.dev0" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..5314d69f --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,57 @@ +[tool.poetry] +name = "python-kasa" +version = "0.4.0.dev0" +description = "Python API for TP-Link Kasa Smarthome devices" +license = "GPL-3.0-or-later" +authors = ["Your Name "] +repository = "https://github.com/python-kasa/python-kasa" +readme = "README.md" +packages = [ + { include = "kasa" } +] + +[tool.poetry.scripts] +kasa = "kasa.cli:cli" + +[tool.poetry.dependencies] +python = "^3.7" +importlib-metadata = "*" +asyncclick = "^7" + +[tool.poetry.dev-dependencies] +pytest = "^5" +pytest-azurepipelines = "^0.8" +pytest-cov = "^2.8" +pytest-asyncio = "^0.11" +pytest-sugar = "*" +pre-commit = "*" +voluptuous = "*" +toml = "*" +tox = "*" +pytest-mock = "^3.1.0" +codecov = "^2.0" + +[tool.isort] +multi_line_output = 3 +include_trailing_comma = true +force_grid_wrap = 0 +use_parentheses = true +line_length = 88 +known_first_party = "kasa" +known_third_party = ["asyncclick", "pytest", "setuptools", "voluptuous"] + +[tool.coverage.run] +source = ["kasa"] +branch = true +omit = ["kasa/cli.py", "kasa/tests/*"] + +[tool.coverage.report] +exclude_lines = [ + # ignore abstract methods + "raise NotImplementedError", + "def __repr__" +] + +[build-system] +requires = ["poetry>=0.12"] +build-backend = "poetry.masonry.api" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index cbd43b81..00000000 --- a/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -asyncclick -pre-commit -voluptuous diff --git a/requirements_test.txt b/requirements_test.txt deleted file mode 100644 index 901116e3..00000000 --- a/requirements_test.txt +++ /dev/null @@ -1,8 +0,0 @@ -pytest -pytest-azurepipelines -pytest-cov -pytest-asyncio -pytest-mock -asyncclick -voluptuous -codecov diff --git a/setup.py b/setup.py deleted file mode 100644 index 3b43b078..00000000 --- a/setup.py +++ /dev/null @@ -1,19 +0,0 @@ -from setuptools import setup - -with open("kasa/version.py") as f: - exec(f.read()) - -setup( - name="python-kasa", - version=__version__, # type: ignore # noqa: F821 - description="Python API for TP-Link Kasa Smarthome products", - url="https://github.com/python-kasa/python-kasa", - author="", - author_email="", - license="GPLv3", - packages=["kasa"], - install_requires=["asyncclick"], - python_requires=">=3.7", - entry_points={"console_scripts": ["kasa=kasa.cli:cli"]}, - zip_safe=False, -) diff --git a/tox.ini b/tox.ini index b1c4b4ba..7cc957ed 100644 --- a/tox.ini +++ b/tox.ini @@ -1,16 +1,35 @@ [tox] -envlist=py37,py38,flake8,linting,typing +envlist=py37,py38,flake8,lint,coverage skip_missing_interpreters = True +isolated_build = True -[tox:travis] -3.7 = py37 -3.8 = py38 [testenv] -passenv = TRAVIS TRAVIS_JOB_ID TRAVIS_BRANCH -deps = -r{toxinidir}/requirements_test.txt -commands= - pytest --cov --cov-config=tox.ini kasa +whitelist_externals = + poetry + coverage +commands = + poetry install -v + poetry run pytest --cov kasa/tests/ + +[testenv:clean] +deps = coverage +skip_install = true +commands = coverage erase + +[testenv:py37] +commands = coverage run -m pytest {posargs} + +[testenv:py38] +commands = coverage run -m pytest {posargs} + +[testenv:coverage] +basepython = python3.8 +skip_install = true +deps = coverage[toml] +commands = + coverage report + coverage html [testenv:flake8] deps= @@ -18,44 +37,7 @@ deps= flake8-docstrings commands=flake8 kasa -[testenv:typing] -skip_install=true -deps=mypy -commands=mypy --ignore-missing-imports kasa - -[flake8] -exclude = .git,.tox,__pycache__,kasa/tests/newfakes.py,kasa/tests/test_fixtures.py -max-line-length = 88 -per-file-ignores = - kasa/tests/*.py:D100,D101,D102,D103,D104 - setup.py:D100 -ignore = D105, D107, E203, E501, W503 -#ignore = E203, E266, E501, W503, F403, F401 -#max-complexity = 18 -#select = B,C,E,F,W,T4,B9 - [testenv:lint] deps = pre-commit skip_install = true commands = pre-commit run --all-files - -[coverage:run] -source = kasa -branch = True -omit = - kasa/tests/* - -[coverage:report] -exclude_lines = - # ignore abstract methods - raise NotImplementedError - def __repr__ - -[isort] -multi_line_output=3 -include_trailing_comma=True -force_grid_wrap=0 -use_parentheses=True -line_length=88 -known_first_party=kasa -known_third_party=click,pytest,setuptools,voluptuous