mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Drop Python 3.10 support, require Python 3.11+ (#9522)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
This commit is contained in:
		| @@ -395,7 +395,7 @@ async def wait_and_connect_api_client( | ||||
|         # Wait for connection with timeout | ||||
|         try: | ||||
|             await asyncio.wait_for(connected_future, timeout=timeout) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             raise TimeoutError(f"Failed to connect to API after {timeout} seconds") | ||||
|  | ||||
|         yield client | ||||
| @@ -575,12 +575,12 @@ async def run_binary_and_wait_for_port( | ||||
|             process.send_signal(signal.SIGINT) | ||||
|             try: | ||||
|                 await asyncio.wait_for(process.wait(), timeout=SIGINT_TIMEOUT) | ||||
|             except asyncio.TimeoutError: | ||||
|             except TimeoutError: | ||||
|                 # If SIGINT didn't work, try SIGTERM | ||||
|                 process.terminate() | ||||
|                 try: | ||||
|                     await asyncio.wait_for(process.wait(), timeout=SIGTERM_TIMEOUT) | ||||
|                 except asyncio.TimeoutError: | ||||
|                 except TimeoutError: | ||||
|                     # Last resort: SIGKILL | ||||
|                     process.kill() | ||||
|                     await process.wait() | ||||
|   | ||||
| @@ -177,7 +177,7 @@ async def test_api_message_size_batching( | ||||
|         # Wait for states with timeout | ||||
|         try: | ||||
|             await asyncio.wait_for(states_future, timeout=5.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             missing_keys = expected_keys - received_keys | ||||
|             pytest.fail( | ||||
|                 f"Did not receive states from all entities within 5 seconds. " | ||||
|   | ||||
| @@ -29,7 +29,7 @@ async def test_api_reboot_timeout( | ||||
|         # (0.5s reboot timeout + some margin for processing) | ||||
|         try: | ||||
|             await asyncio.wait_for(reboot_future, timeout=2.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("Device did not reboot within expected timeout") | ||||
|  | ||||
|     # Test passes if we get here - reboot was detected | ||||
|   | ||||
| @@ -98,7 +98,7 @@ async def test_areas_and_devices( | ||||
|         # Wait for sensor states | ||||
|         try: | ||||
|             await asyncio.wait_for(states_future, timeout=10.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail( | ||||
|                 f"Did not receive all sensor states within 10 seconds. " | ||||
|                 f"Received {len(states)} states" | ||||
|   | ||||
| @@ -77,7 +77,7 @@ async def test_device_id_in_state( | ||||
|         # Wait for states | ||||
|         try: | ||||
|             await asyncio.wait_for(states_future, timeout=10.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail( | ||||
|                 f"Did not receive all entity states within 10 seconds. " | ||||
|                 f"Received {len(states)} states, expected {len(entity_device_mapping)}" | ||||
|   | ||||
| @@ -206,7 +206,7 @@ async def test_duplicate_entities_not_allowed_on_different_devices( | ||||
|         # Wait for all entity states | ||||
|         try: | ||||
|             await asyncio.wait_for(states_future, timeout=10.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail( | ||||
|                 f"Did not receive all entity states within 10 seconds. " | ||||
|                 f"Expected {expected_count}, received {state_count}" | ||||
|   | ||||
| @@ -82,7 +82,7 @@ async def test_entity_icon( | ||||
|         # Wait for states | ||||
|         try: | ||||
|             await asyncio.wait_for(state_received.wait(), timeout=5.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("No states received within 5 seconds") | ||||
|  | ||||
|         # Verify we received states | ||||
|   | ||||
| @@ -44,7 +44,7 @@ async def test_host_mode_batch_delay( | ||||
|         # Wait for states from all entities with timeout | ||||
|         try: | ||||
|             entity_count = await asyncio.wait_for(entity_count_future, timeout=5.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail( | ||||
|                 f"Did not receive states from at least 7 entities within 5 seconds. " | ||||
|                 f"Received {len(states)} states" | ||||
|   | ||||
| @@ -99,7 +99,7 @@ async def test_host_mode_empty_string_options( | ||||
|         # Wait for initial states with timeout | ||||
|         try: | ||||
|             await asyncio.wait_for(states_received_future, timeout=5.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail( | ||||
|                 f"Did not receive states for all select entities. " | ||||
|                 f"Expected keys: {expected_select_keys}, Received: {received_select_keys}" | ||||
|   | ||||
| @@ -86,7 +86,7 @@ async def test_host_mode_entity_fields( | ||||
|         # Wait for at least one state | ||||
|         try: | ||||
|             await asyncio.wait_for(state_received.wait(), timeout=5.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("No states received within 5 seconds") | ||||
|  | ||||
|         # Verify we received states (which means has_state flag is working) | ||||
|   | ||||
| @@ -41,7 +41,7 @@ async def test_host_mode_many_entities( | ||||
|         # Wait for states from at least 50 sensors with timeout | ||||
|         try: | ||||
|             sensor_count = await asyncio.wait_for(sensor_count_future, timeout=10.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             sensor_states = [ | ||||
|                 s | ||||
|                 for s in states.values() | ||||
|   | ||||
| @@ -50,7 +50,7 @@ async def test_host_mode_many_entities_multiple_connections( | ||||
|                 asyncio.wait_for(client1_ready, timeout=10.0), | ||||
|                 asyncio.wait_for(client2_ready, timeout=10.0), | ||||
|             ) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail( | ||||
|                 f"One or both clients did not receive enough states within 10 seconds. " | ||||
|                 f"Client1: {len(states1)}, Client2: {len(states2)}" | ||||
|   | ||||
| @@ -40,7 +40,7 @@ async def test_host_mode_with_sensor( | ||||
|         # Wait for sensor with specific value (42.0) with timeout | ||||
|         try: | ||||
|             test_sensor_state = await asyncio.wait_for(sensor_future, timeout=5.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail( | ||||
|                 f"Sensor with value 42.0 not received within 5 seconds. " | ||||
|                 f"Received states: {list(states.values())}" | ||||
|   | ||||
| @@ -150,7 +150,7 @@ async def test_loop_disable_enable( | ||||
|         # Wait for self_disable_10 to disable itself | ||||
|         try: | ||||
|             await asyncio.wait_for(self_disable_10_disabled.wait(), timeout=10.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("self_disable_10 did not disable itself within 10 seconds") | ||||
|  | ||||
|         # Verify it ran at least 10 times before disabling | ||||
| @@ -164,7 +164,7 @@ async def test_loop_disable_enable( | ||||
|         # Wait for normal_component to run at least 10 times | ||||
|         try: | ||||
|             await asyncio.wait_for(normal_component_10_loops.wait(), timeout=10.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail( | ||||
|                 f"normal_component did not reach 10 loops within timeout, got {len(normal_component_counts)}" | ||||
|             ) | ||||
| @@ -172,12 +172,12 @@ async def test_loop_disable_enable( | ||||
|         # Wait for redundant operation tests | ||||
|         try: | ||||
|             await asyncio.wait_for(redundant_enable_tested.wait(), timeout=10.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("redundant_enable did not test enabling when already enabled") | ||||
|  | ||||
|         try: | ||||
|             await asyncio.wait_for(redundant_disable_tested.wait(), timeout=10.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail( | ||||
|                 "redundant_disable did not test disabling when will be disabled" | ||||
|             ) | ||||
| @@ -185,7 +185,7 @@ async def test_loop_disable_enable( | ||||
|         # Wait to see if self_disable_10 gets re-enabled | ||||
|         try: | ||||
|             await asyncio.wait_for(self_disable_10_re_enabled.wait(), timeout=5.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("self_disable_10 was not re-enabled within 5 seconds") | ||||
|  | ||||
|         # Component was re-enabled - verify it ran more times | ||||
| @@ -198,7 +198,7 @@ async def test_loop_disable_enable( | ||||
|         # Wait for ISR component to disable itself after 5 loops | ||||
|         try: | ||||
|             await asyncio.wait_for(isr_component_disabled.wait(), timeout=3.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("ISR component did not disable itself within 3 seconds") | ||||
|  | ||||
|         # Verify it ran exactly 5 times before disabling | ||||
| @@ -210,7 +210,7 @@ async def test_loop_disable_enable( | ||||
|         # Wait for component to be re-enabled by periodic ISR simulation and run again | ||||
|         try: | ||||
|             await asyncio.wait_for(isr_component_re_enabled.wait(), timeout=2.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("ISR component was not re-enabled after ISR call") | ||||
|  | ||||
|         # Verify it's running again after ISR enable | ||||
| @@ -222,7 +222,7 @@ async def test_loop_disable_enable( | ||||
|         # Wait for pure ISR enable (no main loop enable) to work | ||||
|         try: | ||||
|             await asyncio.wait_for(isr_component_pure_re_enabled.wait(), timeout=2.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("ISR component was not re-enabled by pure ISR call") | ||||
|  | ||||
|         # Verify it ran after pure ISR enable | ||||
| @@ -235,7 +235,7 @@ async def test_loop_disable_enable( | ||||
|         # Wait for update component to disable its loop | ||||
|         try: | ||||
|             await asyncio.wait_for(update_component_loop_disabled.wait(), timeout=3.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("Update component did not disable its loop within 3 seconds") | ||||
|  | ||||
|         # Verify it ran exactly 3 loops before disabling | ||||
| @@ -248,7 +248,7 @@ async def test_loop_disable_enable( | ||||
|             await asyncio.wait_for( | ||||
|                 update_component_manual_update_called.wait(), timeout=5.0 | ||||
|             ) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("Manual component.update was not called within 5 seconds") | ||||
|  | ||||
|         # The key test: verify that manual component.update worked after loop was disabled | ||||
|   | ||||
| @@ -103,7 +103,7 @@ async def test_scheduler_bulk_cleanup( | ||||
|         # Wait for test completion | ||||
|         try: | ||||
|             await asyncio.wait_for(test_complete_future, timeout=10.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("Bulk cleanup test timed out") | ||||
|  | ||||
|         # Verify bulk cleanup was triggered | ||||
|   | ||||
| @@ -85,7 +85,7 @@ async def test_scheduler_defer_cancel( | ||||
|         try: | ||||
|             await asyncio.wait_for(test_complete_future, timeout=10.0) | ||||
|             executed_defer = await asyncio.wait_for(test_result_future, timeout=1.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("Test did not complete within timeout") | ||||
|  | ||||
|         # Verify that only defer 10 was executed | ||||
|   | ||||
| @@ -64,7 +64,7 @@ async def test_scheduler_defer_cancels_regular( | ||||
|         # Wait for test completion | ||||
|         try: | ||||
|             await asyncio.wait_for(test_complete_future, timeout=5.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail(f"Test timed out. Log messages: {log_messages}") | ||||
|  | ||||
|         # Verify results | ||||
|   | ||||
| @@ -90,7 +90,7 @@ async def test_scheduler_defer_fifo_simple( | ||||
|         try: | ||||
|             await asyncio.wait_for(test_complete_future, timeout=5.0) | ||||
|             test1_passed = await asyncio.wait_for(test_result_future, timeout=1.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("Test set_timeout(0) did not complete within 5 seconds") | ||||
|  | ||||
|         assert test1_passed is True, ( | ||||
| @@ -108,7 +108,7 @@ async def test_scheduler_defer_fifo_simple( | ||||
|         try: | ||||
|             await asyncio.wait_for(test_complete_future, timeout=5.0) | ||||
|             test2_passed = await asyncio.wait_for(test_result_future, timeout=1.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("Test defer() did not complete within 5 seconds") | ||||
|  | ||||
|         # Verify the test passed | ||||
|   | ||||
| @@ -97,7 +97,7 @@ async def test_scheduler_defer_stress( | ||||
|         # Wait for all defers to execute (should be quick) | ||||
|         try: | ||||
|             await asyncio.wait_for(test_complete_future, timeout=5.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             # Report how many we got | ||||
|             pytest.fail( | ||||
|                 f"Stress test timed out. Only {len(executed_defers)} of " | ||||
|   | ||||
| @@ -104,7 +104,7 @@ async def test_scheduler_heap_stress( | ||||
|         # Wait for all callbacks to execute (should be quick, but give more time for scheduling) | ||||
|         try: | ||||
|             await asyncio.wait_for(test_complete_future, timeout=60.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             # Report how many we got | ||||
|             pytest.fail( | ||||
|                 f"Stress test timed out. Only {len(executed_callbacks)} of " | ||||
|   | ||||
| @@ -53,7 +53,7 @@ async def test_scheduler_null_name( | ||||
|             # Wait for test completion | ||||
|             try: | ||||
|                 await asyncio.wait_for(test_complete_future, timeout=10.0) | ||||
|             except asyncio.TimeoutError: | ||||
|             except TimeoutError: | ||||
|                 pytest.fail( | ||||
|                     "Test did not complete within timeout - likely crashed due to NULL name" | ||||
|                 ) | ||||
|   | ||||
| @@ -112,7 +112,7 @@ async def test_scheduler_rapid_cancellation( | ||||
|         # Wait for test to complete with timeout | ||||
|         try: | ||||
|             await asyncio.wait_for(test_complete_future, timeout=10.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail(f"Test timed out. Stats: {test_stats}") | ||||
|  | ||||
|         # Check for any errors | ||||
|   | ||||
| @@ -84,7 +84,7 @@ async def test_scheduler_recursive_timeout( | ||||
|         # Wait for test to complete | ||||
|         try: | ||||
|             await asyncio.wait_for(test_complete_future, timeout=10.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail( | ||||
|                 f"Recursive timeout test timed out. Got sequence: {execution_sequence}" | ||||
|             ) | ||||
|   | ||||
| @@ -103,7 +103,7 @@ async def test_scheduler_simultaneous_callbacks( | ||||
|         # Wait for test to complete | ||||
|         try: | ||||
|             await asyncio.wait_for(test_complete_future, timeout=30.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail(f"Simultaneous callbacks test timed out. Stats: {test_stats}") | ||||
|  | ||||
|         # Check for any errors | ||||
|   | ||||
| @@ -157,7 +157,7 @@ async def test_scheduler_string_lifetime( | ||||
|             client.execute_service(test_services["final"], {}) | ||||
|             await asyncio.wait_for(all_tests_complete.wait(), timeout=5.0) | ||||
|  | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail(f"String lifetime test timed out. Stats: {test_stats}") | ||||
|  | ||||
|         # Check for any errors | ||||
|   | ||||
| @@ -97,7 +97,7 @@ async def test_scheduler_string_name_stress( | ||||
|         # Wait for test to complete or crash | ||||
|         try: | ||||
|             await asyncio.wait_for(test_complete_future, timeout=30.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail( | ||||
|                 f"String name stress test timed out. Executed {len(executed_callbacks)} callbacks. " | ||||
|                 f"This might indicate a deadlock." | ||||
|   | ||||
| @@ -122,22 +122,22 @@ async def test_scheduler_string_test( | ||||
|         # Wait for static string tests | ||||
|         try: | ||||
|             await asyncio.wait_for(static_timeout_1_fired.wait(), timeout=0.5) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("Static timeout 1 did not fire within 0.5 seconds") | ||||
|  | ||||
|         try: | ||||
|             await asyncio.wait_for(static_timeout_2_fired.wait(), timeout=0.5) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("Static timeout 2 did not fire within 0.5 seconds") | ||||
|  | ||||
|         try: | ||||
|             await asyncio.wait_for(static_interval_fired.wait(), timeout=1.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("Static interval did not fire within 1 second") | ||||
|  | ||||
|         try: | ||||
|             await asyncio.wait_for(static_interval_cancelled.wait(), timeout=2.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("Static interval was not cancelled within 2 seconds") | ||||
|  | ||||
|         # Verify static interval ran at least 3 times | ||||
| @@ -153,41 +153,41 @@ async def test_scheduler_string_test( | ||||
|         # Wait for static defer tests | ||||
|         try: | ||||
|             await asyncio.wait_for(static_defer_1_fired.wait(), timeout=0.5) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("Static defer 1 did not fire within 0.5 seconds") | ||||
|  | ||||
|         try: | ||||
|             await asyncio.wait_for(static_defer_2_fired.wait(), timeout=0.5) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("Static defer 2 did not fire within 0.5 seconds") | ||||
|  | ||||
|         # Wait for dynamic string tests | ||||
|         try: | ||||
|             await asyncio.wait_for(dynamic_timeout_fired.wait(), timeout=1.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("Dynamic timeout did not fire within 1 second") | ||||
|  | ||||
|         try: | ||||
|             await asyncio.wait_for(dynamic_interval_fired.wait(), timeout=1.5) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("Dynamic interval did not fire within 1.5 seconds") | ||||
|  | ||||
|         # Wait for dynamic defer test | ||||
|         try: | ||||
|             await asyncio.wait_for(dynamic_defer_fired.wait(), timeout=1.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("Dynamic defer did not fire within 1 second") | ||||
|  | ||||
|         # Wait for cancel test | ||||
|         try: | ||||
|             await asyncio.wait_for(cancel_test_done.wait(), timeout=1.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("Cancel test did not complete within 1 second") | ||||
|  | ||||
|         # Wait for final results | ||||
|         try: | ||||
|             await asyncio.wait_for(final_results_logged.wait(), timeout=4.0) | ||||
|         except asyncio.TimeoutError: | ||||
|         except TimeoutError: | ||||
|             pytest.fail("Final results were not logged within 4 seconds") | ||||
|  | ||||
|         # Verify results | ||||
|   | ||||
		Reference in New Issue
	
	Block a user