mirror of
https://github.com/esphome/esphome.git
synced 2026-10-08 03:54:03 +00:00
[core] Warn on every run that Intel Mac support ends by 2027.6.0 (#20303)
This commit is contained in:
+31
-5
@@ -7,6 +7,7 @@ import importlib
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import platform
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
@@ -54,7 +55,7 @@ from esphome.const import (
|
||||
)
|
||||
from esphome.core import CORE, EsphomeError, coroutine
|
||||
from esphome.enum import StrEnum
|
||||
from esphome.helpers import get_bool_env, indent, is_ip_address
|
||||
from esphome.helpers import IS_MACOS, get_bool_env, indent, is_ip_address
|
||||
from esphome.log import AnsiFore, color, setup_log
|
||||
from esphome.stacktrace import LogLineProcessor
|
||||
from esphome.types import ConfigType
|
||||
@@ -1311,9 +1312,9 @@ def _choose_ota_platform(config: ConfigType, requested: str | None) -> str:
|
||||
# platform's final-validate hook merges duplicates anyway.
|
||||
available: dict[str, None] = {}
|
||||
for ota_item in config.get(CONF_OTA, []):
|
||||
platform = ota_item.get(CONF_PLATFORM)
|
||||
if platform in (CONF_ESPHOME, CONF_WEB_SERVER):
|
||||
available[platform] = None
|
||||
ota_platform = ota_item.get(CONF_PLATFORM)
|
||||
if ota_platform in (CONF_ESPHOME, CONF_WEB_SERVER):
|
||||
available[ota_platform] = None
|
||||
|
||||
if not available:
|
||||
raise EsphomeError(
|
||||
@@ -1945,7 +1946,10 @@ def run_multiple_configs(
|
||||
safe_print()
|
||||
|
||||
cmd = command_builder(f)
|
||||
rc = run_external_process(*cmd)
|
||||
# The parent already logged the Intel macOS warning; children skip it.
|
||||
rc = run_external_process(
|
||||
*cmd, env={**os.environ, _INTEL_MACOS_WARNED_ENV: "1"}
|
||||
)
|
||||
|
||||
if rc == 0:
|
||||
print_bar(f"[{color(AnsiFore.BOLD_GREEN, 'SUCCESS')}] {str(f)}")
|
||||
@@ -2614,6 +2618,27 @@ def _warn_if_source_tree_mismatch() -> None:
|
||||
)
|
||||
|
||||
|
||||
_INTEL_MACOS_REMOVAL = "2027.6.0"
|
||||
_INTEL_MACOS_WARNED_ENV = "ESPHOME_INTEL_MACOS_WARNED"
|
||||
|
||||
|
||||
def _warn_if_intel_macos() -> None:
|
||||
"""Warn that Intel (x86_64) Python on macOS loses support by _INTEL_MACOS_REMOVAL."""
|
||||
if (
|
||||
not IS_MACOS
|
||||
or platform.machine() != "x86_64"
|
||||
or _INTEL_MACOS_WARNED_ENV in os.environ
|
||||
):
|
||||
return
|
||||
_LOGGER.warning(
|
||||
"Support for Intel Macs will end in ESPHome %s or earlier. The Python "
|
||||
"packages ESPHome depends on have stopped publishing Intel macOS builds, "
|
||||
"so future releases will not install on this machine. On an Apple "
|
||||
"Silicon Mac, switch to a native arm64 Python.",
|
||||
_INTEL_MACOS_REMOVAL,
|
||||
)
|
||||
|
||||
|
||||
def run_esphome(argv):
|
||||
from esphome.address_cache import AddressCache
|
||||
|
||||
@@ -2633,6 +2658,7 @@ def run_esphome(argv):
|
||||
|
||||
setup_log(log_level=args.log_level)
|
||||
_warn_if_source_tree_mismatch()
|
||||
_warn_if_intel_macos()
|
||||
|
||||
if args.command in PRE_CONFIG_ACTIONS:
|
||||
try:
|
||||
|
||||
@@ -6705,6 +6705,45 @@ def test_check_permissions_unreadable_port() -> None:
|
||||
check_permissions("/dev/ttyUSB99")
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("is_macos", "machine", "warned", "warns"),
|
||||
[
|
||||
pytest.param(True, "x86_64", False, True, id="intel_mac"),
|
||||
pytest.param(True, "x86_64", True, False, id="intel_mac_child"),
|
||||
pytest.param(True, "arm64", False, False, id="apple_silicon"),
|
||||
pytest.param(False, "x86_64", False, False, id="linux_x86_64"),
|
||||
],
|
||||
)
|
||||
def test_warn_if_intel_macos(
|
||||
is_macos: bool,
|
||||
machine: str,
|
||||
warned: bool,
|
||||
warns: bool,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Only Intel Python on macOS gets the warning, and only once per invocation."""
|
||||
monkeypatch.setattr(main, "IS_MACOS", is_macos)
|
||||
monkeypatch.setattr(main.platform, "machine", lambda: machine)
|
||||
if warned:
|
||||
monkeypatch.setenv(main._INTEL_MACOS_WARNED_ENV, "1")
|
||||
else:
|
||||
monkeypatch.delenv(main._INTEL_MACOS_WARNED_ENV, raising=False)
|
||||
|
||||
with caplog.at_level(logging.WARNING):
|
||||
main._warn_if_intel_macos()
|
||||
|
||||
assert (main._INTEL_MACOS_REMOVAL in caplog.text) is warns
|
||||
|
||||
|
||||
def test_run_multiple_configs_marks_children_warned(tmp_path: Path) -> None:
|
||||
"""Multi-config children get the env marker so they skip the Intel warning."""
|
||||
with patch.object(main, "run_external_process", return_value=0) as mock_run:
|
||||
main.run_multiple_configs([tmp_path / "a.yaml"], lambda f: ["esphome", str(f)])
|
||||
|
||||
assert mock_run.call_args.kwargs["env"][main._INTEL_MACOS_WARNED_ENV] == "1"
|
||||
|
||||
|
||||
def _make_checkout(root: Path) -> Path:
|
||||
"""Create a directory that looks like an esphome checkout."""
|
||||
(root / "esphome").mkdir(parents=True)
|
||||
|
||||
Reference in New Issue
Block a user