mirror of
https://github.com/esphome/esphome.git
synced 2025-09-06 21:32:21 +01:00
Merge remote-tracking branch 'upstream/dev' into protosize_object
This commit is contained in:
@@ -562,11 +562,16 @@ class StringType(TypeInfo):
|
||||
@property
|
||||
def public_content(self) -> list[str]:
|
||||
content: list[str] = []
|
||||
# Add std::string storage if message needs decoding
|
||||
if self._needs_decode:
|
||||
|
||||
# Check if no_zero_copy option is set
|
||||
no_zero_copy = get_field_opt(self._field, pb.no_zero_copy, False)
|
||||
|
||||
# Add std::string storage if message needs decoding OR if no_zero_copy is set
|
||||
if self._needs_decode or no_zero_copy:
|
||||
content.append(f"std::string {self.field_name}{{}};")
|
||||
|
||||
if self._needs_encode:
|
||||
# Only add StringRef if encoding is needed AND no_zero_copy is not set
|
||||
if self._needs_encode and not no_zero_copy:
|
||||
content.extend(
|
||||
[
|
||||
# Add StringRef field if message needs encoding
|
||||
@@ -581,13 +586,28 @@ class StringType(TypeInfo):
|
||||
|
||||
@property
|
||||
def encode_content(self) -> str:
|
||||
return f"buffer.encode_string({self.number}, this->{self.field_name}_ref_);"
|
||||
# Check if no_zero_copy option is set
|
||||
no_zero_copy = get_field_opt(self._field, pb.no_zero_copy, False)
|
||||
|
||||
if no_zero_copy:
|
||||
# Use the std::string directly
|
||||
return f"buffer.encode_string({self.number}, this->{self.field_name});"
|
||||
else:
|
||||
# Use the StringRef
|
||||
return f"buffer.encode_string({self.number}, this->{self.field_name}_ref_);"
|
||||
|
||||
def dump(self, name):
|
||||
# Check if no_zero_copy option is set
|
||||
no_zero_copy = get_field_opt(self._field, pb.no_zero_copy, False)
|
||||
|
||||
# If name is 'it', this is a repeated field element - always use string
|
||||
if name == "it":
|
||||
return "append_quoted_string(out, StringRef(it));"
|
||||
|
||||
# If no_zero_copy is set, always use std::string
|
||||
if no_zero_copy:
|
||||
return f'out.append("\'").append(this->{self.field_name}).append("\'");'
|
||||
|
||||
# For SOURCE_CLIENT only, always use std::string
|
||||
if not self._needs_encode:
|
||||
return f'out.append("\'").append(this->{self.field_name}).append("\'");'
|
||||
@@ -607,6 +627,13 @@ class StringType(TypeInfo):
|
||||
|
||||
@property
|
||||
def dump_content(self) -> str:
|
||||
# Check if no_zero_copy option is set
|
||||
no_zero_copy = get_field_opt(self._field, pb.no_zero_copy, False)
|
||||
|
||||
# If no_zero_copy is set, always use std::string
|
||||
if no_zero_copy:
|
||||
return f'dump_field(out, "{self.name}", this->{self.field_name});'
|
||||
|
||||
# For SOURCE_CLIENT only, use std::string
|
||||
if not self._needs_encode:
|
||||
return f'dump_field(out, "{self.name}", this->{self.field_name});'
|
||||
@@ -622,8 +649,17 @@ class StringType(TypeInfo):
|
||||
return o
|
||||
|
||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||
# For SOURCE_CLIENT only messages, use the string field directly
|
||||
if not self._needs_encode:
|
||||
# Check if no_zero_copy option is set
|
||||
no_zero_copy = get_field_opt(self._field, pb.no_zero_copy, False)
|
||||
|
||||
# For SOURCE_CLIENT only messages or no_zero_copy, use the string field directly
|
||||
if not self._needs_encode or no_zero_copy:
|
||||
# For no_zero_copy, we need to use .size() on the string
|
||||
if no_zero_copy and name != "it":
|
||||
field_id_size = self.calculate_field_id_size()
|
||||
return (
|
||||
f"size.add_length({field_id_size}, this->{self.field_name}.size());"
|
||||
)
|
||||
return self._get_simple_size_calculation(name, force, "add_length")
|
||||
|
||||
# Check if this is being called from a repeated field context
|
||||
|
@@ -197,7 +197,7 @@ def lint_content_find_check(find, only_first=False, **kwargs):
|
||||
find_ = find(fname, content)
|
||||
errs = []
|
||||
for line, col in find_all(content, find_):
|
||||
err = func(fname)
|
||||
err = func(fname, line, col, content)
|
||||
errs.append((line + 1, col + 1, err))
|
||||
if only_first:
|
||||
break
|
||||
@@ -264,12 +264,12 @@ def lint_executable_bit(fname):
|
||||
"esphome/dashboard/static/ext-searchbox.js",
|
||||
],
|
||||
)
|
||||
def lint_tabs(fname):
|
||||
def lint_tabs(fname, line, col, content):
|
||||
return "File contains tab character. Please convert tabs to spaces."
|
||||
|
||||
|
||||
@lint_content_find_check("\r", only_first=True)
|
||||
def lint_newline(fname):
|
||||
def lint_newline(fname, line, col, content):
|
||||
return "File contains Windows newline. Please set your editor to Unix newline mode."
|
||||
|
||||
|
||||
@@ -512,7 +512,7 @@ def relative_cpp_search_text(fname, content):
|
||||
|
||||
|
||||
@lint_content_find_check(relative_cpp_search_text, include=["esphome/components/*.cpp"])
|
||||
def lint_relative_cpp_import(fname):
|
||||
def lint_relative_cpp_import(fname, line, col, content):
|
||||
return (
|
||||
"Component contains absolute import - Components must always use "
|
||||
"relative imports.\n"
|
||||
@@ -529,6 +529,20 @@ def relative_py_search_text(fname, content):
|
||||
return f"esphome.components.{integration}"
|
||||
|
||||
|
||||
def convert_path_to_relative(abspath, current):
|
||||
"""Convert an absolute path to a relative import path."""
|
||||
if abspath == current:
|
||||
return "."
|
||||
absparts = abspath.split(".")
|
||||
curparts = current.split(".")
|
||||
uplen = len(curparts)
|
||||
while absparts and curparts and absparts[0] == curparts[0]:
|
||||
absparts.pop(0)
|
||||
curparts.pop(0)
|
||||
uplen -= 1
|
||||
return "." * uplen + ".".join(absparts)
|
||||
|
||||
|
||||
@lint_content_find_check(
|
||||
relative_py_search_text,
|
||||
include=["esphome/components/*.py"],
|
||||
@@ -537,14 +551,19 @@ def relative_py_search_text(fname, content):
|
||||
"esphome/components/web_server/__init__.py",
|
||||
],
|
||||
)
|
||||
def lint_relative_py_import(fname):
|
||||
def lint_relative_py_import(fname, line, col, content):
|
||||
import_line = content.splitlines()[line]
|
||||
abspath = import_line[col:].split(" ")[0]
|
||||
current = fname.removesuffix(".py").replace(os.path.sep, ".")
|
||||
replacement = convert_path_to_relative(abspath, current)
|
||||
newline = import_line.replace(abspath, replacement)
|
||||
return (
|
||||
"Component contains absolute import - Components must always use "
|
||||
"relative imports within the integration.\n"
|
||||
"Change:\n"
|
||||
' from esphome.components.abc import abc_ns"\n'
|
||||
f" {import_line}\n"
|
||||
"to:\n"
|
||||
" from . import abc_ns\n\n"
|
||||
f" {newline}\n"
|
||||
)
|
||||
|
||||
|
||||
@@ -588,7 +607,7 @@ def lint_namespace(fname, content):
|
||||
|
||||
|
||||
@lint_content_find_check('"esphome.h"', include=cpp_include, exclude=["tests/custom.h"])
|
||||
def lint_esphome_h(fname):
|
||||
def lint_esphome_h(fname, line, col, content):
|
||||
return (
|
||||
"File contains reference to 'esphome.h' - This file is "
|
||||
"auto-generated and should only be used for *custom* "
|
||||
@@ -679,7 +698,7 @@ def lint_trailing_whitespace(fname, match):
|
||||
"tests/custom.h",
|
||||
],
|
||||
)
|
||||
def lint_log_in_header(fname):
|
||||
def lint_log_in_header(fname, line, col, content):
|
||||
return (
|
||||
"Found reference to ESP_LOG in header file. Using ESP_LOG* in header files "
|
||||
"is currently not possible - please move the definition to a source file (.cpp)"
|
||||
|
@@ -6,7 +6,7 @@ set -e
|
||||
cd "$(dirname "$0")/.."
|
||||
if [ ! -n "$VIRTUAL_ENV" ]; then
|
||||
if [ -x "$(command -v uv)" ]; then
|
||||
uv venv venv
|
||||
uv venv --seed venv
|
||||
else
|
||||
python3 -m venv venv
|
||||
fi
|
||||
|
Reference in New Issue
Block a user