From 6a506224a25f4e105c7ea76cb7074347a2a0aeae Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Fri, 8 May 2026 09:41:45 +0900 Subject: [ruby/rubygems] Avoid forcing a remote gemspec load when seeding LazySpec overrides SpecSet#with_overrides cascaded into each contained spec via `respond_to?(:overrides=)`. RemoteSpecification#respond_to? forwards to _remote_specification, which materializes the backing gemspec just to answer the predicate. spec/runtime/require_spec.rb verifies that Bundler does not load gemspecs it does not need by deliberately poisoning one with `raise 'broken gemspec'`; the cascade tripped that guard and made `Bundler.setup` blow up. Gate the cascade on `is_a?(LazySpecification)` instead. Only LazySpecification declares `attr_accessor :overrides` (used by `#choose_compatible`), so the predicate is equivalent for any spec we ever set overrides on, and it never triggers the lazy gemspec load. https://github.com/ruby/rubygems/commit/2a1e7d5c23 Co-Authored-By: Claude Opus 4.7 (1M context) --- lib/bundler/spec_set.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb index 163e16863b..72e4d9c1dd 100644 --- a/lib/bundler/spec_set.rb +++ b/lib/bundler/spec_set.rb @@ -16,7 +16,11 @@ module Bundler def with_overrides(overrides) @overrides = overrides || [] - @specs.each {|s| s.overrides = @overrides if s.respond_to?(:overrides=) } + # Only LazySpecification carries an overrides accessor. Avoid + # respond_to?(:overrides=) here because RemoteSpecification#respond_to? + # forwards to _remote_specification, which would force-load the + # backing gemspec to answer the question. + @specs.each {|s| s.overrides = @overrides if s.is_a?(LazySpecification) } self end -- cgit v1.2.3