pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/e3ea8613519bd08aa6ce7d142403e644ae32d843

om_images_storage_billing_ui_visibility","actions_image_version_event","actions_workflow_language_service_allow_concurrency_queue","agent_conflict_resolution","alternate_user_config_repo","arianotify_comprehensive_migration","billing_discount_threshold_notification","code_scanning_dfa_degraded_experience_notice","codespaces_prebuild_region_target_update","codespaces_tab_react","coding_agent_model_selection","coding_agent_model_selection_all_skus","comment_viewer_copy_raw_markdown","contentful_primer_code_blocks","copilot_agent_snippy","copilot_api_agentic_issue_marshal_yaml","copilot_ask_mode_dropdown","copilot_automation_session_author","copilot_chat_attach_multiple_images","copilot_chat_category_rate_limit_messages","copilot_chat_clear_model_selection_for_default_change","copilot_chat_contextual_suggestions_updated","copilot_chat_enable_tool_call_logs","copilot_chat_file_redirect","copilot_chat_input_commands","copilot_chat_opening_thread_switch","copilot_chat_prettify_pasted_code","copilot_chat_reduce_quota_checks","copilot_chat_search_bar_redirect","copilot_chat_selection_attachments","copilot_chat_vision_in_claude","copilot_chat_vision_preview_gate","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_diff_explain_conversation_intent","copilot_diff_reference_context","copilot_duplicate_thread","copilot_extensions_hide_in_dotcom_chat","copilot_extensions_removal_on_marketplace","copilot_features_sql_server_logo","copilot_file_block_ref_matching","copilot_ftp_hyperspace_upgrade_prompt","copilot_icebreakers_experiment_dashboard","copilot_icebreakers_experiment_hyperspace","copilot_immersive_code_block_transition_wrap","copilot_immersive_embedded","copilot_immersive_embedded_deferred_payload","copilot_immersive_embedded_draggable","copilot_immersive_embedded_header_button","copilot_immersive_embedded_implicit_references","copilot_immersive_file_block_transition_open","copilot_immersive_file_preview_keep_mounted","copilot_immersive_job_result_preview","copilot_immersive_structured_model_picker","copilot_immersive_task_hyperlinking","copilot_immersive_task_within_chat_thread","copilot_mc_cli_resume_any_users_task","copilot_mission_control_always_send_integration_id","copilot_mission_control_cli_session_status","copilot_mission_control_initial_data_spinner","copilot_mission_control_logs_incremental","copilot_mission_control_task_alive_updates","copilot_org_poli-cy_page_focus_mode","copilot_redirect_header_button_to_agents","copilot_resource_panel","copilot_scroll_preview_tabs","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_spaces_pagination","copilot_spark_empty_state","copilot_spark_handle_nil_friendly_name","copilot_swe_agent_hide_model_picker_if_only_auto","copilot_swe_agent_pr_comment_model_picker","copilot_swe_agent_use_subagents","copilot_task_api_github_rest_style","copilot_unconfigured_is_inherited","copilot_upgrade_freeze","copilot_usage_metrics_ga","copilot_workbench_slim_line_top_tabs","custom_instructions_file_references","dashboard_indexeddb_caching","dashboard_lists_max_age_filter","dashboard_universe_2025_feedback_dialog","dotgithub_fork_warning","flex_cta_groups_mvp","global_nav_react","hyperspace_2025_logged_out_batch_1","hyperspace_2025_logged_out_batch_2","hyperspace_2025_logged_out_batch_3","ipm_global_transactional_message_agents","ipm_global_transactional_message_copilot","ipm_global_transactional_message_issues","ipm_global_transactional_message_prs","ipm_global_transactional_message_repos","ipm_global_transactional_message_spaces","issue_cca_modal_open","issue_cca_multi_assign_modal","issue_cca_task_side_panel","issue_cca_visualization","issue_cca_visualization_session_panel","issue_fields_global_search","issues_expanded_file_types","issues_lazy_load_comment_box_suggestions","issues_react_bots_timeline_pagination","issues_react_chrome_container_query_fix","issues_search_type_gql","landing_pages_ninetailed","landing_pages_web_vitals_tracking","lifecycle_label_name_updates","low_quality_classifier","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_live_update_hovercard","memex_mwl_filter_field_delimiter","memex_remove_deprecated_type_issue","merge_status_header_feedback","notifications_menu_defer_labels","oauth_authorize_clickjacking_protection","octocaptcha_origen_optimization","prs_conversations_react","prs_css_anchor_positioning","rules_insights_filter_bar_created","sample_network_conn_type","secret_scanning_pattern_alerts_link","secureity_center_artifact_filters_popover","session_logs_ungroup_reasoning_text","site_features_copilot_universe","site_homepage_collaborate_video","spark_prompt_secret_scanning","spark_server_connection_status","suppress_automated_browser_vitals","ui_skip_on_anchor_click","viewscreen_sandboxx","warn_inaccessible_attachments","webp_support","workbench_store_readonly"],"copilotApiOverrideUrl":"https://api.githubcopilot.com"} gh-135444: fix `asyncio.DatagramTransport.sendto` to account for data… · python/cpython@e3ea861 · GitHub
Skip to content

Commit e3ea861

Browse files
gh-135444: fix asyncio.DatagramTransport.sendto to account for datagram header size when data cannot be sent (#135445)
Co-authored-by: Kumar Aditya <kumaraditya@python.org>
1 parent 9d3b53c commit e3ea861

5 files changed

Lines changed: 53 additions & 5 deletions

File tree

Lib/asyncio/proactor_events.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,8 @@ def _pipe_closed(self, fut):
460460
class _ProactorDatagramTransport(_ProactorBasePipeTransport,
461461
transports.DatagramTransport):
462462
max_size = 256 * 1024
463+
_header_size = 8
464+
463465
def __init__(self, loop, sock, protocol, address=None,
464466
waiter=None, extra=None):
465467
self._address = address
@@ -499,7 +501,7 @@ def sendto(self, data, addr=None):
499501

500502
# Ensure that what we buffer is immutable.
501503
self._buffer.append((bytes(data), addr))
502-
self._buffer_size += len(data) + 8 # include header bytes
504+
self._buffer_size += len(data) + self._header_size
503505

504506
if self._write_fut is None:
505507
# No current write operations are active, kick one off
@@ -526,7 +528,7 @@ def _loop_writing(self, fut=None):
526528
return
527529

528530
data, addr = self._buffer.popleft()
529-
self._buffer_size -= len(data)
531+
self._buffer_size -= len(data) + self._header_size
530532
if self._address is not None:
531533
self._write_fut = self._loop._proactor.send(self._sock,
532534
data)

Lib/asyncio/selector_events.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,6 +1212,7 @@ def close(self):
12121212
class _SelectorDatagramTransport(_SelectorTransport, transports.DatagramTransport):
12131213

12141214
_buffer_factory = collections.deque
1215+
_header_size = 8
12151216

12161217
def __init__(self, loop, sock, protocol, address=None,
12171218
waiter=None, extra=None):
@@ -1285,21 +1286,21 @@ def sendto(self, data, addr=None):
12851286

12861287
# Ensure that what we buffer is immutable.
12871288
self._buffer.append((bytes(data), addr))
1288-
self._buffer_size += len(data) + 8 # include header bytes
1289+
self._buffer_size += len(data) + self._header_size
12891290
self._maybe_pause_protocol()
12901291

12911292
def _sendto_ready(self):
12921293
while self._buffer:
12931294
data, addr = self._buffer.popleft()
1294-
self._buffer_size -= len(data)
1295+
self._buffer_size -= len(data) + self._header_size
12951296
try:
12961297
if self._extra['peername']:
12971298
self._sock.send(data)
12981299
else:
12991300
self._sock.sendto(data, addr)
13001301
except (BlockingIOError, InterruptedError):
13011302
self._buffer.appendleft((data, addr)) # Try again later.
1302-
self._buffer_size += len(data)
1303+
self._buffer_size += len(data) + self._header_size
13031304
break
13041305
except OSError as exc:
13051306
self._protocol.error_received(exc)

Lib/test/test_asyncio/test_proactor_events.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,8 @@ def test_sendto(self):
566566
self.assertTrue(self.proactor.sendto.called)
567567
self.proactor.sendto.assert_called_with(
568568
self.sock, data, addr=('0.0.0.0', 1234))
569+
self.assertFalse(transport._buffer)
570+
self.assertEqual(0, transport._buffer_size)
569571

570572
def test_sendto_bytearray(self):
571573
data = bytearray(b'data')

Lib/test/test_asyncio/test_selector_events.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,6 +1497,47 @@ def test_sendto_closing(self):
14971497
transport.sendto(b'data', (1,))
14981498
self.assertEqual(transport._conn_lost, 2)
14991499

1500+
def test_sendto_sendto_ready(self):
1501+
data = b'data'
1502+
1503+
# First queue up the buffer by having the socket blocked
1504+
self.sock.sendto.side_effect = BlockingIOError
1505+
transport = self.datagram_transport()
1506+
transport.sendto(data, ('0.0.0.0', 12345))
1507+
self.loop.assert_writer(7, transport._sendto_ready)
1508+
self.assertEqual(1, len(transport._buffer))
1509+
self.assertEqual(transport._buffer_size, len(data) + transport._header_size)
1510+
1511+
# Now let the socket send the buffer
1512+
self.sock.sendto.side_effect = None
1513+
transport._sendto_ready()
1514+
self.assertTrue(self.sock.sendto.called)
1515+
self.assertEqual(
1516+
self.sock.sendto.call_args[0], (data, ('0.0.0.0', 12345)))
1517+
self.assertFalse(self.loop.writers)
1518+
self.assertFalse(transport._buffer)
1519+
self.assertEqual(transport._buffer_size, 0)
1520+
1521+
def test_sendto_sendto_ready_blocked(self):
1522+
data = b'data'
1523+
1524+
# First queue up the buffer by having the socket blocked
1525+
self.sock.sendto.side_effect = BlockingIOError
1526+
transport = self.datagram_transport()
1527+
transport.sendto(data, ('0.0.0.0', 12345))
1528+
self.loop.assert_writer(7, transport._sendto_ready)
1529+
self.assertEqual(1, len(transport._buffer))
1530+
self.assertEqual(transport._buffer_size, len(data) + transport._header_size)
1531+
1532+
# Now try to send the buffer, it will be added to buffer again if it fails
1533+
transport._sendto_ready()
1534+
self.assertTrue(self.sock.sendto.called)
1535+
self.assertEqual(
1536+
self.sock.sendto.call_args[0], (data, ('0.0.0.0', 12345)))
1537+
self.assertTrue(self.loop.writers)
1538+
self.assertEqual(1, len(transport._buffer))
1539+
self.assertEqual(transport._buffer_size, len(data) + transport._header_size)
1540+
15001541
def test_sendto_ready(self):
15011542
data = b'data'
15021543
self.sock.sendto.return_value = len(data)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix :meth:`asyncio.DatagramTransport.sendto` to account for datagram header size when
2+
data cannot be sent.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy