[core] Enable ruff PIE (flake8-pie) lint family (#16658)

This commit is contained in:
J. Nick Koston
2026-05-26 06:46:44 -05:00
committed by GitHub
parent 8b62cfded7
commit ceb9d406e1
15 changed files with 25 additions and 33 deletions

View File

@@ -100,7 +100,7 @@ def position(min=-MAX_POSITION, max=MAX_POSITION):
if isinstance(value, str) and value.endswith("%"):
value = percent_to_position(value)
if isinstance(value, str) and (value.endswith("°") or value.endswith("deg")):
if isinstance(value, str) and value.endswith(("°", "deg")):
return angle_to_position(
value,
min=round(min * POSITION_TO_ANGLE),

View File

@@ -72,7 +72,7 @@ def _file_schema(value: ConfigType | str) -> ConfigType:
def _validate_file_shorthand(value: str) -> ConfigType:
value = cv.string_strict(value)
if value.startswith("http://") or value.startswith("https://"):
if value.startswith(("http://", "https://")):
return _file_schema(
{
CONF_TYPE: TYPE_WEB,

View File

@@ -401,7 +401,7 @@ def validate_file_shorthand(value):
data[CONF_WEIGHT] = weight[1:]
return font_file_schema(data)
if value.startswith("http://") or value.startswith("https://"):
if value.startswith(("http://", "https://")):
return font_file_schema(
{
CONF_TYPE: TYPE_WEB,

View File

@@ -65,7 +65,7 @@ CONF_JSON = "json"
def validate_url(value):
value = cv.url(value)
if value.startswith("http://") or value.startswith("https://"):
if value.startswith(("http://", "https://")):
return value
raise cv.Invalid("URL must start with 'http://' or 'https://'")

View File

@@ -408,7 +408,7 @@ def validate_file_shorthand(value):
raise cv.Invalid(f"Could not parse mdi icon name from '{value}'.")
return download_gh_svg(parts[1], parts[0])
if value.startswith("http://") or value.startswith("https://"):
if value.startswith(("http://", "https://")):
return download_image(value)
value = cv.file_(value)

View File

@@ -112,7 +112,7 @@ def expand_file_to_files(config: dict):
def validate_yaml_filename(value):
value = cv.string(value)
if not (value.endswith(".yaml") or value.endswith(".yml")):
if not value.endswith((".yaml", ".yml")):
raise cv.Invalid("Only YAML (.yaml / .yml) files are supported.")
return value

View File

@@ -418,11 +418,11 @@ async def setup_time_core_(time_var, config):
for conf in config.get(CONF_ON_TIME, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], time_var)
seconds = conf.get(CONF_SECONDS, list(range(0, 61)))
seconds = conf.get(CONF_SECONDS, list(range(61)))
cg.add(trigger.add_seconds(seconds))
minutes = conf.get(CONF_MINUTES, list(range(0, 60)))
minutes = conf.get(CONF_MINUTES, list(range(60)))
cg.add(trigger.add_minutes(minutes))
hours = conf.get(CONF_HOURS, list(range(0, 24)))
hours = conf.get(CONF_HOURS, list(range(24)))
cg.add(trigger.add_hours(hours))
days_of_month = conf.get(CONF_DAYS_OF_MONTH, list(range(1, 32)))
cg.add(trigger.add_days_of_month(days_of_month))

View File

@@ -28,10 +28,12 @@ class AnsiFore(Enum):
class AnsiStyle(Enum):
# BOLD/BRIGHT and THIN/DIM are intentional ANSI synonyms; Enum treats the
# second name in each pair as an alias of the first.
BRIGHT = "\033[1m"
BOLD = "\033[1m"
BOLD = "\033[1m" # noqa: PIE796
DIM = "\033[2m"
THIN = "\033[2m"
THIN = "\033[2m" # noqa: PIE796
NORMAL = "\033[22m"
RESET_ALL = "\033[0m"

View File

@@ -57,7 +57,7 @@ def get_port_type(port: str) -> PortType:
"""
if port == "BOOTSEL":
return PortType.BOOTSEL
if port.startswith("/") or port.startswith("COM"):
if port.startswith(("/", "COM")):
return PortType.SERIAL
if port == "MQTT":
return PortType.MQTT

View File

@@ -126,6 +126,7 @@ select = [
"LOG", # flake8-logging
"NPY", # numpy-specific rules
"PERF", # performance
"PIE", # flake8-pie
"PL", # pylint
"PTH", # flake8-use-pathlib
"PYI", # flake8-pyi

View File

@@ -84,12 +84,7 @@ def indent_list(text: str, padding: str = " ") -> list[str]:
"""Indent each line of the given text with the specified padding."""
lines = []
for line in text.splitlines():
if (
line == ""
or line.startswith("#ifdef")
or line.startswith("#if ")
or line.startswith("#endif")
):
if line == "" or line.startswith(("#ifdef", "#if ", "#endif")):
p = ""
else:
p = padding

View File

@@ -483,9 +483,7 @@ def should_run_device_builder(branch: str | None = None) -> bool:
True if the device-builder downstream tests should run, False otherwise.
"""
target_branch = get_target_branch()
if target_branch and (
target_branch.startswith("release") or target_branch.startswith("beta")
):
if target_branch and (target_branch.startswith(("release", "beta"))):
return False
for file in changed_files(branch):
@@ -955,9 +953,7 @@ def detect_memory_impact_config(
# all components at once would produce nonsensical memory impact results.
# Memory impact analysis is most useful for focused PRs targeting dev.
target_branch = get_target_branch()
if target_branch and (
target_branch.startswith("release") or target_branch.startswith("beta")
):
if target_branch and (target_branch.startswith(("release", "beta"))):
print(
f"Memory impact: Skipping analysis for target branch {target_branch} "
f"(would try to build all components at once, giving nonsensical results)",
@@ -1311,7 +1307,7 @@ def main() -> None:
# (no isolation, all components are groupable)
target_branch = get_target_branch()
is_release_branch = target_branch and (
target_branch.startswith("release") or target_branch.startswith("beta")
target_branch.startswith(("release", "beta"))
)
if is_release_branch:

View File

@@ -103,9 +103,7 @@ def get_component_from_path(file_path: str) -> str | None:
Returns:
Component name if path is in components or tests directory, None otherwise
"""
if file_path.startswith(ESPHOME_COMPONENTS_PATH) or file_path.startswith(
ESPHOME_TESTS_COMPONENTS_PATH
):
if file_path.startswith((ESPHOME_COMPONENTS_PATH, ESPHOME_TESTS_COMPONENTS_PATH)):
parts = file_path.split("/")
if len(parts) >= 3 and parts[2]:
# Verify that parts[2] is actually a component directory, not a file
@@ -160,7 +158,7 @@ def is_validate_only_file(test_file: Path) -> bool:
``esphome config`` only and skipped during compile.
"""
name = test_file.name
return name.startswith("validate.") or name.startswith("validate-")
return name.startswith(("validate.", "validate-"))
@dataclass(frozen=True)

View File

@@ -43,7 +43,7 @@ async def test_gpio_expander_cache(
# ensure logs are in the expected order
log_order = [
(digital_read_hw_pattern, 0),
[(digital_read_cache_pattern, i) for i in range(0, 8)],
[(digital_read_cache_pattern, i) for i in range(8)],
(digital_read_hw_pattern, 8),
[(digital_read_cache_pattern, i) for i in range(8, 16)],
(digital_read_hw_pattern, 16),
@@ -68,7 +68,7 @@ async def test_gpio_expander_cache(
# uint16_t component tests (single bank of 16 pins)
(uint16_read_hw_pattern, 0), # First pin triggers hw read
[
(uint16_read_cache_pattern, i) for i in range(0, 16)
(uint16_read_cache_pattern, i) for i in range(16)
], # All 16 pins return via cache
# After cache reset
(uint16_read_hw_pattern, 5), # First read after reset triggers hw

View File

@@ -70,11 +70,11 @@ def test_numeric_offset_slash() -> None:
def test_star() -> None:
assert _parse_cron_part("*", 0, 59, {}) == set(range(0, 60))
assert _parse_cron_part("*", 0, 59, {}) == set(range(60))
def test_question() -> None:
assert _parse_cron_part("?", 0, 59, {}) == set(range(0, 60))
assert _parse_cron_part("?", 0, 59, {}) == set(range(60))
def test_range() -> None: