Skip to content

Commit

Permalink
Show unexpected keywords when no keywords accepcted
Browse files Browse the repository at this point in the history
  • Loading branch information
nobu committed Aug 4, 2023
1 parent 86cf401 commit 16aef10
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 7 deletions.
12 changes: 11 additions & 1 deletion class.c
Original file line number Diff line number Diff line change
Expand Up @@ -2347,7 +2347,17 @@ VALUE
rb_keyword_error_new(const char *error, VALUE keys)
{
long i = 0, len = RARRAY_LEN(keys);
VALUE error_message = rb_sprintf("%s keyword%.*s", error, len > 1, "s");
VALUE error_message;

if (error) {
static const char keywords[] = " keywords";
int mlen = (int)sizeof(keywords) - 1;
error_message = rb_str_new_cstr(error);
rb_str_cat(error_message, keywords, mlen - (len == 1));
}
else {
error_message = rb_str_new_cstr("no keywords accepted");
}

if (len > 0) {
rb_str_cat_cstr(error_message, ": ");
Expand Down
2 changes: 1 addition & 1 deletion enumerator.c
Original file line number Diff line number Diff line change
Expand Up @@ -3736,7 +3736,7 @@ enumerator_s_product(int argc, VALUE *argv, VALUE klass)
rb_scan_args(argc, argv, "*:&", &enums, &options, &block);

if (!NIL_P(options) && !RHASH_EMPTY_P(options)) {
rb_exc_raise(rb_keyword_error_new("unknown", rb_hash_keys(options)));
rb_exc_raise(rb_keyword_error_new(NULL, rb_hash_keys(options)));
}

VALUE obj = enum_product_initialize(argc, argv, enum_product_allocate(rb_cEnumProduct));
Expand Down
13 changes: 9 additions & 4 deletions test/ruby/test_keyword.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# frozen_string_literal: false
require 'test/unit'
require '-test-/rb_call_super_kw'
require '-test-/iter'
%w[-test-/rb_call_super_kw -test-/iter].each do |r|
require r
rescue LoadError
end

class TestKeywordArguments < Test::Unit::TestCase
def f1(str: "foo", num: 424242)
Expand Down Expand Up @@ -138,6 +140,9 @@ def test_f11
assert_equal([], f11)
assert_equal([], f11(**{}))
assert_equal([], f11(**h))
assert_raise_with_message(ArgumentError, "no keywords accepted: :a") {
f11(a: 1)
}
end

def f12(**nil, &b)
Expand Down Expand Up @@ -2068,7 +2073,7 @@ def c.method_missing(_, arg=1, **args)
assert_equal([1, h2], c.m(**h2))
assert_equal([1, h3], c.m(**h3))
assert_equal([1, h3], c.m(a: 1, **h2))
end
end if defined?(Bug::RbCallSuperKw)

def test_define_method_kwsplat
kw = {}
Expand Down Expand Up @@ -3454,7 +3459,7 @@ def c.c(arg=1, **args)
assert_equal([h, kw], c.m(:c, h))
assert_equal([h2, kw], c.m(:c, h2))
assert_equal([h3, kw], c.m(:c, h3))
end
end if defined?(Bug::Iter::Yield)

def p1
Proc.new do |str: "foo", num: 424242|
Expand Down
5 changes: 4 additions & 1 deletion vm_args.c
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,9 @@ setup_parameters_complex(rb_execution_context_t * const ec, const rb_iseq_t * co
given_argc--;
keyword_hash = last_arg;
}
else if (ISEQ_BODY(iseq)->param.flags.accepts_no_kwarg) {
keyword_hash = last_arg;
}
}
}
}
Expand All @@ -629,7 +632,7 @@ setup_parameters_complex(rb_execution_context_t * const ec, const rb_iseq_t * co
}

if (kw_flag && ISEQ_BODY(iseq)->param.flags.accepts_no_kwarg) {
rb_raise(rb_eArgError, "no keywords accepted");
argument_kw_error(ec, iseq, NULL, rb_hash_keys(keyword_hash));
}

switch (arg_setup_type) {
Expand Down

0 comments on commit 16aef10

Please sign in to comment.