From 301053f1c2fa6dd13fb3f99da0c7739973de9e1b Mon Sep 17 00:00:00 2001 From: poolitzer <25934244+poolitzer@users.noreply.github.com> Date: Thu, 20 Feb 2020 08:14:09 -0800 Subject: [PATCH 01/16] adding mypy to the repo --- .github/CONTRIBUTING.rst | 6 +++++- .github/workflows/mypy.yml | 25 +++++++++++++++++++++++++ .pre-commit-config.yaml | 10 +++++++--- requirements-dev.txt | 1 + setup.cfg | 5 +++++ 5 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/mypy.yml diff --git a/.github/CONTRIBUTING.rst b/.github/CONTRIBUTING.rst index 40332fc3fa1..a7fd0ebbeed 100644 --- a/.github/CONTRIBUTING.rst +++ b/.github/CONTRIBUTING.rst @@ -68,7 +68,9 @@ Here's how to make a one-off code change. - You can refer to relevant issues in the commit message by writing, e.g., "#105". - Your code should adhere to the `PEP 8 Style Guide`_, with the exception that we have a maximum line length of 99. - + + - Provide static typing with signature annotations. The documentation of `MyPy`_ will be a good start, the cheat sheet is `here`_. + - Document your code. This project uses `sphinx`_ to generate static HTML docs. To build them, first make sure you have the required dependencies: .. code-block:: bash @@ -251,3 +253,5 @@ break the API classes. For example: .. _`Google Python Style Guide`: http://google.github.io/styleguide/pyguide.html .. _`Google Python Style Docstrings`: https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html .. _AUTHORS.rst: ../AUTHORS.rst +.. _`MyPy`: https://mypy.readthedocs.io/en/stable/index.html +.. _`here`: https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml new file mode 100644 index 00000000000..2727fa3f5a3 --- /dev/null +++ b/.github/workflows/mypy.yml @@ -0,0 +1,25 @@ +name: mypy +on: + pull_request: + branches: + - master + push: + branches: + - master +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python 3.7 + uses: actions/setup-python@v1 + with: + python-version: 3.7 + - name: Install dependencies and mypy + run: | + pip install -r requirements.txt + pip install -r requirements-dev.txt + - name: Verify mypy types + run: | + mypy --version + mypy telegram \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 46910487dc7..f6eb75fd4f4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,20 +1,24 @@ repos: - repo: git://github.com/python-telegram-bot/mirrors-yapf - sha: 5769e088ef6e0a0d1eb63bd6d0c1fe9f3606d6c8 + rev: 5769e088ef6e0a0d1eb63bd6d0c1fe9f3606d6c8 hooks: - id: yapf files: ^(telegram|tests)/.*\.py$ args: - --diff - repo: git://github.com/pre-commit/pre-commit-hooks - sha: 0b70e285e369bcb24b57b74929490ea7be9c4b19 + rev: v2.5.0 hooks: - id: flake8 - repo: git://github.com/pre-commit/mirrors-pylint - sha: 9d8dcbc2b86c796275680f239c1e90dcd50bd398 + rev: v2.4.4 hooks: - id: pylint files: ^telegram/.*\.py$ args: - --errors-only - --disable=import-error +- repo: https://github.com/pre-commit/mirrors-mypy + rev: 'v0.761' + hooks: + - id: mypy \ No newline at end of file diff --git a/requirements-dev.txt b/requirements-dev.txt index 577e6dd5381..4c0009150ab 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -9,3 +9,4 @@ pytest==4.2.0 pytest-timeout wheel attrs==19.1.0 +mypy==0.761 diff --git a/setup.cfg b/setup.cfg index e30e2fdacf2..39c8de4322d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -40,3 +40,8 @@ omit = telegram/__main__.py telegram/vendor/* +[mypy] +warn_unused_configs = True + +[mypy-telegram.vendor.*] +ignore_errors = True \ No newline at end of file From f4e7ce506ffc6bc78ffc8f6c413adefd124bea32 Mon Sep 17 00:00:00 2001 From: poolitzer <25934244+poolitzer@users.noreply.github.com> Date: Thu, 20 Feb 2020 14:49:20 -0800 Subject: [PATCH 02/16] first take on only testing changed files --- .github/workflows/mypy.yml | 22 +++++++++++++++++++++- requirements-dev.txt | 1 - 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml index 2727fa3f5a3..3fcb2572247 100644 --- a/.github/workflows/mypy.yml +++ b/.github/workflows/mypy.yml @@ -19,7 +19,27 @@ jobs: run: | pip install -r requirements.txt pip install -r requirements-dev.txt + pip install mypy==0.761 - name: Verify mypy types run: | mypy --version - mypy telegram \ No newline at end of file + - name: running mypy on the changed files + uses: lots0logs/gh-action-get-changed-files@2.0.6 + with: + token: ${{ secrets.GITHUB_TOKEN }} + run: | + sudo apt install jq + echo $HOME + echo $HOME/files.json + for FILENAME in $(jq '.[]' $HOME/files.json); do + FILENAME="${FILENAME:1}" + FILENAME="${FILENAME::-1}" + if [ ${FILENAME: -3} == ".py" ] + then + echo Testing $FILENAME + python -m mypy $FILENAME + else + echo Skipping $FILENAME + fi + done + shell: bash \ No newline at end of file diff --git a/requirements-dev.txt b/requirements-dev.txt index 4c0009150ab..577e6dd5381 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -9,4 +9,3 @@ pytest==4.2.0 pytest-timeout wheel attrs==19.1.0 -mypy==0.761 From 2407b66c0a26c6d1e2d418eba1135c24a2458044 Mon Sep 17 00:00:00 2001 From: poolitzer <25934244+poolitzer@users.noreply.github.com> Date: Thu, 20 Feb 2020 14:51:12 -0800 Subject: [PATCH 03/16] spaces --- .github/workflows/mypy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml index 3fcb2572247..b0cf5fe32a8 100644 --- a/.github/workflows/mypy.yml +++ b/.github/workflows/mypy.yml @@ -25,8 +25,8 @@ jobs: mypy --version - name: running mypy on the changed files uses: lots0logs/gh-action-get-changed-files@2.0.6 - with: - token: ${{ secrets.GITHUB_TOKEN }} + with: + token: ${{ secrets.GITHUB_TOKEN }} run: | sudo apt install jq echo $HOME From 1dd9c2d31205cf7f14d33419f37cdf6330ddc6c9 Mon Sep 17 00:00:00 2001 From: poolitzer <25934244+poolitzer@users.noreply.github.com> Date: Thu, 20 Feb 2020 14:53:51 -0800 Subject: [PATCH 04/16] spaces --- .github/workflows/mypy.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml index b0cf5fe32a8..b4bf655aaf0 100644 --- a/.github/workflows/mypy.yml +++ b/.github/workflows/mypy.yml @@ -23,10 +23,11 @@ jobs: - name: Verify mypy types run: | mypy --version - - name: running mypy on the changed files + - name: saving changed files in local json uses: lots0logs/gh-action-get-changed-files@2.0.6 with: token: ${{ secrets.GITHUB_TOKEN }} + - name: Running mypy on changed files run: | sudo apt install jq echo $HOME From 3f97ce0ede365b7ac791b13b70849dc49d112aa2 Mon Sep 17 00:00:00 2001 From: poolitzer <25934244+poolitzer@users.noreply.github.com> Date: Thu, 20 Feb 2020 15:02:56 -0800 Subject: [PATCH 05/16] allowing test branch --- .github/workflows/mypy.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml index b4bf655aaf0..5f70a0aeaf8 100644 --- a/.github/workflows/mypy.yml +++ b/.github/workflows/mypy.yml @@ -3,6 +3,7 @@ on: pull_request: branches: - master + - type_hinting_master push: branches: - master From 71b360d89018a0668d1ef046262f5f296c5529f0 Mon Sep 17 00:00:00 2001 From: Poolitzer <25934244+Poolitzer@users.noreply.github.com> Date: Thu, 20 Feb 2020 15:04:34 -0800 Subject: [PATCH 06/16] Update bot.py --- telegram/bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telegram/bot.py b/telegram/bot.py index 11794a7ad88..ea743e39d9f 100644 --- a/telegram/bot.py +++ b/telegram/bot.py @@ -18,7 +18,7 @@ # # You should have received a copy of the GNU Lesser Public License # along with this program. If not, see [http://www.gnu.org/licenses/]. -"""This module contains an object that represents a Telegram Bot.""" +"""This module contains an object that represents a Telegram Bot and is being used as a workflow test now.""" import functools import inspect From c74f8691e353c9467381687e2d521b5bfccef320 Mon Sep 17 00:00:00 2001 From: poolitzer <25934244+poolitzer@users.noreply.github.com> Date: Thu, 20 Feb 2020 15:16:31 -0800 Subject: [PATCH 07/16] improving start condition of workflow --- .github/workflows/mypy.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml index 5f70a0aeaf8..ea263a215e5 100644 --- a/.github/workflows/mypy.yml +++ b/.github/workflows/mypy.yml @@ -4,9 +4,15 @@ on: branches: - master - type_hinting_master + paths: + - 'telegram/**' + - '**.py' push: branches: - master + paths: + - 'telegram/**' + - '**.py' jobs: build: runs-on: ubuntu-latest From d83e5c66af6ada8f567b1e2f9ed5b3b35d3abf87 Mon Sep 17 00:00:00 2001 From: Hinrich Mahler Date: Sat, 7 Mar 2020 20:38:49 +0100 Subject: [PATCH 08/16] Add mypy to pre-commit and make --- .gitignore | 1 + .pre-commit-config.yaml | 4 ++-- Makefile | 6 ++++++ requirements-dev.txt | 2 ++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index a98e967bce0..a2e9366ddaf 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,7 @@ htmlcov/ .coverage.* .cache .pytest_cache +.mypy_cache nosetests.xml coverage.xml *,cover diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f6eb75fd4f4..3cf07cf3459 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,8 +6,8 @@ repos: files: ^(telegram|tests)/.*\.py$ args: - --diff -- repo: git://github.com/pre-commit/pre-commit-hooks - rev: v2.5.0 +- repo: https://gitlab.com/pycqa/flake8 + rev: 3.7.9 hooks: - id: flake8 - repo: git://github.com/pre-commit/mirrors-pylint diff --git a/Makefile b/Makefile index ac90c183a70..c91817264f1 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ PYTEST := pytest PEP257 := pep257 PEP8 := flake8 YAPF := yapf +MYPY := mypy PIP := pip clean: @@ -28,6 +29,9 @@ yapf: lint: $(PYLINT) -E telegram --disable=no-name-in-module,import-error +mypy: + $(MYPY) -p telegram + test: $(PYTEST) -v @@ -41,6 +45,7 @@ help: @echo "- pep8 Check style with flake8" @echo "- lint Check style with pylint" @echo "- yapf Check style with yapf" + @echo "- mypy Check type hinting with mypy" @echo "- test Run tests using pytest" @echo @echo "Available variables:" @@ -49,4 +54,5 @@ help: @echo "- PEP257 default: $(PEP257)" @echo "- PEP8 default: $(PEP8)" @echo "- YAPF default: $(YAPF)" + @echo "- MYPY default: $(MYPY)" @echo "- PIP default: $(PIP)" diff --git a/requirements-dev.txt b/requirements-dev.txt index 577e6dd5381..0d26131e7df 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -3,6 +3,8 @@ pep257 pylint flaky yapf +mypy==0.761 +diff-cover pre-commit beautifulsoup4 pytest==4.2.0 From adb7f7e272f9377146477d43125f166d1e656919 Mon Sep 17 00:00:00 2001 From: Hinrich Mahler Date: Sat, 7 Mar 2020 20:42:47 +0100 Subject: [PATCH 09/16] Try computing typing coverage in CI --- .github/workflows/mypy.yml | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml index ea263a215e5..11ef3ce33bd 100644 --- a/.github/workflows/mypy.yml +++ b/.github/workflows/mypy.yml @@ -1,4 +1,4 @@ -name: mypy +name: typing coverage on: pull_request: branches: @@ -14,7 +14,7 @@ on: - 'telegram/**' - '**.py' jobs: - build: + mypy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 @@ -26,28 +26,14 @@ jobs: run: | pip install -r requirements.txt pip install -r requirements-dev.txt - pip install mypy==0.761 - name: Verify mypy types run: | mypy --version - - name: saving changed files in local json - uses: lots0logs/gh-action-get-changed-files@2.0.6 - with: - token: ${{ secrets.GITHUB_TOKEN }} - - name: Running mypy on changed files + - name: Running mypy on changed files and save report + run: | + python -m mypy -p telegram --cobertura-xml-report . || true + shell: bash + - name: Computing typing coverage run: | - sudo apt install jq - echo $HOME - echo $HOME/files.json - for FILENAME in $(jq '.[]' $HOME/files.json); do - FILENAME="${FILENAME:1}" - FILENAME="${FILENAME::-1}" - if [ ${FILENAME: -3} == ".py" ] - then - echo Testing $FILENAME - python -m mypy $FILENAME - else - echo Skipping $FILENAME - fi - done + diff-cover --fail-under=100 cobertura.xml --html-report report.html shell: bash \ No newline at end of file From be988851cbe61cb58e5c054075134860443ae717 Mon Sep 17 00:00:00 2001 From: Hinrich Mahler Date: Sat, 7 Mar 2020 20:46:08 +0100 Subject: [PATCH 10/16] Some typing for testing --- telegram/ext/filters.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/telegram/ext/filters.py b/telegram/ext/filters.py index d7b5dba00a8..2c21528dc3e 100644 --- a/telegram/ext/filters.py +++ b/telegram/ext/filters.py @@ -21,7 +21,7 @@ import re from future.utils import string_types - +from typing import Optional from telegram import Chat, Update, MessageEntity __all__ = ['Filters', 'BaseFilter', 'InvertedFilter', 'MergedFilter'] @@ -78,11 +78,11 @@ class variable. (depends on the handler). """ - name = None - update_filter = False - data_filter = False + name: Optional[str] = None + update_filter: bool = False + data_filter: bool = False - def __call__(self, update): + def __call__(self, update: int) -> Optional[bool]: if self.update_filter: return self.filter(update) else: From 62579deea19004131860848923c49cf223b4cea5 Mon Sep 17 00:00:00 2001 From: Hinrich Mahler Date: Sat, 7 Mar 2020 20:48:47 +0100 Subject: [PATCH 11/16] Add dependeny for xml report --- requirements-dev.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements-dev.txt b/requirements-dev.txt index 0d26131e7df..ee24b062b6d 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -5,6 +5,7 @@ flaky yapf mypy==0.761 diff-cover +lxml pre-commit beautifulsoup4 pytest==4.2.0 From 517a468edee2f806e60db1e212c2d829fee04d80 Mon Sep 17 00:00:00 2001 From: Hinrich Mahler Date: Sun, 8 Mar 2020 10:44:12 +0100 Subject: [PATCH 12/16] Save coverage report as artifact --- .github/workflows/mypy.yml | 10 ++++++++-- .github/workflows/test.yml | 1 + requirements-dev.txt | 1 - 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml index 11ef3ce33bd..4407c3a1884 100644 --- a/.github/workflows/mypy.yml +++ b/.github/workflows/mypy.yml @@ -26,6 +26,7 @@ jobs: run: | pip install -r requirements.txt pip install -r requirements-dev.txt + pip install diff-cover lxml - name: Verify mypy types run: | mypy --version @@ -35,5 +36,10 @@ jobs: shell: bash - name: Computing typing coverage run: | - diff-cover --fail-under=100 cobertura.xml --html-report report.html - shell: bash \ No newline at end of file + diff-cover --fail-under=100 cobertura.xml --html-report typing_coverage.html + shell: bash + - name: Uploading coverage report as html + uses: actions/upload-artifact@v1 + with: + name: typing_coverage + path: typing_coverage.html \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 85df007add7..515fe78f106 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,6 +3,7 @@ on: pull_request: branches: - master + - type_hinting_master schedule: - cron: 7 3 * * * push: diff --git a/requirements-dev.txt b/requirements-dev.txt index 0d26131e7df..185f70d9cb7 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -4,7 +4,6 @@ pylint flaky yapf mypy==0.761 -diff-cover pre-commit beautifulsoup4 pytest==4.2.0 From aafac74f8b4330617294eea0202a8b18726645d4 Mon Sep 17 00:00:00 2001 From: Hinrich Mahler Date: Sun, 8 Mar 2020 10:48:50 +0100 Subject: [PATCH 13/16] Some more typing for testing --- telegram/ext/filters.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/telegram/ext/filters.py b/telegram/ext/filters.py index 2c21528dc3e..85f6c15f0e3 100644 --- a/telegram/ext/filters.py +++ b/telegram/ext/filters.py @@ -82,7 +82,7 @@ class variable. update_filter: bool = False data_filter: bool = False - def __call__(self, update: int) -> Optional[bool]: + def __call__(self, update: Update) -> Optional[bool]: if self.update_filter: return self.filter(update) else: @@ -103,7 +103,7 @@ def __repr__(self): self.name = self.__class__.__name__ return self.name - def filter(self, update): + def filter(self, update: Update) -> Optional[bool]: """This method must be overwritten. Note: From ff8b08505374e58eae5dbcd5c9df83da2b615500 Mon Sep 17 00:00:00 2001 From: Hinrich Mahler Date: Sun, 8 Mar 2020 10:55:10 +0100 Subject: [PATCH 14/16] indention --- .github/workflows/mypy.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml index 4407c3a1884..98d9deb1efa 100644 --- a/.github/workflows/mypy.yml +++ b/.github/workflows/mypy.yml @@ -40,6 +40,6 @@ jobs: shell: bash - name: Uploading coverage report as html uses: actions/upload-artifact@v1 - with: - name: typing_coverage - path: typing_coverage.html \ No newline at end of file + with: + name: typing_coverage + path: typing_coverage.html \ No newline at end of file From 7662138cd9d8fb221f7ec09924e4cc08efe23db5 Mon Sep 17 00:00:00 2001 From: Hinrich Mahler Date: Sun, 8 Mar 2020 11:27:54 +0100 Subject: [PATCH 15/16] Some more typing for testing --- telegram/ext/filters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telegram/ext/filters.py b/telegram/ext/filters.py index 85f6c15f0e3..cbc44a8e30c 100644 --- a/telegram/ext/filters.py +++ b/telegram/ext/filters.py @@ -97,7 +97,7 @@ def __or__(self, other): def __invert__(self): return InvertedFilter(self) - def __repr__(self): + def __repr__(self) -> str: # We do this here instead of in a __init__ so filter don't have to call __init__ or super() if self.name is None: self.name = self.__class__.__name__ From 8bf1a1874dad0898e111cbfbe72a3aa01de44018 Mon Sep 17 00:00:00 2001 From: Hinrich Mahler Date: Sun, 8 Mar 2020 12:53:39 +0100 Subject: [PATCH 16/16] try comparing to correct branch --- .github/workflows/mypy.yml | 8 +------- telegram/ext/filters.py | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml index 98d9deb1efa..2f1cd53bcc9 100644 --- a/.github/workflows/mypy.yml +++ b/.github/workflows/mypy.yml @@ -7,12 +7,6 @@ on: paths: - 'telegram/**' - '**.py' - push: - branches: - - master - paths: - - 'telegram/**' - - '**.py' jobs: mypy: runs-on: ubuntu-latest @@ -36,7 +30,7 @@ jobs: shell: bash - name: Computing typing coverage run: | - diff-cover --fail-under=100 cobertura.xml --html-report typing_coverage.html + diff-cover --fail-under=100 cobertura.xml --html-report typing_coverage.html --compare-branch=origin/$GITHUB_BASE_REF shell: bash - name: Uploading coverage report as html uses: actions/upload-artifact@v1 diff --git a/telegram/ext/filters.py b/telegram/ext/filters.py index 85f6c15f0e3..ac96b0e4aa4 100644 --- a/telegram/ext/filters.py +++ b/telegram/ext/filters.py @@ -136,7 +136,7 @@ def __init__(self, f): def filter(self, update): return not bool(self.f(update)) - def __repr__(self): + def __repr__(self) -> str: return "".format(self.f)