mirror of
https://github.com/esphome/esphome.git
synced 2026-10-07 11:26:39 +00:00
[core] Fix placement new storage name for templated types (#15096)
This commit is contained in:
@@ -565,6 +565,29 @@ def new_variable(
|
|||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
def _extract_component_ns(type_str: str) -> str:
|
||||||
|
"""Extract the component namespace from a fully-qualified C++ type string.
|
||||||
|
|
||||||
|
Strips leading ``esphome::`` and template arguments, then returns
|
||||||
|
the first namespace segment. Falls back to ``"esphome"`` when the
|
||||||
|
type has no namespace qualifier (after stripping templates).
|
||||||
|
|
||||||
|
Examples::
|
||||||
|
|
||||||
|
esphome::dsmr::Dsmr -> dsmr
|
||||||
|
esphome::logger::Logger -> logger
|
||||||
|
esphome::Automation<std::optional<bool>, std::optional<bool>> -> esphome
|
||||||
|
Logger -> esphome
|
||||||
|
"""
|
||||||
|
bare = type_str.removeprefix("esphome::")
|
||||||
|
# Strip template arguments before namespace extraction to avoid
|
||||||
|
# matching :: inside template params (e.g. Automation<std::optional<bool>>)
|
||||||
|
bare_no_template = bare.split("<", maxsplit=1)[0]
|
||||||
|
if "::" in bare_no_template:
|
||||||
|
return bare_no_template.split("::", maxsplit=1)[0].rstrip("_")
|
||||||
|
return "esphome"
|
||||||
|
|
||||||
|
|
||||||
def Pvariable(id_: ID, rhs: SafeExpType, type_: "MockObj" = None) -> "MockObj":
|
def Pvariable(id_: ID, rhs: SafeExpType, type_: "MockObj" = None) -> "MockObj":
|
||||||
"""Declare a new pointer variable in the code generation.
|
"""Declare a new pointer variable in the code generation.
|
||||||
|
|
||||||
@@ -585,14 +608,7 @@ def Pvariable(id_: ID, rhs: SafeExpType, type_: "MockObj" = None) -> "MockObj":
|
|||||||
# to avoid heap fragmentation on embedded devices.
|
# to avoid heap fragmentation on embedded devices.
|
||||||
the_type = id_.type
|
the_type = id_.type
|
||||||
# Extract component namespace from type for memory analysis attribution
|
# Extract component namespace from type for memory analysis attribution
|
||||||
type_str = str(the_type)
|
component_ns = _extract_component_ns(str(the_type))
|
||||||
# Strip leading esphome:: to get the component namespace
|
|
||||||
# e.g. esphome::dsmr::Dsmr -> dsmr, logger::Logger -> logger
|
|
||||||
bare = type_str.removeprefix("esphome::")
|
|
||||||
if "::" in bare:
|
|
||||||
component_ns = bare.split("::", maxsplit=1)[0].rstrip("_")
|
|
||||||
else:
|
|
||||||
component_ns = "esphome"
|
|
||||||
storage_name = f"{component_ns}__{id_.id}__pstorage"
|
storage_name = f"{component_ns}__{id_.id}__pstorage"
|
||||||
|
|
||||||
# Declare aligned byte array for the object storage
|
# Declare aligned byte array for the object storage
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from esphome import codegen as cg
|
from esphome import codegen as cg
|
||||||
|
from esphome.cpp_generator import _extract_component_ns
|
||||||
|
|
||||||
|
|
||||||
# Test interface remains the same.
|
# Test interface remains the same.
|
||||||
@@ -75,3 +76,29 @@ from esphome import codegen as cg
|
|||||||
)
|
)
|
||||||
def test_exists(attr):
|
def test_exists(attr):
|
||||||
assert hasattr(cg, attr)
|
assert hasattr(cg, attr)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("type_str", "expected"),
|
||||||
|
(
|
||||||
|
("esphome::dsmr::Dsmr", "dsmr"),
|
||||||
|
("esphome::logger::Logger", "logger"),
|
||||||
|
("esphome::web_server::WebServer", "web_server"),
|
||||||
|
("esphome::deep_sleep::DeepSleep", "deep_sleep"),
|
||||||
|
("esphome::Component", "esphome"),
|
||||||
|
("Logger", "esphome"),
|
||||||
|
# Template types with :: in template args must not confuse extraction
|
||||||
|
(
|
||||||
|
"esphome::Automation<std::optional<bool>, std::optional<bool>>",
|
||||||
|
"esphome",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"esphome::StatelessLambdaAction<std::optional<bool>, std::optional<bool>>",
|
||||||
|
"esphome",
|
||||||
|
),
|
||||||
|
# Namespaced template type
|
||||||
|
("esphome::sensor::Sensor<std::string>", "sensor"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
def test_extract_component_ns(type_str, expected):
|
||||||
|
assert _extract_component_ns(type_str) == expected
|
||||||
|
|||||||
Reference in New Issue
Block a user