From a43acf9a3f411fac78d92b9f2f8060c83f9ab15b Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Mon, 10 Nov 2025 10:52:01 +0900 Subject: [PATCH 01/13] [ruby/resolv] [DOC] `Resolv::LOC` itself is undocumented https://github.com/ruby/resolv/commit/7c5bfe7acd --- lib/resolv.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/resolv.rb b/lib/resolv.rb index 34749afb674af7..b98c7ecdd2aa32 100644 --- a/lib/resolv.rb +++ b/lib/resolv.rb @@ -3250,7 +3250,7 @@ def make_udp_requester # :nodoc: end - module LOC + module LOC # :nodoc: ## # A Resolv::LOC::Size From 8fa29a75abf265c20cdeb9779bf25c1b3eafcf26 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Mon, 10 Nov 2025 11:10:15 +0900 Subject: [PATCH 02/13] Fix condition for Timeout Error with >= macOS 26.1 --- test/resolv/test_dns.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/resolv/test_dns.rb b/test/resolv/test_dns.rb index 2bb8061edbd1ac..86a1ecf569c181 100644 --- a/test/resolv/test_dns.rb +++ b/test/resolv/test_dns.rb @@ -525,7 +525,7 @@ def test_no_server if RUBY_PLATFORM.match?(/mingw/) # cannot repo locally omit 'Timeout Error on MinGW CI' - elsif macos?(26,1) + elsif macos?([26,1]..) omit 'Timeout Error on macOS 26.1+' else raise Timeout::Error From f710e6bb54a1e2cfe808222bc8d70d8f68ab5dc9 Mon Sep 17 00:00:00 2001 From: Daisuke Aritomo Date: Thu, 17 Jul 2025 00:09:47 +0900 Subject: [PATCH 03/13] [ruby/net-http] Replace Timeout.timeout with TCPSocket.open(open_timeout:) when available This patch replaces the implementation of #open_timeout from Timeout.timeout from the builtin timeout in TCPSocket.open, which was introduced in Ruby 3.5 (https://bugs.ruby-lang.org/issues/21347). The builtin timeout in TCPSocket.open is better in several ways than Timeout.timeout. It does not rely on a separate Ruby Thread for monitoring Timeout (which is what the timeout library internally does). Furthermore, it is compatible with Ractors, as opposed to Timeout.timeout (it internally uses Thread::Mutex which can not be used in non-main Ractors). This change allows the following code to work. require 'net/http' Ractor.new { uri = URI('http://example.com/') http = Net::HTTP.new(uri.host, uri.port) http.open_timeout = 1 http.get(uri.path) }.value In Ruby <3.5 environments where `TCPSocket.open` does not have the `open_timeout` option, I have kept the behavior unchanged. net/http will use `Timeout.timeout { TCPSocket.open }`. https://github.com/ruby/net-http/commit/728eb8fc42 --- lib/net/http.rb | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/net/http.rb b/lib/net/http.rb index 7efb468e782e06..d6db9ba132abfe 100644 --- a/lib/net/http.rb +++ b/lib/net/http.rb @@ -1672,14 +1672,22 @@ def connect end debug "opening connection to #{conn_addr}:#{conn_port}..." - s = Timeout.timeout(@open_timeout, Net::OpenTimeout) { - begin - TCPSocket.open(conn_addr, conn_port, @local_host, @local_port) - rescue => e - raise e, "Failed to open TCP connection to " + - "#{conn_addr}:#{conn_port} (#{e.message})" + begin + s = begin + # Use built-in timeout in TCPSocket.open if available + TCPSocket.open(conn_addr, conn_port, @local_host, @local_port, open_timeout: @open_timeout) + rescue ArgumentError => e + raise if !e.message.include?('unknown keyword: :open_timeout') + # Fallback to Timeout.timeout if TCPSocket.open does not support open_timeout + Timeout.timeout(@open_timeout, Net::OpenTimeout) { + TCPSocket.open(conn_addr, conn_port, @local_host, @local_port) + } end - } + rescue => e + e = Net::OpenTimeout.new(e) if e.is_a?(Errno::ETIMEDOUT) # for compatibility with previous versions + raise e, "Failed to open TCP connection to " + + "#{conn_addr}:#{conn_port} (#{e.message})" + end s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) debug "opened" if use_ssl? From 97efbc47d080e3ade3b5db889d3740fdf0711161 Mon Sep 17 00:00:00 2001 From: Daisuke Aritomo Date: Tue, 22 Jul 2025 23:34:25 +0900 Subject: [PATCH 04/13] [ruby/net-http] Ruby 2 compat https://github.com/ruby/net-http/commit/09bf573dd5 --- lib/net/http.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/net/http.rb b/lib/net/http.rb index d6db9ba132abfe..810ee008facaaf 100644 --- a/lib/net/http.rb +++ b/lib/net/http.rb @@ -1677,7 +1677,7 @@ def connect # Use built-in timeout in TCPSocket.open if available TCPSocket.open(conn_addr, conn_port, @local_host, @local_port, open_timeout: @open_timeout) rescue ArgumentError => e - raise if !e.message.include?('unknown keyword: :open_timeout') + raise if !(e.message.include?('unknown keyword: :open_timeout') || e.message.include?('wrong number of arguments (given 5, expected 2..4)')) # Fallback to Timeout.timeout if TCPSocket.open does not support open_timeout Timeout.timeout(@open_timeout, Net::OpenTimeout) { TCPSocket.open(conn_addr, conn_port, @local_host, @local_port) From f29d772a73ed25c5bcc6eab1d55684894292d160 Mon Sep 17 00:00:00 2001 From: Daisuke Aritomo Date: Thu, 6 Nov 2025 11:20:11 +0900 Subject: [PATCH 05/13] [ruby/net-http] Remember if TCPSocket impl supports open_timeout For open_timeout support detection, the previous implementation relied on an ArgumentError being raised and then rescued. In Ruby, rescue is a rather expensive operation and should be avoided when possible. This patch reduces the number of begin-rescues by remembering if the TCPSocket implementation supports open_timeout. https://github.com/ruby/net-http/commit/06d982f3a1 --- lib/net/http.rb | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/lib/net/http.rb b/lib/net/http.rb index 810ee008facaaf..c60649b8123c09 100644 --- a/lib/net/http.rb +++ b/lib/net/http.rb @@ -1179,6 +1179,7 @@ def initialize(address, port = nil) # :nodoc: @debug_output = options[:debug_output] @response_body_encoding = options[:response_body_encoding] @ignore_eof = options[:ignore_eof] + @tcpsocket_supports_open_timeout = nil @proxy_from_env = false @proxy_uri = nil @@ -1673,16 +1674,30 @@ def connect debug "opening connection to #{conn_addr}:#{conn_port}..." begin - s = begin - # Use built-in timeout in TCPSocket.open if available - TCPSocket.open(conn_addr, conn_port, @local_host, @local_port, open_timeout: @open_timeout) - rescue ArgumentError => e - raise if !(e.message.include?('unknown keyword: :open_timeout') || e.message.include?('wrong number of arguments (given 5, expected 2..4)')) - # Fallback to Timeout.timeout if TCPSocket.open does not support open_timeout - Timeout.timeout(@open_timeout, Net::OpenTimeout) { - TCPSocket.open(conn_addr, conn_port, @local_host, @local_port) - } - end + s = + case @tcpsocket_supports_open_timeout + when nil, true + begin + # Use built-in timeout in TCPSocket.open if available + sock = TCPSocket.open(conn_addr, conn_port, @local_host, @local_port, open_timeout: @open_timeout) + @tcpsocket_supports_open_timeout = true + sock + rescue ArgumentError => e + raise if !(e.message.include?('unknown keyword: :open_timeout') || e.message.include?('wrong number of arguments (given 5, expected 2..4)')) + @tcpsocket_supports_open_timeout = false + + # Fallback to Timeout.timeout if TCPSocket.open does not support open_timeout + Timeout.timeout(@open_timeout, Net::OpenTimeout) { + TCPSocket.open(conn_addr, conn_port, @local_host, @local_port) + } + end + when false + # The current Ruby is known to not support TCPSocket(open_timeout:). + # Directly fall back to Timeout.timeout to avoid performance penalty incured by rescue. + Timeout.timeout(@open_timeout, Net::OpenTimeout) { + TCPSocket.open(conn_addr, conn_port, @local_host, @local_port) + } + end rescue => e e = Net::OpenTimeout.new(e) if e.is_a?(Errno::ETIMEDOUT) # for compatibility with previous versions raise e, "Failed to open TCP connection to " + From cb50ed2cc2218f077789e75fca3afeaf51ebba0e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 02:04:22 +0000 Subject: [PATCH 06/13] Bump actions/checkout from 4 to 5 Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/auto_review_pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/auto_review_pr.yml b/.github/workflows/auto_review_pr.yml index c8095dfd8e34a0..c8c9a76777cb76 100644 --- a/.github/workflows/auto_review_pr.yml +++ b/.github/workflows/auto_review_pr.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - uses: ruby/setup-ruby@ab177d40ee5483edb974554986f56b33477e21d0 # v1.265.0 with: From 3147df87baf8898e6fb3c1482e7a5ed58945c97a Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Mon, 10 Nov 2025 12:36:55 +0900 Subject: [PATCH 07/13] [ruby/net-http] [DOC] Suppress documentation for internals https://github.com/ruby/net-http/commit/b7c586985a --- lib/net/http/responses.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/net/http/responses.rb b/lib/net/http/responses.rb index 2fa01e2c0c3f33..941a6fed80414b 100644 --- a/lib/net/http/responses.rb +++ b/lib/net/http/responses.rb @@ -4,6 +4,7 @@ module Net + # Unknown HTTP response class HTTPUnknownResponse < HTTPResponse # :stopdoc: HAS_BODY = true From b1dfcd6507452d577162d12ecb0828abe64d8162 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Mon, 10 Nov 2025 12:40:32 +0900 Subject: [PATCH 08/13] [ruby/stringio] [DOC] Suppress documentation for internals https://github.com/ruby/stringio/commit/27b2fb2fce --- ext/stringio/stringio.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c index 39e4be58538f9f..5da0b4c9457a2e 100644 --- a/ext/stringio/stringio.c +++ b/ext/stringio/stringio.c @@ -2244,7 +2244,9 @@ Init_stringio(void) rb_define_method(StringIO, "set_encoding_by_bom", strio_set_encoding_by_bom, 0); { + /* :stopdoc: */ VALUE mReadable = rb_define_module_under(rb_cIO, "generic_readable"); + /* :startdoc: */ rb_define_method(mReadable, "readchar", strio_readchar, 0); rb_define_method(mReadable, "readbyte", strio_readbyte, 0); rb_define_method(mReadable, "readline", strio_readline, -1); @@ -2254,7 +2256,9 @@ Init_stringio(void) rb_include_module(StringIO, mReadable); } { + /* :stopdoc: */ VALUE mWritable = rb_define_module_under(rb_cIO, "generic_writable"); + /* :startdoc: */ rb_define_method(mWritable, "<<", strio_addstr, 1); rb_define_method(mWritable, "print", strio_print, -1); rb_define_method(mWritable, "printf", strio_printf, -1); From 40d6626bbf0b0bd4c672d48dbf928ab8429912f9 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Sat, 8 Nov 2025 07:25:33 +0900 Subject: [PATCH 09/13] [ruby/rubygems] Fixed with Lint/RedundantSplatExpansion https://github.com/ruby/rubygems/commit/2078f3d351 --- lib/bundler/current_ruby.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bundler/current_ruby.rb b/lib/bundler/current_ruby.rb index abb7ca2195daa6..ab6520a106a40f 100644 --- a/lib/bundler/current_ruby.rb +++ b/lib/bundler/current_ruby.rb @@ -11,7 +11,7 @@ def self.current_ruby end class CurrentRuby - ALL_RUBY_VERSIONS = [*18..27, *30..34, *40].freeze + ALL_RUBY_VERSIONS = [*18..27, *30..34, 40].freeze KNOWN_MINOR_VERSIONS = ALL_RUBY_VERSIONS.map {|v| v.digits.reverse.join(".") }.freeze KNOWN_MAJOR_VERSIONS = ALL_RUBY_VERSIONS.map {|v| v.digits.last.to_s }.uniq.freeze PLATFORM_MAP = { From 19295f5db3316dd47d0aded90a21b07d7e761902 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Mon, 10 Nov 2025 12:55:41 +0900 Subject: [PATCH 10/13] [ruby/cgi] [DOC] Missing documents https://github.com/ruby/cgi/commit/ebd04d1eb1 --- lib/cgi/escape.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/cgi/escape.rb b/lib/cgi/escape.rb index 59a310b32d6187..6d84773fdd62f6 100644 --- a/lib/cgi/escape.rb +++ b/lib/cgi/escape.rb @@ -1,11 +1,15 @@ # frozen_string_literal: true +# :stopdoc class CGI module Escape; end include Escape extend Escape + module EscapeExt; end # :nodoc: end +# :startdoc: +# Escape/unescape for CGI, HTML, URI. module CGI::Escape @@accept_charset = Encoding::UTF_8 unless defined?(@@accept_charset) From 28f760bf70085d97bab62c29e13c69c5a732e758 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Mon, 10 Nov 2025 13:03:50 +0900 Subject: [PATCH 11/13] [ruby/stringio] Suppress warnings against pattern matching on ruby 2.7 https://github.com/ruby/stringio/commit/cf58a203eb --- test/stringio/test_stringio.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/stringio/test_stringio.rb b/test/stringio/test_stringio.rb index fe890406074654..024906261efaac 100644 --- a/test/stringio/test_stringio.rb +++ b/test/stringio/test_stringio.rb @@ -996,7 +996,7 @@ def test_overflow intptr_max = RbConfig::LIMITS["INTPTR_MAX"] return if intptr_max > StringIO::MAX_LENGTH limit = intptr_max - 0x10 - assert_separately(%w[-rstringio], "#{<<-"begin;"}\n#{<<-"end;"}") + assert_separately(%w[-W0 -rstringio], "#{<<-"begin;"}\n#{<<-"end;"}") begin; limit = #{limit} ary = [] From 73339ff2a1e5e8f35ad7224886ed56ae1da3e3ca Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Mon, 10 Nov 2025 13:21:17 +0900 Subject: [PATCH 12/13] [ruby/rubygems] [DOC] Fix the location of Gem::Deprecate document It was bound to `module Gem`, instead of `module Deprecate`. https://github.com/ruby/rubygems/commit/da29f74ba1 --- lib/rubygems/deprecate.rb | 138 +++++++++++++++++++------------------- 1 file changed, 69 insertions(+), 69 deletions(-) diff --git a/lib/rubygems/deprecate.rb b/lib/rubygems/deprecate.rb index 303b344d42c838..fae99052ea4f6a 100644 --- a/lib/rubygems/deprecate.rb +++ b/lib/rubygems/deprecate.rb @@ -1,75 +1,75 @@ # frozen_string_literal: true -## -# Provides 3 methods for declaring when something is going away. -# -# +deprecate(name, repl, year, month)+: -# Indicate something may be removed on/after a certain date. -# -# +rubygems_deprecate(name, replacement=:none)+: -# Indicate something will be removed in the next major RubyGems version, -# and (optionally) a replacement for it. -# -# +rubygems_deprecate_command+: -# Indicate a RubyGems command (in +lib/rubygems/commands/*.rb+) will be -# removed in the next RubyGems version. -# -# Also provides +skip_during+ for temporarily turning off deprecation warnings. -# This is intended to be used in the test suite, so deprecation warnings -# don't cause test failures if you need to make sure stderr is otherwise empty. -# -# -# Example usage of +deprecate+ and +rubygems_deprecate+: -# -# class Legacy -# def self.some_class_method -# # ... -# end -# -# def some_instance_method -# # ... -# end -# -# def some_old_method -# # ... -# end -# -# extend Gem::Deprecate -# deprecate :some_instance_method, "X.z", 2011, 4 -# rubygems_deprecate :some_old_method, "Modern#some_new_method" -# -# class << self -# extend Gem::Deprecate -# deprecate :some_class_method, :none, 2011, 4 -# end -# end -# -# -# Example usage of +rubygems_deprecate_command+: -# -# class Gem::Commands::QueryCommand < Gem::Command -# extend Gem::Deprecate -# rubygems_deprecate_command -# -# # ... -# end -# -# -# Example usage of +skip_during+: -# -# class TestSomething < Gem::Testcase -# def test_some_thing_with_deprecations -# Gem::Deprecate.skip_during do -# actual_stdout, actual_stderr = capture_output do -# Gem.something_deprecated -# end -# assert_empty actual_stdout -# assert_equal(expected, actual_stderr) -# end -# end -# end - module Gem + ## + # Provides 3 methods for declaring when something is going away. + # + # +deprecate(name, repl, year, month)+: + # Indicate something may be removed on/after a certain date. + # + # +rubygems_deprecate(name, replacement=:none)+: + # Indicate something will be removed in the next major RubyGems version, + # and (optionally) a replacement for it. + # + # +rubygems_deprecate_command+: + # Indicate a RubyGems command (in +lib/rubygems/commands/*.rb+) will be + # removed in the next RubyGems version. + # + # Also provides +skip_during+ for temporarily turning off deprecation warnings. + # This is intended to be used in the test suite, so deprecation warnings + # don't cause test failures if you need to make sure stderr is otherwise empty. + # + # + # Example usage of +deprecate+ and +rubygems_deprecate+: + # + # class Legacy + # def self.some_class_method + # # ... + # end + # + # def some_instance_method + # # ... + # end + # + # def some_old_method + # # ... + # end + # + # extend Gem::Deprecate + # deprecate :some_instance_method, "X.z", 2011, 4 + # rubygems_deprecate :some_old_method, "Modern#some_new_method" + # + # class << self + # extend Gem::Deprecate + # deprecate :some_class_method, :none, 2011, 4 + # end + # end + # + # + # Example usage of +rubygems_deprecate_command+: + # + # class Gem::Commands::QueryCommand < Gem::Command + # extend Gem::Deprecate + # rubygems_deprecate_command + # + # # ... + # end + # + # + # Example usage of +skip_during+: + # + # class TestSomething < Gem::Testcase + # def test_some_thing_with_deprecations + # Gem::Deprecate.skip_during do + # actual_stdout, actual_stderr = capture_output do + # Gem.something_deprecated + # end + # assert_empty actual_stdout + # assert_equal(expected, actual_stderr) + # end + # end + # end + module Deprecate def self.skip # :nodoc: @skip ||= false From 57f2ac720d70b2245706f323cd7f3178aa5cfe6c Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Mon, 10 Nov 2025 13:46:15 +0900 Subject: [PATCH 13/13] [ruby/rubygems] [DOC] Fix markups Use `` instead of `+` that cannot enclose punctuations. https://github.com/ruby/rubygems/commit/f84035c0b6 --- lib/rubygems/deprecate.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rubygems/deprecate.rb b/lib/rubygems/deprecate.rb index fae99052ea4f6a..eb503bb2699976 100644 --- a/lib/rubygems/deprecate.rb +++ b/lib/rubygems/deprecate.rb @@ -4,10 +4,10 @@ module Gem ## # Provides 3 methods for declaring when something is going away. # - # +deprecate(name, repl, year, month)+: + # deprecate(name, repl, year, month): # Indicate something may be removed on/after a certain date. # - # +rubygems_deprecate(name, replacement=:none)+: + # rubygems_deprecate(name, replacement=:none): # Indicate something will be removed in the next major RubyGems version, # and (optionally) a replacement for it. #