diff --git a/.coveragerc b/.coveragerc index d1e79c9..f70c551 100644 --- a/.coveragerc +++ b/.coveragerc @@ -5,6 +5,7 @@ omit = .venv/* [report] +fail_under = 100 show_missing = True skip_covered = False exclude_lines = diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml new file mode 100644 index 0000000..0ce784d --- /dev/null +++ b/.github/workflows/main.yaml @@ -0,0 +1,85 @@ +name: CI +on: [push] +jobs: + tests: + name: Python ${{ matrix.python-version }} Tests + runs-on: ubuntu-latest + strategy: + matrix: + python-version: + - '3.9' + - '3.10' + steps: + - uses: actions/checkout@v3 + + - uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + cache: 'pip' + cache-dependency-path: 'requirements/dev.txt' + + - name: Upgrade packaging tools + run: pip install -U pip + + - name: Install dependencies + run: pip install -U -r requirements/dev.txt + + - name: Install asyncio-taskpool + run: pip install -e . + + - name: Run tests for Python ${{ matrix.python-version }} + if: ${{ matrix.python-version != '3.10' }} + run: python -m tests + + - name: Run tests for Python 3.10 and save coverage + if: ${{ matrix.python-version == '3.10' }} + run: echo "coverage=$(./coverage.sh)" >> $GITHUB_ENV + + outputs: + coverage: ${{ env.coverage }} + + update_badges: + needs: tests + name: Update Badges + env: + meta_gist_id: 3f8240a976e8781a765d9c74a583dcda + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Download `cloc` + run: sudo apt-get update -y && sudo apt-get install -y cloc + + - name: Count lines of code/comments + run: | + echo "cloc_code=$(./cloc.sh -c src/)" >> $GITHUB_ENV + echo "cloc_comments=$(./cloc.sh -m src/)" >> $GITHUB_ENV + echo "cloc_commentpercent=$(./cloc.sh -p src/)" >> $GITHUB_ENV + + - name: Create badge for lines of code + uses: Schneegans/dynamic-badges-action@v1.2.0 + with: + auth: ${{ secrets.GIST_META_DATA }} + gistID: ${{ env.meta_gist_id }} + filename: cloc-code.json + label: Lines of Code + message: ${{ env.cloc_code }} + + - name: Create badge for lines of comments + uses: Schneegans/dynamic-badges-action@v1.2.0 + with: + auth: ${{ secrets.GIST_META_DATA }} + gistID: ${{ env.meta_gist_id }} + filename: cloc-comments.json + label: Comments + message: ${{ env.cloc_comments }} (${{ env.cloc_commentpercent }}%) + + - name: Create badge for test coverage + uses: Schneegans/dynamic-badges-action@v1.2.0 + with: + auth: ${{ secrets.GIST_META_DATA }} + gistID: ${{ env.meta_gist_id }} + filename: test-coverage.json + label: Coverage + message: ${{ needs.tests.outputs.coverage }} diff --git a/README.md b/README.md index 4f5bce2..14a6d81 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,29 @@ +[//]: # (This file is part of asyncio-taskpool.) + +[//]: # (asyncio-taskpool is free software: you can redistribute it and/or modify it under the terms of) +[//]: # (version 3.0 of the GNU Lesser General Public License as published by the Free Software Foundation.) + +[//]: # (asyncio-taskpool is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;) +[//]: # (without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.) +[//]: # (See the GNU Lesser General Public License for more details.) + +[//]: # (You should have received a copy of the GNU Lesser General Public License along with asyncio-taskpool.) +[//]: # (If not, see .) + # asyncio-taskpool +[![GitHub last commit][github-last-commit-img]][github-last-commit] +![Lines of code][gist-cloc-code-img] +![Lines of comments][gist-cloc-comments-img] +![Test coverage][gist-test-coverage-img] +[![License: LGPL v3.0][lgpl3-img]][lgpl3] + **Dynamically manage pools of asyncio tasks** +Full documentation available at [RtD](https://asyncio-taskpool.readthedocs.io/en/latest). + +--- + ## Contents - [Contents](#contents) - [Summary](#summary) @@ -67,3 +89,11 @@ The full license texts for the [GNU GPLv3.0](COPYING) and the [GNU LGPLv3.0](COP --- © 2022 Daniil Fajnberg + +[github-last-commit]: https://github.com/daniil-berg/asyncio-taskpool/commits +[github-last-commit-img]: https://img.shields.io/github/last-commit/daniil-berg/asyncio-taskpool?label=Last%20commit&logo=git& +[gist-cloc-code-img]: https://img.shields.io/endpoint?logo=python&color=blue&url=https://gist.githubusercontent.com/daniil-berg/3f8240a976e8781a765d9c74a583dcda/raw/cloc-code.json +[gist-cloc-comments-img]: https://img.shields.io/endpoint?logo=sharp&color=lightgrey&url=https://gist.githubusercontent.com/daniil-berg/3f8240a976e8781a765d9c74a583dcda/raw/cloc-comments.json +[gist-test-coverage-img]: https://img.shields.io/endpoint?logo=pytest&color=blue&url=https://gist.githubusercontent.com/daniil-berg/3f8240a976e8781a765d9c74a583dcda/raw/test-coverage.json +[lgpl3]: https://www.gnu.org/licenses/lgpl-3.0 +[lgpl3-img]: https://img.shields.io/badge/License-LGPL_v3.0-darkgreen.svg?logo=gnu diff --git a/cloc.sh b/cloc.sh new file mode 100755 index 0000000..eebfc52 --- /dev/null +++ b/cloc.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +# This file is part of asyncio-taskpool. + +# asyncio-taskpool is free software: you can redistribute it and/or modify it under the terms of +# version 3.0 of the GNU Lesser General Public License as published by the Free Software Foundation. + +# asyncio-taskpool is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public License along with asyncio-taskpool. +# If not, see . + +typeset option +if getopts 'bcmp' option; then + if [[ ${option} == [bcmp] ]]; then + shift + else + echo >&2 "Invalid option '$1' provided" + exit 1 + fi +fi + +typeset source=$1 +if [[ -z ${source} ]]; then + echo >&2 Source file/directory missing + exit 1 +fi + +typeset blank code comment commentpercent +read blank comment code commentpercent < <( \ + cloc --csv --quiet --hide-rate --include-lang Python ${source} | + awk -F, '$2 == "SUM" {printf ("%d %d %d %1.0f", $3, $4, $5, 100 * $4 / ($5 + $4)); exit}' +) + +case ${option} in + b) echo ${blank} ;; + c) echo ${code} ;; + m) echo ${comment} ;; + p) echo ${commentpercent} ;; + *) echo Blank lines: ${blank} + echo Lines of comments: ${comment} + echo Lines of code: ${code} + echo Comment percentage: ${commentpercent} ;; +esac diff --git a/coverage.sh b/coverage.sh index 786075e..c0e4597 100755 --- a/coverage.sh +++ b/coverage.sh @@ -1,3 +1,24 @@ -#!/usr/bin/env sh +#!/usr/bin/env bash -coverage erase && coverage run -m unittest discover && coverage report +# This file is part of asyncio-taskpool. + +# asyncio-taskpool is free software: you can redistribute it and/or modify it under the terms of +# version 3.0 of the GNU Lesser General Public License as published by the Free Software Foundation. + +# asyncio-taskpool is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public License along with asyncio-taskpool. +# If not, see . + +coverage erase && coverage run -m unittest discover 2> /dev/null + +typeset total +total=$(coverage report | awk '$1 == "TOTAL" {print $NF}') + +if [[ $total == 100% ]]; then + echo $total +else + coverage report +fi diff --git a/setup.cfg b/setup.cfg index f8bb68b..f141b17 100644 --- a/setup.cfg +++ b/setup.cfg @@ -25,7 +25,7 @@ classifiers = package_dir = = src packages = find: -python_requires = >=3.8 +python_requires = >=3.9 [options.extras_require] dev = diff --git a/src/asyncio_taskpool/internals/types.py b/src/asyncio_taskpool/internals/types.py index 69c6816..65dd98d 100644 --- a/src/asyncio_taskpool/internals/types.py +++ b/src/asyncio_taskpool/internals/types.py @@ -31,8 +31,8 @@ T = TypeVar('T') ArgsT = Iterable[Any] KwArgsT = Mapping[str, Any] -AnyCallableT = Callable[[...], Union[T, Awaitable[T]]] -CoroutineFunc = Callable[[...], Coroutine] +AnyCallableT = Callable[..., Union[T, Awaitable[T]]] +CoroutineFunc = Callable[..., Coroutine] EndCB = Callable CancelCB = Callable diff --git a/src/asyncio_taskpool/pool.py b/src/asyncio_taskpool/pool.py index 320144c..acc9522 100644 --- a/src/asyncio_taskpool/pool.py +++ b/src/asyncio_taskpool/pool.py @@ -640,7 +640,7 @@ class TaskPool(BaseTaskPool): kwargs (optional): The keyword-arguments to pass into each function call. num (optional): - The number of tasks to spawn with the specified parameters. + The number of tasks to spawn with the specified parameters. Defaults to 1. group_name (optional): Name of the task group to add the new tasks to. By default, a unique name is constructed in the form :code:`'apply-{name}-group-{idx}'` (with `name` being the name of the `func` and `idx` being an diff --git a/tests/__main__.py b/tests/__main__.py new file mode 100644 index 0000000..3b17d90 --- /dev/null +++ b/tests/__main__.py @@ -0,0 +1,30 @@ +__author__ = "Daniil Fajnberg" +__copyright__ = "Copyright © 2022 Daniil Fajnberg" +__license__ = """GNU LGPLv3.0 + +This file is part of asyncio-taskpool. + +asyncio-taskpool is free software: you can redistribute it and/or modify it under the terms of +version 3.0 of the GNU Lesser General Public License as published by the Free Software Foundation. + +asyncio-taskpool is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along with asyncio-taskpool. +If not, see .""" + +__doc__ = """ +Main entry point for all unit tests. +""" + + +import sys +import unittest + + +if __name__ == '__main__': + test_suite = unittest.defaultTestLoader.discover('.') + test_runner = unittest.TextTestRunner(resultclass=unittest.TextTestResult) + result = test_runner.run(test_suite) + sys.exit(not result.wasSuccessful())