Skip to content

Commit

Permalink
Merge pull request #11 from tkf/logprogress
Browse files Browse the repository at this point in the history
Simplify at-logprogress call signature
  • Loading branch information
pfitzseb authored Nov 5, 2019
2 parents 339eb78 + b205966 commit 0eae8c6
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 19 deletions.
47 changes: 34 additions & 13 deletions src/ProgressLogging.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module ProgressLogging

export @progress, @withprogress, @logprogress

using Base.Meta: isexpr
using Logging: Logging, @logmsg, LogLevel

const ProgressLevel = LogLevel(-1)
Expand Down Expand Up @@ -45,19 +46,21 @@ function progress(f; name = "")
end
end

const _id_name = gensym(:progress_id)
const _id_var = gensym(:progress_id)
const _name_var = gensym(:progress_name)

"""
@withprogress [name=""] ex
Create a lexical environment in which [`@logprogress`](@ref) can be used to
emit progress log events without manually specifying the log level and `_id`.
emit progress log events without manually specifying the log level, `_id`,
and name (log message).
```julia
@withprogress begin
@withprogress name="iterating" begin
for i = 1:10
sleep(0.5)
@logprogress "iterating" progress=i/10
@logprogress i/10
end
end
```
Expand All @@ -73,29 +76,47 @@ function _withprogress(kwarg, ex)
end
name = kwarg.args[2]

@gensym name_var
m = @__MODULE__
quote
let $_id_name = gensym(:progress_id),
$name_var = $name
$m.@logprogress $name_var progress = NaN
let $_id_var = gensym(:progress_id),
$_name_var = $name
$m.@logprogress NaN
try
$ex
finally
$m.@logprogress $name_var progress = "done"
$m.@logprogress "done"
end
end
end |> esc
end

"""
@logprogress name progress=value ...
@logprogress [name] progress [key1=val1 [key2=val2 ...]]
See [`@withprogress`](@ref).
This macro must be used inside [`@withprogress`](@ref) macro.
Log a progress event with a value `progress`. The expression
`progress` must be evaluated to be a real number between `0` and `1`
(inclusive), a `NaN`, or a string `"done"`.
Optional first argument `name` can be used to change the name of the
progress bar. Additional keyword arguments are passed to `@logmsg`.
"""
macro logprogress(name, args...)
macro logprogress(name, progress = nothing, args...)
if progress == nothing
# Handle: @logprogress progress
kwargs = (:(progress = $name), args...)
name = _name_var
elseif isexpr(progress, :(=)) && progress.args[1] isa Symbol
# Handle: @logprogress progress key1=val1 ...
kwargs = (:(progress = $name), progress, args...)
name = _name_var
else
# Otherwise, it's: @logprogress name progress key1=val1 ...
kwargs = (:(progress = $progress), args...)
end
quote
$Logging.@logmsg($ProgressLevel, $name, _id = $_id_name, $(args...))
$Logging.@logmsg($ProgressLevel, $name, _id = $_id_var, $(kwargs...))
end |> esc
end

Expand Down
41 changes: 35 additions & 6 deletions test/test_withprogress_macro.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,49 @@ using ProgressLogging: ProgressLevel
using Test
using Test: collect_test_logs

@testset "simple" begin
@testset "specify name in `@logprogress`" begin
logs, = collect_test_logs(min_level = ProgressLevel) do
@withprogress @logprogress "hello" progress = 0.1
@withprogress @logprogress "hello" 0.1
end
@test length(logs) == 3
@test logs[1].kwargs[:progress] === NaN
@test logs[2].kwargs[:progress] === 0.1
@test logs[3].kwargs[:progress] === "done"
@test logs[1].message === ""
@test logs[2].message === "hello"
@test logs[3].message === ""
@test length(unique([l.id for l in logs])) == 1
end

@testset "specify name in `@withprogress`" begin
logs, = collect_test_logs(min_level = ProgressLevel) do
@withprogress name = "hello" @logprogress 0.1
end
@test length(logs) == 3
@test logs[1].kwargs[:progress] === NaN
@test logs[2].kwargs[:progress] === 0.1
@test logs[3].kwargs[:progress] === "done"
@test logs[1].message === "hello"
@test logs[2].message === "hello"
@test logs[3].message === "hello"
@test length(unique([l.id for l in logs])) == 1
end

@testset "keyword argument when no name" begin
logs, = collect_test_logs(min_level = ProgressLevel) do
@withprogress @logprogress 0.1 message = "hello"
end
@test length(logs) == 3
@test logs[1].kwargs[:progress] === NaN
@test logs[2].kwargs[:progress] === 0.1
@test logs[3].kwargs[:progress] === "done"
@test logs[2].kwargs[:message] === "hello"
@test length(unique([l.id for l in logs])) == 1
end

@testset "with name" begin
@testset "change name" begin
logs, = collect_test_logs(min_level = ProgressLevel) do
@withprogress name = "name" @logprogress "hello" progress = 0.1
@withprogress name = "name" @logprogress "hello" 0.1
end
@test length(logs) == 3
@test logs[1].kwargs[:progress] === NaN
Expand All @@ -34,9 +63,9 @@ end
@testset "nested" begin
logs, = collect_test_logs(min_level = ProgressLevel) do
@withprogress begin
@logprogress "hello" progress = 0.1
@logprogress "hello" 0.1
@withprogress begin
@logprogress "world" progress = 0.2
@logprogress "world" 0.2
end
end
end
Expand Down

0 comments on commit 0eae8c6

Please sign in to comment.