diff --git a/esphome/analyze_memory/__init__.py b/esphome/analyze_memory/__init__.py index 15cadaf859..71e86e3788 100644 --- a/esphome/analyze_memory/__init__.py +++ b/esphome/analyze_memory/__init__.py @@ -54,15 +54,20 @@ _COMPONENT_PREFIX_EXTERNAL = "[external]" _COMPONENT_CORE = f"{_COMPONENT_PREFIX_ESPHOME}core" _COMPONENT_API = f"{_COMPONENT_PREFIX_ESPHOME}api" +# C++ namespace prefixes +_NAMESPACE_ESPHOME = "esphome::" +_NAMESPACE_STD = "std::" + +# Type alias for symbol information: (symbol_name, size, component) +SymbolInfoType = tuple[str, int, str] + @dataclass class MemorySection: """Represents a memory section with its symbols.""" name: str - symbols: list[tuple[str, int, str]] = field( - default_factory=list - ) # (symbol_name, size, component) + symbols: list[SymbolInfoType] = field(default_factory=list) total_size: int = 0 @@ -246,7 +251,7 @@ class MemoryAnalyzer: # Check for special component classes first (before namespace pattern) # This handles cases like esphome::ESPHomeOTAComponent which should map to ota - if "esphome::" in demangled: + if _NAMESPACE_ESPHOME in demangled: # Check for special component classes that include component name in the class # For example: esphome::ESPHomeOTAComponent -> ota component for component_name in get_esphome_components(): @@ -271,7 +276,7 @@ class MemoryAnalyzer: return _COMPONENT_CORE # Check for esphome core namespace (no component namespace) - if "esphome::" in demangled: + if _NAMESPACE_ESPHOME in demangled: # If no component match found, it's core return _COMPONENT_CORE @@ -480,7 +485,7 @@ class MemoryAnalyzer: if any(pattern in demangled for pattern in _CPP_RUNTIME_PATTERNS): return "C++ Runtime (vtables/RTTI)" - if demangled.startswith("std::"): + if demangled.startswith(_NAMESPACE_STD): return "C++ STL" # Check against patterns from const.py diff --git a/esphome/analyze_memory/helpers.py b/esphome/analyze_memory/helpers.py index 1b5a1c67c2..cb503b37c5 100644 --- a/esphome/analyze_memory/helpers.py +++ b/esphome/analyze_memory/helpers.py @@ -5,6 +5,11 @@ from pathlib import Path from .const import SECTION_MAPPING +# Import namespace constant from parent module +# Note: This would create a circular import if done at module level, +# so we'll define it locally here as well +_NAMESPACE_ESPHOME = "esphome::" + # Get the list of actual ESPHome components by scanning the components directory @cache @@ -40,10 +45,10 @@ def get_component_class_patterns(component_name: str) -> list[str]: component_upper = component_name.upper() component_camel = component_name.replace("_", "").title() return [ - f"esphome::{component_upper}Component", # e.g., esphome::OTAComponent - f"esphome::ESPHome{component_upper}Component", # e.g., esphome::ESPHomeOTAComponent - f"esphome::{component_camel}Component", # e.g., esphome::OtaComponent - f"esphome::ESPHome{component_camel}Component", # e.g., esphome::ESPHomeOtaComponent + f"{_NAMESPACE_ESPHOME}{component_upper}Component", # e.g., esphome::OTAComponent + f"{_NAMESPACE_ESPHOME}ESPHome{component_upper}Component", # e.g., esphome::ESPHomeOTAComponent + f"{_NAMESPACE_ESPHOME}{component_camel}Component", # e.g., esphome::OtaComponent + f"{_NAMESPACE_ESPHOME}ESPHome{component_camel}Component", # e.g., esphome::ESPHomeOtaComponent ] diff --git a/esphome/platformio_api.py b/esphome/platformio_api.py index c50bb2acff..d59523a74a 100644 --- a/esphome/platformio_api.py +++ b/esphome/platformio_api.py @@ -378,17 +378,19 @@ class IDEData: @property def objdump_path(self) -> str: # replace gcc at end with objdump + path = self.cc_path return ( - f"{self.cc_path[:-7]}objdump.exe" - if self.cc_path.endswith(".exe") - else f"{self.cc_path[:-3]}objdump" + f"{path[:-7]}objdump.exe" + if path.endswith(".exe") + else f"{path[:-3]}objdump" ) @property def readelf_path(self) -> str: # replace gcc at end with readelf + path = self.cc_path return ( - f"{self.cc_path[:-7]}readelf.exe" - if self.cc_path.endswith(".exe") - else f"{self.cc_path[:-3]}readelf" + f"{path[:-7]}readelf.exe" + if path.endswith(".exe") + else f"{path[:-3]}readelf" )