- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 5.7k
          Add @check macro for non-disable-able @assert
          #41342
        
          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
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 strongly 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...) endthe macro may be in base. differents behaviors may even be handled in different module via multidispatch. | 
I've found that sometimes folks use
@assertfor 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@asserthere, so@assertwould work as well, although that would be an incorrect usage of it here@assertandprepare_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_catexample 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_warntypeand@macroexpandit looked like it was doing what I wanted.@kleinschmidt jokingly suggested the name
@auditwhen I was calling it@throw_unlessand I ended up liking it so I figured I'd use it here.closes: #10614