Skip to content

Commit

Permalink
Bump python min to 3.9 (esphome#3871)
Browse files Browse the repository at this point in the history
  • Loading branch information
jesserockz authored Oct 5, 2022
1 parent c3a8972 commit d220d41
Show file tree
Hide file tree
Showing 25 changed files with 130 additions and 147 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ repos:
rev: v3.0.0
hooks:
- id: pyupgrade
args: [--py38-plus]
args: [--py39-plus]
3 changes: 1 addition & 2 deletions esphome/components/esp8266/gpio.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import logging
from dataclasses import dataclass
from typing import List

from esphome.const import (
CONF_ID,
Expand Down Expand Up @@ -200,7 +199,7 @@ async def esp8266_pin_to_code(config):
@coroutine_with_priority(-999.0)
async def add_pin_initial_states_array():
# Add includes at the very end, so that they override everything
initial_states: List[PinInitialState] = CORE.data[KEY_ESP8266][
initial_states: list[PinInitialState] = CORE.data[KEY_ESP8266][
KEY_PIN_INITIAL_STATES
]
initial_modes_s = ", ".join(str(x.mode) for x in initial_states)
Expand Down
4 changes: 2 additions & 2 deletions esphome/components/neopixelbus/_methods.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from dataclasses import dataclass
from typing import Any, List
from typing import Any
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.const import (
Expand Down Expand Up @@ -349,7 +349,7 @@ def _spi_extra_validate(config):
class MethodDescriptor:
method_schema: Any
to_code: Any
supported_chips: List[str]
supported_chips: list[str]
extra_validate: Any = None


Expand Down
7 changes: 3 additions & 4 deletions esphome/components/select/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from typing import List
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import automation
Expand Down Expand Up @@ -60,7 +59,7 @@
)


async def setup_select_core_(var, config, *, options: List[str]):
async def setup_select_core_(var, config, *, options: list[str]):
await setup_entity(var, config)

cg.add(var.traits.set_options(options))
Expand All @@ -76,14 +75,14 @@ async def setup_select_core_(var, config, *, options: List[str]):
await mqtt.register_mqtt_component(mqtt_, config)


async def register_select(var, config, *, options: List[str]):
async def register_select(var, config, *, options: list[str]):
if not CORE.has_id(config[CONF_ID]):
var = cg.Pvariable(config[CONF_ID], var)
cg.add(cg.App.register_select(var))
await setup_select_core_(var, config, options=options)


async def new_select(config, *, options: List[str]):
async def new_select(config, *, options: list[str]):
var = cg.new_Pvariable(config[CONF_ID])
await register_select(var, config, options=options)
return var
Expand Down
52 changes: 23 additions & 29 deletions esphome/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from esphome.helpers import indent
from esphome.util import safe_print, OrderedDict

from typing import List, Optional, Tuple, Union
from typing import Optional, Union
from esphome.loader import get_component, get_platform, ComponentManifest
from esphome.yaml_util import is_secret, ESPHomeDataBase, ESPForceValue
from esphome.voluptuous_schema import ExtraKeysInvalid
Expand All @@ -50,10 +50,10 @@ def iter_components(config):
yield p_name, platform, p_config


ConfigPath = List[Union[str, int]]
ConfigPath = list[Union[str, int]]


def _path_begins_with(path, other): # type: (ConfigPath, ConfigPath) -> bool
def _path_begins_with(path: ConfigPath, other: ConfigPath) -> bool:
if len(path) < len(other):
return False
return path[: len(other)] == other
Expand All @@ -67,7 +67,7 @@ def __init__(self, priority: float, id_number: int, step: "ConfigValidationStep"
self.step = step

@property
def _cmp_tuple(self) -> Tuple[float, int]:
def _cmp_tuple(self) -> tuple[float, int]:
return (-self.priority, self.id_number)

def __eq__(self, other):
Expand All @@ -84,21 +84,20 @@ class Config(OrderedDict, fv.FinalValidateConfig):
def __init__(self):
super().__init__()
# A list of voluptuous errors
self.errors = [] # type: List[vol.Invalid]
self.errors: list[vol.Invalid] = []
# A list of paths that should be fully outputted
# The values will be the paths to all "domain", for example (['logger'], 'logger')
# or (['sensor', 'ultrasonic'], 'sensor.ultrasonic')
self.output_paths = [] # type: List[Tuple[ConfigPath, str]]
self.output_paths: list[tuple[ConfigPath, str]] = []
# A list of components ids with the config path
self.declare_ids = [] # type: List[Tuple[core.ID, ConfigPath]]
self.declare_ids: list[tuple[core.ID, ConfigPath]] = []
self._data = {}
# Store pending validation tasks (in heap order)
self._validation_tasks: List[_ValidationStepTask] = []
self._validation_tasks: list[_ValidationStepTask] = []
# ID to ensure stable order for keys with equal priority
self._validation_tasks_id = 0

def add_error(self, error):
# type: (vol.Invalid) -> None
def add_error(self, error: vol.Invalid) -> None:
if isinstance(error, vol.MultipleInvalid):
for err in error.errors:
self.add_error(err)
Expand Down Expand Up @@ -132,20 +131,16 @@ def catch_error(self, path=None):
e.prepend(path)
self.add_error(e)

def add_str_error(self, message, path):
# type: (str, ConfigPath) -> None
def add_str_error(self, message: str, path: ConfigPath) -> None:
self.add_error(vol.Invalid(message, path))

def add_output_path(self, path, domain):
# type: (ConfigPath, str) -> None
def add_output_path(self, path: ConfigPath, domain: str) -> None:
self.output_paths.append((path, domain))

def remove_output_path(self, path, domain):
# type: (ConfigPath, str) -> None
def remove_output_path(self, path: ConfigPath, domain: str) -> None:
self.output_paths.remove((path, domain))

def is_in_error_path(self, path):
# type: (ConfigPath) -> bool
def is_in_error_path(self, path: ConfigPath) -> bool:
for err in self.errors:
if _path_begins_with(err.path, path):
return True
Expand All @@ -157,16 +152,16 @@ def set_by_path(self, path, value):
conf = conf[key]
conf[path[-1]] = value

def get_error_for_path(self, path):
# type: (ConfigPath) -> Optional[vol.Invalid]
def get_error_for_path(self, path: ConfigPath) -> Optional[vol.Invalid]:
for err in self.errors:
if self.get_deepest_path(err.path) == path:
self.errors.remove(err)
return err
return None

def get_deepest_document_range_for_path(self, path, get_key=False):
# type: (ConfigPath, bool) -> Optional[ESPHomeDataBase]
def get_deepest_document_range_for_path(
self, path: ConfigPath, get_key: bool = False
) -> Optional[ESPHomeDataBase]:
data = self
doc_range = None
for index, path_item in enumerate(path):
Expand Down Expand Up @@ -207,8 +202,7 @@ def get_nested_item(
return {}
return data

def get_deepest_path(self, path):
# type: (ConfigPath) -> ConfigPath
def get_deepest_path(self, path: ConfigPath) -> ConfigPath:
"""Return the path that is the deepest reachable by following path."""
data = self
part = []
Expand Down Expand Up @@ -532,7 +526,7 @@ def run(self, result: Config) -> None:
# because the component that did not validate doesn't have any IDs set
return

searching_ids = [] # type: List[Tuple[core.ID, ConfigPath]]
searching_ids: list[tuple[core.ID, ConfigPath]] = []
for id, path in iter_ids(result):
if id.is_declaration:
if id.id is not None:
Expand Down Expand Up @@ -780,8 +774,7 @@ def _get_parent_name(path, config):
return path[-1]


def _format_vol_invalid(ex, config):
# type: (vol.Invalid, Config) -> str
def _format_vol_invalid(ex: vol.Invalid, config: Config) -> str:
message = ""

paren = _get_parent_name(ex.path[:-1], config)
Expand Down Expand Up @@ -862,8 +855,9 @@ def _print_on_next_line(obj):
return False


def dump_dict(config, path, at_root=True):
# type: (Config, ConfigPath, bool) -> Tuple[str, bool]
def dump_dict(
config: Config, path: ConfigPath, at_root: bool = True
) -> tuple[str, bool]:
conf = config.get_nested_item(path)
ret = ""
multiline = False
Expand Down
3 changes: 1 addition & 2 deletions esphome/config_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
from esphome.helpers import read_file


def read_config_file(path):
# type: (str) -> str
def read_config_file(path: str) -> str:
if CORE.vscode and (
not CORE.ace or os.path.abspath(path) == os.path.abspath(CORE.config_path)
):
Expand Down
20 changes: 10 additions & 10 deletions esphome/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import math
import os
import re
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple, Union
from typing import TYPE_CHECKING, Optional, Union

from esphome.const import (
CONF_COMMENT,
Expand Down Expand Up @@ -469,19 +469,19 @@ def __init__(self):
# Task counter for pending tasks
self.task_counter = 0
# The variable cache, for each ID this holds a MockObj of the variable obj
self.variables: Dict[str, "MockObj"] = {}
self.variables: dict[str, "MockObj"] = {}
# A list of statements that go in the main setup() block
self.main_statements: List["Statement"] = []
self.main_statements: list["Statement"] = []
# A list of statements to insert in the global block (includes and global variables)
self.global_statements: List["Statement"] = []
self.global_statements: list["Statement"] = []
# A set of platformio libraries to add to the project
self.libraries: List[Library] = []
self.libraries: list[Library] = []
# A set of build flags to set in the platformio project
self.build_flags: Set[str] = set()
self.build_flags: set[str] = set()
# A set of defines to set for the compile process in esphome/core/defines.h
self.defines: Set["Define"] = set()
self.defines: set["Define"] = set()
# A map of all platformio options to apply
self.platformio_options: Dict[str, Union[str, List[str]]] = {}
self.platformio_options: dict[str, Union[str, list[str]]] = {}
# A set of strings of names of loaded integrations, used to find namespace ID conflicts
self.loaded_integrations = set()
# A set of component IDs to track what Component subclasses are declared
Expand Down Expand Up @@ -701,7 +701,7 @@ def add_define(self, define):
_LOGGER.debug("Adding define: %s", define)
return define

def add_platformio_option(self, key: str, value: Union[str, List[str]]) -> None:
def add_platformio_option(self, key: str, value: Union[str, list[str]]) -> None:
new_val = value
old_val = self.platformio_options.get(key)
if isinstance(old_val, list):
Expand Down Expand Up @@ -734,7 +734,7 @@ def _get_variable_with_full_id_generator(self, id):
_LOGGER.debug("Waiting for variable %s", id)
yield

async def get_variable_with_full_id(self, id: ID) -> Tuple[ID, "MockObj"]:
async def get_variable_with_full_id(self, id: ID) -> tuple[ID, "MockObj"]:
if not isinstance(id, ID):
raise ValueError(f"ID {id!r} must be of type ID!")
return await _FakeAwaitable(self._get_variable_with_full_id_generator(id))
Expand Down
7 changes: 4 additions & 3 deletions esphome/coroutine.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ def my_coroutine(config):
import inspect
import logging
import types
from typing import Any, Awaitable, Callable, Generator, Iterator, List, Tuple
from typing import Any, Callable
from collections.abc import Awaitable, Generator, Iterator

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -177,7 +178,7 @@ def with_priority(self, priority: float) -> "_Task":
return _Task(priority, self.id_number, self.iterator, self.original_function)

@property
def _cmp_tuple(self) -> Tuple[float, int]:
def _cmp_tuple(self) -> tuple[float, int]:
return (-self.priority, self.id_number)

def __eq__(self, other):
Expand All @@ -194,7 +195,7 @@ class FakeEventLoop:
"""Emulate an asyncio EventLoop to run some registered coroutine jobs in sequence."""

def __init__(self):
self._pending_tasks: List[_Task] = []
self._pending_tasks: list[_Task] = []
self._task_counter = 0

def add_job(self, func, *args, **kwargs):
Expand Down
26 changes: 11 additions & 15 deletions esphome/cpp_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,10 @@
from typing import (
Any,
Callable,
Generator,
List,
Optional,
Tuple,
Type,
Union,
Sequence,
)
from collections.abc import Generator, Sequence

from esphome.core import ( # noqa
CORE,
Expand Down Expand Up @@ -54,9 +50,9 @@ def __str__(self):
int,
float,
TimePeriod,
Type[bool],
Type[int],
Type[float],
type[bool],
type[int],
type[float],
Sequence[Any],
]

Expand Down Expand Up @@ -150,7 +146,7 @@ def __str__(self):
class StructInitializer(Expression):
__slots__ = ("base", "args")

def __init__(self, base: Expression, *args: Tuple[str, Optional[SafeExpType]]):
def __init__(self, base: Expression, *args: tuple[str, Optional[SafeExpType]]):
self.base = base
# TODO: args is always a Tuple, is this check required?
if not isinstance(args, OrderedDict):
Expand Down Expand Up @@ -210,7 +206,7 @@ class ParameterListExpression(Expression):
__slots__ = ("parameters",)

def __init__(
self, *parameters: Union[ParameterExpression, Tuple[SafeExpType, str]]
self, *parameters: Union[ParameterExpression, tuple[SafeExpType, str]]
):
self.parameters = []
for parameter in parameters:
Expand Down Expand Up @@ -629,7 +625,7 @@ def add_define(name: str, value: SafeExpType = None):
CORE.add_define(Define(name, safe_exp(value)))


def add_platformio_option(key: str, value: Union[str, List[str]]):
def add_platformio_option(key: str, value: Union[str, list[str]]):
CORE.add_platformio_option(key, value)


Expand All @@ -646,7 +642,7 @@ async def get_variable(id_: ID) -> "MockObj":
return await CORE.get_variable(id_)


async def get_variable_with_full_id(id_: ID) -> Tuple[ID, "MockObj"]:
async def get_variable_with_full_id(id_: ID) -> tuple[ID, "MockObj"]:
"""
Wait for the given ID to be defined in the code generation and
return it as a MockObj.
Expand All @@ -661,7 +657,7 @@ async def get_variable_with_full_id(id_: ID) -> Tuple[ID, "MockObj"]:

async def process_lambda(
value: Lambda,
parameters: List[Tuple[SafeExpType, str]],
parameters: list[tuple[SafeExpType, str]],
capture: str = "=",
return_type: SafeExpType = None,
) -> Generator[LambdaExpression, None, None]:
Expand Down Expand Up @@ -715,7 +711,7 @@ def is_template(value):

async def templatable(
value: Any,
args: List[Tuple[SafeExpType, str]],
args: list[tuple[SafeExpType, str]],
output_type: Optional[SafeExpType],
to_exp: Any = None,
):
Expand Down Expand Up @@ -763,7 +759,7 @@ def __getattr__(self, attr: str) -> "MockObj":
attr = attr[1:]
return MockObj(f"{self.base}{self.op}{attr}", next_op)

def __call__(self, *args): # type: (SafeExpType) -> MockObj
def __call__(self, *args: SafeExpType) -> "MockObj":
call = CallExpression(self.base, *args)
return MockObj(call, self.op)

Expand Down
Loading

0 comments on commit d220d41

Please sign in to comment.