Skip to content

Commit

Permalink
Drop Python 3.6 support (home-assistant#29978)
Browse files Browse the repository at this point in the history
  • Loading branch information
scop authored and balloob committed Dec 16, 2019
1 parent bfafa77 commit 445fd15
Show file tree
Hide file tree
Showing 15 changed files with 19 additions and 135 deletions.
1 change: 0 additions & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ omit =
homeassistant/__main__.py
homeassistant/helpers/signal.py
homeassistant/helpers/typing.py
homeassistant/monkey_patch.py
homeassistant/scripts/*.py
homeassistant/util/async.py

Expand Down
2 changes: 1 addition & 1 deletion .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build:
image: latest

python:
version: 3.6
version: 3.7
setup_py_install: true

requirements_file: requirements_docs.txt
10 changes: 4 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,13 @@ addons:
matrix:
fast_finish: true
include:
- python: "3.6.1"
- python: "3.7.0"
env: TOXENV=lint
- python: "3.6.1"
- python: "3.7.0"
env: TOXENV=pylint PYLINT_ARGS=--jobs=0 TRAVIS_WAIT=30
- python: "3.6.1"
- python: "3.7.0"
env: TOXENV=typing
- python: "3.6.1"
env: TOXENV=py36
- python: "3.7"
- python: "3.7.0"
env: TOXENV=py37

cache:
Expand Down
6 changes: 1 addition & 5 deletions azure-pipelines-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ pr:

resources:
containers:
- container: 36
image: homeassistant/ci-azure:3.6
- container: 37
image: homeassistant/ci-azure:3.7
repositories:
Expand All @@ -25,7 +23,7 @@ resources:
endpoint: 'home-assistant'
variables:
- name: PythonMain
value: '36'
value: '37'
- group: codecov

stages:
Expand Down Expand Up @@ -108,8 +106,6 @@ stages:
strategy:
maxParallel: 3
matrix:
Python36:
python.container: '36'
Python37:
python.container: '37'
container: $[ variables['python.container'] ]
Expand Down
14 changes: 3 additions & 11 deletions homeassistant/__main__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
"""Start Home Assistant."""
import argparse
import asyncio
import os
import platform
import subprocess
import sys
import threading
from typing import TYPE_CHECKING, Any, Dict, List

from homeassistant import monkey_patch
from homeassistant.const import REQUIRED_PYTHON_VER, RESTART_EXIT_CODE, __version__

if TYPE_CHECKING:
Expand All @@ -16,7 +16,6 @@

def set_loop() -> None:
"""Attempt to use different loop."""
import asyncio
from asyncio.events import BaseDefaultEventLoopPolicy

if sys.platform == "win32":
Expand Down Expand Up @@ -345,11 +344,6 @@ def main() -> int:
"""Start Home Assistant."""
validate_python()

monkey_patch_needed = sys.version_info[:3] < (3, 6, 3)
if monkey_patch_needed and os.environ.get("HASS_NO_MONKEY") != "1":
monkey_patch.disable_c_asyncio()
monkey_patch.patch_weakref_tasks()

set_loop()

# Run a simple daemon runner process on Windows to handle restarts
Expand Down Expand Up @@ -383,13 +377,11 @@ def main() -> int:
if args.pid_file:
write_pid(args.pid_file)

from homeassistant.util.async_ import asyncio_run

exit_code = asyncio_run(setup_and_run_hass(config_dir, args))
exit_code = asyncio.run(setup_and_run_hass(config_dir, args))
if exit_code == RESTART_EXIT_CODE and not args.runner:
try_to_restart()

return exit_code # type: ignore
return exit_code


if __name__ == "__main__":
Expand Down
6 changes: 3 additions & 3 deletions homeassistant/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
PATCH_VERSION = "0.dev0"
__short_version__ = "{}.{}".format(MAJOR_VERSION, MINOR_VERSION)
__version__ = "{}.{}".format(__short_version__, PATCH_VERSION)
REQUIRED_PYTHON_VER = (3, 6, 1)
REQUIRED_PYTHON_VER = (3, 7, 0)
# Truthy date string triggers showing related deprecation warning messages.
REQUIRED_NEXT_PYTHON_VER = (3, 7, 0)
REQUIRED_NEXT_PYTHON_DATE = "December 15, 2019"
REQUIRED_NEXT_PYTHON_VER = (3, 8, 0)
REQUIRED_NEXT_PYTHON_DATE = ""

# Format for platform files
PLATFORM_FORMAT = "{platform}.{domain}"
Expand Down
73 changes: 0 additions & 73 deletions homeassistant/monkey_patch.py

This file was deleted.

3 changes: 1 addition & 2 deletions homeassistant/package_constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ async_timeout==3.0.1
attrs==19.3.0
bcrypt==3.1.7
certifi>=2019.11.28
contextvars==2.4;python_version<"3.7"
cryptography==2.8
defusedxml==0.6.0
distro==1.4.0
Expand All @@ -29,7 +28,7 @@ zeroconf==0.24.0

pycryptodome>=3.6.6

# Breaks Python 3.6 and is not needed for our supported Python versions
# Not needed for our supported Python versions
enum34==1000000000.0.0

# This is a old unmaintained library and is replaced with pycryptodome
Expand Down
21 changes: 1 addition & 20 deletions homeassistant/util/async_.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,14 @@
"""Asyncio backports for Python 3.6 compatibility."""
import asyncio
from asyncio import coroutines, ensure_future
from asyncio.events import AbstractEventLoop
import concurrent.futures
import logging
import threading
from typing import Any, Awaitable, Callable, Coroutine, TypeVar
from typing import Any, Callable, Coroutine

_LOGGER = logging.getLogger(__name__)


try:
# pylint: disable=invalid-name
asyncio_run = asyncio.run # type: ignore
except AttributeError:
_T = TypeVar("_T")

def asyncio_run(main: Awaitable[_T], *, debug: bool = False) -> _T:
"""Minimal re-implementation of asyncio.run (since 3.7)."""
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.set_debug(debug)
try:
return loop.run_until_complete(main)
finally:
asyncio.set_event_loop(None)
loop.close()


def fire_coroutine_threadsafe(coro: Coroutine, loop: AbstractEventLoop) -> None:
"""Submit a coroutine object to a given event loop.
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[tool.black]
target-version = ["py36", "py37", "py38"]
target-version = ["py37", "py38"]
exclude = 'generated'
1 change: 0 additions & 1 deletion requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ async_timeout==3.0.1
attrs==19.3.0
bcrypt==3.1.7
certifi>=2019.11.28
contextvars==2.4;python_version<"3.7"
importlib-metadata==0.23
jinja2>=2.10.3
PyJWT==1.7.1
Expand Down
2 changes: 1 addition & 1 deletion script/gen_requirements_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
CONSTRAINT_BASE = """
pycryptodome>=3.6.6
# Breaks Python 3.6 and is not needed for our supported Python versions
# Not needed for our supported Python versions
enum34==1000000000.0.0
# This is a old unmaintained library and is replaced with pycryptodome
Expand Down
5 changes: 2 additions & 3 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ classifier =
Intended Audience :: Developers
License :: OSI Approved :: Apache Software License
Operating System :: OS Independent
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Topic :: Home Automation

Expand Down Expand Up @@ -57,15 +56,15 @@ forced_separate = tests
combine_as_imports = true

[mypy]
python_version = 3.6
python_version = 3.7
ignore_errors = true
follow_imports = silent
ignore_missing_imports = true
warn_incomplete_stub = true
warn_redundant_casts = true
warn_unused_configs = true

[mypy-homeassistant.bootstrap,homeassistant.components,homeassistant.config_entries,homeassistant.config,homeassistant.const,homeassistant.core,homeassistant.data_entry_flow,homeassistant.exceptions,homeassistant.loader,homeassistant.__main__,homeassistant.monkey_patch,homeassistant.requirements,homeassistant.setup,homeassistant.util,homeassistant.auth.*,homeassistant.components.automation.*,homeassistant.components.binary_sensor.*,homeassistant.components.calendar.*,homeassistant.components.cover.*,homeassistant.components.device_automation.*,homeassistant.components.frontend.*,homeassistant.components.geo_location.*,homeassistant.components.group.*,homeassistant.components.history.*,homeassistant.components.http.*,homeassistant.components.image_processing.*,homeassistant.components.integration.*,homeassistant.components.light.*,homeassistant.components.lock.*,homeassistant.components.mailbox.*,homeassistant.components.media_player.*,homeassistant.components.notify.*,homeassistant.components.persistent_notification.*,homeassistant.components.proximity.*,homeassistant.components.remote.*,homeassistant.components.scene.*,homeassistant.components.sensor.*,homeassistant.components.sun.*,homeassistant.components.switch.*,homeassistant.components.systemmonitor.*,homeassistant.components.tts.*,homeassistant.components.vacuum.*,homeassistant.components.water_heater.*,homeassistant.components.weather.*,homeassistant.components.websocket_api.*,homeassistant.components.zone.*,homeassistant.helpers.*,homeassistant.scripts.*,homeassistant.util.*]
[mypy-homeassistant.bootstrap,homeassistant.components,homeassistant.config_entries,homeassistant.config,homeassistant.const,homeassistant.core,homeassistant.data_entry_flow,homeassistant.exceptions,homeassistant.loader,homeassistant.__main__,homeassistant.requirements,homeassistant.setup,homeassistant.util,homeassistant.auth.*,homeassistant.components.automation.*,homeassistant.components.binary_sensor.*,homeassistant.components.calendar.*,homeassistant.components.cover.*,homeassistant.components.device_automation.*,homeassistant.components.frontend.*,homeassistant.components.geo_location.*,homeassistant.components.group.*,homeassistant.components.history.*,homeassistant.components.http.*,homeassistant.components.image_processing.*,homeassistant.components.integration.*,homeassistant.components.light.*,homeassistant.components.lock.*,homeassistant.components.mailbox.*,homeassistant.components.media_player.*,homeassistant.components.notify.*,homeassistant.components.persistent_notification.*,homeassistant.components.proximity.*,homeassistant.components.remote.*,homeassistant.components.scene.*,homeassistant.components.sensor.*,homeassistant.components.sun.*,homeassistant.components.switch.*,homeassistant.components.systemmonitor.*,homeassistant.components.tts.*,homeassistant.components.vacuum.*,homeassistant.components.water_heater.*,homeassistant.components.weather.*,homeassistant.components.websocket_api.*,homeassistant.components.zone.*,homeassistant.helpers.*,homeassistant.scripts.*,homeassistant.util.*]
ignore_errors = false
check_untyped_defs = true
disallow_incomplete_defs = true
Expand Down
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
"attrs==19.3.0",
"bcrypt==3.1.7",
"certifi>=2019.11.28",
'contextvars==2.4;python_version<"3.7"',
"importlib-metadata==0.23",
"jinja2>=2.10.3",
"PyJWT==1.7.1",
Expand Down
7 changes: 1 addition & 6 deletions tests/util/test_async.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Tests for async util methods from Python source."""
import asyncio
import sys
from unittest import TestCase
from unittest.mock import MagicMock, patch

Expand Down Expand Up @@ -112,11 +111,7 @@ def add_coroutine(self, a, b, fail, invalid, cancel):
"""Wait 0.05 second and return a + b."""
yield from asyncio.sleep(0.05, loop=self.loop)
if cancel:
if sys.version_info[:2] >= (3, 7):
current_task = asyncio.current_task
else:
current_task = asyncio.tasks.Task.current_task
current_task(self.loop).cancel()
asyncio.current_task(self.loop).cancel()
yield
return self.add_callback(a, b, fail, invalid)

Expand Down

0 comments on commit 445fd15

Please sign in to comment.