mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	[core] Improve error reporting for entity name conflicts with non-ASCII characters (#10329)
This commit is contained in:
		
				
					committed by
					
						 Jesse Hills
						Jesse Hills
					
				
			
			
				
	
			
			
			
						parent
						
							50408d9abb
						
					
				
				
					commit
					03836ee2d2
				
			| @@ -236,10 +236,21 @@ def entity_duplicate_validator(platform: str) -> Callable[[ConfigType], ConfigTy | |||||||
|             if existing_component != "unknown": |             if existing_component != "unknown": | ||||||
|                 conflict_msg += f" from component '{existing_component}'" |                 conflict_msg += f" from component '{existing_component}'" | ||||||
|  |  | ||||||
|  |             # Show both original names and their ASCII-only versions if they differ | ||||||
|  |             sanitized_msg = "" | ||||||
|  |             if entity_name != existing_name: | ||||||
|  |                 sanitized_msg = ( | ||||||
|  |                     f"\n  Original names: '{entity_name}' and '{existing_name}'" | ||||||
|  |                     f"\n  Both convert to ASCII ID: '{name_key}'" | ||||||
|  |                     "\n  To fix: Add unique ASCII characters (e.g., '1', '2', or 'A', 'B')" | ||||||
|  |                     "\n          to distinguish them" | ||||||
|  |                 ) | ||||||
|  |  | ||||||
|             raise cv.Invalid( |             raise cv.Invalid( | ||||||
|                 f"Duplicate {platform} entity with name '{entity_name}' found{device_prefix}. " |                 f"Duplicate {platform} entity with name '{entity_name}' found{device_prefix}. " | ||||||
|                 f"{conflict_msg}. " |                 f"{conflict_msg}. " | ||||||
|                 f"Each entity on a device must have a unique name within its platform." |                 "Each entity on a device must have a unique name within its platform." | ||||||
|  |                 f"{sanitized_msg}" | ||||||
|             ) |             ) | ||||||
|  |  | ||||||
|         # Store metadata about this entity |         # Store metadata about this entity | ||||||
|   | |||||||
| @@ -705,3 +705,48 @@ def test_empty_or_null_device_id_on_entity() -> None: | |||||||
|     config2 = {CONF_NAME: "Temperature", CONF_DEVICE_ID: None} |     config2 = {CONF_NAME: "Temperature", CONF_DEVICE_ID: None} | ||||||
|     validated2 = validator(config2) |     validated2 = validator(config2) | ||||||
|     assert validated2 == config2 |     assert validated2 == config2 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def test_entity_duplicate_validator_non_ascii_names() -> None: | ||||||
|  |     """Test that non-ASCII names show helpful error messages.""" | ||||||
|  |     # Create validator for binary_sensor platform | ||||||
|  |     validator = entity_duplicate_validator("binary_sensor") | ||||||
|  |  | ||||||
|  |     # First Russian sensor should pass | ||||||
|  |     config1 = {CONF_NAME: "Датчик открытия основного крана"} | ||||||
|  |     validated1 = validator(config1) | ||||||
|  |     assert validated1 == config1 | ||||||
|  |  | ||||||
|  |     # Second Russian sensor with different text but same ASCII conversion should fail | ||||||
|  |     config2 = {CONF_NAME: "Датчик закрытия основного крана"} | ||||||
|  |     with pytest.raises( | ||||||
|  |         Invalid, | ||||||
|  |         match=re.compile( | ||||||
|  |             r"Duplicate binary_sensor entity with name 'Датчик закрытия основного крана' found.*" | ||||||
|  |             r"Original names: 'Датчик закрытия основного крана' and 'Датчик открытия основного крана'.*" | ||||||
|  |             r"Both convert to ASCII ID: '_______________________________'.*" | ||||||
|  |             r"To fix: Add unique ASCII characters \(e\.g\., '1', '2', or 'A', 'B'\)", | ||||||
|  |             re.DOTALL, | ||||||
|  |         ), | ||||||
|  |     ): | ||||||
|  |         validator(config2) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def test_entity_duplicate_validator_same_name_no_enhanced_message() -> None: | ||||||
|  |     """Test that identical names don't show the enhanced message.""" | ||||||
|  |     # Create validator for sensor platform | ||||||
|  |     validator = entity_duplicate_validator("sensor") | ||||||
|  |  | ||||||
|  |     # First entity should pass | ||||||
|  |     config1 = {CONF_NAME: "Temperature"} | ||||||
|  |     validated1 = validator(config1) | ||||||
|  |     assert validated1 == config1 | ||||||
|  |  | ||||||
|  |     # Second entity with exact same name should fail without enhanced message | ||||||
|  |     config2 = {CONF_NAME: "Temperature"} | ||||||
|  |     with pytest.raises( | ||||||
|  |         Invalid, | ||||||
|  |         match=r"Duplicate sensor entity with name 'Temperature' found.*" | ||||||
|  |         r"Each entity on a device must have a unique name within its platform\.$", | ||||||
|  |     ): | ||||||
|  |         validator(config2) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user