Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IRB crashing on sorting completions if $LOAD_PATH contains Pathname #394

Closed
alexeevit opened this issue Aug 23, 2022 · 6 comments · Fixed by #400
Closed

IRB crashing on sorting completions if $LOAD_PATH contains Pathname #394

alexeevit opened this issue Aug 23, 2022 · 6 comments · Fixed by #400

Comments

@alexeevit
Copy link

alexeevit commented Aug 23, 2022

Description

Expected behavior: IRB proposes options to autocomplete the "require" method argument (or just doesn't crash).
Actual behavior: IRB crashes once I add any symbol after require '

In my case, Rails config.eager_load_paths contains an instance of Pathname and when I replace it with a String, the error disappear. Probably, we should convert all options to String before sorting.

irb(main):001:0' require 'iKilling session flusher
Shutting down background worker
Traceback (most recent call last):
	54: from bin/rails:4:in `<main>'
	53: from /usr/local/bundle/gems/bootsnap-1.12.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	52: from /usr/local/bundle/gems/bootsnap-1.12.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
	51: from /usr/local/bundle/gems/railties-6.1.6/lib/rails/commands.rb:18:in `<main>'
	50: from /usr/local/bundle/gems/railties-6.1.6/lib/rails/command.rb:48:in `invoke'
	49: from /usr/local/bundle/gems/railties-6.1.6/lib/rails/command/base.rb:69:in `perform'
	48: from /usr/local/bundle/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch'
	47: from /usr/local/bundle/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command'
	46: from /usr/local/bundle/gems/thor-1.2.1/lib/thor/command.rb:27:in `run'
	45: from /usr/local/bundle/gems/railties-6.1.6/lib/rails/commands/console/console_command.rb:102:in `perform'
	44: from /usr/local/bundle/gems/railties-6.1.6/lib/rails/commands/console/console_command.rb:19:in `start'
	43: from /usr/local/bundle/gems/railties-6.1.6/lib/rails/commands/console/console_command.rb:70:in `start'
	42: from /usr/local/bundle/gems/irb-1.4.1/lib/irb.rb:419:in `start'
	41: from /usr/local/bundle/gems/irb-1.4.1/lib/irb.rb:490:in `run'
	40: from /usr/local/bundle/gems/irb-1.4.1/lib/irb.rb:490:in `catch'
	39: from /usr/local/bundle/gems/irb-1.4.1/lib/irb.rb:491:in `block in run'
	38: from /usr/local/bundle/gems/irb-1.4.1/lib/irb.rb:557:in `eval_input'
	37: from /usr/local/bundle/gems/irb-1.4.1/lib/irb/ruby-lex.rb:249:in `each_top_level_statement'
	36: from /usr/local/bundle/gems/irb-1.4.1/lib/irb/ruby-lex.rb:249:in `catch'
	35: from /usr/local/bundle/gems/irb-1.4.1/lib/irb/ruby-lex.rb:250:in `block in each_top_level_statement'
	34: from /usr/local/bundle/gems/irb-1.4.1/lib/irb/ruby-lex.rb:250:in `loop'
	33: from /usr/local/bundle/gems/irb-1.4.1/lib/irb/ruby-lex.rb:253:in `block (2 levels) in each_top_level_statement'
	32: from /usr/local/bundle/gems/irb-1.4.1/lib/irb/ruby-lex.rb:284:in `lex'
	31: from /usr/local/bundle/gems/irb-1.4.1/lib/irb.rb:538:in `block in eval_input'
	30: from /usr/local/bundle/gems/irb-1.4.1/lib/irb.rb:770:in `signal_status'
	29: from /usr/local/bundle/gems/irb-1.4.1/lib/irb.rb:539:in `block (2 levels) in eval_input'
	28: from /usr/local/bundle/gems/irb-1.4.1/lib/irb/input-method.rb:418:in `gets'
	27: from /usr/local/lib/ruby/2.7.0/forwardable.rb:235:in `readmultiline'
	26: from /usr/local/lib/ruby/2.7.0/forwardable.rb:235:in `readmultiline'
	25: from /usr/local/bundle/gems/reline-0.3.1/lib/reline.rb:254:in `readmultiline'
	24: from /usr/local/bundle/gems/reline-0.3.1/lib/reline.rb:324:in `inner_readline'
	23: from /usr/local/bundle/gems/reline-0.3.1/lib/reline.rb:324:in `loop'
	22: from /usr/local/bundle/gems/reline-0.3.1/lib/reline.rb:326:in `block in inner_readline'
	21: from /usr/local/bundle/gems/reline-0.3.1/lib/reline.rb:373:in `read_io'
	20: from /usr/local/bundle/gems/reline-0.3.1/lib/reline.rb:373:in `loop'
	19: from /usr/local/bundle/gems/reline-0.3.1/lib/reline.rb:403:in `block in read_io'
	18: from /usr/local/bundle/gems/reline-0.3.1/lib/reline.rb:328:in `block (2 levels) in inner_readline'
	17: from /usr/local/bundle/gems/reline-0.3.1/lib/reline.rb:328:in `each'
	16: from /usr/local/bundle/gems/reline-0.3.1/lib/reline.rb:330:in `block (3 levels) in inner_readline'
	15: from /usr/local/bundle/gems/reline-0.3.1/lib/reline/line_editor.rb:510:in `rerender'
	14: from /usr/local/bundle/gems/reline-0.3.1/lib/reline/line_editor.rb:650:in `render_dialog'
	13: from /usr/local/bundle/gems/reline-0.3.1/lib/reline/line_editor.rb:650:in `each'
	12: from /usr/local/bundle/gems/reline-0.3.1/lib/reline/line_editor.rb:651:in `block in render_dialog'
	11: from /usr/local/bundle/gems/reline-0.3.1/lib/reline/line_editor.rb:667:in `render_each_dialog'
	10: from /usr/local/bundle/gems/reline-0.3.1/lib/reline/line_editor.rb:623:in `call'
	 9: from /usr/local/bundle/gems/reline-0.3.1/lib/reline/line_editor.rb:588:in `call'
	 8: from /usr/local/bundle/gems/reline-0.3.1/lib/reline/line_editor.rb:588:in `instance_exec'
	 7: from /usr/local/bundle/gems/reline-0.3.1/lib/reline.rb:226:in `block in <class:Core>'
	 6: from /usr/local/bundle/gems/reline-0.3.1/lib/reline/line_editor.rb:543:in `call_completion_proc_with_checking_args'
	 5: from /usr/local/bundle/gems/reline-0.3.1/lib/reline/line_editor.rb:1681:in `call_completion_proc_with_checking_args'
	 4: from /usr/local/bundle/gems/irb-1.4.1/lib/irb/completion.rb:128:in `block in <module:InputCompletor>'
	 3: from /usr/local/bundle/gems/irb-1.4.1/lib/irb/completion.rb:110:in `block in <module:InputCompletor>'
	 2: from /usr/local/bundle/gems/irb-1.4.1/lib/irb/completion.rb:70:in `retrieve_files_to_require_from_load_path'
	 1: from /usr/local/bundle/gems/irb-1.4.1/lib/irb/completion.rb:63:in `retrieve_gem_and_system_load_path'
/usr/local/bundle/gems/irb-1.4.1/lib/irb/completion.rb:63:in `sort': comparison of Pathname with String failed (ArgumentError)

Result of irb_info

Ruby version: 2.7.6
IRB version: irb 1.4.1 (2021-12-25)
InputMethod: ReidlineInputMethod with Reline 0.3.1
.irbrc path: /Users/vyacheslav/.irbrc
RUBY_PLATFORM: arm64-darwin21
LC_ALL env: en_US.UTF-8
East Asian Ambiguous Width: 1

and in Docker:

Ruby version: 2.7.6
IRB version: irb 1.4.1 (2021-12-25)
InputMethod: ReidlineInputMethod with Reline 0.3.1
RUBY_PLATFORM: aarch64-linux
LANG env: C.UTF-8
East Asian Ambiguous Width: 1

Terminal Emulator

iTerm

Setting Files

Are you using ~/.irbrc and ~/.inputrc?

No

@alexeevit alexeevit changed the title IRB crashing on completion of path for the "require" method IRB crashing on sorting completions if $LOAD_PATH contains Pathname Aug 23, 2022
@st0012
Copy link
Member

st0012 commented Aug 23, 2022

In case it's confusing, the Killing session flusher\nShutting down background worker message is printed by the sentry-ruby's at_exit callback. So it's likely triggered by the crashing, not causing the crashing.

@alexeevit
Copy link
Author

In case it's confusing, the Killing session flusher\nShutting down background worker message is printed by the sentry-ruby's at_exit callback. So it's likely triggered by the crashing, not causing the crashing.

Yeah, I probably should've attach logs from a clean rails app. I described above, the issue is in having an instance of Pathname in $LOAD_PATH, instead of a string.

@domon-envato
Copy link

I just bumped into the same issue. It can be reproduced by adding a Pathname to Rails' eager_load_paths or autoload_paths like what people on the Internet suggest.

e.g.

# config/application.rb

class Application < Rails::Application
  config.eager_load_paths << config.root.join('lib')
end

@nirvdrum
Copy link
Contributor

nirvdrum commented Sep 1, 2022

Ruby will happily accept any entry in the $LOAD_PATH that can be coerced to a String. It may not be a terribly common use case, but you can do:

class X
  def to_str
    __dir__
  end
end

$LOAD_PATH << X.new

require 'some_file_in_current_directory'

I think

(gem_paths.to_a | $LOAD_PATH).sort
ought to be (gem_paths.to_a | $LOAD_PATH).sort_by { |path| String(path) rescue "" }. As far as I can tell that, matches what MRI does when processing the $LOAD_PATH with an extra bit of error handling so entries that can't be coerced to a String don't break IRB.

I can pull this into a PR, but I need to familiarize myself with the tests first. Having to modify $LOAD_PATH for a test is not ideal for test isolation. If someone else can take care of that quicker, please go ahead.

@st0012
Copy link
Member

st0012 commented Sep 1, 2022

Thanks for look into it. I think in this case something like this should be acceptable?

  $LOAD_PATH << pathname_path
  # test
ensure
  $LOAD_PATH.pop

We can just dup and reassign the $LOAD_PATH value like what rubygems does as well. And also in the require tests.

@st0012
Copy link
Member

st0012 commented Sep 19, 2022

FYI, I created #400 to address this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

4 participants