Skip to content

Quote number-like device names in generated YAML - #2841

Merged
bdraco merged 1 commit into
mainfrom
fix-numeric-device-name
Sep 26, 2026
Merged

bdraco merged 1 commit into
mainfrom
fix-numeric-device-name

Conversation

@bdraco

@bdraco bdraco commented Sep 26, 2026

Copy link
Copy Markdown
Member

What does this implement/fix?

Creating a device with an all digit name like 8266 failed validation, because the generators wrote name: 8266 unquoted and esphome read it back as an int. The name now goes through _safe_yaml_scalar like friendly_name already does, so number like names get quoted and normal slugs stay plain.

Related issue or feature (if applicable):

Types of changes

  • Bugfix (non-breaking change which fixes an issue) — bugfix
  • New feature (non-breaking change which adds functionality) — new-feature
  • Enhancement to an existing feature — enhancement
  • Breaking change (fix or feature that would cause existing functionality to not work as expected) — breaking-change
  • Refactor (no behaviour change) — refactor
  • Documentation only — docs
  • Maintenance / chore — maintenance
  • CI / workflow change — ci
  • Dependencies bump — dependencies

Frontend coordination

  • No frontend change needed
  • Companion frontend PR: esphome/device-builder-frontend#

Checklist

  • The code change is tested and works locally.
  • Pre-commit hooks pass (ruff, codespell, yaml/json/python checks).
  • Tests have been added or updated under tests/ where applicable.
  • components.index.json / definitions/components/*.json have not been hand-edited (regenerate via script/sync_components.py if a sync is needed).
  • Architecture-level changes are reflected in docs/ARCHITECTURE.md and/or docs/API.md.

@bdraco bdraco added the bugfix Bug fix label Sep 26, 2026
@bdraco

bdraco commented Sep 26, 2026

Copy link
Copy Markdown
Member Author

@esphbot review

@codspeed

codspeed Bot commented Sep 26, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 28 untouched benchmarks
⏩ 1 skipped benchmark1


Comparing fix-numeric-device-name (509e9ee) with main (f0ce3b7)

Open in CodSpeed

Footnotes

  1. 1 benchmark was skipped, so the baseline result was used instead. If it was deleted from the codebase, click here and archive it to remove it from the performance reports. ↩

@bdraco
bdraco marked this pull request as ready for review September 26, 2026 17:20
Copilot AI lite review requested due to automatic review settings September 26, 2026 17:20
@codecov

codecov Bot commented Sep 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.75%. Comparing base (f0ce3b7) to head (509e9ee).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #2841   +/-   ##
=======================================
  Coverage   99.75%   99.75%           
=======================================
  Files         294      294           
  Lines       25436    25436           
=======================================
  Hits        25374    25374           
  Misses         62       62           
Flag Coverage Δ
py3.12 99.71% <100.00%> (-0.01%) ⬇️
py3.14 99.60% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
..._device_builder/helpers/device_yaml/_generation.py 99.31% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

No blocking issues were identified; only a minor comment-convention nit remains.

Review effort: Lite
Findings: None

What changed in this PR

Fixes YAML generation for numeric-like device names by safely quoting them.

Changes:

  • Applies _safe_yaml_scalar to generated names.
  • Adds regression coverage for generators and device creation.
  • Preserves plain formatting for normal slugs.
File Description
tests/​test_device_yaml.py Tests name handling across YAML generators.
tests/​controllers/​devices/​test_create.py Tests creating a device named 8266.
esphome_device_builder/​helpers/​device_yaml/​_generation.py Safely renders generated names.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@esphbot

esphbot commented Sep 26, 2026

Copy link
Copy Markdown
Contributor

PR Review — Quote number-like device names in generated YAML

Merge-ready. The fix is small and correct, and it closes the int-coercion hole in every generator that writes esphome.name.

Strengths:

  • It reuses the canonical _safe_yaml_scalar (helpers/yaml/scalar.py:320) and doesn't add a special case for digits. PyYAML's resolver decides whether to quote, so octal-like (017), hex-like (0x1f) and plain-digit names are all handled. Normal slugs still take the fast path unquoted, so existing output doesn't change.
  • All three generators that write a name literal are covered: generate_adoption_yaml (L172), generate_device_yaml (L224) and generate_minimal_stub_yaml (L497). A grep across the package found no other place that writes a name: literal. Only {label} Firmware at L449 remains, and it always parses as a string.
  • The creation path now matches the rename and clone paths, which already go through _safe_yaml_scalar in rewrite_name_or_substitution (helpers/yaml/substitution.py:115) and top_block.py:147.
  • The parametrized test parses each generator's output back with esphome's own yaml_util.parse_yaml and asserts the result is a str. That tests the behaviour itself rather than the quoting text, and esp-8266 confirms a normal slug still works. The controller-level test in test_create.py covers the reported 8266 case from start to finish.
  • The rewritten comment in generate_device_yaml is shorter than the old one and still explains the non-obvious reason for the change, as the repo's comment conventions ask.

No blocking or non-blocking issues found.



Checklist

  • No injection / unsafe YAML emission
  • All name-emitting generators covered
  • Regression tests verify behaviour (parsed type), not source
  • No backward-incompatible output for existing slugs
  • PR description matches diff

Automated review by Kōan (Claude) HEAD=509e9ee 27s

@esphbot esphbot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tip

No blocking issues found — ready to merge.

@bdraco
bdraco merged commit e8f6f20 into main Sep 26, 2026
26 checks passed
@bdraco
bdraco deleted the fix-numeric-device-name branch September 26, 2026 17:26
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 28, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

bugfix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Creating a device with an all-digit name fails validation

3 participants