Suppress deprecation warnings in Julia 0.6 without using `--depwarn=no` or a package - julia

I am writing a tool in Julia that requires a package with a deprecated function.
My script is called from the command line and takes many arguments so I would like to avoid using --depwarn=no to suppress deprecation warnings.
Instead, I'd like to embed this --depwarn=no or somehow signal this into my script so the user doesn't have to type it in, or worry about it whenever they run the script.
Does anyone know how can I do this using only Base Julia without installing any another package like Suppressor.jl?

I wrote Suppressor initially, as far as I know there is no other way right now, which is why I started Suppressor.
You could always copy paste verbatim the suppress* macro you need, into your code (but I would advise just to use Suppressor honestly, in case of updates), all the Suppressor macros are self contained and require only Base (if you are on 0.6.x this macros shouldn't need Compat).
#suppress_err (latest version):
"""
#suppress_err expr
Suppress the STDERR stream for the given expression.
"""
macro suppress_err(block)
quote
if ccall(:jl_generating_output, Cint, ()) == 0
ORIGINAL_STDERR = STDERR
err_rd, err_wr = redirect_stderr()
err_reader = #async read(err_rd, String)
end
value = $(esc(block))
if ccall(:jl_generating_output, Cint, ()) == 0
redirect_stderr(ORIGINAL_STDERR)
close(err_wr)
end
value
end
end
If you just want to get rid of the deprecation warnings, then #suppress_err is all you need. There have been improvements recently on the current Julia master branch related to logging, but I haven't checked out those yet.

Related

Redirect standard output produced by a call to a C function from Julia using ccall

I am making a Julia wrapper for a C/C++ library. The C/C++ functions that I am wrapping write to standard output. Is there a way to redirect those messages from the Julia side without commenting/removing the write statements from the C/C++ code?
You can use redirect_stdout for this.
oldstd = stdout
redirect_stdout(somewhere_else)
ccall(:printf, Cint, (Cstring,), "Hello World!")
Base.Libc.flush_cstdio() # it might be necessary to flush C stdio to maintain the correct order of outputs or forcing a flush
redirect_stdout(oldstd) # recover original stdout
You may want to use redirect_stdout(f::Function, stream) method instead. Here, f should be a function taking no parameter (i.e. like () -> do_something(...)). This method automatically recovers the stream to stdout. Using do syntax;
redirect_stdout(somewhere) do
ccall(:printf, Cint, (Cstring,), "Hello World!")
Base.Libc.flush_cstdio() # might be needed
end

Parameter file in ArgParse.jl?

Python's argparse has a simple way to read parameters from a file:
https://docs.python.org/2/library/argparse.html#fromfile-prefix-chars
Instead of passing your arguments one by one:
python script.py --arg1 val1 --arg2 val2 ...
You can say:
python script.py #args.txt
and then the arguments are read from args.txt.
Is there a way to do this in ArgParse.jl?
P.S.: If there is no "default" way of doing this, maybe I can do it by hand, by calling parse_args on a list of arguments read from a file. I know how to do this in a dirty way, but it gets messy if I want to replicate the behavior of argparse in Python, where I can pass multiple files with #, as well as arguments in the command line, and then the value of a parameter is simply the last value passed to this parameter. What's the best way of doing this?
This feature is not currently present in ArgParse.jl, although it would not be difficult to add. I have prepared a pull request.
In the interim, the following code suffices for what you need:
# faithful reproduction of Python 3.5.1 argparse.py
# partial copyright Python Software Foundation
function read_args_from_files(arg_strings, prefixes)
new_arg_strings = AbstractString[]
for arg_string in arg_strings
if isempty(arg_string) || arg_string[1] ∉ prefixes
# for regular arguments, just add them back into the list
push!(new_arg_strings, arg_string)
else
# replace arguments referencing files with the file content
open(arg_string[2:end]) do args_file
arg_strings = AbstractString[]
for arg_line in readlines(args_file)
push!(arg_strings, rstrip(arg_line, '\n'))
end
arg_strings = read_args_from_files(arg_strings, prefixes)
append!(new_arg_strings, arg_strings)
end
end
end
# return the modified argument list
return new_arg_strings
end
# preprocess args, then parse as usual
ARGS = read_args_from_files(ARGS, ['#'])
args = parse_args(ARGS, s)

How to quit/exit from file included in the terminal

What can I do within a file "example.jl" to exit/return from a call to include() in the command line
julia> include("example.jl")
without existing julia itself. quit() will just terminate julia itself.
Edit: For me this would be useful while interactively developing code, for example to include a test file and return from the execution to the julia prompt when a certain condition is met or do only compile the tests I am currently working on without reorganizing the code to much.
I'm not quite sure what you're looking to do, but it sounds like you might be better off writing your code as a function, and use a return to exit. You could even call the function in the include.
Kristoffer will not love it, but
stop(text="Stop.") = throw(StopException(text))
struct StopException{T}
S::T
end
function Base.showerror(io::IO, ex::StopException, bt; backtrace=true)
Base.with_output_color(get(io, :color, false) ? :green : :nothing, io) do io
showerror(io, ex.S)
end
end
will give a nice, less alarming message than just throwing an error.
julia> stop("Stopped. Reason: Converged.")
ERROR: "Stopped. Reason: Converged."
Source: https://discourse.julialang.org/t/a-julia-equivalent-to-rs-stop/36568/12
You have a latent need for a debugging workflow in Julia. If you use Revise.jl and Rebugger.jl you can do exactly what you are asking for.
You can put in a breakpoint and step into code that is in an included file.
If you include a file from the julia prompt that you want tracked by Revise.jl, you need to use includet(.
The keyboard shortcuts in Rebugger let you iterate and inspect variables and modify code and rerun it from within an included file with real values.
Revise lets you reload functions and modules without needing to restart a julia session to pick up the changes.
https://timholy.github.io/Rebugger.jl/stable/
https://timholy.github.io/Revise.jl/stable/
The combination is very powerful and is described deeply by Tim Holy.
https://www.youtube.com/watch?v=SU0SmQnnGys
https://youtu.be/KuM0AGaN09s?t=515
Note that there are some limitations with Revise, such as it doesn't reset global variables, so if you are using some global count or something, it won't reset it for the next run through or when you go back into it. Also it isn't great with runtests.jl and the Test package. So as you develop with Revise, when you are done, you move it into your runtests.jl.
Also the Juno IDE (Atom + uber-juno package) has good support for code inspection and running line by line and the debugging has gotten some good support lately. I've used Rebugger from the julia prompt more than from the Juno IDE.
Hope that helps.
#DanielArndt is right.
It's just create a dummy function in your include file and put all the code inside (except other functions and variable declaration part that will be place before). So you can use return where you wish. The variables that only are used in the local context can stay inside dummy function. Then it's just call the new function in the end.
Suppose that the previous code is:
function func1(...)
....
end
function func2(...)
....
end
var1 = valor1
var2 = valor2
localVar = valor3
1st code part
# I want exit here!
2nd code part
Your code will look like this:
var1 = valor1
var2 = valor2
function func1(...)
....
end
function func2(...)
....
end
function dummy()
localVar = valor3
1st code part
return # it's the last running line!
2nd code part
end
dummy()
Other possibility is placing the top variables inside a function with a global prefix.
function dummy()
global var1 = valor1
global var2 = valor2
...
end
That global variables can be used inside auxiliary function (static scope) and outside in the REPL
Another variant only declares the variables and its posterior use is free
function dummy()
global var1, var2
...
end

Compiler messages in Julia

Consider the following code:
File C.jl
module C
export printLength
printLength = function(arr)
println(lentgh(arr))
end
end #module
File Main.jl
using C
main = function()
arr = Array(Int64, 4)
printLength(arr)
end
main()
Let's try to execute it.
$ julia Main.jl
ERROR: lentgh not defined
in include at /usr/bin/../lib64/julia/sys.so
in process_options at /usr/bin/../lib64/julia/sys.so
in _start at /usr/bin/../lib64/julia/sys.so
while loading /home/grzes/julia_sucks/Main.jl, in expression starting on line 8
Obviously, it doesn't compile, because lentgh is misspelled. The problem is the message I received. expression starting on line 8 is simply main(). Julia hopelessly fails to point the invalid code fragment -- it just points to the invocation of main, but the erroneous line is not even in that file! Now imagine a real project where an error hides really deep in the call stack. Julia still wouldn't tell anything more than that the problem started on the entry point of the execution. It is impossible to work like that...
Is there a way to force Julia to give a little more precise messages?
In this case it's almost certainly a consequence of inlining: your printLength function is so short, it's almost certainly inlined into the call site, which is why you get the line number 8.
Eventually, it is expected that inlining won't cause problems for backtraces. At the moment, your best bet---if you're running julia's pre-release 0.4 version---is to start julia as julia --inline=no and run your tests again.

How to alias quit() to quit?

This is just a convenience but I think useful. Note that IPython allows a pure quit as does Matlab. Thus it would be reasonble in Julia to allow aliasing.
Thanks for any ideas as to how to do this.
Quitting in Julia
If you are using Julia from the command line then ctrl-d works. But if your intention is to quit by typing a command this is not possible exactly the way you want it because typing quit in the REPL already has a meaning which is return the value associated with quit, which is the function quit.
julia> quit
quit (generic function with 1 method)
julia> typeof(quit)
Function
Also Python
But that's not rare, for example Python has similar behavior.
>>> quit
Use quit() or Ctrl-D (i.e. EOF) to exit
Using a macro
Using \q might be nice in the Julia REPL like in postgres REPL, but unfortunately \ also already has a meaning. However, if you were seeking a simple way to do this, how about a macro
julia> macro q() quit() end
julia> #q
Causes Julia to Quit
If you place the macro definition in a .juliarc.jl file, it will be available every time you run the interpreter.
As waTeim notes, when you type quit into the REPL, it simply shows the function itself… and there's no way to change this behavior. You cannot execute a function without calling it, and there are a limited number of ways to call functions in Julia's syntax.
What you can do, however, is change how the Functions are displayed. This is extremely hacky and is not guaranteed to work, but if you want this behavior badly enough, here's what you can do: hack this behavior into the display method.
julia> function Base.writemime(io::IO, ::MIME"text/plain", f::Function)
f == quit && quit()
if isgeneric(f)
n = length(f.env)
m = n==1 ? "method" : "methods"
print(io, "$(f.env.name) (generic function with $n $m)")
else
show(io, f)
end
end
Warning: Method definition writemime(IO,MIME{symbol("text/plain")},Function) in module Base at replutil.jl:5 overwritten in module Main at none:2.
writemime (generic function with 34 methods)
julia> print # other functions still display normally
print (generic function with 22 methods)
julia> quit # but when quit is displayed, it actually quits!
$
Unfortunately there's no type more specific than ::Function, so you must completely overwrite the writemime(::IO,::MIME"text/plain",::Function) definition, copying its implementation.
Also note that this is pretty unexpected and somewhat dangerous. Some library may actually end up trying to display the function quit… causing you to lose your work from that session.
Related to Quitting in Julia
I was searching for something simple. This question hasn't been updated since 2017, as I try to learn Julia now, and spend some time googling for something simple and similar to python. Here, what I found:
You can use:
exit()
Note
I use julia 1.53

Resources