-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Add @check
macro for non-disable-able @assert
#41342
base: master
Are you sure you want to change the base?
Conversation
12049a4
to
ac18ab0
Compare
Regarding the name, maybe |
The ArgCheck.jl package has the |
|
I thought that could be confusing since
True, it does. One difference is the outlining feature, but I'm sure that could be added to ArgCheck.jl. One reason I think it would be good to have something like this in Base is that |
I agree. I would love it if the ArgCheck package could be deprecated and Base would have that functionality instead. julia> using Test, ArgCheck
julia> x = NaN
NaN
julia> @assert isfinite(x)
ERROR: AssertionError: isfinite(x)
julia> @test isfinite(x)
Test Failed at REPL[28]:1
Expression: isfinite(x)
ERROR: There was an error during testing
julia> @check isfinite(x)
ERROR: CheckError: isfinite(x) must hold. Got
x => NaN
julia> @assert x ≈ 2
ERROR: AssertionError: x ≈ 2
julia> @test x ≈ 2
Test Failed at REPL[32]:1
Expression: x ≈ 2
Evaluated: NaN ≈ 2
ERROR: There was an error during testing
julia> @check x ≈ 2
ERROR: CheckError: x ≈ 2 must hold. Got
≈ => isapprox
x => NaN |
|
I started working on tests and realized the outlined function in my code only works if the msg you pass is a string, not an exception or even arbitrary code like |
You can take a look at ArgCheck.jl. It does outline the error generation. It only inlines the throw, which would be trivial to outline as well. @macroexpand @argcheck x > 1 DimensionMismatch
begin
#= /home/jan/.julia/packages/ArgCheck/5xEDR/src/checks.jl:239 =#
var"#1###calle#274" = (>)
var"#2###arg#272" = x
var"#3###arg#273" = 1
#= /home/jan/.julia/packages/ArgCheck/5xEDR/src/checks.jl:240 =#
if var"#1###calle#274"(var"#2###arg#272", var"#3###arg#273")
#= /home/jan/.julia/packages/ArgCheck/5xEDR/src/checks.jl:241 =#
ArgCheck.nothing
else
#= /home/jan/.julia/packages/ArgCheck/5xEDR/src/checks.jl:243 =#
ArgCheck.throw(ArgCheck.build_error(ArgCheck.CallErrorInfo($(QuoteNode(:(x > 1))), ArgCheck.ArgCheckFlavor(), $(QuoteNode(Any[:>, :x, 1])), [var"#1###calle#274", var"#2###arg#272", var"#3###arg#273"], (DimensionMismatch,))))
end
end |
base/error.jl
Outdated
msg = prepare_error(ex, msgs...) | ||
fn = gensym("audit") | ||
|
||
@eval @noinline function $(fn)() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps these should all be put into some submodule to not pollute the namespace of e.g. Base
too much?
also outline string for assert; fix name move AuditError out of boot add export
cdb3cf1
to
22a5ef9
Compare
@audit
macro for non-disable-able @assert
with outlined exceptions@check
macro for non-disable-able @assert
Ok, I removed the outlining exceptions bit because I couldn't figure out how to do it quickly (despite the nice example provided by ArgCheck.jl), but I figure that can be done in a future PR since it doesn't change the semantics. I also renamed it to |
Bump 🤞 |
It would be great to get this into 1.8. |
Bump |
Why not copy code from ArgCheck.jl which provides strictly more information and also is battle-tested? We can optimize this more later using the same logic as #41342 (comment) |
Just because this is simpler and having a nice alternative to |
Quoting your comment in Zulip
I agree with your observation. However, this PR as-is seems to make That said, I don't know enough about the principle on which the core devs operate and so I can't guess which way can be more easily accepted. |
My take here is that some package exporting a name can't be considered to block Base from exporting the same name. |
What about |
I don't see how |
It's just a different suggestion to avoid conflicts with the ecosystem 🤷 In Hypothesis (and my soon-to-be-released port of it), I'm fine with |
there's no conflict here with meaning; semantically, this PR's |
Maybe @jw3126 would be willing to upstream ArgCheck’s |
I would love to have
Because of this, I am hesitant to put work into julialang PRs. I am happy to do the work, but only if triage or some core dev states that we want it and promises that the PR either gets merged or rejected for good technical reasons. |
Why can't the answer here be to just use ArgCheck.jl? It looks great, you can get updates whenever etc. |
|
BTW, ArgCheck hasn't had any changes since June 2022, so the slow release cadence of Base actually seems totally fine at this stage of maturity. |
Twocents: I would prefer
I think doing this would also make #37874 more palpable, since some of the more recent objections are assert-related. |
I agree with that. macro logmsg(level, exs...) logmsg_code((@_sourceinfo)..., esc(level), exs...) end
macro debug(exs...) logmsg_code((@_sourceinfo)..., :Debug, exs...) end
macro info(exs...) logmsg_code((@_sourceinfo)..., :Info, exs...) end
macro warn(exs...) logmsg_code((@_sourceinfo)..., :Warn, exs...) end
macro error(exs...) logmsg_code((@_sourceinfo)..., :Error, exs...) end the macro may be in base. differents behaviors may even be handled in different module via multidispatch. |
I've found that sometimes folks use
@assert
for its simple syntax and clear error message in cases that are inappropriate for asserts (e.g. checking that data is consistent rather than program logic is consistent). I think it would be great to provide an alternative with an equally simple syntax and clear error messages that will never be disabled. At the same time, we can use the opportunity of the macro to outline the string creation to improve performance. E.g. with this PR,matches the "fast" performance of #41307 for me (~23ns, instead of ~80ns for the "slow" performance). (
I made the same tweaks tonevermind, took that out due to bootstrap issues. Which incidentally is why there's code duplication from@assert
here, so@assert
would work as well, although that would be an incorrect usage of it here@assert
andprepare_error
).I also experimented with using code from FastCaptures to outline the whole logic check + error (as suggested by @KristofferC in #29688 (comment)) in 6a6b9ac, but in the
hv_cat
example it was the same speed as not outlining at all. Perhaps I made a mistake (I am not very experienced with macros), though from@code_warntype
and@macroexpand
it looked like it was doing what I wanted.@kleinschmidt jokingly suggested the name
@audit
when I was calling it@throw_unless
and I ended up liking it so I figured I'd use it here.closes: #10614