From 3689c29fc7aa77d82c09d04ec6fea506de0b1899 Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Sun, 1 Dec 2024 11:21:26 -0600 Subject: [PATCH 1/2] Improve error message in the absence of arguments to `@b` and add tests --- src/macro_tools.jl | 22 ++++++++++++---------- test/runtests.jl | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/macro_tools.jl b/src/macro_tools.jl index 0ef2acb8..b89000e1 100644 --- a/src/macro_tools.jl +++ b/src/macro_tools.jl @@ -75,23 +75,25 @@ function process_args(exprs) end primary_index = length(args) รท 2 + 2 i = 3 - while args[i] === :_ && i <= lastindex(args) + while i <= lastindex(args) && args[i] === :_ args[i] = nothing i += 1 end - if i == primary_index && args[i] isa Expr && args[i].head === :tuple - map!(create_first_function, args[i].args, args[i].args) - else - args[i] = create_first_function(args[i]) - end - i += 1 - while i <= lastindex(args) + if i <= lastindex(args) if i == primary_index && args[i] isa Expr && args[i].head === :tuple - map!(create_function, args[i].args, args[i].args) + map!(create_first_function, args[i].args, args[i].args) else - args[i] = create_function(args[i]) + args[i] = create_first_function(args[i]) end i += 1 + while i <= lastindex(args) + if i == primary_index && args[i] isa Expr && args[i].head === :tuple + map!(create_function, args[i].args, args[i].args) + else + args[i] = create_function(args[i]) + end + i += 1 + end end call = exprarray(:call, args) esc(isempty(interpolations) ? call : Expr(:let, exprarray(:block, interpolations), Expr(:block, call))) diff --git a/test/runtests.jl b/test/runtests.jl index d20740de..f4a04a12 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -73,6 +73,14 @@ else @test Chairmarks.only(b.samples).evals == 1 end + @testset "process_args" begin + @test Chairmarks.process_args(()) == esc(:($(Chairmarks.benchmark)(;))) + @test Chairmarks.process_args((:(k=v),)) == esc(:($(Chairmarks.benchmark)(; k=v))) + @test Chairmarks.process_args((:(k=v), :(k=v2))) == esc(:($(Chairmarks.benchmark)(; k=v, k=v2))) + @test Chairmarks.process_args((:f,:(k=v))) == esc(:($(Chairmarks.benchmark)(f; k=v))) + @test_throws ErrorException("Positional argument after keyword argument") Chairmarks.process_args((:(k=v),:f)) + end + @testset "errors" begin @test_throws UndefKeywordError Sample(allocs=1.5, bytes=1729) # needs `time` @@ -89,6 +97,14 @@ else t = @test_throws LoadError @eval(@b seconds=1 1+1) @test t.value.error == ErrorException("Positional argument after keyword argument") + + #149 + t = @test_throws MethodError @b # no arguments + @test t.value.f === Chairmarks.benchmark + @test t.value.args === () + + t = @test_throws ErrorException @eval(@b seconds=1 seconds=2) + @test startswith(t.value.msg, "syntax: keyword argument \"seconds\" repeated in call to \"Chairmarks.benchmark\"") end @testset "time_ns() close to typemax(UInt64)" begin From d494b55142f628cdbb9090e025f5994b89088c0d Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Sun, 1 Dec 2024 11:31:54 -0600 Subject: [PATCH 2/2] loosen error message text to account for variability across Julia versions --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index f4a04a12..42c5ac9b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -104,7 +104,7 @@ else @test t.value.args === () t = @test_throws ErrorException @eval(@b seconds=1 seconds=2) - @test startswith(t.value.msg, "syntax: keyword argument \"seconds\" repeated in call to \"Chairmarks.benchmark\"") + @test startswith(t.value.msg, "syntax: keyword argument \"seconds\" repeated in call to \"") end @testset "time_ns() close to typemax(UInt64)" begin