Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TEST: Mypy #55

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 145 additions & 5 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ env:
MYPY_CACHE_VERSION: 8
HA_SHORT_VERSION: "2024.5"
DEFAULT_PYTHON: "3.12"
# Only use default version below
ALL_PYTHON_VERSIONS: "['3.12']"
# 10.3 is the oldest supported version
# - 10.3.32 is the version currently shipped with Synology (as of 17 Feb 2022)
Expand All @@ -61,9 +62,9 @@ env:
PYTHONASYNCIODEBUG: 1
HASS_CI: 1

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
# concurrency:
# group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
# cancel-in-progress: true

jobs:
info:
Expand Down Expand Up @@ -460,6 +461,7 @@ jobs:
with:
path: venv
lookup-only: true
fail-on-cache-miss: true
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}
Expand Down Expand Up @@ -620,6 +622,11 @@ jobs:
needs:
- info
- base
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CACHING: true
REMOTE: cdce8p
BRANCH: dev
steps:
- name: Check out code from GitHub
uses: actions/[email protected]
Expand All @@ -629,10 +636,32 @@ jobs:
with:
python-version: ${{ env.DEFAULT_PYTHON }}
check-latest: true

- name: Fetch mypy version string (${{ env.BRANCH }})
id: fetch-version
run: |
echo "Checking mypy branch: ${{ env.BRANCH }}"
base=$(curl -sS \
https://raw.githubusercontent.com/${{ env.REMOTE }}/mypy/${{ env.BRANCH }}/mypy/version.py | \
grep -e ^__version__ | \
cut -d '=' -f2 | tr -d ' "')
sha=$(gh api \
-H "Accept: application/vnd.github+json" \
/repos/${{ env.REMOTE }}/mypy/git/ref/heads/${{ env.BRANCH }} | \
jq -r '.object.sha')
if [[ $base == *"+dev" ]]; then
version="v$base.$sha"
else
version="v$base"
fi
echo "version=$version" >> $GITHUB_OUTPUT
echo "name=(${{ env.BRANCH }} -- $version)" >> $GITHUB_OUTPUT
echo "Found: $version"

- name: Generate partial mypy restore key
id: generate-mypy-key
run: |
mypy_version=$(cat requirements_test.txt | grep mypy | cut -d '=' -f 3)
mypy_version=${{ steps.fetch-version.outputs.version }}
echo "version=$mypy_version" >> $GITHUB_OUTPUT
echo "key=mypy-${{ env.MYPY_CACHE_VERSION }}-$mypy_version-${{
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')" >> $GITHUB_OUTPUT
Expand All @@ -645,8 +674,105 @@ jobs:
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
needs.info.outputs.python_cache_key }}

- name: Remove old mypy version
run: |
. venv/bin/activate
pip uninstall -y mypy
- name: Restore custom mypy version in venv ${{ steps.fetch-version.outputs.name }}
id: cache-venv-mypy
uses: actions/cache/[email protected]
with:
path: |
venv/lib/python*/site-packages/*__mypyc.cpython-*.so
venv/lib/python*/site-packages/mypy*
venv/bin/mypy
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-venv_mypy-${{
env.CACHE_VERSION }}-${{ steps.fetch-version.outputs.version }}-compiled
restore-keys: |
${{ runner.os }}-${{ steps.python.outputs.python-version }}-venv_mypy-${{
env.CACHE_VERSION }}-${{ steps.fetch-version.outputs.version }}-compiled-custom
${{ runner.os }}-${{ steps.python.outputs.python-version }}-venv_mypy-${{
env.CACHE_VERSION }}-${{ steps.fetch-version.outputs.version }}
- name: Install compiled version if available
if: steps.cache-venv-mypy.outputs.cache-hit != 'true'
id: install-compiled
continue-on-error: true
run: |
. venv/bin/activate
tag=${{ steps.fetch-version.outputs.version }}
echo "$tag"
res=$(gh api \
-H "Accept: application/vnd.github+json" \
/repos/mypyc/mypy_mypyc-wheels/releases/tags/$tag)
py=$(echo ${{ env.DEFAULT_PYTHON }} | tr -d '.')
url=$(echo $res | jq -r \
--arg search_name "$py-manylinux" \
'.assets[] | select(.name | test($search_name)) .browser_download_url')
if [[ -n url ]]; then
echo "Found compiled version"
pip install -U $url
echo "status=done" >> $GITHUB_OUTPUT
echo "key-suffix=-compiled" >> $GITHUB_OUTPUT
exit 0
fi
- name: Install compiled version if available (custom)
if: |
steps.cache-venv-mypy.outputs.cache-hit != 'true'
&& steps.install-compiled.outputs.status != 'done'
&& endsWith( steps.cache-venv-mypy.outputs.cache-matched-key, '-compiled-custom' ) != true
id: install-compiled-custom
continue-on-error: true
run: |
. venv/bin/activate
tag=${{ steps.fetch-version.outputs.version }}
echo "$tag"
res=$(gh api \
-H "Accept: application/vnd.github+json" \
/repos/${{ env.REMOTE }}/mypy-wheels/releases/tags/$tag)
py=$(echo ${{ env.DEFAULT_PYTHON }} | tr -d '.')
url=$(echo $res | jq -r \
--arg search_name "$py-manylinux" \
'.assets[] | select(.name | test($search_name)) .browser_download_url')
if [[ -n url ]]; then
echo "Found compiled version"
pip install -U $url
echo "status=done" >> $GITHUB_OUTPUT
echo "key-suffix=-compiled-custom" >> $GITHUB_OUTPUT
exit 0
fi
- name: Install custom dependencies
if: |
steps.cache-venv-mypy.outputs.cache-matched-key == ''
&& steps.install-compiled.outputs.status != 'done'
&& steps.install-compiled-custom.outputs.status != 'done'
run: |
. venv/bin/activate
python --version
pip install -U git+https://github.com/${{ env.REMOTE }}/mypy.git@${{ env.BRANCH }}
- name: Save mypy version in venv
if: |
steps.cache-venv-mypy.outputs.cache-hit != 'true'
&& (
steps.cache-venv-mypy.outputs.cache-matched-key == ''
|| steps.install-compiled.outputs.status == 'done'
|| steps.install-compiled-custom.outputs.status == 'done'
)
uses: actions/cache/[email protected]
with:
path: |
venv/lib/python*/site-packages/*__mypyc.cpython-*.so
venv/lib/python*/site-packages/mypy*
venv/bin/mypy
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-venv_mypy-${{
env.CACHE_VERSION }}-${{ steps.fetch-version.outputs.version }}${{
steps.install-compiled.outputs.key-suffix || steps.install-compiled-custom.outputs.key-suffix }}

- name: Restore mypy cache
uses: actions/[email protected]
if: env.CACHING != 'false'
uses: actions/cache/[email protected]
with:
path: .mypy_cache
key: >-
Expand All @@ -664,6 +790,9 @@ jobs:
run: |
. venv/bin/activate
python --version
git branch --show-current
# For issues with serialize, add --cache-dir=/dev/null
# To install types: --install-types --non-interactive
mypy homeassistant pylint
- name: Run mypy (partially)
if: needs.info.outputs.test_full_suite == 'false'
Expand All @@ -672,10 +801,19 @@ jobs:
. venv/bin/activate
python --version
mypy homeassistant/components/${{ needs.info.outputs.integrations_glob }}
- name: Save mypy cache
if: success() || failure()
uses: actions/cache/[email protected]
with:
path: .mypy_cache
key: >-
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
steps.generate-mypy-key.outputs.key }}

prepare-pytest-full:
runs-on: ubuntu-22.04
if: |
false &&
(github.event_name != 'push' || github.event.repository.full_name == 'home-assistant/core')
&& github.event.inputs.lint-only != 'true'
&& github.event.inputs.pylint-only != 'true'
Expand Down Expand Up @@ -840,6 +978,7 @@ jobs:
MYSQL_ROOT_PASSWORD: password
options: --health-cmd="mysqladmin ping -uroot -ppassword" --health-interval=5s --health-timeout=2s --health-retries=3
if: |
false &&
(github.event_name != 'push' || github.event.repository.full_name == 'home-assistant/core')
&& github.event.inputs.lint-only != 'true'
&& github.event.inputs.pylint-only != 'true'
Expand Down Expand Up @@ -962,6 +1101,7 @@ jobs:
POSTGRES_PASSWORD: password
options: --health-cmd="pg_isready -hlocalhost -Upostgres" --health-interval=5s --health-timeout=2s --health-retries=3
if: |
false &&
(github.event_name != 'push' || github.event.repository.full_name == 'home-assistant/core')
&& github.event.inputs.lint-only != 'true'
&& github.event.inputs.pylint-only != 'true'
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/util/enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def lru_cache(func: _LruCacheT) -> _LruCacheT:
"""Stub for lru_cache."""

else:
from functools import lru_cache
from functools import lru_cache # TODO # pylint: disable=fixme

_EnumT = TypeVar("_EnumT", bound=Enum)

Expand Down
1 change: 1 addition & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ platform = linux
plugins = pydantic.mypy
show_error_codes = true
follow_imports = normal
show_traceback = true
local_partial_types = true
strict_equality = true
no_implicit_optional = true
Expand Down
2 changes: 2 additions & 0 deletions script/hassfest/mypy_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
"plugins": "pydantic.mypy",
"show_error_codes": "true",
"follow_imports": "normal",
"show_traceback": "true",
# "enable_incomplete_feature": ",".join(["PreciseTupleTypes"]),
# Enable some checks globally.
"local_partial_types": "true",
"strict_equality": "true",
Expand Down