Skip to content

Commit 0bb0601

Browse files
committed
[Fix] Fix a SyntaxError on Ruby 2.7.0 Caused by Arguments Forwarding Syntax
## Motivation and Context The gemspec already declares `required_ruby_version >= 2.7.0`, but `ServerContext` used the `...` arguments forwarding syntax in `method_missing`. That syntax was added in Ruby 2.7.3, so requiring the gem raised a `SyntaxError` on Ruby 2.7.0 through 2.7.2, and the library could not be loaded at all. RuboCop did not catch this because its Parser backend runs on Ruby 2.7.8, where the syntax is valid. CI missed it too because the test matrix tested `2.7`, which resolves to the latest 2.7.x rather than the declared minimum. ## How Has This Been Tested? Forward arguments explicitly with `*args, **kwargs, &block` so the method loads on Ruby 2.7.0, and pin the CI test matrix to 2.7.0 so the suite runs against the declared minimum instead of the latest 2.7.x. Running the suite on 2.7.0 also requires a `Hash.ruby2_keywords_hash?` shim in the test helper, since mocha would otherwise raise a `NoMethodError` on that version. ## Breaking Changes None. Closes modelcontextprotocol#418
1 parent 217542f commit 0bb0601

4 files changed

Lines changed: 32 additions & 3 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
strategy:
1010
matrix:
1111
entry:
12-
- { ruby: '2.7', allowed-failure: false }
12+
- { ruby: '2.7.0', allowed-failure: false } # Minimum supported Ruby version.
1313
- { ruby: '3.0', allowed-failure: false }
1414
- { ruby: '3.1', allowed-failure: false }
1515
- { ruby: '3.2', allowed-failure: false }

lib/mcp/server_context.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,14 @@ def notify_elicitation_complete(**kwargs)
130130
end
131131
end
132132

133-
def method_missing(name, ...)
133+
# Forward arguments explicitly with `*args, **kwargs, &block` rather than the `...` forwarding syntax.
134+
# The gem supports Ruby 2.7.0 (see `required_ruby_version`), but RuboCop's Parser backend only runs on Ruby 2.7.8,
135+
# so leading-argument forwarding like `def method_missing(name, ...)` is allowed by the linter even though it
136+
# raises a `SyntaxError` on Ruby 2.7.0 through 2.7.2 (it was added in Ruby 2.7.3). Explicit forwarding keeps
137+
# this method loadable on Ruby 2.7.0.
138+
def method_missing(name, *args, **kwargs, &block)
134139
if @context.respond_to?(name)
135-
@context.public_send(name, ...)
140+
@context.public_send(name, *args, **kwargs, &block)
136141
else
137142
super
138143
end

test/mcp/server_context_test.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,20 @@ def context.custom_method
201201
assert_equal "custom_value", server_context.custom_method
202202
end
203203

204+
test "ServerContext forwards positional, keyword, and block arguments to the context" do
205+
context = Object.new
206+
def context.combine(prefix, suffix:, &block)
207+
block.call("#{prefix}-#{suffix}")
208+
end
209+
progress = Progress.new(notification_target: mock, progress_token: nil)
210+
211+
server_context = ServerContext.new(context, progress: progress, notification_target: mock)
212+
213+
result = server_context.combine("a", suffix: "b", &:upcase)
214+
215+
assert_equal "A-B", result
216+
end
217+
204218
test "ServerContext#report_progress works with nil context" do
205219
progress = mock
206220
progress.expects(:report).with(50, total: 100, message: nil).once

test/test_helper.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@
66
require "minitest/mock"
77
require "mocha/minitest"
88

9+
# mocha relies on `Hash.ruby2_keywords_hash?`, which is absent on Ruby 2.7.0 and the earlier 2.7.x releases
10+
# before it was backported. Those versions also lack the flag-setting APIs, so no hash is ever flagged as
11+
# ruby2_keywords and returning `false` is correct. Without this shim, mocha raises `NoMethodError` and
12+
# the suite cannot run on Ruby 2.7.0.
13+
unless Hash.respond_to?(:ruby2_keywords_hash?)
14+
def Hash.ruby2_keywords_hash?(_hash)
15+
false
16+
end
17+
end
18+
919
require "active_support"
1020
require "active_support/test_case"
1121

0 commit comments

Comments
 (0)