ruby-changes:73665
From: st0012 <ko1@a...>
Date: Wed, 21 Sep 2022 22:24:38 +0900 (JST)
Subject: [ruby-changes:73665] 6325fc8854 (master): [ruby/irb] Handle non-String $LOAD_PATH values more carefully
https://git.ruby-lang.org/ruby.git/commit/?id=6325fc8854 From 6325fc885474937e1250d6605fd594cf70f0794c Mon Sep 17 00:00:00 2001 From: st0012 <stan001212@g...> Date: Mon, 19 Sep 2022 16:14:03 +0100 Subject: [ruby/irb] Handle non-String $LOAD_PATH values more carefully In addition to String values, $LOAD_PATH can also take objects that respond_to the `to_path` method, like Pathname objects. So `irb` should be able to handle those objects too. And if $LOAD_PATH contains objects that can't be converted into String, `irb` should simply ignore it. https://github.com/ruby/irb/commit/b2f562176b --- lib/irb/completion.rb | 9 ++++++++- test/irb/test_completion.rb | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/lib/irb/completion.rb b/lib/irb/completion.rb index 9121174a50..bfe6c7e7a4 100644 --- a/lib/irb/completion.rb +++ b/lib/irb/completion.rb @@ -60,7 +60,14 @@ module IRB https://github.com/ruby/ruby/blob/trunk/lib/irb/completion.rb#L60 end } }.flatten if defined?(Gem::Specification) - (gem_paths.to_a | $LOAD_PATH).sort + candidates = (gem_paths.to_a | $LOAD_PATH) + candidates.map do |p| + if p.respond_to?(:to_path) + p.to_path + else + String(p) rescue nil + end + end.compact.sort end def self.retrieve_files_to_require_from_load_path diff --git a/test/irb/test_completion.rb b/test/irb/test_completion.rb index 3aa99d74d3..4bc3fc7783 100644 --- a/test/irb/test_completion.rb +++ b/test/irb/test_completion.rb @@ -4,6 +4,11 @@ require "irb" https://github.com/ruby/ruby/blob/trunk/test/irb/test_completion.rb#L4 module TestIRB class TestCompletion < Test::Unit::TestCase + def setup + # make sure require completion candidates are not cached + IRB::InputCompletor.class_variable_set(:@@files_from_load_path, nil) + end + def test_nonstring_module_name begin require "irb/completion" @@ -84,6 +89,43 @@ module TestIRB https://github.com/ruby/ruby/blob/trunk/test/irb/test_completion.rb#L89 end end + def test_complete_require_with_pathname_in_load_path + temp_dir = Dir.mktmpdir + File.write(File.join(temp_dir, "foo.rb"), "test") + test_path = Pathname.new(temp_dir) + $LOAD_PATH << test_path + + candidates = IRB::InputCompletor::CompletionProc.("'foo", "require ", "") + assert_equal ["'foo"], candidates + ensure + $LOAD_PATH.pop if test_path + FileUtils.remove_entry(temp_dir) if temp_dir + end + + def test_complete_require_with_string_convertable_in_load_path + temp_dir = Dir.mktmpdir + File.write(File.join(temp_dir, "foo.rb"), "test") + object = Object.new + object.define_singleton_method(:to_s) { temp_dir } + $LOAD_PATH << object + + candidates = IRB::InputCompletor::CompletionProc.("'foo", "require ", "") + assert_equal ["'foo"], candidates + ensure + $LOAD_PATH.pop if object + FileUtils.remove_entry(temp_dir) if temp_dir + end + + def test_complete_require_with_malformed_object_in_load_path + object = Object.new + def object.to_s; raise; end + $LOAD_PATH << object + + assert_empty IRB::InputCompletor::CompletionProc.("'foo", "require ", "") + ensure + $LOAD_PATH.pop if object + end + def test_complete_require_library_name_first pend 'Need to use virtual library paths' candidates = IRB::InputCompletor::CompletionProc.("'csv", "require ", "") -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/