Bug #22508
open`Resolv.new(use_ipv6: ...)` is silently ignored since resolv 0.6.0 (Ruby 3.4)
Description
Since resolv 0.6.0 (bundled with Ruby 3.4.0), the use_ipv6: keyword argument of Resolv.new is silently ignored when no positional argument is given. In resolv 0.3.0 (Ruby 3.3) it set use_ipv6 of the DNS resolver. Is this intended?
require 'resolv'
puts "ruby #{RUBY_VERSION}, resolv #{Resolv::VERSION}"
def dns_use_ipv6(r)
dns = r.instance_variable_get(:@resolvers).find { |x| x.is_a?(Resolv::DNS) }
cfg = dns.instance_variable_get(:@config)
cfg.lazy_initialize
cfg.use_ipv6?
end
p dns_use_ipv6(Resolv.new(use_ipv6: false))
p dns_use_ipv6(Resolv.new(use_ipv6: true))
p dns_use_ipv6(Resolv.new({use_ipv6: false}))
ruby 3.3.0, resolv 0.3.0
false
true
(NoMethodError: a Hash is not accepted as resolvers in 0.3.0)
ruby 3.4.0, resolv 0.6.0
nil
nil
false
ruby 3.4.12, resolv 0.7.2
nil
nil
false
The same nil / nil / false is printed on Ruby 4.0.9 (resolv 0.7.2) and 4.1.0dev (resolv 0.8.1). No warning is printed; the deprecation warning only appears when a positional argument and the keyword are given together.
When Resolv::DNS::Config#use_ipv6? is nil, Resolv::DNS#use_ipv6? falls back to checking Socket.ip_address_list for a global IPv6 address, so Resolv.new(use_ipv6: false).getaddresses(name) queries AAAA records on an IPv6-capable host, which is what the keyword was meant to turn off.
Background:
- The keyword was added in resolv 0.3.0 (ruby/resolv#1, merged 2023-11-24; v0.3.0 was tagged 2023-12-13 and bundled with Ruby 3.3.0):
DNS.new(DNS::Config.default_config_hash.merge(use_ipv6: use_ipv6)). - ruby/resolv#43 (opened 2023-11-25, merged 2024-12-13, released as resolv 0.6.0 with Ruby 3.4.0) changed
Resolv#initializeto accept a Hash asresolversand merge it into the DNS config. Since thenuse_ipv6:is only used to decide whether to print the deprecation warning, and only when a positional argument is also given; its value is never passed toResolv::DNS. The PR description says "This is backwards compatible, because there has not yet been a release with the use_ipv6 keyword supported", but 0.3.0 had been released a year before the merge. - The warning text ("Support for separate use_ipv6 keyword is deprecated, as it is ignored if an argument is provided. Do not provide a positional argument if using the use_ipv6 keyword argument.") implies that the keyword alone still works. The RDoc of
Resolv.newin 0.6.0 and later does not mentionuse_ipv6:at all.
Questions:
- Should
Resolv.new(use_ipv6: v)without a positional argument be honored again (for example by merginguse_ipv6: vinto the DNS config whenresolversisnil), as the warning text suggests? - If the keyword is meant to go away, should it warn (or raise
ArgumentError) whenever it is given, so that existingResolv.new(use_ipv6: false)callers notice, and should the RDoc ofResolv.newmentionResolv.new({use_ipv6: false})as the replacement?
I am asking because the Japanese reference manual currently documents the behavior as is (https://github.com/rurema/doctree/pull/3698) and I would like to know which behavior to describe.
Reproduced with the ghcr.io/ruby/all-ruby (3.3.0, 3.4.0, 4.0.0), ghcr.io/ruby/ruby:3.4 (3.4.12), ghcr.io/ruby/ruby:4.0 (4.0.9) and ghcr.io/ruby/ruby:master Docker images (x86_64-linux).
No data to display